I have a problem: I need to change the angular position of the element when scrolling.
As on my webpage, this is a long way with a background - and I need to animate the movement of the car along that path during scrolling.

I will explain here: http://prinzhorn.imtqy.com/skrollr-path/ is the perfect solution to meet my requirements. But, unfortunately, it is very outdated.

Maybe someone has a modern library of solutions? Or code ideas, how to animate an item via svg-path with scrolling page?

I also tried http://scrollmagic.io/examples/expert/bezier_path_animation.html - but this is not what I need, because my path more complex, and not just a couple of circles.

A source

1 answer 1

Here is some vanilla JavaScript code that moves the "car" along the way depending on how far the page has scrolled.

This should work in all modern browsers. The part of the code that you may need to customize is how we get the page height ( document.documentElement.scrollHeight ).

You may have to use different methods depending on the browsers you want to support.

 function positionCar() { var scrollY = window.scrollY || window.pageYOffset; var maxScrollY = document.documentElement.scrollHeight - window.innerHeight; var path = document.getElementById("path1"); // Calculate distance along the path the car should be for the current scroll amount var pathLen = path.getTotalLength(); var dist = pathLen * scrollY / maxScrollY; var pos = path.getPointAtLength(dist); // Calculate position a little ahead of the car (or behind if we are at the end), so we can calculate car angle if (dist + 1 <= pathLen) { var posAhead = path.getPointAtLength(dist + 1); var angle = Math.atan2(posAhead.y - pos.y, posAhead.x - pos.x); } else { var posBehind = path.getPointAtLength(dist - 1); var angle = Math.atan2(pos.y - posBehind.y, pos.x - posBehind.x); } // Position the car at "pos" totated by "angle" var car = document.getElementById("car"); car.setAttribute("transform", "translate(" + pos.x + "," + pos.y + ") rotate(" + rad2deg(angle) + ")"); } function rad2deg(rad) { return 180 * rad / Math.PI; } // Reposition car whenever there is a scroll event window.addEventListener("scroll", positionCar); // Position the car initially positionCar(); 
 body { min-height: 3000px; } svg { position: fixed; } 
 <svg width="500" height="500" viewBox="0 0 672.474 933.78125"> <g transform="translate(-54.340447,-64.21875)" id="layer1"> <path d="m 60.609153,64.432994 c 0,0 -34.345187,72.730986 64.649767,101.015256 98.99494,28.28427 321.2285,-62.62946 321.2285,-62.62946 0,0 131.31984,-52.527932 181.82746,16.16244 50.50763,68.69037 82.04198,196.41856 44.44671,284.86302 -30.25843,71.18422 -74.75128,129.29952 -189.90867,133.34013 -115.15739,4.04061 -72.73099,-153.54318 -72.73099,-153.54318 0,0 42.42641,-129.29953 135.36044,-119.198 92.93404,10.10152 -14.14213,-129.29953 -141.42135,-94.95434 -127.27922,34.34518 -183.84777,80.8122 -206.07112,121.2183 -22.22336,40.40611 -42.06243,226.23742 -26.26397,305.06607 8.77013,43.75982 58.20627,196.1403 171.72594,270.72088 73.8225,48.50019 181.82745,2.02031 181.82745,2.02031 0,0 94.95434,-12.12183 78.7919,-155.56349 -16.16244,-143.44166 -111.68403,-138.77778 -139.9683,-138.77778 -28.28427,0 83.39976,-156.18677 83.39976,-156.18677 0,0 127.27922,-189.90867 107.07617,16.16245 C 634.3758,640.21994 864.69058,888.71747 591.94939,941.2454 319.2082,993.77334 -16.162441,539.20469 153.54319,997.81395" id="path1" style="fill:none;stroke:#ff0000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"/> <path id="car" d="M-15,-10 L15,0 L -15,10 z" fill="yellow" stroke="red" stroke-width="7.06"/> </g> </svg> 

A source

  • one
    I'll take a note, it was interesting to come up with - Arthur