简体   繁体   中英

Animated line with a SVG

The following code snippet animates an SVG element on scroll. I'm trying to replace the SVG in the example with my own SVG.

original code

 $(document).ready(function(){ $(window).scroll(function() { drawLine( $('#route'), document.getElementById('path') ); }); // init the line length drawLine( $('#route'), document.getElementById('path') ); //draw the line function drawLine(container, line){ var pathLength = line.getTotalLength(), maxScrollTop = $(document).height() - $(window).height(), percentDone = $(window).scrollTop() / maxScrollTop, length = percentDone * pathLength; line.style.strokeDasharray = [ length ,pathLength].join(' '); } }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <svg id="route" xmlns="http://www.w3.org/2000/svg" version="1.1" width="294" height="7293" viewBox="0 0 294.152 7293.492"> <path id="path" fill="none" stroke="#D1232A" stroke-width="3" stroke-linecap="round" d="M157.656 7.212c0 0 100.344 178.906 100.344 321.913 0 271.418-220.792 286.061-220.792 407.951 0 121.889 240.638 175.278 240.638 249.546 0 57.827-52.157 57.26-55.559 127.03 -3.892 79.807 13.039 89.348 12.094 158.324 -0.944 68.977-77.071 136.497-115.275 179.528 -36.022 40.573-93.084 86.74-108.851 132.131 -13.381 38.524-19.24 132.253 67.276 164.471 86.516 32.217 178.575 58.708 207.387 133.319 28.812 74.611-41.038 146.05-92.111 183.308 -51.074 37.257-164.657 113.385-145.163 169.133 19.493 55.748 150.832 34.69 150.832 134.983s49.134 71.002 49.134 135.254 -36.851 200.126-36.851 247.37c0 47.243 50.41 99.401 50.41 172.157 0 72.756-45.686 154.016-45.686 235.275 0 114.331 22.678 205.04 23.622 280.63 1.469 117.537-190.866 112.442-190.866 222.048 0.945 113.385 182.567 178.233 187.958 295.748 13.138 286.299-153.376 635.527-186.667 782.361 -22.621 99.773-19.622 232.261 101.765 229.205 45.046-1.134 78.928-36.449 81.196-76.231 2.034-35.705-34.017-76.437-89.575-66.8 -59.712 10.357-91.345 60.498-106.016 136.087 -7.235 37.278-11.828 98.358-12.739 160.63 -2.394 163.629 76.938 201.007 105.149 220.85 14.682 10.326 106.274 49.377 103.748 94.15 -3.969 70.318-200.126 101.541-196.725 159.904 3.402 58.363 73.126 72.615 65.764 149.072 -7.37 76.535-80.933 101.479-80.933 180.85 0 121.324 78.098 200.126 71.295 283.465 -6.422 78.672-56.126 159.184-38.551 227.904 21.565 84.326 197.38 62.931 192.756 153.072 -3.386 65.994-171.22 82.799-212.599 141.732 -37.417 53.291-1.928 159.781 22.678 235.275 24.944 76.535 89.368 238.621 111.541 297.914"/> </svg> 

my SVG

<?xml version="1.0" encoding="UTF-8"?>
<svg width="100%" height="100%" viewBox="0 0 1160 12974" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch -->
    <title>Slice 1</title>
    <desc>Created with Sketch.</desc>
    <defs></defs>
    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <path d="M5.9,12973 C8.7,12973 10.9,12970.7 10.9,12968 L10.9,12129.4 L1150,12129.4 C1152.8,12129.4 1155,12127.2 1155,12124.4 L1155,10233 C1155,10230.2 1152.8,10228 1150,10228 L34,10228 L34,8520 L1088.3,8520 C1091.1,8520 1093.3,8517.8 1093.3,8515 L1093.3,6735.3 C1093.3,6732.5 1091.1,6730.3 1088.3,6730.3 L34,6730.3 L34,4887.5 L1153.9,4887.5 C1156.7,4887.5 1158.9,4885.3 1158.9,4882.5 L1158.9,3110.5 C1158.9,3107.7 1156.7,3105.5 1153.9,3105.5 L37.9,3105.5 L37.9,1459.1 L537.4,1459.1 C540.2,1459.1 542.4,1456.9 542.4,1454.1 L542.4,5.7 C542.4,2.9 540.2,0.7 537.4,0.7 C534.6,0.7 532.4,2.9 532.4,5.7 L532.4,1449.1 L32.8,1449.1 C30,1449.1 27.8,1451.3 27.8,1454.1 L27.8,3110.5 C27.8,3113.3 30,3115.5 32.8,3115.5 L1148.8,3115.5 L1148.8,4877.5 L29,4877.5 C26.2,4877.5 24,4879.7 24,4882.5 L24,6735.3 C24,6738.1 26.2,6740.3 29,6740.3 L1083.3,6740.3 L1083.3,8510 L29,8510 C26.2,8510 24,8512.2 24,8515 L24,10233 C24,10235.8 26.2,10238 29,10238 L1145,10238 L1145,12119.4 L5.9,12119.4 C3.1,12119.4 0.9,12121.6 0.9,12124.4 L0.9,12968" id="path" stroke="#979797" fill="#C51586" fill-rule="nonzero"></path>
    </g>
</svg>

This is my attempt at replacing the SVG:

code with my SVG

 $(document).ready(function(){ $(window).scroll(function() { drawLine( $('#route'), document.getElementById('path') ); }); // init the line length drawLine( $('#route'), document.getElementById('path') ); //draw the line function drawLine(container, line){ var pathLength = line.getTotalLength(), maxScrollTop = $(document).height() - $(window).height(), percentDone = $(window).scrollTop() / maxScrollTop, length = percentDone * pathLength; line.style.strokeDasharray = [ length ,pathLength].join(' '); } }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <svg width="100%" height="100%" viewBox="0 0 1160 12974" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="route"> <path d="M5.9,12973 C8.7,12973 10.9,12970.7 10.9,12968 L10.9,12129.4 L1150,12129.4 C1152.8,12129.4 1155,12127.2 1155,12124.4 L1155,10233 C1155,10230.2 1152.8,10228 1150,10228 L34,10228 L34,8520 L1088.3,8520 C1091.1,8520 1093.3,8517.8 1093.3,8515 L1093.3,6735.3 C1093.3,6732.5 1091.1,6730.3 1088.3,6730.3 L34,6730.3 L34,4887.5 L1153.9,4887.5 C1156.7,4887.5 1158.9,4885.3 1158.9,4882.5 L1158.9,3110.5 C1158.9,3107.7 1156.7,3105.5 1153.9,3105.5 L37.9,3105.5 L37.9,1459.1 L537.4,1459.1 C540.2,1459.1 542.4,1456.9 542.4,1454.1 L542.4,5.7 C542.4,2.9 540.2,0.7 537.4,0.7 C534.6,0.7 532.4,2.9 532.4,5.7 L532.4,1449.1 L32.8,1449.1 C30,1449.1 27.8,1451.3 27.8,1454.1 L27.8,3110.5 C27.8,3113.3 30,3115.5 32.8,3115.5 L1148.8,3115.5 L1148.8,4877.5 L29,4877.5 C26.2,4877.5 24,4879.7 24,4882.5 L24,6735.3 C24,6738.1 26.2,6740.3 29,6740.3 L1083.3,6740.3 L1083.3,8510 L29,8510 C26.2,8510 24,8512.2 24,8515 L24,10233 C24,10235.8 26.2,10238 29,10238 L1145,10238 L1145,12119.4 L5.9,12119.4 C3.1,12119.4 0.9,12121.6 0.9,12124.4 L0.9,12968" id="path" stroke="#D1232A" stroke-width="3" fill="none"></path> </svg> 

As you can see, something didn't work quite right. I really struggle to understand why. It seems that my SVG is reversed, so I reversed it back on Sketch but it doesn't change anything (also tried with Inkscape).

I'm very new to SVGs so forgive me if the answer is obvious!

Thanks!

Its the order in which your points were added. Lets simplify your line to something that just goes top to bottom and you see everything is working correctly:

 $(document).ready(function(){ $(window).scroll(function() { drawLine( $('#route'), document.getElementById('path') ); }); // init the line length drawLine( $('#route'), document.getElementById('path') ); //draw the line function drawLine(container, line){ var pathLength = line.getTotalLength(), maxScrollTop = $(document).height() - $(window).height(), percentDone = $(window).scrollTop() / maxScrollTop, length = percentDone * pathLength; line.style.strokeDasharray = [ length ,pathLength].join(' '); } }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <svg width="100%" height="100%" viewBox="0 0 1160 12974" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="route"> <path d="M100, 0 L 100,12974" id="path" stroke="#D1232A" stroke-width="3" fill="none"></path> </svg> 

Now lets try recreating your line sort-of:

 $(document).ready(function(){ $(window).scroll(function() { drawLine( $('#route'), document.getElementById('path') ); }); // init the line length drawLine( $('#route'), document.getElementById('path') ); //draw the line function drawLine(container, line){ var pathLength = line.getTotalLength(), maxScrollTop = $(document).height() - $(window).height(), percentDone = $(window).scrollTop() / maxScrollTop, length = percentDone * pathLength; line.style.strokeDasharray = [ length ,pathLength].join(' '); } }); 
 svg { margin-top: 100vh } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <svg width="100%" height="100%" viewBox="0 0 1160 11600" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="route"> <path d=" M 10, 0 h 1140 v 1160 h -1140 v 1160 h 1140 v 1160 h -1140 v 1160 h 1140 v 1160 h -1140 v 1160 h 1140 v 1160 h -1140 v 1160 h 1140 v 1160 h -1140 v 1160" id="path" stroke="#D1232A" stroke-width="3" fill="none"></path> </svg> 

This has to do with how paths are created, have a look here for docs: https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths

What I did is use the h to move horizontal and v to move vertical (lowercase to make it relative to the last point) to recreate your path. When making these paths, make sure to add the first points first and continue going from there or it will not achieve the right effect. Order is important!

Another issue with this path, though, is that its length does not represent your scroll distance one-to-one, so depending on your screen size, the path might not be visible at all. These are all limitations when using the stroke-dasharray to recreate a path filling in. I moved your svg 100vh down to be able to see the line consistently.

your second (own) svg has no id="route". I've checked it with a online viewer. Your own svg isn't filled and the path is not closed I guess.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM