'How to scroll into view, a part of a svg path animation?
I have an svg animation in a react app like the one shown below :
path {
stroke-dasharray: 100;
stroke-dashoffset: 100;
animation: dash 5s linear forwards;
}
@keyframes dash {
100% {
stroke-dashoffset: 0;
}
}
<svg width="100%" height="100%" viewBox="0 0 1303 1746" fill="none" xmlns="http://www.w3.org/2000/svg"> <path
d="M495.674 19C553.546 53.1388 589.991 55.0358 663.789 59.9498C737.587 64.8637 791.945 74.6917 820.024 74.0365C848.103 73.3813 1016.94 59.9498 1016.94 59.9498C1034.02 61.1928 1045.66 66.4237 1069.86 83.5368C1083.69 96.7405 1087.74 105.547 1090.74 122.849C1090.17 139.224 1097.22 153.315 1089.3 164.781C1081.38 176.247 1042.58 186.028 1016.94 186.075L946.74 201.8H892.022H850.983L755.586 214.248H626.71L552.552 201.8H472.275L329.719 230.301L306.32 255.198L301.28 260.561L293 279.44L301.28 299.424L329.719 313.838L440.956 326.287L601.151 343.977H626.71H782.945L843.424 351.184L987.779 361.995L1108.74 372.478L1165.25 399.014C1209.07 419.059 1211.36 430.761 1178.93 452.412L1134.11 473.706L1089.3 495L957.5 592L782.945 668.5L544 683L354 718.5L231.5 787.5L177 839L293 1005.5L524.5 1019L700 1035H892.5H1075.5L1190 1060L1275.5 1132.5L1241.5 1195.5L1121 1325H1009H865L686.5 1356L564.5 1325L488 1279.5L354 1288.5L326 1325L134.5 1334L24 1418L40 1522.5L58 1588.5L267 1616.5V1481L407 1493L473 1588.5L623.5 1703.5L776.5 1720H913.5"
stroke="#403737"
strokeWidth="36"
pathLength="100"
strokeLinecap="round"
/>
</svg>
It's path is a long path (kind of like a race track) and has a very long height.
What I want to do is when I am animating the path (like water flowing in a pipe), i want scroll into view, that one end of the path which is being animated.
So how do i know how much to scroll to see that particular segment when its animating ?
How to make it dynamic so that the scroll follows that animating path.
NOTE : I want to SET THE SCROLL position based on the svg animation path and not the other way around. I DONT WANT to set the animation values based on the user's scroll position.
Solution 1:[1]
Here is a function set_dashoffset() that calculates the offset and set it on the <path>. height is the height of the entire window and window.innerHeight is the height of the visible part. The offset is a number between (100-half-innerHeight) and 0. So in the initial state the path is already half way down the visible window.
Instead of the @keyframes I use transition to make a smooth animation when setting a new offset.
var body = document.body,
html = document.documentElement;
var height = Math.max(body.scrollHeight, body.offsetHeight,
html.clientHeight, html.scrollHeight, html.offsetHeight);
var path = document.querySelector('path');
const set_dashoffset = e => {
var offset = 100 - (window.scrollY + window.innerHeight/2) / (height - window.innerHeight/2) * 100;
path.style.strokeDashoffset = offset;
};
set_dashoffset();
document.addEventListener('scroll', set_dashoffset);
path {
stroke-dasharray: 100;
stroke-dashoffset: 100;
transition: stroke-dashoffset 3s;
}
<svg width="100%" height="100%" viewBox="0 0 1303 1746" fill="none" xmlns="http://www.w3.org/2000/svg"> <path
d="M495.674 19C553.546 53.1388 589.991 55.0358 663.789 59.9498C737.587 64.8637 791.945 74.6917 820.024 74.0365C848.103 73.3813 1016.94 59.9498 1016.94 59.9498C1034.02 61.1928 1045.66 66.4237 1069.86 83.5368C1083.69 96.7405 1087.74 105.547 1090.74 122.849C1090.17 139.224 1097.22 153.315 1089.3 164.781C1081.38 176.247 1042.58 186.028 1016.94 186.075L946.74 201.8H892.022H850.983L755.586 214.248H626.71L552.552 201.8H472.275L329.719 230.301L306.32 255.198L301.28 260.561L293 279.44L301.28 299.424L329.719 313.838L440.956 326.287L601.151 343.977H626.71H782.945L843.424 351.184L987.779 361.995L1108.74 372.478L1165.25 399.014C1209.07 419.059 1211.36 430.761 1178.93 452.412L1134.11 473.706L1089.3 495L957.5 592L782.945 668.5L544 683L354 718.5L231.5 787.5L177 839L293 1005.5L524.5 1019L700 1035H892.5H1075.5L1190 1060L1275.5 1132.5L1241.5 1195.5L1121 1325H1009H865L686.5 1356L564.5 1325L488 1279.5L354 1288.5L326 1325L134.5 1334L24 1418L40 1522.5L58 1588.5L267 1616.5V1481L407 1493L473 1588.5L623.5 1703.5L776.5 1720H913.5"
stroke="#403737"
strokeWidth="36"
pathLength="100"
strokeLinecap="round"
/>
</svg>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | chrwahl |
