How is Google's buckyball doodle implemented?
I've had a look at the markup it creates, namely a bunch of
images for the atoms, and a big background image, which is used rather strangely to create the bonds.There are some things that I can't work 开发者_运维问答out:
- Where the javascript is
- What makes the bonds at the rear narrower
- Why the atoms also have the bond background applied
Here's what the google doodle looked like, for those who are interested:
If you take a look at the markup, it is just a bunch of images and divs with position attributes, forming them into a sort of grid. This file: http://www.google.com/logos/2010/buckyball10-hp-bond.png is a sprite containing every bond, in every direction. This image is the atom: http://www.google.com/logos/2010/buckyball10-hp-atom.png. The JavaScript they use animates these elements by changing the positions of them.
The JavaScript is in a Script element right after the Google logo and doodle markup. The rear bonds appear narrower because their opacity is changed to be slightly transparent. Finally, it doesn't look like the atoms have the bond background. They have their own sprite (cited above.)
Ok, here's the javascript, after having run it through jsBeautifier:
(function () {
var a = true,
c = false;
try {
if (!google.doodle) google.doodle = {};
var aa = -1 / 14,
ba = Math.PI / 180,
d = (1 + Math.sqrt(5)) / 2,
e = 1 / 3,
k = 2 / 3,
l = d / 3,
n = 2 * l,
o = [
[-k, -e - n, -l],
[-e, -k - l, -n],
[e, -k - l, -n],
[k, -e - n, -l],
[e, -d, 0],
[-e, -d, 0],
[-l, -k, -e - n],
[-n, -e, -k - l],
[-e - n, -l, -k],
[-k - l, -n, -e],
[-k, -e - n, l],
[-e, -k - l, n],
[e, -k - l, n],
[k, -e - n, l],
[-l, -k, e + n],
[-n, -e, k + l],
[-e - n, -l, k],
[-k - l, -n, e],
[-d, 0, -e],
[-d, 0, e],
[-k, e + n, -l],
[-e, k + l, -n],
[e, k + l, -n],
[k, e + n, -l],
[e, d, 0],
[-e, d, 0],
[-l, k, -e - n],
[-n, e, -k - l],
[-e - n, l, -k],
[-k - l, n, -e],
[-k, e + n, l],
[-e, k + l, n],
[e, k + l, n],
[k, e + n, l],
[-l, k, e + n],
[-n, e, k + l],
[-e - n, l, k],
[-k - l, n, e],
[0, -e, -d],
[0, e, -d],
[l, k, -e - n],
[n, e, -k - l],
[n, -e, -k - l],
[l, -k, -e - n],
[k + l, -n, -e],
[e + n, -l, -k],
[0, -e, d],
[0, e, d],
[l, k, e + n],
[n, e, k + l],
[n, -e, k + l],
[l, -k, e + n],
[k + l, -n, e],
[e + n, -l, k],
[k + l, n, -e],
[e + n, l, -k],
[k + l, n, e],
[e + n, l, k],
[d, 0, -e],
[d, 0, e]
],
q = [
[0, 1],
[0, 5],
[0, 9],
[1, 2],
[1, 6],
[2, 3],
[2, 43],
[3, 4],
[3, 44],
[4, 5],
[4, 13],
[5, 10],
[6, 7],
[6, 38],
[7, 8],
[7, 27],
[8, 9],
[8, 18],
[9, 17],
[10, 11],
[10, 17],
[11, 12],
[11, 14],
[12, 13],
[12, 51],
[13, 52],
[14, 15],
[14, 46],
[15, 16],
[15, 35],
[16, 17],
[16, 19],
[18, 19],
[18, 28],
[19, 36],
[20, 21],
[20, 25],
[20, 29],
[21, 22],
[21, 26],
[22, 23],
[22, 40],
[23, 24],
[23, 54],
[24, 25],
[24, 33],
[25, 30],
[26, 27],
[26, 39],
[27, 28],
[28, 29],
[29, 37],
[30, 31],
[30, 37],
[31, 32],
[31, 34],
[32, 33],
[32, 48],
[33, 56],
[34, 35],
[34, 47],
[35, 36],
[36, 37],
[38, 39],
[38, 43],
[39, 40],
[40, 41],
[41, 42],
[41, 55],
[42, 43],
[42, 45],
[44, 45],
[44, 52],
[45, 58],
[46, 47],
[46, 51],
[47, 48],
[48, 49],
[49, 50],
[49, 57],
[50, 51],
[50, 53],
[52, 53],
[53, 59],
[54, 55],
[54, 56],
[55, 58],
[56, 57],
[57, 59],
[58, 59]
],
r, s, t, u, v, z, A, B, da = 0,
C = 0,
D = [],
E = [],
F = [],
G = 0,
H = 0,
I, J = 0,
K = 0,
L = 0,
M = 0,
N = 0,
O = 0,
P = 0,
Q = 0,
R, S = c,
T = c,
U = a,
V, W, ea, fa, ha = function () {
if (S) {
var b = C - 20;
if (Math.abs(b) > 0.01) {
H += -0.5 * b;
H *= 0.6;
C += H;
if (C < 0) C = 0
} else C = 20;
var f = J - L,
g = K - M;
if (b = I && Math.sqrt(J * J + K * K) < 35) {
N += f;
O += g
} else {
if (R) {
Q = Math.min(20, Math.sqrt(f * f + g * g));
P = Math.atan2(g, f)
}
N += Math.cos(P) * Q;
O += Math.sin(P) * Q;
Q = Math.max(1, Q * 0.97)
}
var h = N * 0.4;
g = O * 0.4;
N -= h;
O -= g;
f = o;
var i = Math.sqrt(h * h + g * g);
if (i == 0) o = f;
else {
g = g / i;
h = -h / i;
i = i * ba;
var w = 1 - Math.cos(i),
x = Math.sin(i),
j = g * h;
i = 1 + w * (g * g - 1);
j = w * j;
var m = h * x,
y = j,
ka = 1 + w * (h * h - 1),
la = -g * x,
ma = -h * x;
x = g * x;
w = 1 + w * -1;
for (var ca = [], na = 0, p; p = f[na++];) {
g = p[0];
h = p[1];
p = p[2];
ca.push([i * g + j * h + m * p, y * g + ka * h + la * p, ma * g + x * h + w * p])
}
o = ca
}
L = J;
M = K;
R = b;
b = o;
f = [];
for (g = 0; h = b[g++];) {
i = 3.8 / (3.8 + h[2]);
f.push([h[0] * i, h[1] * i, i])
}
b = f;
for (f = 0; i = b[f]; ++f) {
g = i[0] * C;
h = i[1] * C;
j = i[2] * 4;
m = D[f];
m.width = j;
m.height = j;
m.style.left = 143 + g - j / 2 + "px";
m.style.top = 70 + h - j / 2 + "px";
m.style.zIndex = i[2] > 1 ? "4" : "1";
ga(m, i[2]);
T && r.appendChild(m)
}
T = c;
for (f = 0; g = q[f]; ++f) {
i = b[g[0]];
j = b[g[1]];
if (i && j) {
g = (i[0] + j[0]) / 2 * C;
h = (i[1] + j[1]) / 2 * C;
m = (i[2] + j[2]) / 2;
y = E[f];
y.l((i[0] - j[0]) * C, (i[1] - j[1]) * C);
y.position(g, h);
y.a.style.zIndex = m > 1 ? "3" : "0";
ga(y.a, m)
}
}
} else {
f = da++ * aa;
b = 143 + Math.sin(f) * 20;
f = 70 + Math.cos(f) * 20;
B.style.left = b + "px";
B.style.top = f + "px";
if (U && A) {
r.appendChild(B);
U = c
}
F[G].m(b + Math.random() * 2, f + Math.random() * 2);
G = modulo(++G, F.length);
for (b = 0; f = F[b++];) f.i()
}
},
X = function () {
if (!S) {
T = S = a;
google.dom.remove(B);
for (var b = 0, f; f = F[b++];) f.h();
Q = Math.random() * 20;
P = Math.random() * Math.PI
}
},
Y = function () {
this.d = this.e = 35;
this.c = c;
this.a = document.createElement("div");
this.a.className = "logo-bond";
this.a.style.background = "url(" + s.src + ")"
};
Y.prototype.position = function (b, f) {
this.a.style.left = 143 + b - this.e / 2 + "px";
this.a.style.top = 70 + f - this.d / 2 + "px";
if (!this.c) {
r.appendChild(this.a);
this.c = a
}
};
Y.prototype.l = function (b, f) {
var g = modulo(-Math.atan2(f, b), Math.PI),
h = Math.PI / 90;
h = Math.round(g / h) * 35;
g = 0 - (35 - this.e) / 2;
h = h - (35 - this.d) / 2;
this.a.style.backgroundPosition = g + "px " + h + "px";
this.e = Math.max(5, Math.abs(b));
this.d = Math.max(5, Math.abs(f));
this.a.style.width = this.e + "px";
this.a.style.height = this.d + "px"
};
var Z = function () {
this.c = this.g = c;
this.a = document.createElement("div");
this.a.className = "logo-dust"
};
Z.prototype.m = function (b, f) {
this.g = a;
this.a.style.top = f + "px";
this.a.style.left = b + "px";
this.opacity = 1;
if (!this.c) {
r.appendChild(this.a);
this.c = a
}
};
Z.prototype.i = function () {
if (this.g) {
this.opacity -= 0.02;
this.opacity <= 0 ? this.h() : ia(this.a, this.opacity, c)
}
};
Z.prototype.h = function () {
this.a.style.display = "none";
google.dom.remove(this.a);
this.g = c
};
var ja = function (b) {
I = a;
J = (b.clientX || b.pageX || 0) - r.offsetLeft - 143;
K = (b.clientY || b.pageY || 0) - r.offsetTop - 70;
t && I && Math.sqrt(J * J + K * K) < 30 && X()
};
eval("function modulo(a,n){return a" + "%%".charAt(0) + "n;}");
var oa = function () {
var b = document.createElement("img");
b.src = z.src;
b.border = 0;
b.style.position = "absolute";
return b
},
ia = function (b, f, g) {
b.style.opacity = f;
if (W) if (f < 0.6) {
b.style.filter = "alpha(opacity=" + f * 100 + ")";
if (g) b.style.backgroundImage = "url(" + u.src + ")"
} else {
b.style.filter = "";
if (g) b.style.backgroundImage = "url(" + s.src + ")"
}
},
ga = function (b, f) {
var g = f > 1 ? 1 : Math.pow(f, 4);
ia(b, g, a)
};
google.doodle.init = function () {
if (window.location.href.indexOf("#") == -1) if (r = document.getElementById("hplogo")) if (!fa) {
fa = a;
google.j && google.j.en && $(100, pa, function () {
return google.rein && google.dstr
});
$(100, qa, function () {
return google.listen && google.browser && google.dom
})
}
};
var $ = function (b, f, g) {
if (g()) f();
else b < 200 && window.setTimeout(function () {
$(b + 1, f, g)
}, b)
},
pa = function () {
if (!google.doodle.k) {
google.doodle.k = a;
google.rein.push(google.doodle.init);
google.dstr.push(ra)
}
},
qa = function () {
W = google.browser.engine.IE;
sa();
google.listen(document, "mousemove", ja);
for (var b = 0; o[b++];) D.push(oa());
for (b = 0; q[b++];) E.push(new Y);
for (; F.length < 40;) F.push(new Z);
B = oa();
B.width = B.height = 7;
V = window.setInterval(ha, 30);
ea = window.setTimeout(ta, 5E3)
},
ta = function () {
if (t) X();
else v = a
},
sa = function () {
z = new Image;
z.onload = function () {
A = a
};
z.src = "/logos/2010/buckyball10-hp-atom.png";
if (W) {
u = new Image;
u.onload = function () {};
u.src = "/logos/2010/buckyball10-hp-bond-ie.png"
}
s = new Image;
s.onload = function () {
t = a;
v && X()
};
s.src = "/logos/2010/buckyball10-hp-bond.png"
},
ra = function () {
google.unlisten(document, "mousemove", ja);
window.clearInterval(V);
window.clearTimeout(ea)
}
} catch (ua) {
google.ml(ua, c, {
_sn: "BKY"
})
};
})();
google.doodle.init()
Ain't that pretty?
精彩评论