Scroll Drawing

Avatar of Chris Coyier
Chris Coyier on (Updated on )

We’ve taken an in-depth look at how SVG line drawing works before. It’s a clever trick where you use dashed lines for the stroke, but the gap in the dash is so long it covers the entire path. Then you can move it such that it covers the entire path again, which makes it appear as if it’s drawing itself.

Using a bit of JavaScript, we can get a little fancier, drawing the shape to completion as page is scrolled to the bottom.

Demo

See the Pen Scroll Drawing by Chris Coyier (@chriscoyier) on CodePen.

Step 1: Get a <path>

It has to be a <path>. Any other kind of SVG element won’t work (e.g. <rect>). You can force elements to be paths though. I have a Lodge video on this. You may need to resort to trickery like adding an additional vector point along an already straight edge.

In my demo here, I just copy-and-pasted the shape right out of Illustrator.

Give the path an ID if it doesn’t have one:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100.6 107.6" id="star-svg">
  <path id="star-path" fill="none" stroke="black" stroke-width="2"  d=" ... " />
</svg>

Step 2: Find length of that path

// Get a reference to the <path>
var path = document.querySelector('#star-path');

// Get length of path... ~577px in this demo
var pathLength = path.getTotalLength();

Step 3: Hide shape by offsetting dash

// 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;

Step 4: When page scrolls, offset dash same amount as % scrolled

// When the page scrolls...
window.addEventListener("scroll", function(e) {
 
  // What % down is it? 
  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;
  
});

Step 5: If scrolled to bottom, remove dashing

If you don’t do this, the shape doesn’t look quite as neatly/sharply finished as if you didn’t applying any dashing at all.

I’m not sure why. I don’t think you can fiddle with the numbers to fix it. But it’s easy enough to remove.

  // ... at bottom of scrolling function

  // When complete, remove the dash array, otherwise shape isn't quite sharp
  if (scrollPercentage >= 0.99) {
    path.style.strokeDasharray = "none";
  } else {
    path.style.strokeDasharray = pathLength + ' ' + pathLength;
  }

The 0.99 is to account for fuzzy math. Sometimes you don’t get a perfect 1.0 from the division.


See a full page demo.