UNPKG

processing-js

Version:

For the project website, visit http://processingjs.org

150 lines (131 loc) • 5.1 kB
/* L A Z Y L O A D I N G F O R P R O C E S S I N G . J S Part of the Processing.js project License : MIT Web Site : http://processingjs.org Github Repo. : http://github.com/jeresig/processing-js Bug Tracking : http://processing-js.lighthouseapp.com */ (function() { /** * Can we rely on there being a w3c DOM available? */ var isDOMPresent = ("document" in this) && !("fake" in this.document); /** * If there is no DOM, don't run. */ if (!isDOMPresent) { throw("This browser does not support the w3c DOM interface, which this extension for Processing.js relies on."); } /** * If there is no Processing.js, don't run. */ if (!Processing) { throw("Please load Processing.js before loading the \"lazy loading\" extension."); } /** * Prevent processing from running its init function */ Processing.disableInit(); // constructor LazyLoading = this.LazyLoading = {}; /** * This object will track every sketch that needs to be lazily loaded */ var sketches = {}; /** * Get all canvas elements on the page, and if they indicate that * they load processing sources, add them to our to-do collection/ */ var setSketches = function() { var elements = document.getElementsByTagName('canvas'); var _id = 0; for (var e=0, end=elements.length; e<end; e++) { var canvas = elements[e]; // make sure we only grab canvas elements that are associated with processing source files if (canvas.getAttribute("data-processing-sources") || canvas.getAttribute("data-src") || canvas.getAttribute("datasrc")) { if(!canvas.id) { canvas.id = "canvas"+(_id++); } var sketch = {}; sketch.canvas = canvas; sketches[canvas.id] = sketch; } } }; /** * This function sets the height values for the sketch's * canvas's top and bottom. * @param {sketch} sketch The sketch object for which the top/bottom values are set */ var setHeightValues = function(sketch) { sketch.top = getElementPosition(sketch.canvas); sketch.bottom = sketch.top + sketch.canvas.clientHeight; }; /** * General purpose "height of element on page" function. * Code from http://www.quirksmode.org/js/findpos.html * @param {HTMLElement} element The HTML element for which the height on the page is being checked */ var getElementPosition = function(obj) { var curTop = 0; if (obj.offsetParent) { do { curTop += obj.offsetTop; } while (!!(obj = obj.offsetParent)); } return curTop; }; /** * For each sketch in the to-do list, check whether it should be loaded * based on whether or not the user can see any part of the canvas it * is to be loaded in is visible on their screen. */ var checkPositions = LazyLoading.checkPositions = function() { var top = 0, bottom = 0; Object.keys(sketches).forEach(function(s) { var sketch = sketches[s]; top = window.pageYOffset; bottom = top + window.innerHeight; setHeightValues(sketch); if ((top <= sketch.top && sketch.top <= bottom) || (top <= sketch.bottom && sketch.bottom <= bottom)) { LazyLoading.loadSketch(sketch); delete sketches[s]; } }); }; /** * Load the sketch associated with a canvas, from source indicated by that canvas. * @param {sketch} sketch An administrative sketch object */ var loadSketch = LazyLoading.loadSketch = function(sketch) { if (sketch.canvas) { // form an array of which files must be loaded for this sketch var processingSources = sketch.canvas.getAttribute('data-processing-sources'); if(processingSources===null) { processingSources = sketch.canvas.getAttribute('data-src'); } if(processingSources===null) { processingSources = sketch.canvas.getAttribute('datasrc'); } var filenames = processingSources.split(' '); for (var j = 0; j < filenames.length;) { if (filenames[j]) { j++; } else { filenames.splice(j, 1); }} // make Processing.js load this sketch into its canvas Processing.loadSketchFromSources(sketch.canvas, filenames); } }; /** * In order for lazy-loading to do its work when it is started, it needs to first builds * the to-do list for sketches that may eventually need loading, then check whether * any of them need immediate loading, and finally, it needs to set up a scroll event * listener so that every time a user scrolls the page (in whichever way), the lazy * loader checks whether this resulted in one or more sketches needing to be loaded * because they have become visible to the user. */ var init = function() { setSketches(); checkPositions(); document.addEventListener("scroll", LazyLoading.checkPositions, false); }; /** * Finally, we kick-start the whole lazy loading process by making sure init() is called * when the document signals it has finished building the page's DOM. */ document.addEventListener('DOMContentLoaded', init, false); })();