HTML
<div id="project-sections-wrap">
<svg version="1.1" id="scrolling-line" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1 727.7" style="enable-background:new 0 0 1 727.7;" xml:space="preserve">
<style type="text/css">
.scrolling-line{fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:10;vector-effect: non-scaling-stroke;}
</style>
<line class="scrolling-line" x1="0.5" y1="0" x2="0.5" y2="727.7"/>
</svg>
</div>
CSS
#project-sections-wrap{
height: 5000px;
position: relative;
background: linear-gradient(to top, rgba(255,110, 88,1) 0%, rgba(255,255, 88,1) 33%, rgba(189, 92,243,1) 66%, rgba( 84,246,133,1) 100%);
}
#scrolling-line {
position: absolute;
right: calc(50% - 2px);
height: 100% !important;
top: 0;
}
JAVASCRIPT
// Get a reference to the <path>
var path = document.querySelector('.scrolling-line');
// Get length of path... ~577px in this case
var pathLength = 5000;
// Make very long dashes (the length of the path itself)
path.style.strokeDasharray = pathLength + ' ' + pathLength;
// Offset the dashes so the it appears hidden entirely
path.style.strokeDashoffset = pathLength;
// Jake Archibald says so
// https://jakearchibald.com/2013/animated-line-drawing-svg/
path.getBoundingClientRect();
// When the page scrolls...
window.addEventListener("scroll", function(e) {
// What % down is it?
// https://stackoverflow.com/questions/2387136/cross-browser-method-to-determine-vertical-scroll-percentage-in-javascript/2387222#2387222
// Had to try three or four differnet methods here. Kind of a cross-browser nightmare.
var scrollPercentage = (document.documentElement.scrollTop + document.body.scrollTop) / (document.documentElement.scrollHeight - document.documentElement.clientHeight);
// Length to offset the dashes
var drawLength = pathLength * scrollPercentage;
// Draw in reverse
path.style.strokeDashoffset = pathLength - drawLength;
// When complete, remove the dash array, otherwise shape isn't quite sharp
// Accounts for fuzzy math
if (scrollPercentage >= 0.99) {
path.style.strokeDasharray = "none";
} else {
path.style.strokeDasharray = pathLength + ' ' + pathLength;
}
});