How to start function at specific scroll position on page?

Viewed 135

I'm experimenting with the following code where images flip through in a canvas.

If I put the canvas, let's say at the middle of my page, I was wondering if there's a way to only make the images flip through once the viewer gets to that specific section of the page.

Right now, from the looks of it, the images start flipping through right at the top of the page, immediately when you scroll down. By the time you get to the middle of the page where the actual canvas is, the images have already finished flipping through, and it's stopped on the last frame.

I assume I have to set the function to only trigger after the user scrolls to a specific number of pixels on the Y-axis? What's the best way to do so?

Please see code below.

Thanks!

var images = new Array();
var currentLocation = 0;
var totalImages = 200;

for (var i = 1; i < totalImages; i++) {
  var img = new Image;
  var slug = '000' + i;
  img.src = 'https://s3.amazonaws.com/clearmotion/hero/high-min/frame' + slug.slice(-3) + '-low.jpg'
  images.push(img);
}

var c = document.getElementById("background");
var ctx = c.getContext("2d");

var mouseWheel = function() {
  var newLocation = null;
  window.addEventListener('wheel', function(e) {
    e.preventDefault(); // No scroll

    // update our variable at high frequency
    var delta = Math.max(-1, Math.min(1, e.deltaY));
    if (delta == -1) currentLocation += 1;
    if (delta == 1) currentLocation -= 1;
    if (currentLocation < 0) currentLocation = 0;
    if (currentLocation >= (totalImages - 1)) currentLocation = (totalImages - 1);

    if (newLocation === null) { // if set, we already are waiting to draw
      requestAnimationFrame(setImage);
    }
    newLocation = currentLocation;
  });

  function setImage() {
    if (images[newLocation]) {
      ctx.fillRect(0, 0, c.width, c.height);
      ctx.drawImage(images[newLocation], 0, 0, 1000, 1000);
    }
    newLocation = null; // so the throttler knows we can draw again
  }

}


images[0].onload = function() {
  ctx.fillRect(0, 0, c.width, c.height);
  ctx.drawImage(images[currentLocation], 0, 0, 1000, 1000);
  mouseWheel();
};
<canvas id="background" width="1000" height="1000"></canvas>

1 Answers

You can actually start make the images flip through once the viewer gets to that specific section of the page by using The Intersection Observer API

So you have to detect when your element in the the viewport, the canvas in this case.

To do this you have multiple ways.

By using Observer API

const element = document.querySelector("#background")
const Ob = new IntersectionObserver((entries) => {
    if (entries[0].intersectionRatio <= 0) {
        // Not in the viewport      
    } else {
        // In the viewport 
        // You're code here         
    }
});
Ob.observe(element);

Or if you want to do it in you're own.

You can use this and adapt it if needed

function elementInViewport(el) {
        var top = el.offsetTop
        var height = el.offsetHeight;
      
        while(el.offsetParent) {
          el = el.offsetParent;
          top += el.offsetTop;
        }
      
        return (
          top >= window.pageYOffset &&
          (top + height) <= (window.pageYOffset + window.innerHeight)
        );
      }
Related