Draw SVG dashed line on scroll? [closed]

2019-09-27 14:27发布

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?

1条回答
虎瘦雄心在
2楼-- · 2019-09-27 15:13

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>

查看更多
登录 后发表回答