This thing is giving me headaches as I just can't find the way to do it. I downloaded a script which helped me make the charts with an animation (jquery.lineProgressbar.js).
The charts works pretty well, but the problem is the animation runs when the page is loaded. I want people to be able to see the animation of each chart. I have a lot of charts in the same page, and I need them all to execute the animation as they enter the viewport.
I know this question has been posted a lot of times, but none of them solves my problem.
I decided to make a Plunker example of my code so you can see better how it works. Here is my Plunker
I tried adding a code before the "Progressing" part in the jquery.lineProgressbar.js, to tell "apply the animation once the div called "progressbar" enter viewport:
$.fn.isOnScreen = function() {
var win = $(window);
var viewport = {
top: win.scrollTop(),
left: win.scrollLeft()
};
viewport.right = viewport.left + win.width();
viewport.bottom = viewport.top + win.height();
var bounds = this.offset();
bounds.right = bounds.left + this.outerWidth();
bounds.bottom = bounds.top + this.outerHeight();
return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));
};
if($('.progressbar').isOnScreen()) {
// Progressing
progressFill.animate(
etc...
)
}
...but this isn't working.
I hope someone can help me, thanks in advance!
CODE UPDATE:
I added the functional code, based on troyw1636 answer. Here the new plunker
function TestViewPort(elementID, chartPercentage){
var top_of_element = $("#" + elementID).offset().top;
var bottom_of_element = $("#" + elementID).offset().top + $("#element").outerHeight();
var bottom_of_screen = $(window).scrollTop() + $(window).innerHeight();
var top_of_screen = $(window).scrollTop();
if ((bottom_of_screen > top_of_element) && (top_of_screen < bottom_of_element)){
if (!$("#" + elementID).hasClass('on-view')) {
$("#" + elementID).LineProgressbar({percentage:chartPercentage}).addClass('on-view');
}
}
}
You're on the right track. I've used a different method for determining viewport visiblity, and have wrapped the progress bar call within that. I've also added the same calls within a $(window).scroll() event so that the viewport visibility for all divs is recalculated when the viewport changes.
I've edited your Plunker: https://plnkr.co/edit/k5aop0cnP9uziTZwDY3Y?p=preview
function TestViewPort(elementID, chartPercentage) {
var top_of_element = $("#" + elementID).offset().top;
var bottom_of_element = $("#" + elementID).offset().top + $("#element").outerHeight();
var bottom_of_screen = $(window).scrollTop() + $(window).innerHeight();
var top_of_screen = $(window).scrollTop();
if ((bottom_of_screen > top_of_element) && (top_of_screen < bottom_of_element)) {
//div is visible so set up chart
$("#" + elementID).LineProgressbar({
percentage: chartPercentage
});
} else {
// div not visible
}
}
As a next step, you'd likely want to determine which charts have already been initialised and stop the code within TestViewPort from re-initialising them after a scroll event.