UNPKG

tm-odometer

Version:

TmOdometer: Lightweight JavaScript library for animated numeric counters with smooth transitions and precise decimal handling.

3 lines (2 loc) 9.68 kB
/*! tm-odometer-lib v2.0.0 | MIT License */ (function(){var t,e,i,n,r,o,s,a,d,h,l,u,m,c,p,f,g,v,w;t=/^\(?([^)]*)\)?(?:(.)(d+))?$/,e=1e3/30,f=document.createElement("div").style,n=null!=f.transition||null!=f.webkitTransition||null!=f.mozTransition||null!=f.oTransition,c=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame,i=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver,d=function(t){var e;return(e=document.createElement("div")).innerHTML=t,e.children[0]},m=function(t,e){return t.className=t.className.replace(new RegExp(`(^| )${e.split(" ").join("|")}( |$)`,"gi")," ")},a=function(t,e){return m(t,e),t.className+=` ${e}`},g=function(t,e){var i;if(null!=document.createEvent)return(i=document.createEvent("HTMLEvents")).initEvent(e,!0,!0),t.dispatchEvent(i)},h=function(){var t,e;return null!=(t=null!=(e=window.performance)&&"function"==typeof e.now?e.now():void 0)?t:+new Date},p=function(t,e=0){return e?(t*=Math.pow(10,e),t+=.5,(t=Math.floor(t))/Math.pow(10,e)):Math.round(t)},v=function(t){return t<0?Math.ceil(t):Math.floor(t)},o=!1,(w=function(){var t,e,i,n,r;if(!o&&null!=window.jQuery){for(o=!0,r=[],t=0,e=(n=["html","text"]).length;t<e;t++)i=n[t],r.push(function(t){var e;return e=window.jQuery.fn[t],window.jQuery.fn[t]=function(t){var i;return null==t||null==(null!=(i=this[0])?i.odometer:void 0)?e.apply(this,arguments):this[0].odometer.update(t)}}(i));return r}})(),setTimeout(w,0),r=class r{constructor(t){var i,n,o,s,a,d,h,l,u;if(this.options=t,this.el=this.options.el,null!=this.el.odometer)return this.el.odometer;for(n in this.el.odometer=this,d=r.options)u=d[n],null==this.options[n]&&(this.options[n]=u);null==(i=this.options).duration&&(i.duration=2e3),this.MAX_VALUES=this.options.duration/e/2|0,this.resetFormat(),this.value=this.cleanValue(null!=(h=this.options.value)?h:""),this.renderInside(),this.render();try{for(o=0,s=(l=["innerHTML","innerText","textContent"]).length;o<s;o++)a=l[o],null!=this.el[a]&&(t=>{Object.defineProperty(this.el,t,{get:()=>{var e;return"innerHTML"===t?this.inside.outerHTML:null!=(e=this.inside.innerText)?e:this.inside.textContent},set:t=>this.update(t)})})(a)}catch(t){this.watchForMutations()}}renderInside(){return this.inside=document.createElement("div"),this.inside.className="odometer-inside",this.el.innerHTML="",this.el.appendChild(this.inside)}watchForMutations(){if(null!=i)try{return null==this.observer&&(this.observer=new i((t=>{var e;return e=this.el.innerText,this.renderInside(),this.render(this.value),this.update(e)}))),this.watchMutations=!0,this.startWatchingMutations()}catch(t){0}}startWatchingMutations(){if(this.watchMutations)return this.observer.observe(this.el,{childList:!0})}stopWatchingMutations(){var t;return null!=(t=this.observer)?t.disconnect():void 0}cleanValue(t){var e;return"string"==typeof t&&(t=(t=(t=t.replace(null!=(e=this.format.radix)?e:".","<radix>")).replace(/[.,]/g,"")).replace("<radix>","."),t=parseFloat(t,10)||0),p(t,this.format.precision)}bindTransitionEnd(){var t,e,i,n,r,o;if(!this.transitionEndBound){for(this.transitionEndBound=!0,r=!1,o=[],e=0,i=(n="transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd".split(" ")).length;e<i;e++)t=n[e],o.push(this.el.addEventListener(t,(()=>(r||(r=!0,setTimeout((()=>(this.render(),r=!1,g(this.el,"odometerdone"))),0)),!0)),!1));return o}}resetFormat(){var e,i,n,r,o,s,a;if((e=null!=(s=this.options.format)?s:"(,ddd).dd")||(e="d"),!(n=t.exec(e)))throw new Error("TmOdometer: Unparsable digit format");return[a,o,i]=n.slice(1,4),r=(null!=i?i.length:void 0)||0,this.format={repeating:a,radix:o,precision:r}}render(t=this.value){var e,i,r,o,s,a,d;for(this.stopWatchingMutations(),this.resetFormat(),this.inside.innerHTML="",d=this.options.theme,a=[],r=0,o=(e=this.el.className.split(" ")).length;r<o;r++)(i=e[r]).length&&((s=/^odometer-theme-(.+)$/.exec(i))?d=s[1]:/^odometer(-|$)/.test(i)||a.push(i));return a.push("odometer"),n||a.push("odometer-no-transitions"),d?a.push(`odometer-theme-${d}`):a.push("odometer-auto-theme"),this.el.className=a.join(" "),this.ribbons={},this.formatDigits(t),this.startWatchingMutations()}formatDigits(t){var e,i,n,r,o,s,a,d,h;if(this.digits=[],this.options.formatFunction)for(i=0,n=(s=this.options.formatFunction(t).split("").reverse()).length;i<n;i++)(d=s[i]).match(/0-9/)?((e=this.renderDigit()).querySelector(".odometer-value").innerHTML=d,this.digits.push(e),this.insertDigit(e)):this.addSpacer(d);else for(t=this.preservePrecision(t),h=!this.format.precision,o=0,r=(a=t.toString().split("").reverse()).length;o<r;o++)"."===(e=a[o])&&(h=!0),this.addDigit(e,h)}preservePrecision(t){var e,i,n,r,o;if(e=t,this.format.precision)for(1===(r=e.toString().split(".")).length&&(e+=".",r[1]=""),i=n=0,o=this.format.precision;0<=o?n<o:n>o;i=0<=o?++n:--n)r[1][i]||(e+="0");return e}update(t){var e;if(e=(t=this.cleanValue(t))-this.value)return m(this.el,"odometer-animating-up odometer-animating-down odometer-animating"),a(this.el,e>0?"odometer-animating-up":"odometer-animating-down"),this.stopWatchingMutations(),this.animate(t),this.startWatchingMutations(),setTimeout((()=>(this.el.offsetHeight,a(this.el,"odometer-animating"))),0),this.value=t}renderDigit(){return d('<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,e,i){var n;return(n=d('<span class="odometer-formatting-mark"></span>')).innerHTML=t,i&&a(n,i),this.insertDigit(n,e)}addDigit(t,e=!0){var i,n,r,o;if("-"===t)return this.addSpacer(t,null,"odometer-negation-mark");if("."===t)return this.addSpacer(null!=(r=this.format.radix)?r:".",null,"odometer-radix-mark");if(e)for(o=!1;;){if(!this.format.repeating.length){if(o)throw new Error("Bad odometer format without digits");this.resetFormat(),o=!0}if(i=this.format.repeating[this.format.repeating.length-1],this.format.repeating=this.format.repeating.substring(0,this.format.repeating.length-1),"d"===i)break;this.addSpacer(i)}return(n=this.renderDigit()).querySelector(".odometer-value").innerHTML=t,this.digits.push(n),this.insertDigit(n)}animate(t){return n&&"count"!==this.options.animation?this.animateSlide(t):this.animateCount(t)}animateCount(t){var e,i,n,r,o;if(i=+t-this.value)return r=n=h(),e=this.value,(o=()=>{var s,a;return h()-r>this.options.duration?(this.value=t,this.render(),void g(this.el,"odometerdone")):((s=h()-n)>50&&(n=h(),a=s/this.options.duration,e+=i*a,this.render(Math.round(e))),null!=c?c(o):setTimeout(o,50))})()}getDigitCount(...t){var e,i,n,r,o;for(e=i=0,n=t.length;i<n;e=++i)o=t[e],t[e]=Math.abs(o);return r=Math.max(...t),Math.ceil(Math.log(r+1)/Math.log(10))}getFractionalDigitCount(...t){var e,i,n,r,o,s;for(r=/^\-?\d*\.(\d*?)0*$/,e=i=0,n=t.length;i<n;e=++i)s=t[e],t[e]=s.toString(),o=r.exec(t[e]),t[e]=null==o?0:o[1].length;return Math.max(...t)}resetDigits(){return this.digits=[],this.ribbons=[],this.inside.innerHTML="",this.resetFormat()}animateSlide(t){var e,i,n,r,o,s,d,h,l,u,m,c,p,f,g,w,M,b,T,x,E,S,y,L,D,F,A;if(L=this.value,(l=this.format.precision)&&(t*=Math.pow(10,l),L*=Math.pow(10,l)),r=t-L){for(this.bindTransitionEnd(),s=[],i=0,c=g=0,D=o=this.getDigitCount(L,t);0<=D?g<D:g>D;c=0<=D?++g:--g){if(A=v(L/Math.pow(10,o-c-1)),d=(h=v(t/Math.pow(10,o-c-1)))-A,Math.abs(d)>this.MAX_VALUES){for(m=[],p=d/(this.MAX_VALUES+this.MAX_VALUES*i*.5),n=A;d>0&&n<h||d<0&&n>h;)m.push(Math.round(n)),n+=p;m[m.length-1]!==h&&m.push(h),i++}else m=function(){for(var t=[],e=A;A<=h?e<=h:e>=h;A<=h?e++:e--)t.push(e);return t}.apply(this);for(c=T=0,w=m.length;T<w;c=++T)u=m[c],m[c]=Math.abs(u%10);s.push(m)}for(this.resetDigits(),c=E=0,M=(F=s.reverse()).length;E<M;c=++E)for(m=F[c],this.digits[c]||this.addDigit(" ",c>=l),null==(e=this.ribbons)[c]&&(e[c]=this.digits[c].querySelector(".odometer-ribbon-inner")),this.ribbons[c].innerHTML="",r<0&&(m=m.reverse()),f=y=0,b=m.length;y<b;f=++y)u=m[f],(S=document.createElement("div")).className="odometer-value",S.innerHTML=u,this.ribbons[c].appendChild(S),f===m.length-1&&a(S,"odometer-last-value"),0===f&&a(S,"odometer-first-value");return A<0&&this.addDigit("-"),null!=(x=this.inside.querySelector(".odometer-radix-mark"))&&x.parent.removeChild(x),l?this.addSpacer(this.format.radix,this.digits[l-1],"odometer-radix-mark"):void 0}}},r.options=null!=(l=window.odometerOptions)?l:{},setTimeout((function(){var t,e,i,n,o;if(window.odometerOptions){for(e in n=[],i=window.odometerOptions)o=i[e],n.push(null!=(t=r.options)[e]?t[e]:t[e]=o);return n}}),0),r.init=function(){var t,e,i,n,o,s;if(null!=document.querySelectorAll){for(s=[],i=0,n=(e=document.querySelectorAll(r.options.selector||".odometer")).length;i<n;i++)t=e[i],s.push(t.odometer=new r({el:t,value:null!=(o=t.innerText)?o:t.textContent}));return s}},null!=(null!=(u=document.documentElement)?u.doScroll:void 0)&&null!=document.createEventObject?(s=document.onreadystatechange,document.onreadystatechange=function(){return"complete"===document.readyState&&!1!==r.options.auto&&r.init(),null!=s?s.apply(this,arguments):void 0}):document.addEventListener("DOMContentLoaded",(function(){if(!1!==r.options.auto)return r.init()}),!1),"function"==typeof define&&define.amd?define([],(function(){return r})):"undefined"!=typeof exports&&null!==exports?(module.exports=r,module.exports.Odometer=r):(window.TmOdometer=r,window.Odometer=r)}).call(this);