How to start svg scroll animation on specific part of page

447 views Asked by At

I have a simple svg animation that happens on scroll. But how can I get the animation to start further down the page?

Now it starts right when I start scrolling.

// Get the id of the <path> element and the length of <path>
var triangle = document.getElementById("triangle");
var length = triangle.getTotalLength();

// The start position of the drawing
triangle.style.strokeDasharray = length;

// Hide the triangle by offsetting dash. Remove this line to show the triangle before scroll draw
triangle.style.strokeDashoffset = length;

// Find scroll percentage on scroll (using cross-browser properties), and offset dash same amount as percentage scrolled
window.addEventListener("scroll", myFunction);

function myFunction() {
var scrollpercent = (document.body.scrollTop + document.documentElement.scrollTop) / (document.documentElement.scrollHeight - document.documentElement.clientHeight);

  var draw = length * scrollpercent;
  
  // Reverse the drawing (when scrolling upwards)
  triangle.style.strokeDashoffset = length - draw;
}
<h2>Scroll down this window to draw a triangle.</h2>
<p>Scroll back up to reverse the drawing.</p>

<svg id="mySVG">
  <path fill="none" stroke="red" stroke-width="3" id="triangle" d="M150 0 L75 200 L225 200 Z" />
  Sorry, your browser does not support inline SVG.
</svg>

1

There are 1 answers

0
Paul LeBeau On

Decide which portion of the scroll you want the animation to happen within. Then map that to your actual animation percentage.

For example, say you want the animation to happen in the range 50% scroll to 90% scroll. Then you need to map the range (0.5->0.9) to (0.0->1.0).

  • So any input value <= 0.5 maps to output value of 0.
  • And any input value >= 0.9 maps to 1.
  • Values in between are scaled proportionately between 0 and 1.

See the mapRange() function in the following example for the code for this mapping.

// Get the id of the <path> element and the length of <path>
var triangle = document.getElementById("triangle");
var length = triangle.getTotalLength();

// The start position of the drawing
triangle.style.strokeDasharray = length;

// Hide the triangle by offsetting dash. Remove this line to show the triangle before scroll draw
triangle.style.strokeDashoffset = length;

// Find scroll percentage on scroll (using cross-browser properties), and offset dash same amount as percentage scrolled
window.addEventListener("scroll", myFunction);

function myFunction() {
  var scrollpercent = (document.body.scrollTop + document.documentElement.scrollTop) / (document.documentElement.scrollHeight - document.documentElement.clientHeight);

  var draw = length * mapRange(scrollpercent, 0.5, 0.9, 0, 1);
  
  // Reverse the drawing (when scrolling upwards)
  triangle.style.strokeDashoffset = length - draw;
}

// Maps n from the range (fromStart->fromEnd) to the range (toStart->toEnd).
function mapRange(n, fromStart, fromEnd, toStart, toEnd) {
  const out = toStart + (n - fromStart) * ((toEnd - toStart) / (fromEnd - fromStart));
  // Exclude any values outside to toStart->toEnd range
  return Math.min(toEnd, Math.max(toStart, out));
}
body {
  min-height: 1000px;
}

svg {
  position: fixed;
  width: 300px;
  height: 300px;
}
<h2>Scroll down this window to draw a triangle.</h2>
<p>Scroll back up to reverse the drawing.</p>

<svg id="mySVG">
  <path fill="none" stroke="red" stroke-width="3" id="triangle" d="M150 0 L75 200 L225 200 Z" />
  Sorry, your browser does not support inline SVG.
</svg>