forked from adrian2x/odometer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
odometer.min.js
2 lines (2 loc) · 7.83 KB
/
odometer.min.js
1
2
/*! odometer 0.5.0 */
const t=/^\(?([^)]*)\)?(?:(.)(D*)(d*))?$/,e=t=>{const e=document.createElement("div");return e.innerHTML=t,e.children[0]},i=(t,...e)=>t.classList.remove(...e),n=(t,...e)=>(i(t,...e),t.classList.add(...e)),s=(t,e)=>t.dispatchEvent(new CustomEvent(e,{bubbles:!0,cancelable:!0})),r=()=>window.performance.now(),o=(t,e=0)=>e?(t*=Math.pow(10,e),t+=.5,(t=Math.floor(t))/Math.pow(10,e)):Math.round(t),a=t=>t<0?Math.ceil(t):Math.floor(t);class h{constructor(t){if(this.options=t,this.el=this.options.el,null!=this.el.odometer)return this.el.odometer;this.el.odometer=this;for(let i in h.options){const t=h.options[i];null==this.options[i]&&(this.options[i]=t)}null==this.options.duration&&(this.options.duration=2e3),this.MAX_VALUES=this.options.duration/33.333333333333336/2|0,this.resetFormat(),this.value=this.cleanValue(null!=this.options.value?this.options.value:""),this.renderInside(),this.render();try{for(let t of["innerHTML","innerText","textContent"])null!=this.el[t]&&(t=>{Object.defineProperty(this.el,t,{get:()=>"innerHTML"===t?this.inside.outerHTML:null!=this.inside.innerText?this.inside.innerText:this.inside.textContent,set:t=>this.update(t)})})(t)}catch(e){this.watchForMutations()}}static init(){return document.querySelectorAll(h.options.selector||".odometer").map(t=>t.odometer=new h({el:t,value:null!=t.innerText?t.innerText:t.textContent}))}renderInside(){return this.inside=document.createElement("div"),this.inside.className="odometer-inside",this.el.innerHTML="",this.el.appendChild(this.inside)}watchForMutations(){try{return this.observer||(this.observer=new MutationObserver(t=>{const e=this.el.innerText;return this.renderInside(),this.render(this.value),this.update(e)})),this.watchMutations=!0,this.startWatchingMutations()}catch(t){}}startWatchingMutations(){if(this.watchMutations)return this.observer.observe(this.el,{childList:!0})}stopWatchingMutations(){return this.observer&&this.observer.disconnect()}cleanValue(t){return"string"==typeof t&&(t=(t=(t=t.replace(this.format.radix||".","<radix>")).replace(/[.,]/g,"")).replace("<radix>","."),t=parseFloat(t,10)||0),o(t,this.format.precision)}bindTransitionEnd(){if(this.transitionEndBound)return;this.transitionEndBound=!0;let t=!1;return"transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd".split(" ").map(e=>this.el.addEventListener(e,()=>(t||(t=!0,setTimeout(()=>(this.render(),t=!1,s(this.el,"odometerdone")),0)),!0)))}resetFormat(){let e=this.options.format||"(,ddd).dd";e||(e="d");const i=t.exec(e);if(!i)throw new Error("Odometer: Unparsable digit format");const[n,s,r,o]=Array.from(i.slice(1,5));let a=r?r.length:0;const h=a+(o?o.length:0);return this.format={repeating:n,radix:s,precision:h,fractional:a}}render(t=this.value){this.stopWatchingMutations(),this.resetFormat(),this.inside.innerHTML="";let{theme:e}=this.options;const i=this.el.className.split(" "),n=[];for(let r of i)if(r.length){var s;if(s=/^odometer-theme-(.+)$/.exec(r)){e=s[1];continue}if(/^odometer(-|$)/.test(r))continue;n.push(r)}return n.push("odometer"),e?n.push("odometer-theme-"+e):n.push("odometer-auto-theme"),this.el.className=n.join(" "),this.ribbons={},this.formatDigits(t),this.startWatchingMutations()}formatDigits(t){let e;if(this.digits=[],this.options.formatFunction){const i=this.options.formatFunction(t);for(let t of i.split("").reverse())t.match(/[0-9]/)?(e=this.renderDigit(),e.querySelector(".odometer-value").innerHTML=t,this.digits.push(e),this.insertDigit(e)):this.addSpacer(t)}else{let e=Math.abs(t),i=Math.max(this.format.fractional,this.getFractionalDigitCount(e));i&&(e=Math.round(e*Math.pow(10,i)));let n=0;for(;e>0;)this.addDigit((e%10).toString(),n>=i),e=Math.floor(e/10),n++,n===i&&this.addDigit(".",!0);let s=d(n-i,this.options.minIntegerLength||0);for(let t of s)this.addDigit(0,!0);t<0&&this.addDigit("-",!0)}}update(t){let e;if(e=(t=this.cleanValue(t))-this.value)return i(this.el,"odometer-animating-up","odometer-animating-down","odometer-animating"),n(this.el,e>0?"odometer-animating-up":"odometer-animating-down"),this.stopWatchingMutations(),this.animate(t),this.startWatchingMutations(),setTimeout(()=>(this.el.offsetHeight,n(this.el,"odometer-animating")),0),this.value=t}renderDigit(){return e('<span class="odometer-digit"><span class="odometer-digit-spacer">8</span><span class="odometer-digit-inner"><span class="odometer-ribbon"><span class="odometer-ribbon-inner"><span class="odometer-value"></span></span></span></span></span>')}insertDigit(t,e){return null!=e?this.inside.insertBefore(t,e):this.inside.children.length?this.inside.insertBefore(t,this.inside.children[0]):this.inside.appendChild(t)}addSpacer(t,i,...s){const r=e('<span class="odometer-formatting-mark"></span>');return r.innerHTML=t,s&&n(r,...s),this.insertDigit(r,i)}addDigit(t,e=!0){if("-"===t)return this.addSpacer(t,null,"odometer-negation-mark");if("."===t)return this.addSpacer(this.format.radix||".",null,"odometer-radix-mark");if(e){let t=!1;for(;;){if(!this.format.repeating.length){if(t)throw new Error("Bad odometer format without digits");this.resetFormat(),t=!0}const e=this.format.repeating[this.format.repeating.length-1];if(this.format.repeating=this.format.repeating.substring(0,this.format.repeating.length-1),"d"===e)break;this.addSpacer(e)}}const i=this.renderDigit();return i.querySelector(".odometer-value").innerHTML=t,this.digits.push(i),this.insertDigit(i)}animate(t){return"count"===this.options.animation?this.animateCount(t):this.animateSlide(t)}animateCount(t){let e,i=+t-this.value,n=r();if(!i)return;const o=n;let a=this.value;return(e=()=>{if(r()-o>this.options.duration)return this.value=t,this.render(),s(this.el,"odometerdone");const h=r()-n;if(h>50){n=r();const t=h/this.options.duration;a+=i*t,this.render(Math.round(a))}return requestAnimationFrame(e)})()}getDigitCount(...t){for(let i=0;i<t.length;i++){const e=t[i];t[i]=Math.abs(e)}const e=Math.max(...Array.from(t||[]));return Math.ceil(Math.log(e+1)/Math.log(10))}getFractionalDigitCount(...t){const e=/^\-?\d*\.(\d*?)0*$/;for(let i=0;i<t.length;i++){const n=t[i];t[i]=n.toString();const s=e.exec(t[i]);t[i]=s?s[1].length:0}return Math.max(...Array.from(t||[]))}resetDigits(){return this.digits=[],this.ribbons=[],this.inside.innerHTML="",this.resetFormat()}animateSlide(t){let e,i,s,r,o,h,l,u,m=this.value;const c=Math.max(this.format.fractional,this.getFractionalDigitCount(m,t));if(c&&(t=Math.round(t*Math.pow(10,c)),m=Math.round(m*Math.pow(10,c))),!(e=t-m))return;this.bindTransitionEnd();let p=this.options.minIntegerLength||0;const g=Math.max(this.getDigitCount(m,t),p+c),f=[];let M=0;for(u=0,r=u,l=g,h=0<=l;h?u<l:u>l;h?u++:u--,r=u){o=a(m/Math.pow(10,g-r-1));const e=a(t/Math.pow(10,g-r-1)),n=e-o;if(Math.abs(n)>this.MAX_VALUES){s=[];const t=n/(this.MAX_VALUES+this.MAX_VALUES*M*.5);let i=o;for(;n>0&&i<e||n<0&&i>e;)s.push(Math.round(i)),i+=t;s[s.length-1]!==e&&s.push(e),M++}else s=d(o,e,!0);for(r=0;r<s.length;r++)i=s[r],s[r]=Math.abs(i%10);f.push(s)}this.resetDigits();const b=f.reverse();for(r=0;r<b.length;r++){s=b[r],this.digits[r]||this.addDigit(" ",r>=c),null==this.ribbons[r]&&(this.ribbons[r]=this.digits[r].querySelector(".odometer-ribbon-inner")),this.ribbons[r].innerHTML="",e<0&&(s=s.reverse());for(let t=0;t<s.length;t++){i=s[t];const e=document.createElement("div");e.className="odometer-value",e.innerHTML=i,this.ribbons[r].appendChild(e),t===s.length-1&&n(e,"odometer-last-value"),0===t&&n(e,"odometer-first-value")}}o<0&&this.addDigit("-");const v=this.inside.querySelector(".odometer-radix-mark");return v&&v.parent.removeChild(v),c?this.addSpacer(this.format.radix,this.digits[c-1],"odometer-radix-mark"):void 0}}function d(t,e,i){let n=[],s=t<e,r=i?s?e+1:e-1:e;for(let o=t;s?o<r:o>r;s?o++:o--)n.push(o);return n}h.options=window.odometerOptions||{},document.addEventListener("DOMContentLoaded",()=>{if(!1!==h.options.auto)return h.init()}),"function"==typeof define&&define.amd?define([],()=>h):"undefined"!=typeof exports&&null!=exports?module.exports=h:window.Odometer=h;