Animate counter when in viewport

前端 未结 3 1606
逝去的感伤
逝去的感伤 2020-12-09 17:26

I have a counter which animates to a final number which is defined in the HTML. However I would like this animation to happen once it\'s in the viewport.

I have a fi

相关标签:
3条回答
  • 2020-12-09 17:43

    This solves it if you don't mind change of code. jsfiddle

        var $findme = $('#numbers');
    var exec = false;
    function Scrolled() {
      $findme.each(function() {
        var $section = $(this),
          findmeOffset = $section.offset(),
          findmeTop = findmeOffset.top,
          findmeBottom = $section.height() + findmeTop,
          scrollTop = $(document).scrollTop(),
          visibleBottom = window.innerHeight,
          prevVisible = $section.prop('_visible');
    
        if ((findmeTop > scrollTop + visibleBottom) ||
          findmeBottom < scrollTop) {
          visible = false;
        } else visible = true;
    
        if (!prevVisible && visible) {
        	if(!exec){
                  $('.fig-number').each(function() {
              $(this).prop('Counter', 0).animate({
                Counter: $(this).text()
              }, {
                duration: 1000,
    
                step: function(now) {
                  $(this).text(Math.ceil(now));
                  exec = true;
                }
              });
            });
          }
        }
        $section.prop('_visible', visible);
      });
    
    }
    
    function Setup() {
      var $top = $('#top'),
        $bottom = $('#bottom');
    
      $top.height(500);
      $bottom.height(500);
    
      $(window).scroll(function() {
        Scrolled();
      });
    }
    $(document).ready(function() {
      Setup();
    });
    html,
    body {
      height: 100%;
    }
    
    #upper-push {
      height: 100%;
      width: 100%;
      display: block;
      background: red;
      color: white;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="upper-push">
      Scroll down
    </div>
    <div id="numbers">
      <span class="fig-number">25</span>
      <span class="fig-number">78</span>
    </div>

    0 讨论(0)
  • 2020-12-09 17:43

    Snippet :

    (function($) {
    
      $.fn.visible = function(partial, hidden) {
    
        var $t = $(this).eq(0),
          t = $t.get(0),
          $w = $(window),
          viewTop = $w.scrollTop(),
          viewBottom = viewTop + $w.height(),
          _top = $t.offset().top,
          _bottom = _top + $t.height(),
          compareTop = partial === true ? _bottom : _top,
          compareBottom = partial === true ? _top : _bottom,
          clientSize = hidden === true ? t.offsetWidth * t.offsetHeight : true;
    
        return !!clientSize && ((compareBottom <= viewBottom) && (compareTop >= viewTop));
      };
    
    })(jQuery);
    
    
    // Scrolling Functions
    $(window).scroll(function(event) {
      function padNum(num) {
        if (num < 10) {
          return "" + num;
        }
        return num;
      }
    
      var first = parseInt($('.c1').text());
      var second = parseInt($('.c2').text());
    
      function countStuffUp(points, selector, duration) { //Animate count
        $({
          countNumber: $(selector).text()
        }).animate({
          countNumber: points
        }, {
          duration: duration,
          easing: 'linear',
          step: function() {
            $(selector).text(padNum(parseInt(this.countNumber)));
          },
          complete: function() {
            $(selector).text(points);
          }
        });
      }
    
      // Output to first-count
      $(".first-count").each(function(i, el) {
        var el = $(el);
        if (el.visible(true)) {
          countStuffUp(first, '.first-count', 1600);
        }
      });
    
      // Output to second count
      $(".second-count").each(function(i, el) {
        var el = $(el);
        if (el.visible(true)) {
          countStuffUp(second, '.second-count', 1000);
        }
      });
    
    });
    .block {
      height: 1000px;
      background: #eeeeee;
    }
    .dontShow {
      //display:none;
    
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
    <div class="block">Scroll down to bottom to see counter</div>
    <div>
      <span class="first-count">0</span>
      <span class="second-count">0</span>
    </div>
    <div class="dontShow">
      Max Value of count 1 : <span class="c1">25</span>
      <br />Max Value of count 2 : <span class="c2">78</span>
    </div>

    Refer : Similar

    0 讨论(0)
  • 2020-12-09 17:44

    The .inViewport() plugin triggers a callback on every scroll event.
    It's by design. (Helps to keep the source of a plugin in code! ;) )

    On the "plugin page" you can see how to use it:

    $("selector").inViewport(function(px) {
      console.log( px ); // `px` represents the amount of visible height
      if(px){
        // do this if element enters the viewport // px > 0
      }else{
        // do that if element exits  the viewport // px = 0
      }
    }); // Here you can chain other jQuery methods to your selector 
    

    that means:

    1. You have to listen for the px argument is greater than 0 (element is in viewport)
    2. To prevent chaining additional animations creating buildups, you should use a flag variable
    3. (The $(this).each() inside the callback is not needed. The plugin already operates over a collection of elements.)

    Edited jsFiddle demo

    jQuery(function($) { // DOM ready and $ in scope
    
      $(".fig-number").inViewport(function(px) {
        // if px>0 (entered V.port) and
        // if prop initNumAnim flag is not yet set = Animate numbers
        if(px>0 && !this.initNumAnim) { 
          this.initNumAnim = true; // Set flag to true to prevent re-running the same animation
          // <<< DO SOME COOL STUFF HERE! 
        }
      });
    
    });
    

    Snippet example:

    // inViewport jQuery plugin
    // https://stackoverflow.com/a/26831113/383904
    $(function($, win) {
      $.fn.inViewport = function(cb) {
        return this.each(function(i,el){
          function visPx(){
            var H = $(this).height(),
                r = el.getBoundingClientRect(), t=r.top, b=r.bottom;
            return cb.call(el, Math.max(0, t>0? H-t : (b<H?b:H)));  
          } visPx();
          $(win).on("resize scroll", visPx);
        });
      };
    }(jQuery, window));
    
    
    jQuery(function($) { // DOM ready and $ in scope
    
      $(".fig-number").inViewport(function(px) { // Make use of the `px` argument!!!
        // if element entered V.port ( px>0 ) and
        // if prop initNumAnim flag is not yet set
        //  = Animate numbers
        if(px>0 && !this.initNumAnim) { 
          this.initNumAnim = true; // Set flag to true to prevent re-running the same animation
          $(this).prop('Counter',0).animate({
            Counter: $(this).text()
          }, {
            duration: 1000,
            step: function (now) {
              $(this).text(Math.ceil(now));
            }
          });         
        }
      });
    
    });
    html,
    body {
      height:100%;
    }
    
    #upper-push {
      height:100%;
      width:100%;
      display:block;
      background:red;
      color:white;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="upper-push">
      Scroll down
    </div>
    <div id="numbers">
      <span class="fig-number">25</span>
      <span class="fig-number">78</span>
    </div>

    0 讨论(0)
提交回复
热议问题