frontend.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. var FLBuilderNumber;
  2. (function(undefined) {
  3. /**
  4. * Class for Number Counter Module
  5. *
  6. * @since 1.6.1
  7. */
  8. FLBuilderNumber = function( settings ) {
  9. // set params
  10. this.nodeClass = '.fl-node-' + settings.id;
  11. this.wrapperClass = this.nodeClass + ' .fl-number';
  12. this.layout = settings.layout;
  13. this.type = settings.type;
  14. this.number = settings.number;
  15. this.max = settings.max;
  16. this.speed = settings.speed;
  17. this.wrapper = document.querySelector( this.wrapperClass );
  18. if ( this.wrapper ) {
  19. this.wrapper.FLBuilderNumber = this;
  20. // initialize the number
  21. this._initNumber();
  22. }
  23. };
  24. FLBuilderNumber.addCommas = function( n ) {
  25. var rgx = /(\d+)(\d{3})/;
  26. n += '';
  27. x = n.split( '.' );
  28. x1 = x[0];
  29. x2 = x.length > 1 ? '.' + x[1] : '';
  30. while (rgx.test( x1 )) {
  31. x1 = x1.replace( rgx, '$1' + ',' + '$2' );
  32. }
  33. return x1 + x2;
  34. };
  35. if ( 'IntersectionObserver' in window ) {
  36. FLBuilderNumber.intersectionObserver = new IntersectionObserver( function( entries ) {
  37. entries.forEach( function( entry ) {
  38. if ( entry.intersectionRatio >= 1 ) {
  39. entry.target.FLBuilderNumber._initCount();
  40. FLBuilderNumber.intersectionObserver.unobserve( entry.target );
  41. }
  42. } );
  43. }, {
  44. threshold: [1]
  45. } );
  46. }
  47. FLBuilderNumber.prototype = {
  48. nodeClass : '',
  49. wrapperClass : '',
  50. layout : '',
  51. type : '',
  52. number : 0,
  53. max : 0,
  54. speed : 0,
  55. _initNumber: function() {
  56. var self = this;
  57. var numString = this.wrapper.querySelector( '.fl-number-int' );
  58. if ( numString ) {
  59. numString.innerHTML = '0';
  60. }
  61. if ( FLBuilderNumber.intersectionObserver ) {
  62. FLBuilderNumber.intersectionObserver.observe( this.wrapper );
  63. } else {
  64. self._initCount();
  65. }
  66. },
  67. _initCount: function() {
  68. if ( this.layout == 'circle' ) {
  69. this._triggerCircle();
  70. } else if ( this.layout == 'bars' ) {
  71. this._triggerBar();
  72. }
  73. this._countNumber();
  74. },
  75. _countNumber: function() {
  76. this._numberElement = this.wrapper.querySelector( '.fl-number-string .fl-number-int' );
  77. requestAnimationFrame( this._countNumberStep.bind( this ) );
  78. },
  79. _countNumberStep: function( now ) {
  80. if ( ! this._numberStart ) {
  81. this._numberStart = now;
  82. }
  83. var progress = ( now - this._numberStart ) / this.speed;
  84. this._numberElement.innerHTML = FLBuilderNumber.addCommas( Math.ceil( this.number * progress ) )
  85. if ( progress <= 1 ) {
  86. requestAnimationFrame( this._countNumberStep.bind( this ) );
  87. } else {
  88. this._numberElement.innerHTML = FLBuilderNumber.addCommas( this.number );
  89. }
  90. },
  91. _triggerCircle: function() {
  92. var bar = this.wrapper.querySelector( '.fl-bar' ),
  93. r = parseInt( bar.getAttribute( 'r' ), 10 ),
  94. circle = Math.PI * (r * 2),
  95. max = this.type == 'percent' ? 100 : this.max,
  96. val = Math.max( 0, Math.min( this.number, max ) );
  97. if ( this.type == 'percent' ) {
  98. var pct = ( ( 100 - val ) / 100) * circle;
  99. } else {
  100. var pct = ( 1 - ( val / max ) ) * circle;
  101. }
  102. requestAnimationFrame( function() {
  103. bar.style.transitionDuration = this.speed + 'ms';
  104. bar.style.strokeDashoffset = pct;
  105. }.bind( this ) );
  106. },
  107. _triggerBar: function() {
  108. var bar = this.wrapper.querySelector( '.fl-number-bar' );
  109. if ( this.type == 'percent' ) {
  110. var number = this.number > 100 ? 100 : this.number;
  111. } else {
  112. var number = Math.ceil( ( this.number / this.max ) * 100 );
  113. }
  114. requestAnimationFrame( function() {
  115. bar.style.transitionDuration = this.speed + 'ms';
  116. bar.style.transform = 'scaleX( 1 )';
  117. }.bind( this ) );
  118. }
  119. };
  120. })();