0

I am using a scroll trigger from this answer to build a progressbar.js animation that is triggered once the entire progress bar div is in the viewport.

The animation works normally with no trigger, it just runs on page load. But I can't make it trigger when the element scrolls into full view.

The example code below has a div gap at the top so you can scroll down before the animation starts, although that is obviously the part I cannot get working.

function privacyScoreCircle() {
  // progressbar.js circle
  var bar = new ProgressBar.Circle(document.getElementById('privacy-score-circle'), {
    color: '#aaa',
    // This has to be the same size as the maximum width to
    // prevent clipping
    strokeWidth: 4,
    trailWidth: 4,
    easing: 'easeInOut',
    duration: 1400,
    text: {
      autoStyleContainer: false
    },
    from: {
      color: '#dddddd',
      width: 4
    },
    to: {
      color: '#aaaaaa',
      width: 4
    },
    // Set default step function for all animate calls
    step: function(state, circle) {
      circle.path.setAttribute('stroke', state.color);
      circle.path.setAttribute('stroke-width', state.width);

      var value = Math.round(circle.value() * 100);
      if (value === 0) {
        circle.setText('');
      } else {
        circle.setText(value + '%');
      }

    }
  });
  bar.text.style.fontFamily = '"Montserrat", sans-serif';
  bar.text.style.fontSize = '1.7rem';
  bar.trail.setAttribute('stroke-linecap', 'round');
  bar.path.setAttribute('stroke-linecap', 'round');
  //bar.animate(0.97); // <-- ANIMATION CAN BE TRIGGERED INSTANTLY USING THIS

}
privacyScoreCircle();

// Check if element is scrolled into view
function isScrolledIntoView(elem) {
  var docViewTop = $(window).scrollTop();
  var docViewBottom = docViewTop + $(window).height();

  var elemTop = $(elem).offset().top;
  var elemBottom = elemTop + $(elem).height();

  return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}

function Utils() {

}

Utils.prototype = {
  constructor: Utils,
  isElementInView: function(element, fullyInView) {
    var pageTop = $(window).scrollTop();
    var pageBottom = pageTop + $(window).height();
    var elementTop = $(element).offset().top;
    var elementBottom = elementTop + $(element).height();

    if (fullyInView === true) {
      return ((pageTop < elementTop) && (pageBottom > elementBottom));
    } else {
      return ((elementTop <= pageBottom) && (elementBottom >= pageTop));
    }
  }
};

var Utils = new Utils();

var isElementInView = Utils.isElementInView($('#privacy-score-circle'), false);

if (isElementInView) {
  bar.animate(0.97);
}
#gap {
  height: 500px;
}

#privacy-score-circle {
  margin: auto;
  width: 200px;
  height: 200px;
  position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/progressbar.js/1.0.1/progressbar.min.js"></script>
<div id="gap">Scroll down to activate animation</div>
<div id="privacy-score-circle"></div>
TinyTiger
  • 814
  • 2
  • 16
  • 33

1 Answers1

1

You should apply these changes in your code:

  1. You declared the bar variable within privacyScoreCircle() function. Variables defined inside a function are not accessible from outside the function. So, define it as a global variable.
  2. You should execute animation when window is being scrolled.

You can see the code that works correctly here.

Kavian K.
  • 1,212
  • 1
  • 7
  • 11
  • It is necessary to load `jQuery library` before load other libraries if any of your function in other `js` files, need to access `jQuery`. The reason for the error is that you first putted the `progressbar.js` file to the page and then the `jquery.js` file. (Change their order) – Kavian K. Jun 16 '18 at 14:56
  • I updated the load order to this: jQuery.js > ProgressBar.js > Circles.js. Circles.js is the script which contains your code, and is currently sitting in footer. But the animation is still not loading. I also tried moving ProgressBar to the footer, but it had no effect. And I am still seeing the `TypeError: $ is not a function` error in console after fixing their order. – TinyTiger Jun 16 '18 at 23:44
  • Read [this](https://crunchify.com/how-to-fix-wordpress-uncaught-typeerror-is-not-a-function-jquery-error/). Or may be you use jQuery.noConflict(); So $ is undefined. – Kavian K. Jun 17 '18 at 00:36
  • That did it! Thank you. For anyone else reading along, in WordPress you need to see step 2 from the article linked in comment above, which says replace `$` with `jQuery` in your code. – TinyTiger Jun 17 '18 at 03:05