How to Scroll Draw Each Svg Path One at a Time (Chronologically)

How to scroll draw each SVG path one at a time (chronologically)?

How is this? You can control when each path starts and finishes drawing by setting the startPct and endPct percentage values in the scrollBehaviour array.

Note: this code assumes you are only using paths and rects. If you start using other elements, the calcPathLength() function will have to be updated.

var scrollBehaviour = [     {id: 'line1', startPct: 0, endPct: 30},     {id: 'rect1', startPct: 30, endPct: 60},     {id: 'line2', startPct: 60, endPct: 80},     {id: 'circ1', startPct: 80, endPct: 100}  ];
$(document).ready(function() {
// On a scroll event - execute function $(window).scroll(scrollEventHandler);
// Call the scroll event handler once at the start to initialise the dash offsets scrollEventHandler();
});

function scrollEventHandler(){ // Calculate how far down the page the user is var percentOfScroll = (($(window).scrollTop() / ($("html").height() - $(window).height())) * 100);
// For each lement that is getting drawn... for (var i=0; i<scrollBehaviour.length; i++) { var data = scrollBehaviour[i]; var elem = document.getElementById(data.id);
// Get the length of this elements path var dashLen = calcPathLength(elem);
// Calculate where the current scroll position falls relative to our path var fractionThroughThisElem = (percentOfScroll - data.startPct) / (data.endPct - data.startPct); // Clamp the fraction value to within this path (0 .. 1) fractionThroughThisElem = Math.max(fractionThroughThisElem, 0); fractionThroughThisElem = Math.min(fractionThroughThisElem, 1);
var dashOffset = dashLen * (1 - fractionThroughThisElem);
elem.setAttribute("stroke-dasharray", dashLen); elem.setAttribute("stroke-dashoffset", dashOffset); }}

function calcPathLength(elem){ if (elem.getTotalLength) { // It's a path return elem.getTotalLength(); } else if (elem.tagName === "rect") { // Handle rect elements: perimeter length = w + w + h + h return (elem.width.baseVal.value + elem.height.baseVal.value) * 2; } else if (elem.tagName === "circle") { // Handle circle elements: perimeter length = 2 * r * PI return elem.r.baseVal.value * 2 * Math.PI; } else if (elem.tagName === "line") { // Handle line elements: use pythagoras' theorem var dx = elem.x2.baseVal.value - elem.x1.baseVal.value; var dy = elem.y2.baseVal.value - elem.y1.baseVal.value; return Math.sqrt(dx * dx + dy * dy); } // If you use other elem types, you will have to add support for them here.}
svg {  position: fixed;  margin: auto;  top: 0;  left: 0;  right: 0;  bottom: 0;  width: 50%;}/*.line{  stroke-dashoffset:850;  stroke-dasharray: 850;}.box { stroke-dashoffset:1852; stroke-dasharray: 1852;}.all{ stroke-dashoffset:2702; stroke-dasharray: 2702;}*/
.straightLine { height: 3000px; position: relative; width: 360px; margin: 40vh auto 0 auto;
}
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<main role="article" title="line"><div class="straightLine"><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1280 1000" style="enable-background:new 0 0 1280 800;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;stroke:#000000;stroke-width:8;stroke-miterlimit:10;}
</style> <g class="all">
<path id="line1" class="st0" d="M54,178h509.6c49.9,0,90.4,40.5,90.4,90.4V428"/>
<rect id="rect1" x="498" y="428" class="st0" width="308" height="162"/>
<line id="line2" x1="652" y1="590" x2="652" y2="790" class="st0"/>
<circle id="circ1" cx="652" cy="890" r="100" class="st0"/>
</g></svg>

</div></main>

How to draw SVG curved using single path?

Use something like:

<path d="M 20 0 v 20 a 30 30 0 0 0 30 30 h 600 a 40 40 0 0 1 0 80 h -140 a 30 30 0 0 0 0 60 h 200 a 40 40 0 0 1 0 80 h -100 a 30 30 0 0 0 -30 30 v 20" />

As shown in the documentation, paths can contain an arbitrary number of components.

As a summary:

M/m    Move current position
L/l Draw a line
H/h Draw a horizontal line
V/v Draw a vertical line
C/c Draw a cubic Bezier
Q/q Draw a quadratic Bezier
A/a Draw a circular/elliptal arc
Z/z Close path

In general, uppercase instructions specify absolute coordinates and lowercase instructions specify relative.

ScrollMagic + TweenMax: Draw multiple SVG paths simultaneously?

I figured out, that I can target paths by class inside the TweenMax timeline like so:

var tween_journey = new TimelineMax();
tween_journey.to(".cls-2", 1, { strokeDashoffset: 0, ease: Linear.easeNone });

This animates/draws all paths of the given class at the same time and hence solves my problem.

Animate SVG Path on scroll

The reason it's not working is because this type of path animation works by animating the stroke of a path. Howver, the new path you have inserted has no stroke. It's:

fill="#000000" stroke="none"

If you remove the fill and give it an appropriate stroke, like this:

fill="none" stroke="#000000" stroke-width="20"

You'll get a better result.

function pathPrepare ($el) {
var lineLength = $el[0].getTotalLength();
$el.css("stroke-dasharray", lineLength);
$el.css("stroke-dashoffset", lineLength);
}

var $word = $("path#word");
var $dot = $("path#dot");

// prepare SVG
pathPrepare($word);
pathPrepare($dot);

// init controller
var controller = new ScrollMagic.Controller();

// build tween
var tween = new TimelineMax()
.add(TweenMax.to($word, 0.9, {strokeDashoffset: 0, ease:Linear.easeNone})) // draw word for 0.9
.add(TweenMax.to($dot, 0.1, {strokeDashoffset: 0, ease:Linear.easeNone})) // draw dot for 0.1
.add(TweenMax.to("path", 1, {stroke: "#33629c", ease:Linear.easeNone}), 0); // change color during the whole thing

// build scene
var scene = new ScrollMagic.Scene({triggerElement: "#trigger1", duration: 250, tweenChanges: true})
.setTween(tween)
.addIndicators() // add indicators (requires plugin)
.addTo(controller);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.5/ScrollMagic.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.5/plugins/debug.addIndicators.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.16.1/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.2/plugins/animation.gsap.js"></script>
<div style="height: 400px;"></div>
<div class="spacer s2"></div>
<div id="trigger1" class="spacer s0"></div>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="350" height="200">
<path transform="translate(0.000000,176.000000) scale(0.100000,-0.100000)"
fill="none" stroke="#000000" stroke-width="20" id="word" style="stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 1009.23px; stroke-dashoffset: 1009.23px;" fill="none" stroke="#000000" stroke-width="5" d="M689 1620 c-131 -22 -181 -107 -128 -213 30 -59 149 -171 257 -242
l91 -59 -52 -22 c-80 -32 -188 -89 -232 -121 l-40 -30 -40 18 c-46 20 -251 69
-290 69 -49 0 -85 -28 -85 -67 0 -28 63 -147 107 -200 19 -24 29 -43 22 -43
-23 0 -79 -51 -99 -90 -27 -52 -26 -119 1 -154 44 -55 117 -73 235 -57 68 10
691 176 1069 285 66 19 120 34 120 33 5 -15 70 -106 130 -182 42 -54 94 -125
117 -159 81 -121 181 -206 243 -206 74 0 126 51 149 146 29 117 28 415 0 570
-6 31 -5 31 43 38 79 10 236 70 315 119 86 53 161 129 188 190 26 56 26 146 1
196 -37 71 -117 129 -229 166 -44 14 -78 16 -185 13 -150 -6 -236 -27 -418
-104 l-105 -44 -96 19 c-138 29 -248 45 -563 86 -477 61 -446 58 -526 45z
m496 -74 c353 -46 380 -50 551 -83 l140 -26 110 45 c203 86 335 114 482 105
101 -6 179 -32 245 -82 65 -49 87 -90 87 -159 0 -152 -142 -276 -417 -365 -59
-18 -34 3 45 39 164 75 298 187 323 270 25 83 -22 169 -117 216 -50 24 -72 28
-170 32 -136 5 -205 -8 -419 -82 l-150 -52 -90 18 c-82 17 -358 55 -670 94
-66 8 -200 18 -297 21 -155 5 -180 4 -202 -11 -30 -19 -33 -44 -10 -89 32 -61
68 -99 187 -194 114 -92 167 -141 167 -154 0 -8 -250 -113 -255 -107 -3 2 41
26 96 53 56 27 104 55 106 62 7 17 -23 50 -62 70 -38 20 -182 132 -216 169
-79 85 -103 169 -60 208 62 56 177 57 596 2z m-65 -60 c267 -31 590 -77 682
-95 l97 -20 118 43 c65 24 167 56 227 71 95 24 124 27 217 23 93 -4 114 -8
165 -34 155 -77 137 -208 -46 -334 -101 -69 -326 -170 -379 -170 -38 0 -41
-20 -26 -171 18 -180 18 -301 0 -403 -29 -165 -90 -151 -238 58 -40 56 -109
140 -155 187 -45 48 -93 106 -105 130 -13 24 -31 45 -40 47 -9 2 -130 -29
-269 -68 -322 -91 -858 -238 -915 -250 -110 -25 -185 89 -107 163 13 12 24 32
24 44 0 12 -32 70 -70 129 -39 60 -70 112 -70 116 0 15 84 -4 212 -47 l127
-43 83 43 c46 24 139 66 208 95 137 57 150 65 150 89 0 21 -87 105 -205 199
-92 73 -130 113 -158 169 -21 40 -21 40 1 47 30 9 342 -3 472 -18z m-906 -530
c-3 -14 1 -38 11 -57 14 -30 14 -32 0 -14 -20 25 -29 60 -21 80 9 24 17 17 10
-9z m321 -37 c35 -17 36 -18 10 -13 -16 3 -48 14 -70 24 -35 17 -36 18 -10 13
17 -3 48 -14 70 -24z m1706 12 c-7 -12 -7 -39 -1 -77 14 -81 13 -448 0 -510
-16 -74 -42 -111 -88 -125 -79 -23 -154 32 -270 198 -80 114 -243 327 -256
334 -6 4 -56 -7 -111 -23 -55 -16 -122 -35 -150 -42 -27 -8 -216 -60 -420
-116 -440 -122 -475 -130 -574 -131 -84 -1 -106 5 -138 34 -49 44 -20 152 52
197 41 25 50 47 30 74 -48 66 -67 97 -63 102 7 6 88 -118 88 -135 0 -7 -11
-26 -25 -43 -50 -59 -22 -163 53 -195 46 -20 83 -13 422 82 129 36 242 68 250
70 8 2 15 4 15 5 0 1 10 3 23 6 13 2 143 38 289 79 146 42 267 74 268 73 1 -2
12 -21 25 -43 14 -22 59 -76 101 -121 42 -45 89 -99 104 -120 16 -21 47 -64
69 -94 106 -147 176 -190 223 -138 28 32 42 73 51 148 8 71 -1 384 -13 467 -7
51 -7 51 21 56 16 2 30 5 32 6 1 0 -2 -7 -7 -18z"></path>
<path id="dot" style="stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 44.2974px; stroke-dashoffset: 44.2974px;" fill="none" stroke="#000000" stroke-width="5" d="M247.003,38.567c-7.423,1.437-11.092,9.883-1.737,11.142c14.692,1.978,13.864-13.66,1.12-8.675"></path>
</svg>
<div class="spacer s2"></div>
<div style="height: 400px;"></div>

How to get dashed line svg animation on accordingly scroll?

This can be done by adding an SVG mask and then drawing it over the path:

var path = document.getElementById("thePath");
var mask = document.getElementById("maskPath");

var pathLength = path.getTotalLength();
var maskLength = 1050;

mask.style.strokeDashoffset = maskLength;

window.addEventListener("scroll", myFunction);

function myFunction() {
var scrollpercent = (document.body.scrollTop + document.documentElement.scrollTop) / (document.documentElement.scrollHeight - document.documentElement.clientHeight);

var draw = pathLength * scrollpercent;

mask.style.strokeDashoffset = maskLength - draw;
}
<h1>Scroll down</h1>
<svg width="198px" height="1458px" viewBox="0 0 198 1458">
<defs>
<linearGradient x1="50%" y1="7.06935325%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#DE1652" offset="0%"></stop>
<stop stop-color="#F37121" offset="50.2239948%"></stop>
<stop stop-color="#FBAB26" offset="100%"></stop>
</linearGradient>
<mask id="theMask" maskUnits="userSpaceOnUse">
<path id="maskPath"
d="M702,266 C682,424 795.064639,474.307498 716,600 C599,786 769,821 688,988 C548.560405,1275.48657 822.815807,1223 840.843207,1373 C858.870608,1523 605.485477,1528 687.610302,1728"
fill="none"
fill-rule="evenodd"
stroke-dasharray="1637"
stroke-dashoffset="1050"
transform="translate(-646.000000, -825.000000)"
stroke-width="4"
stroke="#fff"/>
</mask>
</defs>
<g id="content" mask="url(#theMask)">
<path id="thePath"
d="M702,266 C682,424 795.064639,474.307498 716,600 C599,786 769,821 688,988 C548.560405,1275.48657 822.815807,1223 840.843207,1373 C858.870608,1523 605.485477,1528 687.610302,1728"
fill="none"
fill-rule="evenodd"
stroke-dasharray="12,16"
transform="translate(-646.000000, -825.000000)"
stroke-width="4"
stroke="url(#linearGradient-1)"
></path>
</g>
</svg>


Related Topics



Leave a reply



Submit