1

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));
        }
    });
}); 
  }
});  
  

1
  • What exactly isn't working? Is the animation not happening, or is the code never firing? Commented Sep 10, 2016 at 0:42

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Hi, I was just having a look at this code and it works perfect, but how I can make it fire for different elements when they are in the viewport? at the moment all the elements fire at the same time when the first one hits the viewport, can you please help? :)
In that scenario you'll want to simply loop over the elements and trigger it for every element that is within the viewport. If you want a more detailed answer, I'd suggest creating your own question and letting me know about it ;)
Thanks, I could finally sort this out by doing what you said, nice one! :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.