Reputation: 61
The count animation works by itself, but is initially not in the viewport.
Goal is to start the count animation when it comes into view but the code below is not working. Any suggestions?
$(window).on('scroll', function() {
var $elem = $('.showchart');
var $window = $(window);
var docViewTop = $window.scrollTop();
var docViewBottom = docViewTop + $window.height();
var elemTop = $elem.offset().top;
var elemBottom = elemTop + $elem.height();
if (elemBottom < docViewBottom) {
$('.count').each(function () {
$(this).prop('Counter',0).animate({
Counter: $(this).text()
}, {
duration: 2000,
easing: 'swing',
step: function (now) {
$(this).text(Math.ceil(now));
}
});
});
}
});
Upvotes: 1
Views: 370
Reputation: 2549
https://jsfiddle.net/k65ro3po/2/ See this fiddle for a comparison. I noticed you took an example out of this tutorial: https://codepen.io/shivasurya/pen/FatiB , so I grabbed it as well and edited it to work on scroll.
There's a few problems with your code:
Firstly, the scrolling happens on the document
, not the window
. Second, your calculations seem wrong. Also, if you don't put a stop to the triggering, the animation will loop and loop, causing major bugs.
I fixed it like this:
HTML:
<div class="filler">
Scroll down!
</div>
<div id="talkbubble"><span class="count">78</span></div>
CSS
.count {
line-height: 100px;
color: white;
margin-left: 30px;
font-size: 25px;
}
#talkbubble {
width: 120px;
height: 80px;
background: red;
position: relative;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
float: left;
margin: 20px;
}
#talkbubble:before {
content: "";
position: absolute;
right: 100%;
top: 26px;
width: 0;
height: 0;
border-top: 13px solid transparent;
border-right: 26px solid red;
border-bottom: 13px solid transparent;
}
.filler {
height: 800px;
width: 100%;
}
Javascript:
$(function() {
var $elem = $('#talkbubble');
var windowHeight = $(window).height();
var elemTop = $elem.offset().top - windowHeight;
var counted = false;
$(document).on("scroll", function() {
var scrollY = $(this).scrollTop();
if (scrollY > elemTop && !counted) {
//there is no more need to waste CPU power on triggering this after it's done its job
$(document).off("scroll");
//set counted to true so it doesn't trigger again. This is a back-up of the above
counted = true;
$('.count').each(function() {
$(this).prop('Counter', 0).animate({
Counter: $(this).text()
}, {
duration: 2000,
easing: 'swing',
step: function(now) {
$(this).text(Math.ceil(now));
}
});
});
}
});
});
-- You should really avoid re-setting variables that are always the same within a function like on.scroll()
. It will redo calculations hundreds of times that only need to be done once.
Upvotes: 2