七夕节快到了,让我们使用 74 行的纯 HTML/JavaScript 代码,实现一个浪漫的红心下落的动画效果吧。
将下列代码粘贴到一个空白的 html 文件里,用浏览器本地打开即可。
<html>
<canvas></canvas>
<script>
var c = document.getElementsByTagName('canvas')[0];
var b = document.body;
var a = c.getContext('2d');
function d(b, c, d, e) {
a.fillStyle = b;
a.beginPath();
a.arc(c, d, e, 0, 2 * m.PI, !0);
a.fill();
a.fillRect(c, d, 1, 1)
}
m = Math;
r = m.random;
g = Date;
l = +(new g);
e = document;
q = e.createElement("canvas");
w = e.createElement("canvas");
o = {};
h = 100;
H = 200;
v = window;
t = c.width = v.innerWidth;
u = c.height = v.innerHeight - 5;
b.setAttribute("style", "margin:0;background:#000");
k = a;
q.width = q.height = h;
w.width = 1e3;
w.height = H;
for (j = 0; ++j < H; ) {
for (i = 0; 1e3 > ++i; )
a = q.getContext("2d"),
z = .5 - i / h,
f = j / h - .5 + .4 * m.sqrt(m.abs(z)),
f = z * z + 2 * f * f,
.23 > f && d(.16 < f ? "#F00" : "#F88", i, j, 0),
a = w.getContext("2d"),
d(j > 5e-4 * i * i - .3 * i + h ? "#343" : j > 4e-4 * i * i - .9 * i + 500 ? "#232" : "#000", i, j, 0);
o[j] = {
x: r() * t,
y: -h - r() * u,
b: 51 - j / 4,
a: 25 + .4 * j
};
o[H + j] = {
x: r() * t,
y: r() * u - H,
a: 3 * r() + 1,
c: j
}
}
a = k;
v.setInterval(function() {
n = +(new g);
a.clearRect(0, 0, t, u);
d("#FFA", H, 250, 150);
d("#000", 270, 320, h);
a.drawImage(w, 0, u - H, t, H);
for (i = 0; ++i < H; )
f = (n - l) / h,
s = o[H + i],
d("#FFA", s.x, s.y, m.floor(m.max(s.a + m.sin(s.c++ / 10) - .5, 1))),
z = o[i],
a.drawImage(q, z.x += -.1 / (z.b / h) * f, z.y += (5 - z.b / 10) * f, z.a, z.a),
z.y > u && (z.y = -h),
z.x < -H && (z.x = t);
l = n
}, 60)
//L<3
</script>
</html>
效果如下:
下面是具体的代码解析。
首先在 html 里定义 `canvas` 标签,这是 HTML5 在网页上绘制通信的接口元素。`canvas` 本身没有图形绘制功能,因此我们必须首先用 `document.getElementsByTagName` 拿到这个元素的实例,然后通过 JavaScript 来操纵它绘图。
var a = c.getContext('2d');
getContext("2d") 返回的对象是内建的 HTML5 对象,类型为 `CanvasRenderingContext2D`,拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。
接下来的这个函数,封装了一个使用 `CanvasRenderingContext2D` 对象进行的画图操作。
- a.fillStyle = b 将绘制的图形进行染色,颜色值通过参数 b 传入。
- a.beginPath: 每当开始一个新的图形绘制时,需要调用 Canvas 2D API 这个方法,相当于现实生活中会话的落笔动作。
例子:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
// First path
ctx.beginPath();
ctx.strokeStyle = 'blue';
ctx.moveTo(20,20);
ctx.lineTo(200,20);
ctx.stroke();
- a.arc: 这是Canvas 2D API 绘制圆弧路径的方法。
语法:void ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
圆弧路径的圆心在 (x, y) 位置,半径通过参数 raduis 指定,根据anticlockwise 布尔值(默认为顺时针)指定的方向从 startAngle 开始绘制,到 endAngle 结束。
因此,这个高亮方法,在函数 d 的 输入参数 c 和 d 指定的坐标为圆形,以 e 为半径,顺时针方向绘制一个圆形( 2 * m.PI 代表 360 度) 。!0 即 true.
- a.fill: 填充上一行通过 a.arc 绘制的圆形区域。
- a.fillRect(c, d, 1, 1):fillRect()方法绘制一个填充了内容的矩形,这个矩形的开始点(左上点)在参数 c 和 d 指定的位置。它的宽度和高度都为 1,填充样式由当前的 fillStyle 决定。
每隔 60 毫秒,调用 `drawImage` 绘制图形。其中输入参数 w 代表绘制到上下文的元素。
在本例中,w 存储的是通过 document.createElement("canvas") 动态创建的 canvas 元素。