Mulgard
Mulgard

Reputation: 10589

Canvas: Detect if it is visible in browser

I have a list of charts. I use Chart.js to create those charts. Since my list can have 1 to 100 or more entries initializing all charts at once would not be smart because that would make the ui freeze for a long time. So instead I thought it would be much better to only initialize those charts which are visible inside the view bounds of the browser so that for example only the first chart is getting initialized and when the user scrolls down and the second canvas becomes visible the second is getting initialized and so on.

I have everything setup but the only problem that I have right now is: how can I create an eventlistener or anything similiar which I can add to each canvas element that gets triggered when a canvas becomes visible inside the view bounds of the browser so that i can perform the chart initialization for that canvas?

Upvotes: 1

Views: 2926

Answers (3)

Tima
Tima

Reputation: 21

I usually draw some stuff; canvas is an example. Clean JS.Here, you can read a lot more about how it works. https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API

const canvases = document.querySelectorAll("canvas");
canvases.forEach( (canvas) => {
var options = {
      threshold: 0.01,
    };
var canvas_observer = new IntersectionObserver((entries, observer) => {
  // Loop through the entries
  for (const entry of entries) {
    // Check if the entry is intersecting the viewport
    if (entry.isIntersecting) {
            console.log("Intersected")
    }
    else{
            console.log("Exit")
    }
  }
}, options);
canvas_observer.observe(canvas);})

Upvotes: 0

Silvestre Herrera
Silvestre Herrera

Reputation: 445

I'm the author of OnScreen, a small library that can call a callback function when a HTMLElement enters the viewport or the boundaries of its container.

// Uses ES6 syntax
import OnScreen from 'onscreen';

const os = new OnScreen();

os.on('enter', 'canvas', (element) => {
    if (!element.chartInitialized) {
        // Initialize the chart

        // Update the `chartInitialized` property
        // to avoid initializing it over and over
        element.chartInitialized = true;
    }
});

For more information, take a look at the documentation. Don't forget to check the demos repo for a couple simple examples.

Upvotes: 1

pinturic
pinturic

Reputation: 2263

I have used the onScreen jQuery plugin.

It is very easy. You just have to call for each canvas this:

$('elements').onScreen({
   container: window,
   direction: 'vertical',
   doIn: function() {
     // initialize canvas
   },
   doOut: function() {
     // Do something to the matched elements as they get off scren
   },
   tolerance: 0,
   throttle: 50,
   toggleClass: 'onScreen',
   lazyAttr: null,
   lazyPlaceholder: 'someImage.jpg',
   debug: false
});

Upvotes: 1

Related Questions