I have an animation on my webpage where stat numbers count up to reach to a target number. I want this animation to start only when this section scrolls into view, otherwise the animation will already be donw by the time the user gets to that section!
    How can I do that?
    Here is a link:
   [ https://www.boneiolam.org/index2#services](https://www.boneiolam.org/index2#services)

   The numbers in the circles count up

Recommended Answers

All 9 Replies

There are indeed many plugins for this, but if it's just for this one animation then you can/should do it without a plugin. I see you use a jquery plugin for the counters and trigger them on page load, but you have to trigger them when the circles div is in the viewport.

So with the code from that 'do it without a plugin' article, you could do something like this:

<script>

    $.fn.isInViewport = function() {
        var elementTop = $(this).offset().top;
        var elementBottom = elementTop + $(this).outerHeight();

        var viewportTop = $(window).scrollTop();
        var viewportBottom = viewportTop + $(window).height();

        return elementBottom > viewportTop && elementTop < viewportBottom;
    };

    $(window).on('resize scroll', function() {

        if ($('.circles).isInViewport()) {

            $('.timer').countTo({
                from: 0,
                to: 5,
                speed: 1000,
                refreshInterval: 20000,
                onComplete: function(value) {
                    console.debug(this);
                }
            });

            $('.timertwo').countTo({
                from: 0,
                to: 11,
                speed: 1000,
                refreshInterval: 20000,
                onComplete: function(value) {
                    console.debug(this);
                }
            });

            $('.timerthree').countTo({
                from: 0,
                to: 7064,
                speed: 1000,
                refreshInterval: 20000,
                onComplete: function(value) {
                    console.debug(this);
                }
            });

        }

    });

</script>

Thank you! That worked to make the animation start only once it is in the browser viewport. However, each time I scroll in that section, it starts again from zero, even if the animation is not done. How can I avoid that?

There are a couple of things wrong with your implementation.

$(window).on('resize scroll', function() {

    $('.timer').countTo('start') ({

        formatter: function (value, options) {
            return value.toFixed(options.decimals).replace(/\B(?=(?:\d{3})+(?!\d))/g, ',');
        },
        onUpdate: function (value) {
            console.debug(this);
        },
        onComplete: function (value) {
            console.debug(this);
        }

    });

});

You run the timer as soon as you scroll and not when the circles div is in the viewport, because your forgot to wrap it inside if ($('.circles').isInViewport()) { ... )

The second things is that you wrote the .countTo(start) ({..}) wrong. That should have been .countTo({...}).

I was playing myself a bit with it too and I've noticed that the numbers were indeed acting a bit weird even when I had fixed your errors and yes, it was also resetting to 0 when I scrolled a bit more up and/or down while the counter was not finished yet.
I've fixed this by using the onUpdate: callback function to turn the window scroll and resizze events off once the counters had started

Like so:

$(window).on('scroll.count resize.count', function() {

    if ($('.circles').isInViewport()) {

        $('.timer').countTo({
            onUpdate: function () {
                $(window).off('scroll.count resize.count');
            }
        });

    }

});

I gave the window scroll and resize events a name of count, so that I can/should only turn these off and not possible other scroll or resize events that you (might) use for the other animations on the page.

I've also added a -500px offset in the viewport function, see below, so that the counters start a bit earlier while the circles div is noi fully yet at the top the viewport.

$.fn.isInViewport = function() {
    var elementTop = $(this).offset().top-500; // SEE HERE THE -500
    var elementBottom = elementTop + $(this).outerHeight();
    var viewportTop = $(window).scrollTop();
    var viewportBottom = viewportTop + $(window).height();
    return elementBottom > viewportTop && elementTop < viewportBottom;
};

See my little demo:
https://codepen.io/gentlemedia/full/BVQvzo/

Thank you! This is exactly what I needed, but the part that was formatting the number to include a comma is not working anymore. Do you know how I can set it to format the number correctly?
Thanks again

I've just included the formatter in my codepen and it works fine.

Perfect! Thank you so much!

Great! I'm glad it's sorted! And please mark this thread as solved!

Use the existing WOW javascript.
It works very well.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.