<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>HTML5 Canvas穿行梦想之路动画效果</title>
<style>
* {
margin: 0;
padding: 0;
border: 0;
background: #000
}
canvas {
position: relative;
top: 50%;
left: 50%;
margin-left: -50vmin;
width: 100vmin;
height: 100vmin;
overflow: hidden;
display: block;
}
</style>
</head>
<body>
<canvas></canvas>
<script>
var canvas, ctx, tim, gtx, gty, ptank, bg, kk, kt, lv, pen, sei, yo, ue, rand;
(function() {
var a, b, c, d, e, s, grd;
canvas = document.getElementsByTagName('canvas')[0];
ctx = canvas.getContext('2d');
canvas.width = canvas.height = 400;
rand = Math.random;
gtx = gty = 200;
ue = 180;
kk = Math.PI * 2 / 6;
kt = [];
for (a = 0; a < 6; a++) kt[a] = kk * a;
count = 0;
lv = 2;
ctx.globalCompositeOperation = "lighter";
for (a = 1; a < 4; a++) {
grd = ctx.createLinearGradient(0, 0, 0, canvas.height);
grd.addColorStop(0, "hsla(" + (a * 50) + ",90%,10%,0.3)");
grd.addColorStop(ue / 400, "hsla(" + (a * 100) + ",90%,60%,0.5)");
grd.addColorStop(1, "hsla(" + (a * 50) + ",90%,10%,0.3)");
ctx.fillStyle = grd;
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
pen = 13;
sei = pen * Math.sin(Math.PI / 6);
yo = pen * Math.cos(Math.PI / 6);
for (e = 0; e < 3; e++) {
s = 1 - e * 0.3;
a = enbset(10 + e * 7);
for (d = 0; d < a.length; d++) {
b = a[d];
hex(b.x * s + 200, b.y * s + ue, b.col, b.o, b.g, b.e, s, 0.3);
}
}
bg = ctx.getImageData(0, 0, canvas.width, canvas.height);
ptank = [];
for (a = 0; a < 10; a++) ptank.push(enbset());
baum();
})();
function enbset(gen) {
var a, p;
if (!gen) gen = 5;
p = [];
for (a = 0; a < gen; a++) siki(gtx, gty, a, p);
ends(gtx, gty, gen, p);
return p;
}
function baum() {
var a, b, c, d, e, s, x, y, p, len, hei, bai, lit, max;
tim = new Date().getTime() / 12;
ctx.putImageData(bg, 0, 0);
ctx.globalCompositeOperation = "lighter";
max = 200;
for (a = 0; a < max; a++) {
x = a / (max - 1) * canvas.width;
b = (Math.sin(a / 7 + tim / 31) + Math.sin(a / 3 + tim / 41)) / 2;
b *= b * b * b;
ctx.fillStyle = "hsla(244,50%,50%," + ((1 - b) / 2) + ")";
c = 1;
if (a % 2 == 1) c = -1;
ctx.beginPath();
ctx.arc(x, ue + b * 150 * c, 5, 0, Math.PI * 2, 0);
ctx.fill();
}
r = 0;
for (a = 0; a < max; a++) {
b = (Math.sin(a / 7 + tim / 31) + Math.sin(a / 3 + tim / 41)) / 2;
b *= b * b * b;
ctx.fillStyle = "hsla(244,50%,50%," + ((1 - b) / 2) + ")";
x = Math.cos(r) * b * 300;
y = Math.sin(r) * b * 300;
ctx.beginPath();
ctx.arc(x + 200, y + ue, 5, 0, Math.PI * 2, 0);
ctx.fill();
r += Math.PI * 2 / max;
}
len = 100;
hei = (canvas.height - ue) + 5;
bai = hei / len;
p = [];
for (b = 0; b < len; b++) {
x = Math.sin(-tim / 30 + b / 10) * b + Math.sin(-tim / 71 + b / 7) * b + 200;
y = (b + 10) / (len + 10);
y *= y * y;
a = Math.sin(-tim / 20 + b / 15) * 60 * y;
p[b] = [x, ue + y * hei + a];
}
for (e = 0; e < len - 1; e++) {
a = (e + 10) / (len + 10);
s = a * a;
a = s * 170;
c = p[e];
d = p[e + 1];
lit = 1;
if (e > len - 10) lit = (len - e) / 10;
ctx.globalCompositeOperation = "lighter";
ctx.fillStyle = "hsla(244,50%,50%," + (0.4 * lit) + ")";
ctx.beginPath();
ctx.arc(c[0] - a, c[1], 20 * s, 0, Math.PI * 2, 0);
ctx.fill();
ctx.beginPath();
ctx.arc(c[0] + a, c[1], 20 * s, 0, Math.PI * 2, 0);
ctx.fill();
ctx.globalCompositeOperation = "source-over";
ctx.fillStyle = ctx.strokeStyle = "hsla(" + ((200 + Math.sin(e - tim / 3) * 5) | 0) + ",60%," + (40 + e / 2) + "%," + lit + ")";
ctx.lineWidth = 1;
ctx.beginPath();
ctx.lineTo(c[0] - a, c[1]);
ctx.lineTo(c[0] + a, c[1]);
ctx.lineTo(d[0] + a, d[1]);
ctx.lineTo(d[0] - a, d[1]);
ctx.fill();
ctx.stroke();
a = (e - tim / 2) | 0;
if (a % 60 === 0) {
s *= 20;
c = a / 60;
if (c < 0) c = -c;
lit = 1;
if (e > len - 20) lit = (len - e) / 20;
if (e < 20) lit = e / 20;
if (e < 5) ptank[c % ptank.length] = enbset();
c = ptank[c % ptank.length];
for (d = 0; d < c.length; d++) {
b = c[d];
hex(b.x * s + p[e][0], b.y * s + p[e][1], b.col, b.o, b.g, b.e, s, lit);
}
}
if (e == 77) {
hito(p[e][0], p[e][1]);
}
}
requestAnimationFrame(baum);
}
function hito(x, y) {
var r1, r2;
ctx.fillStyle = ctx.strokeStyle = "rgb(0,0,0)";
ctx.beginPath();
ctx.arc(x, y - 30, 10, 0, Math.PI * 2, 0);
ctx.fill();
r1 = 0.5 + Math.sin(tim / 3) / 2;
r2 = 1 - r1;
ctx.lineWidth = 8;
ctx.beginPath();
ctx.lineTo(x, y - 30);
ctx.lineTo(x, y - 5);
ctx.stroke();
ctx.beginPath();
ctx.arc(x - r1 * 2 - 3, y - r1 * 2 - 3, 3, 0, Math.PI * 2, 0);
ctx.fill();
ctx.beginPath();
ctx.arc(x + r2 * 2 + 3, y - r2 * 2 - 3, 3, 0, Math.PI * 2, 0);
ctx.fill();
ctx.lineWidth = 4;
ctx.beginPath();
ctx.lineTo(x, y - 15);
ctx.lineTo(x - 10, y - 20 + r1 * 3);
ctx.stroke();
ctx.lineWidth = 4;
ctx.beginPath();
ctx.lineTo(x, y - 15);
ctx.lineTo(x + 10, y - 20 + r1 * 3);
ctx.stroke();
}
function ends(x, y, rin, p) {
var a, b, c, x1, y1, x2, y2, st, qt, ob;
st = [
[
[3]
],
[
[4]
]
];
qt = [
[
[4]
]
];
x1 = x;
y1 = y + yo * 2 * rin;
for (a = 0; a < 6; a++) {
x2 = Math.sin(kt[(a + 1) % 6]) * yo * 2 * rin + x;
y2 = Math.cos(kt[(a + 1) % 6]) * yo * 2 * rin + y;
rx = (x2 - x1) / rin;
ry = (y2 - y1) / rin;
for (d = 0; d < rin; d++) {
c = st;
if (!d) c = qt;
ob = {
x: x1 - x,
y: y1 - y,
col: rin * 10,
o: c,
g: 6 - a
};
p.push(ob);
x1 += rx;
y1 += ry;
}
x1 = x2;
y1 = y2;
}
}
function siki(x, y, rin, p) {
var a, b, c, d, e, f, g, x1, x2, y1, y2, rx, ry, st, qt, mt, stp, qtp, ob;
if (!rin) {
a = [
[
[0]
],
[
[1]
],
[
[2]
],
[
[3]
],
[
[4]
],
[
[5]
]
];
if (!lv) a = ranst();
ob = {
x: 0,
y: 0,
o: a,
col: 0,
g: 0,
e: 0
};
p.push(ob);
return;
}
st = [
[
[
[1, 4]
],
[
[2, 3]
],
[
[0, 5]
]
],
[
[
[1, 4]
],
[
[2