Comment faire pour déplacer dessiner chaque chemin SVG une à la fois (chronologiquement)?

Ceci est lié à une publication précédente ici . Cependant, je pense que c'était une tâche formidable. Donc, je le décompose en petits morceaux.

J'ai créé une image SVG simple qui comprend un "chemin" et un élément "rect". L'utilisateur peut dessiner les lignes sur et hors de la fenêtre en faisant défiler vers le haut et vers le bas de la page (faites défiler la page pour la page et la page pour désactiver / désactiver). Cependant, les deux éléments "dessinent" / animent en même temps. Ce que je veux faire, c'est que l'utilisateur défile vers le bas de la page, le chemin de ligne s'inspire, puis l'élément "rect" dessine (après), donc il est plus fluide et chronologique.

<!doctype html> <html> <head> <meta charset="UTF-8"> <title>the single line</title> <link rel="stylesheet" type="text/css" href="line.css"> <style> 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; } </style> </head> <body> <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 800" 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 class="st0" d="M54,178h509.6c49.9,0,90.4,40.5,90.4,90.4V428"/> <rect x="498" y="428" class="st0" width="308" height="162"/> </g> </svg> </div> </main> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> <script src="line.js"></script> <script> $(document).ready(function() { //variable for the 'stroke-dashoffset' unit var $dashOffset = $(".all").css("stroke-dashoffset"); //on a scroll event - execute function $(window).scroll(function() { //calculate how far down the page the user is var $percentageComplete = (($(window).scrollTop() / ($("html").height() - $(window).height())) * 100); //convert dashoffset pixel value to interger var $newUnit = parseInt($dashOffset, 10); //get the value to be subtracted from the 'stroke-dashoffset' var $offsetUnit = $percentageComplete * ($newUnit / 100); //set the new value of the dashoffset to create the drawing effect $(".all").css("stroke-dashoffset", $newUnit - $offsetUnit); }); }); </script> </body> </html> 

Comment est-ce? Vous pouvez contrôler quand chaque chemin commence et finit de dessiner en définissant les valeurs de pourcentage startPct et endPct dans le tableau scrollBehaviour .

Remarque: ce code suppose que vous n'utilisez que les chemins et les récits. Si vous commencez à utiliser d'autres éléments, la fonction calcPathLength() devra être mise à jour.

 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>