在滚动中绘制SVG虚线?[英] Draw SVG dashed line on scroll?

本文是小编为大家收集整理的关于在滚动中绘制SVG虚线?的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

本文来自:IT宝库(https://www.itbaoku.cn)

我想在滚动上绘制一条SVG虚线,并在4小时内被卡住.

如果这只是一条直线,我可以通过在CSS动画上设置stroke-dasharray来轻松对其进行动画,但它在虚线上不起作用.

由于身体上有背景图像,所以我也不能使用蒙版技巧.

我只想在滚动上绘制一个简单的45度对角线(约100px).

有建议吗?

推荐答案

在下一个示例中,我正在使用车轮事件,但是您可以使用滚动.我在作弊.我正在通过要动画的路径画一条虚线的路径.您会看到通过空白的动画路径.我希望它有帮助.

var svg = document.querySelector("svg");
var l = track.getTotalLength();
var dasharray = l;
var dashoffset = l;
theUse.style.strokeDasharray = dasharray;
theUse.style.strokeDashoffset = dashoffset;

document.addEventListener("wheel",

  function(e) {

    e.preventDefault();
    if (dashoffset > 0 && e.deltaY > 0 || 
        dashoffset < l && e.deltaY < 0) {
        dashoffset -= e.deltaY;
    }
   if(dashoffset < 0)dashoffset = 0;
   if(dashoffset > l)dashoffset = l;
    
    theUse.style.strokeDashoffset = dashoffset;
  }, false);
svg{border:1px solid}
<svg id="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 -23 238 120">
<defs>
<path id="track" fill="none"  d="M18.265,6.037c0,0,22.354-2.458,32.585,2.709c13.401,6.768,22.928,25.006,33.864,30.677c10.935,5.67,11.901,9.014,21.216,8.608c10.013-0.435,11.08-5.485,14.862-5.485
	c9.801,0,25.631,24.662,36.168,24.115c14.971-0.777,9.135-0.936,22.096-0.531c12.959,0.406,29.501,7.144,41.247,4.309"/>
 </defs>
 <use xlink:href="#track" id="theUse" stroke="black" />
 <use xlink:href="#track" stroke-dasharray="10 10" stroke="white" stroke-width="2" />

更新

有人评论:

我们应该看到的..因为运行摘要时我什么都看不到

移动鼠标的轮子时,您应该看到这样的东西:

移动鼠标的轮子时,您应该看到这样的东西:

更新2

我再次更新作为另一个评论的答案:

好吧,我没有轮子,但是为什么不考虑问题

中所述的滚动

接下来是一个演示,我正在使用滚动事件:

var l = thePath.getTotalLength();
var dasharray = l;
track.style.strokeDasharray = dasharray;
var dashoffset = l;
track.style.strokeDashoffset = dashoffset;
wrap.addEventListener("scroll", function() {
  // - 10 is because I want to offset slightly the dashoffse
  dashoffset =
    -10 + l - this.scrollTop * l / (this.scrollHeight - this.clientHeight);
  
    track.style.strokeDashoffset = dashoffset;
});
#wrap,svg{border:1px solid}
#wrap{height:200px; overflow:scroll}
use{fill:none}
<div id="wrap">
<svg id="svg"
	 width="100" viewBox="0 0 78.571 753.021" >
  
  <defs>
    <path id="thePath" d="M46.249,7c0,0-37.5,0-37.5,32.812s20.312,56.25,37.5,75
	s23.881,51.525,6.25,73.438c-31.43,39.062,21.875,43.882,18.75,70.378s-35.938,63.997-45.312,90.559s17.08,37.5,23.438,81.25
	s-23.438,75-18.75,118.75s45.312,75,26.562,103.125s-51.812,83.438-50.125,100"/>
  </defs>
 <use xlink:href="#thePath" id="track" stroke="black" />
 <use xlink:href="#thePath" stroke-dasharray="10 10" stroke="white" stroke-width="2" /> 
</svg>
</div>

更新num 3

收到另一个评论:

您应该使用掩码代替白色路径来隐藏虚线的路径,以便除了破折号以外的其他所有路径都保持透明.喜欢这里: Animate Animate svg svg line

受此答案的启发动画dashed svg line 白色路径.

var l = thePath.getTotalLength();
var dasharray = l;
mask.style.strokeDasharray = dasharray;
var dashoffset = l;
mask.style.strokeDashoffset = dashoffset;
wrap.addEventListener("scroll", function() {

  dashoffset =
    l - this.scrollTop * l / (this.scrollHeight - this.clientHeight);
  
    mask.style.strokeDashoffset = dashoffset;
});
#wrap,svg{border:1px solid}
#wrap{height:200px; overflow:scroll}
use{fill:none;}
path{stroke-width:3px;}
#mask{stroke:white}
<div id="wrap">
<svg id="svg"
	 width="100" viewBox="0 0 78.571 753.021" >
  
  <defs>
    <path id="thePath" d="M46.249,7c0,0-37.5,0-37.5,32.812s20.312,56.25,37.5,75
	s23.881,51.525,6.25,73.438c-31.43,39.062,21.875,43.882,18.75,70.378s-35.938,63.997-45.312,90.559s17.08,37.5,23.438,81.25
	s-23.438,75-18.75,118.75s45.312,75,26.562,103.125s-51.812,83.438-50.125,100"/>
    
<mask id="mask1">
  <use id="mask" xlink:href="#thePath" />
</mask>
    
  </defs>
 <use xlink:href="#thePath" stroke-dasharray="10 10" stroke="black"  mask="url(#mask1)" /> 
  
</svg>
</div>

本文地址:https://www.itbaoku.cn/post/1552451/Draw-SVG-dashed-line-on-scroll

问题描述

I want to have a svg dashed line drawn on scroll and got stuck on this for 4hrs.

If it's just a straight line, I can easily animate it by setting stroke-dasharray on css animation, but it doesn't work on a dashed line.

Since there's a background image on body, I cannot use a mask trick either.

I just want to have a simple 45 degree diagonal dashed line (about 100px) drawn on scroll.

Any advice?

推荐答案

In the next example I'm using the wheel event but you can use scroll instead. And I'm cheating. I'm drawing a dashed path over the path I want to animate. You'll see the animated path through the gaps. I hope it helps.

var svg = document.querySelector("svg");
var l = track.getTotalLength();
var dasharray = l;
var dashoffset = l;
theUse.style.strokeDasharray = dasharray;
theUse.style.strokeDashoffset = dashoffset;

document.addEventListener("wheel",

  function(e) {

    e.preventDefault();
    if (dashoffset > 0 && e.deltaY > 0 || 
        dashoffset < l && e.deltaY < 0) {
        dashoffset -= e.deltaY;
    }
   if(dashoffset < 0)dashoffset = 0;
   if(dashoffset > l)dashoffset = l;
    
    theUse.style.strokeDashoffset = dashoffset;
  }, false);
svg{border:1px solid}
<svg id="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 -23 238 120">
<defs>
<path id="track" fill="none"  d="M18.265,6.037c0,0,22.354-2.458,32.585,2.709c13.401,6.768,22.928,25.006,33.864,30.677c10.935,5.67,11.901,9.014,21.216,8.608c10.013-0.435,11.08-5.485,14.862-5.485
	c9.801,0,25.631,24.662,36.168,24.115c14.971-0.777,9.135-0.936,22.096-0.531c12.959,0.406,29.501,7.144,41.247,4.309"/>
 </defs>
 <use xlink:href="#track" id="theUse" stroke="black" />
 <use xlink:href="#track" stroke-dasharray="10 10" stroke="white" stroke-width="2" />

UPDATE

Someone commented:

what we are supposed to see .. because I see nothing when running the snippet

When moving the wheel of your mouse you should see something like this:

When moving the wheel of your mouse you should see something like this:

UPDATE 2

I'm updating again as an answer to another comment:

ok I don't have a wheel, but why not considering the scroll as stated in the question

Next comes a demo where I'm using the scroll event:

var l = thePath.getTotalLength();
var dasharray = l;
track.style.strokeDasharray = dasharray;
var dashoffset = l;
track.style.strokeDashoffset = dashoffset;
wrap.addEventListener("scroll", function() {
  // - 10 is because I want to offset slightly the dashoffse
  dashoffset =
    -10 + l - this.scrollTop * l / (this.scrollHeight - this.clientHeight);
  
    track.style.strokeDashoffset = dashoffset;
});
#wrap,svg{border:1px solid}
#wrap{height:200px; overflow:scroll}
use{fill:none}
<div id="wrap">
<svg id="svg"
	 width="100" viewBox="0 0 78.571 753.021" >
  
  <defs>
    <path id="thePath" d="M46.249,7c0,0-37.5,0-37.5,32.812s20.312,56.25,37.5,75
	s23.881,51.525,6.25,73.438c-31.43,39.062,21.875,43.882,18.75,70.378s-35.938,63.997-45.312,90.559s17.08,37.5,23.438,81.25
	s-23.438,75-18.75,118.75s45.312,75,26.562,103.125s-51.812,83.438-50.125,100"/>
  </defs>
 <use xlink:href="#thePath" id="track" stroke="black" />
 <use xlink:href="#thePath" stroke-dasharray="10 10" stroke="white" stroke-width="2" /> 
</svg>
</div>

UPDATE num 3

Got another comment:

You should use a mask instead of a white path for hiding the dashed path, so that everything but the dashes remains transparent. Like here: Animate dashed SVG line

Inspired by this answer Animate dashed SVG line I'm using a mask instead of a white path.

var l = thePath.getTotalLength();
var dasharray = l;
mask.style.strokeDasharray = dasharray;
var dashoffset = l;
mask.style.strokeDashoffset = dashoffset;
wrap.addEventListener("scroll", function() {

  dashoffset =
    l - this.scrollTop * l / (this.scrollHeight - this.clientHeight);
  
    mask.style.strokeDashoffset = dashoffset;
});
#wrap,svg{border:1px solid}
#wrap{height:200px; overflow:scroll}
use{fill:none;}
path{stroke-width:3px;}
#mask{stroke:white}
<div id="wrap">
<svg id="svg"
	 width="100" viewBox="0 0 78.571 753.021" >
  
  <defs>
    <path id="thePath" d="M46.249,7c0,0-37.5,0-37.5,32.812s20.312,56.25,37.5,75
	s23.881,51.525,6.25,73.438c-31.43,39.062,21.875,43.882,18.75,70.378s-35.938,63.997-45.312,90.559s17.08,37.5,23.438,81.25
	s-23.438,75-18.75,118.75s45.312,75,26.562,103.125s-51.812,83.438-50.125,100"/>
    
<mask id="mask1">
  <use id="mask" xlink:href="#thePath" />
</mask>
    
  </defs>
 <use xlink:href="#thePath" stroke-dasharray="10 10" stroke="black"  mask="url(#mask1)" /> 
  
</svg>
</div>