JSFiddle - React, Tailwind, and code Playground
by Jordan Sayner
HTML
<svg width="200" height="1000" xmlns="http://www.w3.org/2000/svg" style="position: fixed; left: 50%; transform: translateX(-50%);">
<!-- Wiggly vertical path -->
<path id="wigglyPath"
d="M100,0 Q120,50 100,100 Q80,150 100,200 Q120,250 100,300 Q80,350 100,400 Q120,450 100,500 Q80,550 100,600 Q120,650 100,700"
fill="transparent"
stroke="black"
stroke-width="2"
stroke-dasharray="2000"
stroke-dashoffset="2000">
</path>
<!-- Text following the path -->
<text font-size="20" fill="black">
<textPath href="#wigglyPath" startOffset="0%">
Follow the wiggly line!
</textPath>
</text>
</svg>
CSS
body {
height: 2000px; /* Make the page scrollable */
margin: 0;
}
path {
stroke-dasharray: 2000; /* Ensure this matches the path length */
stroke-dashoffset: 2000; /* Hide the stroke initially */
transition: stroke-dashoffset 0.2s ease-out;
}
JavaScript
document.addEventListener("scroll", () => {
const path = document.querySelector("#wigglyPath");
const textPath = document.querySelector("textPath");
// Get the bounding rect and calculate the scroll progress
const pathBounding = path.getBoundingClientRect();
const viewportHeight = window.innerHeight;
const progress = Math.min(
1,
Math.max(0, (viewportHeight - pathBounding.top) / (viewportHeight + pathBounding.height))
);
// Animate the line appearance
const pathLength = path.getTotalLength();
path.style.strokeDashoffset = pathLength * (1 - progress);
// Move the text along the path
textPath.setAttribute("startOffset", `${progress * 100}%`);
});