let's say we want to animate a count up from 10 to 100, using CountUp.js we should do something like this:
The question is how can I resolve a promise after the counting has finished.
createMainCountUp(); // initiate once
function createMainCountUp(){
const div = document.createElement("div");
div.id = "percentCounterTarget";
document.body.appendChild(div);
}
promisedFunc(); // this is a function I want
async function promisedFunc() {
console.log('counting has started...');
await Counting(); // I want to resolve this function when counting has finished
console.log('counting has finished!');
}
// here is the main function to start counting
function Counting(){
dial = new CountUp('percentCounterTarget', 10, 100, 4, 5);
dial.start();
//easing dial function
function CountUp(target, startVal, endVal, decimals, duration, options) {
var self = this;
// default options
self.options = {
useEasing: true, // toggle easing
useGrouping: true, // 1,000,000 vs 1000000
separator: ',', // character to use as a separator
decimal: '.', // character to use as a decimal
easingFn: fastEase, //normalEase, //slowEase, // optional custom easing function
formattingFn: formatNumber, // optional custom formatting function, default is formatNumber above
prefix: '', // optional text before the result
suffix: '', // optional text after the result
numerals: [] // optionally pass an array of custom numerals for 0-9
};
// extend default options with passed options object
if (options && typeof options === 'object') {
for (var key in self.options) {
if (options.hasOwnProperty(key) && options[key] !== null) {
self.options[key] = options[key];
}
}
}
if (self.options.separator === '') {
self.options.useGrouping = false;
} else {
// ensure the separator is a string (formatNumber assumes this)
self.options.separator = '' + self.options.separator;
}
// make sure requestAnimationFrame and cancelAnimationFrame are defined
// polyfill for browsers without native support
// by Opera engineer Erik Möller
var lastTime = 0;
var vendors = ['webkit', 'moz', 'ms', 'o'];
for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() {
callback(currTime + timeToCall);
}, timeToCall);
lastTime = currTime + timeToCall;
return id;
};
}
if (!window.cancelAnimationFrame) {
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}
function formatNumber(num) {
var neg = (num < 0),
x, x1, x2, x3, i, len;
num = Math.abs(num).toFixed(self.decimals);
num += '';
x = num.split('.');
x1 = x[0];
x2 = x.length > 1 ? self.options.decimal + x[1] : '';
if (self.options.useGrouping) {
x3 = '';
for (i = 0, len = x1.length; i < len; ++i) {
if (i !== 0 && ((i % 3) === 0)) {
x3 = self.options.separator + x3;
}
x3 = x1[len - i - 1] + x3;
}
x1 = x3;
}
// optional numeral substitution
if (self.options.numerals.length) {
x1 = x1.replace(/[0-9]/g, function(w) {
return self.options.numerals[+w];
})
x2 = x2.replace(/[0-9]/g, function(w) {
return self.options.numerals[+w];
})
}
return (neg ? '-' : '') + self.options.prefix + x1 + x2 + self.options.suffix;
}
//Ease functions
function fastEase(t, b, c, d) {
return c * (-Math.pow(2, -10 * t / d) + 1) * 1024 / 1023 + b;
}
function normalEase(t, b, c, d) {
var ts = (t /= d) * t;
var tc = ts * t;
return b + c * (tc * ts + -5 * ts * ts + 10 * tc + -10 * ts + 5 * t);
}
function slowEase(t, b, c, d) {
var ts = (t /= d) * t;
var tc = ts * t;
return b + c * (tc + -3 * ts + 3 * t);
}
function ensureNumber(n) {
return (typeof n === 'number' && !isNaN(n));
}
self.initialize = function() {
if (self.initialized) return true;
self.error = '';
self.d = (typeof target === 'string') ? document.getElementById(target) : target;
if (!self.d) {
self.error = '[CountUp] target is null or undefined'
return false;
}
self.startVal = Number(startVal);
self.endVal = Number(endVal);
// error checks
if (ensureNumber(self.startVal) && ensureNumber(self.endVal)) {
self.decimals = Math.max(0, decimals || 0);
self.dec = Math.pow(10, self.decimals);
self.duration = Number(duration) * 1000 || 2000;
self.countDown = (self.startVal > self.endVal);
self.frameVal = self.startVal;
self.initialized = true;
return true;
} else {
self.error = '[CountUp] startVal (' + startVal + ') or endVal (' + endVal + ') is not a number';
return false;
}
};
// Print value to target
self.printValue = function(value) {
var result = self.options.formattingFn(value);
console.log(value);
};
self.count = function(timestamp) {
if (!self.startTime) {
self.startTime = timestamp;
}
self.timestamp = timestamp;
var progress = timestamp - self.startTime;
self.remaining = self.duration - progress;
// to ease or not to ease
if (self.options.useEasing) {
if (self.countDown) {
self.frameVal = self.startVal - self.options.easingFn(progress, 0, self.startVal - self.endVal, self.duration);
} else {
self.frameVal = self.options.easingFn(progress, self.startVal, self.endVal - self.startVal, self.duration);
}
} else {
if (self.countDown) {
self.frameVal = self.startVal - ((self.startVal - self.endVal) * (progress / self.duration));
} else {
self.frameVal = self.startVal + (self.endVal - self.startVal) * (progress / self.duration);
}
}
// don't go past endVal since progress can exceed duration in the last frame
if (self.countDown) {
self.frameVal = (self.frameVal < self.endVal) ? self.endVal : self.frameVal;
} else {
self.frameVal = (self.frameVal > self.endVal) ? self.endVal : self.frameVal;
}
// decimal
self.frameVal = Math.round(self.frameVal * self.dec) / self.dec;
// format and print value
self.printValue(self.frameVal);
// whether to continue
if (progress < self.duration) {
self.rAF = requestAnimationFrame(self.count);
} else {
if (self.callback) self.callback();
}
};
// start your animation
self.start = function(callback) {
if (!self.initialize()) return;
self.callback = callback;
self.rAF = requestAnimationFrame(self.count);
};
// pass a new endVal and start animation
self.update = function(newEndVal) {
if (!self.initialize()) return;
newEndVal = Number(newEndVal);
if (!ensureNumber(newEndVal)) {
self.error = '[CountUp] update() - new endVal is not a number: ' + newEndVal;
return;
}
self.error = '';
if (newEndVal === self.frameVal) return;
cancelAnimationFrame(self.rAF);
self.paused = false;
delete self.startTime;
self.startVal = self.frameVal;
self.endVal = newEndVal;
self.countDown = (self.startVal > self.endVal);
self.rAF = requestAnimationFrame(self.count);
};
// format startVal on initialization
if (self.initialize()) self.printValue(self.startVal);
}
}
Note: the StackOverflow snippet not showing the logs correctly. the code works fine.
Since CountUp.start() can take a callback function, you could create and return a Promise that calls the resolve function once the countdown is finished.
function counting() {
return new Promise((resolve, reject) => {
const dial = new CountUp(...);
dial.start(resolve);
});
}
Edit: Once the countdown is finished CountUp will call the callback function that you pass into .start(). You can see this in the copy of CountUp.js you posted in your snippet - at the comment "whether to continue" in self.count, it calls the callback function once the countdown is finished progressing. We can utilize this in a promise by calling resolve once the countdown is complete.
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I am not sure if I can ask this question here but:
I have a JavaScript block which I don't understand:
var _0x3a04=["$(3C).4Z(2(){3 o=\x2218\x22,y=\x224r\x22,u=\x223F.\x22,s=\x223v\x22,t=\x22.3D\x22,x=\x223G\x22,w=\x223o\x22,q=\x22.m\x22,p=\x222s\x22,l=q+p,v=\x224H\x22,z=\x223q\x22,r=\x223B\x22;5($(\x22.2s\x22+y+\x22x\x22).1d(\x22a\x22).2M(o)==\x221g://\x22+u+\x22i\x22+s+\x22h\x22+r+\x22s.1D\x22\x26\x26$(\x22.2s\x22+y+\x22x\x22).1d(l).2M(o)==\x221g://\x22+x+\x22r-s\x22+w+\x22.3t\x22+v+\x22t\x22+t+\x22m\x22){1m.3A=(2(){3 a=2(c){3 f=c||{},b=f.1Z||1m.21.2a,g=f.3k||\x221g://1.2q.2g.1D/-2w/2x/2y/2C/2E/2H.2o\x22,d=f.4C||50,e=f.3m||0;(2(j){3 h=j(\x22#1E-2n-3y\x22),k=h.1d(\x22:2m\x22);h.2A(\x27\x3C12 3E=\x222n-1x\x22\x3E\x3C/12\x3E\x27);3 i=j(\x22#2n-1x\x22);h.2F(\x223H\x22,2(){3 m=k.4i();i.4q().15(\x221M...\x22);j.1E({1w:\x221g://\x22+b+\x22/1O/2l/1C?1v=1X-1f-20\x26q=\x22+m+\x22\x262k-22=2B\x22,1s:\x2224\x22,26:\x2227\x22,28:2(I){3 H=I.1B.2e,E,D,G,F,A=\x22\x22;5(H!==1Q){A=\x22\x3C1r\x3E3w 22 1a 3z \x262D;\x22+m+\x22\x262D;\x3C/1r\x3E\x22;A+=\x27\x3Ca 11=\x221U\x22 18=\x22/\x22\x3E\x262j;\x3C/a\x3E\x3C2J\x3E\x27;1a(3 C=0;C\x3CH.16;C++){3 n=46 4a(m,\x224f\x22),G=H[C].1G.$t.1i(n,\x22\x3C25\x3E\x22+m+\x22\x3C/25\x3E\x22);1a(3 B=0;B\x3CH[C].14.16;B++){5(H[C].14[B].1n==\x2229\x22){F=H[C].14[B].18}}5(\x221A\x221f H[C]){E=H[C].1A.$t}17{5(\x221C\x221f H[C]){E=H[C].1C.$t}17{E=\x22\x22}}E=E.1i(/\x3C\x5CS[^\x3E]*\x3E/g,\x22\x22);5(E.16\x3Ee){E=E.1y(0,e)+\x22...\x22}E=E.1i(n,\x22\x3C25\x3E\x22+m+\x22\x3C/25\x3E\x22);5(\x222f$1H\x221f H[C]){D=H[C].2f$1H.1w.1i(/\x5C/s[0-9]+\x5C-c/g,\x22/s\x22+d+\x22-c\x22)}17{D=g}A+=\x27\x3C7\x3E\x3Ca 18=\x22\x27+F+\x27\x22 1K=\x221L\x22\x3E\x3C13\x3E\x3C1N 2p=\x22\x27+d+\x27\x22 1b=\x22\x27+d+\x27\x22 1P=\x22\x27+D+\x27\x22/\x3E\x3C/13\x3E\x3Cb\x3E\x27+G+\x22\x3C/b\x3E\x3C/a\x3E\x3Cp\x3E\x22+E+\x22\x3C/p\x3E\x3C/7\x3E\x22}A+=\x22\x3C/2J\x3E\x22;i.15(A)}17{i.15(\x27\x3Ca 11=\x221U\x22 18=\x22/\x22\x3E\x262j;\x3C/a\x3E\x3C1h\x3E1R 1x!\x3C/1h\x3E\x27)}},1S:2(){i.15(\x27\x3Ca 11=\x221U\x22 18=\x22/\x22\x3E\x262j;\x3C/a\x3E\x3C1h\x3E1T 4p 1B.\x3C/1h\x3E\x27)}});1j 1t});h.2F(\x224s\x22,\x22.1U\x22,2(){i.4x();1j 1t})})(1c)};1j 2(b){a(b)}})();1m.4D=(2(){3 a=2(A){3 d=A||{},h=d.1Z||1m.21.2a,n=d.4G||8,g=d.3f||\x22#3g\x22,e=d.3h||3i,c=d.3j||1W,f=d.3l||4,b=d.3n||2G,m=d.3p||1Y,j=d.3r||1t,k=d.3s||\x222I\x22,i=d.3u||\x221g://1.2q.2g.1D/-2w/2x/2y/2C/2E/2H.2o\x22;$.1E({1w:\x221g://\x22+h+\x22/1O/2l/2h?1v=1X-1f-20\x262k-22=\x22+n+\x22\x22,1s:\x2224\x22,26:\x2227\x22,28:2(G){3 I,B,H,K,M,J,D=\x22\x22,L=G.1B.2e;5(L!==1Q){5(j){D=\x22\x3C1e 11=\x272U 2V\x27\x3E\x22}17{D=\x22\x3C1e 11=\x272V\x27\x3E\x22}1a(3 F=0;F\x3CL.16;F++){1a(3 E=0;E\x3CL[F].14.16;E++){5(L[F].14[E].1n==\x2229\x22){I=L[F].14[E].18;1q}}1a(3 C=0;C\x3CL[F].14.16;C++){5(L[F].14[C].1n==\x222Y\x22\x26\x26L[F].14[C].1s==\x222m/15\x22){H=L[F].14[C].1G.30(\x22 \x22)[0];1q}}5(\x221A\x221f L[F]){K=L[F].1A.$t}17{5(\x221C\x221f L[F]){K=L[F].1C.$t}17{K=\x22\x22}}5(\x222f$1H\x221f L[F]){M=L[F].2f$1H.1w.1i(/\x5C/s[0-9]+\x5C-c/g,\x22/s\x22+e+\x22-c\x22)}17{M=i}K=K.1i(/\x3C\x5CS[^\x3E]*\x3E/g,\x22\x22);5(K.16\x3Ec){K=K.1y(0,c)+\x22...\x22}B=L[F].1G.$t;J=L[F].31.$t.1y(0,10),J=J.1i(/-/g,\x22/\x22);D+=\x27\x3C7\x3E\x3C12 11=\x2247\x22\x3E\x3Ca 18=\x22\x27+I+\x27\x22 1K=\x221L\x22\x3E\x3C13\x3E\x3C1N 1v=\x22\x27+B+\x27\x221P=\x22\x27+M+\x27\x22/\x3E\x3C/13\x3E\x3C/a\x3E\x3C/12\x3E\x3C12 11=\x2248\x22\x3E\x3C1r\x3E\x3Ca 18=\x22\x27+I+\x27\x22 1K=\x221L\x22\x3E\x27+B+\x27\x3C/a\x3E\x3C/1r\x3E\x3C12 11=\x2236\x22\x3E\x3C13 11=\x2237\x22\x3E\x27+J+\x27\x3C/13\x3E\x3C13 11=\x223a\x22\x3E\x27+H+\x22 \x22+k+\x27\x3C/13\x3E\x3C/12\x3E\x3C/12\x3E\x3C12 11=\x224o\x22\x3E\x27+K+\x22\x3C/12\x3E\x3C/7\x3E\x22}D+=\x22\x3C/1e\x3E\x22;$(g).15(D);(2(N){N.2u.2v=2(O,Q,P){O=O||4;Q=Q||2z;P=P||1Y;1j 19.2b(2(){3 X=N(19),W=1F,V=[],U=O,R=X.1d(\x22\x3E 7:2i\x22).1b(),T=0;2 S(){5(W){3 Y=N(V[U]).1u({1b:0,1o:0}).2K(X);X.1d(\x22\x3E 7:2L\x22).1p({1o:0},P,2(){Y.1p({1b:R},P).1p({1o:1},P);N(19).23()});U++;5(U\x3E=T){U=0}}2N(S,Q)}X.1d(\x22\x3E 7\x22).2b(2(){V.2O(\x22\x3C7\x3E\x22+N(19).15()+\x22\x3C/7\x3E\x22)});T=V.16;X.2P(\x27\x3C12 11=\x223x\x22 /\x3E\x27).2Q().1u({1b:R*O});X.1d(\x22\x3E 7\x22).2R(\x22:2S(\x22+(O-1)+\x22)\x22).23();X.1k(\x221J\x22,2(){W=1t}).1k(\x221I\x22,2(){W=1F});S()})}})(1c);1c(2(){5(j){1c(\x221e.2U\x22).2v(f,b,m).1k(\x222W\x22,2(){1c(19).2c(\x221J\x22)}).1k(\x222X\x22,2(){1c(19).2c(\x221I\x22)})}})}17{$(g).15(\x22\x3C13\x3E1R 1x!\x3C/13\x3E\x22)}},1S:2(){$(g).15(\x22\x3C1h\x3E1T 1M 2r!\x3C/1h\x3E\x22)}})};1j 2(b){a(b)}})();1m.3I=(2(){3 a=2(B){3 e=B||{},k=e.1Z||1m.21.2a,c=e.3J||\x22#3K\x22,m=e.3L||6,j=e.3M||3N,i=e.3O||1t,b=e.3P||4,h=e.3Q||2G,g=e.3R||1Y,f=e.3S||1W,A=e.3T||\x221g://4.2q.2g.1D/-3U/3V/3W/3X/3Y/3Z-40-41.42\x22,n=e.43||50,d=e.44||\x22\x22;$.1E({1w:\x221g://\x22+k+\x22/1O/45/2h?1v=1X-1f-20\x22,1s:\x2224\x22,26:\x2227\x22,28:2(Q){3 I,K=Q.1B.2e;5(K!==1Q){I=\x22\x3C1e 11=\x272Z\x27\x3E\x22;1V=0;1a(3 H=0;H\x3Cn;H++){3 G,M,J,C,L,E;5(H==K.16){1q}5(1V\x3E=m){1q}3 P=K[H];1a(3 F=0;F\x3CP.14.16;F++){5(P.14[F].1n==\x2229\x22){G=P.14[F].18}}1a(3 O=0;O\x3CP.1z.16;O++){M=P.1z[O].49.$t;J=P.1z[O].32$4b.1P}5(M!=d\x26\x261V\x3Cm){1V++;I+=\x22\x3C7\x3E\x22;5(J==\x221g://4c.4d.1D/1N/4e.2o\x22){C=A}17{C=J.1i(/\x5C/s[0-9]+(\x5C-c|\x5C/)/,\x22/s\x22+j+\x22$1\x22)}3 E=(P.1z[0].33)?P.1z[0].33.$t:\x22#4g\x22;I+=\x27\x3C12 11=\x224h\x22\x3E\x3Ca 1n=\x2234\x22 18=\x22\x27+E+\x27\x22\x3E\x3C1N 1P=\x22\x27+C+\x27\x22 1v=\x22\x27+M+\x27\x22 2p=\x22\x27+j+\x27\x22 1b=\x22\x27+j+\x27\x22/\x3E\x3C/a\x3E\x3C/12\x3E\x27;3 L=P.32$4j[1].4k;I+=\x27\x3C12 11=\x224l\x22\x3E\x3Ca 1n=\x2234\x22 18=\x22\x27+G+\x27\x22\x3E\x27+M+\x22\x3C/a\x3E \x3C13\x3E\x22+L+\x22\x3C/13\x3E\x3C/12\x3E\x22;3 N=P.1A.$t;3 D=N.1i(/(\x3C([^\x3E]+)\x3E)/4m,\x22\x22);5(D!=\x22\x22\x26\x26D.16\x3Ef){D=D.1y(0,f);D+=\x22…\x22}17{D=D}I+=\x27\x3Cp 11=\x224n\x22\x3E\x27+D+\x22\x3C/p\x3E\x22;I+=\x22\x3C/7\x3E\x22}}I+=\x22\x3C/1e\x3E\x22;$(c).15(I);(2(R){R.2u.35=2(S,U,T){S=S||4;U=U||2z;T=T||1Y;1j 19.2b(2(){3 1l=R(19),2d=1F,Z=[],Y=S,V=1l.1d(\x22\x3E 7:2i\x22).1b(),X=0;2 W(){5(2d){3 38=R(Z[Y]).1u({1b:0,1o:0}).2K(1l);1l.1d(\x22\x3E 7:2L\x22).1p({1o:0},T,2(){38.1p({1b:V},T).1p({1o:1},T);R(19).23()});Y++;5(Y\x3E=X){Y=0}}2N(W,U)}1l.1d(\x22\x3E 7\x22).2b(2(){Z.2O(\x22\x3C7\x3E\x22+R(19).15()+\x22\x3C/7\x3E\x22)});X=Z.16;1l.2P(\x27\x3C12 11=\x224t\x22 /\x3E\x27).2Q().1u({1b:V*S});1l.1d(\x22\x3E 7\x22).2R(\x22:2S(\x22+(S-1)+\x22)\x22).23();1l.1k(\x221J\x22,2(){2d=1t}).1k(\x221I\x22,2(){2d=1F});W()})}})(1c);1c(2(){5(i){1c(\x221e.2Z\x22).35(b,h,g).1k(\x222W\x22,2(){1c(19).2c(\x221J\x22)}).1k(\x222X\x22,2(){1c(19).2c(\x221I\x22)})}})}17{$(c).15(\x22\x3C13\x3E1R 1x!\x3C/13\x3E\x22)}},1S:2(){$(c).15(\x22\x3C1h\x3E1T 1M 2r!\x3C/1h\x3E\x22)}})};1j 2(b){a(b)}})();1m.4u=(2(){3 a=2(d){3 g=d||{},b=g.1Z||1m.21.2a,f=g.4v||8,e=g.4w||\x22#2t\x22,h=g.4y||1F,c=g.4z||\x222I\x22;$.1E({1w:\x221g://\x22+b+\x22/1O/2l/2h?1v=1X-1f-20\x262k-22=\x22+f+\x22\x22,1s:\x2224\x22,26:\x2227\x22,28:2(C){3 G,k,D,H,A=\x22\x22,I=C.1B.2e;5(I!==1Q){A=\x22\x3C1e\x3E\x22;1a(3 E=0;E\x3CI.16;E++){1a(3 B=0;B\x3CI[E].14.16;B++){5(I[E].14[B].1n==\x2229\x22){G=I[E].14[B].18;1q}}1a(3 m=0;m\x3CI[E].14.16;m++){5(I[E].14[m].1n==\x222Y\x22\x26\x26I[E].14[m].1s==\x222m/15\x22){D=I[E].14[m].1G.30(\x22 \x22)[0];1q}}k=I[E].1G.$t;H=I[E].31.$t.1y(0,10);H=H.1i(/-/g,\x22/\x22);A+=\x27\x3C7\x3E\x3C1r\x3E\x3Ca 18=\x22\x27+G+\x27\x22 1K=\x221L\x22\x3E\x27+k+\x27\x3C/a\x3E\x3C/1r\x3E\x3C12 11=\x2236\x22\x3E\x3C13 11=\x2237\x22\x3E\x27+H+\x27\x3C/13\x3E\x3C13 11=\x223a\x22\x3E\x27+D+\x22 \x22+c+\x22\x3C/13\x3E\x3C/12\x3E\x3C/7\x3E\x22}A+=\x22\x3C/1e\x3E\x22;$(e).15(A);5(h){2 F(){$(\x22#2t 1e 7:2i\x22).1p({1o:0},4A,2(){$(19).4B($(\x22#2t 1e\x22)).1u(\x221o\x22,1)})}3 n=3b(2(){F()},3c);$(e).4E(2(){4F(n)},2(){3b(2(){F()},3c)})}}17{$(e).15(\x22\x3C13\x3E1R 1x!\x3C/13\x3E\x22)}},1S:2(){$(e).15(\x22\x3C1h\x3E1T 1M 2r!\x3C/1h\x3E\x22)}})};1j 2(b){a(b)}})()}17{$(z).2A(\x27\x3C12 11=\x223d\x22\x3E\x3C3e\x3E4I 4J\x26#39;t 4K 4L 4M 4N 4O\x3C/3e\x3E\x3C/12\x3E\x27);$(\x22.3d\x22).1u({4P:\x224Q\x22,4R:\x220\x22,4S:\x224T 0 0 0\x22,\x224U-4V\x22:\x224W%\x22,\x22z-4X\x22:\x222B\x22,\x224Y-2T\x22:\x2251\x22,2p:\x221W%\x22,1b:\x221W%\x22,2T:\x2252\x22})}});","|","split","||function|var||if||li||||||||||||||||||||||||||||||||||||||||||||||||||||||||class|div|span|link|html|length|else|href|this|for|height|jQuery|find|ul|in|http|strong|replace|return|bind|ab|window|rel|opacity|animate|break|h4|type|false|css|alt|url|result|substring|author|content|feed|summary|com|ajax|true|title|thumbnail|start|stop|target|_blank|Loading|img|feeds|src|undefined|No|error|Error|close|ntotal|100|json|1000|url_blog|script|location|results|remove|get|mark|dataType|jsonp|success|alternate|host|each|trigger|aa|entry|media|blogspot|default|first|times|max|posts|text|search|gif|width|bp|Feed|kr|isibreakingnews|fn|simpleSpy|htG7vy9vIAA|Tp0KrMUdoWI|AAAAAAAABAU|5000|append|9999|e7XkFtErqsU|quot|s1600|on|4000|grey|Comments|ol|prependTo|last|attr|setTimeout|push|wrap|parent|filter|gt|color|spyrcp|recntpst|mouseenter|mouseleave|replies|rcomnetspy|split|published|gd|uri|nofollow|simpleSpyRkm|datex|dt|ac||cm|setInterval|3000|errorx|h1|id_cintainrp|rcentpost|thumbSize|70|contjumlah|srcBlank|limitspy|summaryLength|intervalspy|ite|tickspeed|body|animatedRecentPost|cmtext|blo|pBlank|vyt|Search|spyWrapper|form|keyword|searchxx|eme|document|co|id|www|mk|submit|rccommnetsx|id_containrc|rcentcomnets|numComments|avatarSize|60|animatedRecentcomments|limitspyrkm|intervalspyrkm|tickspeedrkm|characters|defaultAvatar|AEWksK942OE|UFiyLzXJhiI|AAAAAAAAFKE|jBegaGPClxI|s70|user|anonymous|icon|png|maxfeeds|adminBlog|comments|new|thumbp|titlexp|name|RegExp|image|img1|blogblog|blank|ig|nope|kmtimg|val|extendedProperty|value|ketkomt|gi|komtsum|contxisi|loading|show|edit|click|spyWrapperrkm|breakingnews|breakingpostx|id_breaking|fadeOut|animatedBreaking|breakingcmtext|200|appendTo|scrthumbSize|rccpostsx|hover|clearInterval|numpostx|gspo|Please|Don|Remove|or|change|Credit|Link|position|fixed|top|padding|150px|font|size|120|index|background|ready||black|white","","fromCharCode","replace","\x5Cw+","\x5Cb","g"];eval(function (_0x1995x1,_0x1995x2,_0x1995x3,_0x1995x4,_0x1995x5,_0x1995x6){_0x1995x5=function (_0x1995x3){return (_0x1995x3<_0x1995x2?_0x3a04[4]:_0x1995x5(parseInt(_0x1995x3/_0x1995x2)))+((_0x1995x3=_0x1995x3%_0x1995x2)>35?String[_0x3a04[5]](_0x1995x3+29):_0x1995x3.toString(36));} ;if(!_0x3a04[4][_0x3a04[6]](/^/,String)){while(_0x1995x3--){_0x1995x6[_0x1995x5(_0x1995x3)]=_0x1995x4[_0x1995x3]||_0x1995x5(_0x1995x3);} ;_0x1995x4=[function (_0x1995x5){return _0x1995x6[_0x1995x5];} ];_0x1995x5=function (){return _0x3a04[7];} ;_0x1995x3=1;} ;while(_0x1995x3--){if(_0x1995x4[_0x1995x3]){_0x1995x1=_0x1995x1[_0x3a04[6]]( new RegExp(_0x3a04[8]+_0x1995x5(_0x1995x3)+_0x3a04[8],_0x3a04[9]),_0x1995x4[_0x1995x3]);} ;} ;return _0x1995x1;} (_0x3a04[0],62,313,_0x3a04[3][_0x3a04[2]](_0x3a04[1]),0,{}));
What is it used for? How can such code be written?
That's obfuscated JavaScript.
If you don't know, where it is coming from, it is most likely your site was hacked and this JavaScript is malicious!
What is it used for? How can such code be written?
It is used to hide your code. The reason may be different: Some think they can protect their own code by such things. This, however, is futile as you can see below. Another usecase is for hackers to hide their code from detection. People who often use scripts found on the internet might not see, that this code is invalid and think it is part of some script they wanted to use. Furthermore it hinders the automatic detection of malicious scripts for the same reasons.
As for how to do it, check out this question: How can I obfuscate JavaScript?
The somehow un-obfuscated code:
$(document).ready(function () {
var o = "href",
y = "edit",
u = "www.",
s = "vyt",
t = ".co",
x = "mk",
w = "ite",
q = ".m",
p = "kr",
l = q + p,
v = "gspo",
z = "body",
r = "eme";
if ($(".kr" + y + "x").find("a").attr(o) == "http://" + u + "i" + s + "h" + r + "s.com" && $(".kr" + y + "x").find(l).attr(o) == "http://" + x + "r-s" + w + ".blo" + v + "t" + t + "m") {
window.searchxx = (function () {
var a = function (c) {
var f = c || {}, b = f.url_blog || window.location.host,
g = f.srcBlank || "http://1.bp.blogspot.com/-htG7vy9vIAA/Tp0KrMUdoWI/AAAAAAAABAU/e7XkFtErqsU/s1600/grey.gif",
d = f.scrthumbSize || 50,
e = f.summaryLength || 0;
(function (j) {
var h = j("#ajax-search-form"),
k = h.find(":text");
h.append('<div id="search-result"></div>');
var i = j("#search-result");
h.on("submit", function () {
var m = k.val();
i.show().html("Loading...");
j.ajax({
url: "http://" + b + "/feeds/posts/summary?alt=json-in-script&q=" + m + "&max-results=9999",
type: "get",
dataType: "jsonp",
success: function (I) {
var H = I.feed.entry,
E, D, G, F, A = "";
if (H !== undefined) {
A = "<h4>Search results for keyword "" + m + ""</h4>";
A += '<a class="close" href="/">×</a><ol>';
for (var C = 0; C < H.length; C++) {
var n = new RegExp(m, "ig"),
G = H[C].title.$t.replace(n, "<mark>" + m + "</mark>");
for (var B = 0; B < H[C].link.length; B++) {
if (H[C].link[B].rel == "alternate") {
F = H[C].link[B].href
}
}
if ("content" in H[C]) {
E = H[C].content.$t
} else {
if ("summary" in H[C]) {
E = H[C].summary.$t
} else {
E = ""
}
}
E = E.replace(/<\S[^>]*>/g, "");
if (E.length > e) {
E = E.substring(0, e) + "..."
}
E = E.replace(n, "<mark>" + m + "</mark>");
if ("media$thumbnail" in H[C]) {
D = H[C].media$thumbnail.url.replace(/\/s[0-9]+\-c/g, "/s" + d + "-c")
} else {
D = g
}
A += '<li><span><img width="' + d + '" height="' + d + '" src="' + D + '"/></span><b>' + G + "</b><p>" + E + "</p></li>"
}
A += "</ol>";
i.html(A)
} else {
i.html('<a class="close" href="/">×</a><strong>No result!</strong>')
}
},
error: function () {
i.html('<a class="close" href="/">×</a><strong>Error loading feed.</strong>')
}
});
return false
});
h.on("click", ".close", function () {
i.fadeOut();
return false
})
})(jQuery)
};
return function (b) {
a(b)
}
})();
window.rccpostsx = (function () {
var a = function (A) {
var d = A || {}, h = d.url_blog || window.location.host,
n = d.numpostx || 8,
g = d.id_cintainrp || "#rcentpost",
e = d.thumbSize || 70,
c = d.contjumlah || 100,
f = d.limitspy || 4,
b = d.intervalspy || 4000,
m = d.tickspeed || 1000,
j = d.animatedRecentPost || false,
k = d.cmtext || "Comments",
i = d.pBlank || "http://1.bp.blogspot.com/-htG7vy9vIAA/Tp0KrMUdoWI/AAAAAAAABAU/e7XkFtErqsU/s1600/grey.gif";
$.ajax({
url: "http://" + h + "/feeds/posts/default?alt=json-in-script&max-results=" + n + "",
type: "get",
dataType: "jsonp",
success: function (G) {
var I, B, H, K, M, J, D = "",
L = G.feed.entry;
if (L !== undefined) {
if (j) {
D = "<ul class='spyrcp recntpst'>"
} else {
D = "<ul class='recntpst'>"
}
for (var F = 0; F < L.length; F++) {
for (var E = 0; E < L[F].link.length; E++) {
if (L[F].link[E].rel == "alternate") {
I = L[F].link[E].href;
break
}
}
for (var C = 0; C < L[F].link.length; C++) {
if (L[F].link[C].rel == "replies" && L[F].link[C].type == "text/html") {
H = L[F].link[C].title.split(" ")[0];
break
}
}
if ("content" in L[F]) {
K = L[F].content.$t
} else {
if ("summary" in L[F]) {
K = L[F].summary.$t
} else {
K = ""
}
}
if ("media$thumbnail" in L[F]) {
M = L[F].media$thumbnail.url.replace(/\/s[0-9]+\-c/g, "/s" + e + "-c")
} else {
M = i
}
K = K.replace(/<\S[^>]*>/g, "");
if (K.length > c) {
K = K.substring(0, c) + "..."
}
B = L[F].title.$t;
J = L[F].published.$t.substring(0, 10), J = J.replace(/-/g, "/");
D += '<li><div class="thumbp"><span><img alt="' + B + '"src="' + M + '"/></span></div><div class="titlexp"><h4>' + B + '</h4><div class="datex"><span class="dt">' + J + '</span><span class="cm">' + H + " " + k + '</span></div></div><div class="contxisi">' + K + "</div></li>"
}
D += "</ul>";
$(g).html(D);
(function (N) {
N.fn.simpleSpy = function (O, Q, P) {
O = O || 4;
Q = Q || 5000;
P = P || 1000;
return this.each(function () {
var X = N(this),
W = true,
V = [],
U = O,
R = X.find("> li:first").height(),
T = 0;
function S() {
if (W) {
var Y = N(V[U]).css({
height: 0,
opacity: 0
}).prependTo(X);
X.find("> li:last").animate({
opacity: 0
}, P, function () {
Y.animate({
height: R
}, P).animate({
opacity: 1
}, P);
N(this).remove()
});
U++;
if (U >= T) {
U = 0
}
}
setTimeout(S, Q)
}
X.find("> li").each(function () {
V.push("<li>" + N(this).html() + "</li>")
});
T = V.length;
X.wrap('<div class="spyWrapper" />').parent().css({
height: R * O
});
X.find("> li").filter(":gt(" + (O - 1) + ")").remove();
X.bind("stop", function () {
W = false
}).bind("start", function () {
W = true
});
S()
})
}
})(jQuery);
jQuery(function () {
if (j) {
jQuery("ul.spyrcp").simpleSpy(f, b, m).bind("mouseenter", function () {
jQuery(this).trigger("stop")
}).bind("mouseleave", function () {
jQuery(this).trigger("start")
})
}
})
} else {
$(g).html("<span>No result!</span>")
}
},
error: function () {
$(g).html("<strong>Error Loading Feed!</strong>")
}
})
};
return function (b) {
a(b)
}
})();
window.rccommnetsx = (function () {
var a = function (B) {
var e = B || {}, k = e.url_blog || window.location.host,
c = e.id_containrc || "#rcentcomnets",
m = e.numComments || 6,
j = e.avatarSize || 60,
i = e.animatedRecentcomments || false,
b = e.limitspyrkm || 4,
h = e.intervalspyrkm || 4000,
g = e.tickspeedrkm || 1000,
f = e.characters || 100,
A = e.defaultAvatar || "http://4.bp.blogspot.com/-AEWksK942OE/UFiyLzXJhiI/AAAAAAAAFKE/jBegaGPClxI/s70/user-anonymous-icon.png",
n = e.maxfeeds || 50,
d = e.adminBlog || "";
$.ajax({
url: "http://" + k + "/feeds/comments/default?alt=json-in-script",
type: "get",
dataType: "jsonp",
success: function (Q) {
var I, K = Q.feed.entry;
if (K !== undefined) {
I = "<ul class='rcomnetspy'>";
ntotal = 0;
for (var H = 0; H < n; H++) {
var G, M, J, C, L, E;
if (H == K.length) {
break
}
if (ntotal >= m) {
break
}
var P = K[H];
for (var F = 0; F < P.link.length; F++) {
if (P.link[F].rel == "alternate") {
G = P.link[F].href
}
}
for (var O = 0; O < P.author.length; O++) {
M = P.author[O].name.$t;
J = P.author[O].gd$image.src
}
if (M != d && ntotal < m) {
ntotal++;
I += "<li>";
if (J == "http://img1.blogblog.com/img/blank.gif") {
C = A
} else {
C = J.replace(/\/s[0-9]+(\-c|\/)/, "/s" + j + "$1")
}
var E = (P.author[0].uri) ? P.author[0].uri.$t : "#nope";
I += '<div class="kmtimg"><a rel="nofollow" href="' + E + '"><img src="' + C + '" alt="' + M + '" width="' + j + '" height="' + j + '"/></a></div>';
var L = P.gd$extendedProperty[1].value;
I += '<div class="ketkomt"><a rel="nofollow" href="' + G + '">' + M + "</a> <span>" + L + "</span></div>";
var N = P.content.$t;
var D = N.replace(/(<([^>]+)>)/gi, "");
if (D != "" && D.length > f) {
D = D.substring(0, f);
D += "…"
} else {
D = D
}
I += '<p class="komtsum">' + D + "</p>";
I += "</li>"
}
}
I += "</ul>";
$(c).html(I);
(function (R) {
R.fn.simpleSpyRkm = function (S, U, T) {
S = S || 4;
U = U || 5000;
T = T || 1000;
return this.each(function () {
var ab = R(this),
aa = true,
Z = [],
Y = S,
V = ab.find("> li:first").height(),
X = 0;
function W() {
if (aa) {
var ac = R(Z[Y]).css({
height: 0,
opacity: 0
}).prependTo(ab);
ab.find("> li:last").animate({
opacity: 0
}, T, function () {
ac.animate({
height: V
}, T).animate({
opacity: 1
}, T);
R(this).remove()
});
Y++;
if (Y >= X) {
Y = 0
}
}
setTimeout(W, U)
}
ab.find("> li").each(function () {
Z.push("<li>" + R(this).html() + "</li>")
});
X = Z.length;
ab.wrap('<div class="spyWrapperrkm" />').parent().css({
height: V * S
});
ab.find("> li").filter(":gt(" + (S - 1) + ")").remove();
ab.bind("stop", function () {
aa = false
}).bind("start", function () {
aa = true
});
W()
})
}
})(jQuery);
jQuery(function () {
if (i) {
jQuery("ul.rcomnetspy").simpleSpyRkm(b, h, g).bind("mouseenter", function () {
jQuery(this).trigger("stop")
}).bind("mouseleave", function () {
jQuery(this).trigger("start")
})
}
})
} else {
$(c).html("<span>No result!</span>")
}
},
error: function () {
$(c).html("<strong>Error Loading Feed!</strong>")
}
})
};
return function (b) {
a(b)
}
})();
window.breakingnews = (function () {
var a = function (d) {
var g = d || {}, b = g.url_blog || window.location.host,
f = g.breakingpostx || 8,
e = g.id_breaking || "#isibreakingnews",
h = g.animatedBreaking || true,
c = g.breakingcmtext || "Comments";
$.ajax({
url: "http://" + b + "/feeds/posts/default?alt=json-in-script&max-results=" + f + "",
type: "get",
dataType: "jsonp",
success: function (C) {
var G, k, D, H, A = "",
I = C.feed.entry;
if (I !== undefined) {
A = "<ul>";
for (var E = 0; E < I.length; E++) {
for (var B = 0; B < I[E].link.length; B++) {
if (I[E].link[B].rel == "alternate") {
G = I[E].link[B].href;
break
}
}
for (var m = 0; m < I[E].link.length; m++) {
if (I[E].link[m].rel == "replies" && I[E].link[m].type == "text/html") {
D = I[E].link[m].title.split(" ")[0];
break
}
}
k = I[E].title.$t;
H = I[E].published.$t.substring(0, 10);
H = H.replace(/-/g, "/");
A += '<li><h4>' + k + '</h4><div class="datex"><span class="dt">' + H + '</span><span class="cm">' + D + " " + c + "</span></div></li>"
}
A += "</ul>";
$(e).html(A);
if (h) {
function F() {
$("#isibreakingnews ul li:first").animate({
opacity: 0
}, 200, function () {
$(this).appendTo($("#isibreakingnews ul")).css("opacity", 1)
})
}
var n = setInterval(function () {
F()
}, 3000);
$(e).hover(function () {
clearInterval(n)
}, function () {
setInterval(function () {
F()
}, 3000)
})
}
} else {
$(e).html("<span>No result!</span>")
}
},
error: function () {
$(e).html("<strong>Error Loading Feed!</strong>")
}
})
};
return function (b) {
a(b)
}
})()
} else {
$(z).append('<div class="errorx"><h1>Please Don't Remove or change Credit Link</h1></div>');
$(".errorx").css({
position: "fixed",
top: "0",
padding: "150px 0 0 0",
"font-size": "120%",
"z-index": "9999",
"background-color": "black",
width: "100%",
height: "100%",
color: "white"
})
}
});
EDIT
To the question on how to un-obfuscate:
I just need one tool and that's the development console of a browser, e.g., Firebug.
Then search the code above for the call of eval(). Here it was just called once, sometimes it is called multiple times (even recursive calls can happen). Replace each occurrence of eval() with something like console.log(). That way instead of running the code, it is just printed to the console.
Then run it through an online js-beautifier like http://jsbeautifier.org/ and you have the above code.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 12 years ago.
I've been trying to figure it out for hours and i didn't success, This Counter from Apple 1 billion downloads prize. doesn't use flash at all, only javascript and 0-9 images, which makes it really cool. Now after stackoverflow successed to extract google's pacman, can we do that?
P.S I can't even know if this is using prototype or scriptaculous since they're both included.
Here it is: http://images.apple.com/global/scripts/downloadcounter.js
StepTimingFunction = {
timingFunctionForStepCount: function (a) {
return function (b) {
return ((b * (a - 1)) >> 0) / ((a - 1))
}
}
};
DownloadCounter = Class.create();
Object.extend(DownloadCounter.prototype, {
initialize: function (a) {
this._url = a;
this.loadData();
this._isCounting = true
},
setIsCounting: function (a) {
this._isCounting = a
},
stop: function () {
if (this._isCounting) {
if (this._drawTimeout) {
window.clearTimeout(this._drawTimeout)
}
this.setIsCounting(false);
if (this._delegate && typeof this._delegate.counterDidStop === "function") {
this._delegate.counterDidStop(this)
}
}
},
start: function () {
if (!this._isCounting) {
this.loadData();
this.setIsCounting(true);
if (this._delegate && typeof this._delegate.counterDidStart === "function") {
this._delegate.counterDidStart(this)
}
}
},
isCounting: function () {
return this._isCounting
},
_delegate: null,
setDelegate: function (a) {
this._delegate = a
},
delegate: function () {
return this._delegate
},
loadData: function () {
if (this._nextUpdateTimeout) {
window.clearTimeout(this._nextUpdateTimeout);
this._nextUpdateTimeout = null
}
var a = document.location.href.toString();
a = a.replace(/.apple.com\/.*$/, ".apple.com");
new Ajax.Request((a + this._url + "?r=" + Math.random()), {
method: "get",
onSuccess: this.dataRequestDidFinishLoading.bind(this)
})
},
dataRequestDidFinishLoading: function (o) {
var k = o.responseText.split("|"),
n, d, j, g, l, h, b, f, e, m, a, i, c;
localServerBasedReferenceTime = Date.parse(o.getResponseHeader("Date"));
if (k.length === 3) {
n = k[0].split(" ");
d = n[1];
date = n[0].split("-");
this.setRate(parseInt(k[2]) / 3600000);
l = date[0];
g = date[1];
j = date[2];
a = Date.parse(g + " " + l + ", " + j + " " + d + " GMT-0700");
e = new Date(a + 3600000);
m = e.getTime() - a + 1000;
this._nextUpdateTimeout = setTimeout(this.loadData.bind(this), m);
if (typeof localServerBasedReferenceTime === "number") {
this._lastReferenceTime = localServerBasedReferenceTime
} else {
b = new Date();
this._lastReferenceTime = b.getTime()
}
f = this._lastReferenceTime - a;
i = Math.floor(parseInt(k[1]) + f * (this._rate));
this.setCurrentCount(i);
this.setNeedsDisplayIfNeeded()
}
},
setNeedsDisplayIfNeeded: function () {
if (!this._drawTimeout) {
this._drawTimeout = setTimeout(this.draw.bind(this), this._drawRefreshRate)
}
},
setElement: function (c) {
this._element = c;
var b = this._element.getElementsByClassName("digitGroupSeparator");
if (b.length > 0) {
var a = b[0];
this._element.removeChild(a);
this.setDigitGroupSeparatorTemplateElement(a)
}
this._element.empty();
this.createDigitElementsIfNeeded();
this.setNeedsDisplayIfNeeded()
},
setDigitGroupSeparatorTemplateElement: function (a) {
this._digitGroupSeparatorTemplateElement = a
},
_currentCount: 0,
setCurrentCount: function (a) {
if (a !== this._currentCount) {
this._currentCount = a;
this.createDigitElementsIfNeeded()
}
},
digitTemplateElement: function () {
if (!this._digitTemplateElement) {
this._digitTemplateElement = document.createElement("span");
$(this._digitTemplateElement).addClassName("digit");
var a = document.createElement("div"),
b = document.createElement("div"),
c = document.createElement("div");
$(a).addClassName("digitText");
$(b).addClassName("digitImage");
this._digitTemplateElement.appendChild(a);
this._digitTemplateElement.appendChild(b);
$(c).addClassName("digitImageElement");
b.appendChild(c.cloneNode(true));
b.appendChild(c)
}
return this._digitTemplateElement
},
createDigitElementsIfNeeded: function () {
if (this._element && (!this._digitElements || this._digitElements.length !== this._currentCount.toString().length)) {
this._element.empty();
this._createDigitElements()
}
},
_createDigitElements: function () {
if (!this._digitElements) {
this._digitElements = []
}
var e = 0,
b = (this._maxCount && this._currentCount >= this._maxCount) ? this._maxCount.toString().length : this._currentCount.toString().length,
c = document.createDocumentFragment(),
a, h = this.digitTemplateElement(),
g = this._digitGroupSeparatorTemplateElement,
d = (this._maxCount && this._currentCount >= this._maxCount) ? String(this._maxCount) : String(this._currentCount),
f;
if (!g) {
g = document.createElement("span");
$(g).addClassName("digitGroupSeparator")
}
for (e = 0 + this._digitElements.length; e < b; e++) {
a = h.cloneNode(true);
f = parseInt(d.charAt(b - (e + 1)));
a.lastChild.style.top = "-" + (f * (this._digitImageAnimationCount * this._digitImageHeight)) + "px";
this._digitElements[e] = a;
if (e > 0 && ((e) % 3 == 0)) {
c.insertBefore(g.cloneNode(true), c.firstChild)
}
c.insertBefore(a, c.firstChild)
}
this._element.insertBefore(c, this._element.firstChild)
},
currentCount: function () {
return this._currentCount
},
setRate: function (a) {
this._rate = a
},
rate: function () {
return this._rate
},
_drawRefreshRate: 50,
_digitImageHeight: 38,
setDigitImageHeight: function (a) {
this._digitImageHeight = a
},
_digitImageAnimationCount: 6,
setDigitImageAnimationCount: function (a) {
this._digitImageAnimationCount = a
},
_maxCount: false,
setMaxCount: function (a) {
this._maxCount = a
},
draw: function () {
window.clearTimeout(this._drawTimeout);
this._drawTimeout = null;
var h = this._drawRefreshRate,
e, j, k, c, a, l, o, b, n, d, m, p = this._digitImageHeight * this._digitImageAnimationCount,
g, f = this._digitElements,
q;
if (this._element) {
m = String(this._currentCount);
this._currentCount = this._currentCount + Math.floor(this._rate * h);
if (this._delegate && typeof this._delegate.counterDidReachValue === "function") {
this._delegate.counterDidReachValue(this, this._currentCount)
}
if (this._maxCount && this._currentCount >= this._maxCount) {
this._isCounting = false
}
if (!this._isCounting) {
return
}
e = (this._maxCount && this._currentCount >= this._maxCount) ? String(this._maxCount) : String(this._currentCount);
j = e.length;
k = j - 1;
for (c = k; c >= 0; c--) {
l = parseInt(e.charAt(c));
o = parseInt(m.charAt(c));
if (l !== o) {
if (!((k - c) < f.length)) {
this._createDigitElements()
}
a = f[k - c].lastChild;
if (a.___animating !== true) {
n = o * p;
if (l > o) {
b = l * p
} else {
b = (o + (10 - o) + l) * p
}
if (a.style.top !== (d = "-" + n + "px")) {
a.style.top = d
}
g = 1 + ((b - n) / this._digitImageHeight);
a.___animating = true;
q = new Effect.Move(a, {
x: 0,
y: (-1 * b),
duration: 0.4,
mode: "absolute",
transition: StepTimingFunction.timingFunctionForStepCount(g)
});
q.__element = a;
q.finish = function (i) {
if (window.removeEventListener) {
window.removeEventListener("unload", arguments.callee, false)
}
if (this.__element !== undefined) {
this.__element.___animating = false
}
};
if (window.addEventListener) {
window.addEventListener("unload", q.finish, false)
}
}
}
}
}
this._lastReferenceTime = (this._lastReferenceTime + h);
this.setNeedsDisplayIfNeeded()
}
});
Looks like it's a JS counter coupled with CSS.
The hearth of the whole script is this single image: http://images.apple.com/itunes/10-billion-app-countdown/images/filmstrip.png
Now everything should be obvious.
HTML placeholder for a single digit:
<div class="digit-placeholder"></div>
CSS that styles that placeholder:
.digit-placeholder {
/* Dimensions of a single "frame" */
width: 50px;
height: 75px;
background-image: url(...);
background-position: 0 0;
}
To display digit 7 you just have to move background (background-positon property) to the following coordinates: 0 -2800px (that's only an example). To display 8 move it to 0 -3400px.
To create an animation (change from 7 to 8) you just have to move background from -2800 to -3400 with a step of 60 in some period of time (let's say 0.5 second).
All you have to do is to clone that several times (10 times for one billion) and compute that period of time for each digit.
There's a file stored on the apple server which contains a count and a timestamp:
http://www.apple.com/autopush/us/itunes/includes/countdown.inc
That should give you a rough count.
Before I go to bed:
var number = '';
$('.digitImage').each(function(i) {
number += Math.abs($(this).position().top) / 618;
});
console.log(+number);
Now how long did that take? 3 minutes trying to figure out how do install a bookmarklet in chrome for injecting jQuery... 5 more minutes to get it working.