theme: fancy
上次编写的文章 韩式浪漫 - 落雪唯美,我们整了个雪花的效果。
咦,那么我们可不可以扩展下,整一个 黑客帝国矩阵雨的效果
呢?
答案是肯定的,下面来整活。
该效果主要完成的功能有两点:
- 矩阵雨绘制
- 红蓝药丸编写
矩阵雨绘制
我们同样使用 canvas
来实现。基本思路如下:
- 初始化画布,画笔
- 初始化矩阵雨有多少列
- 用
0
和1
的初始化绘制的字符串 - 在画布上绘制,以随机的
0
和1
填充,计算绘制的x
和y
轴的距离,并重复绘制 - 监听视图窗口的更改,更新画布的大小和矩阵雨多少列的数据
实现的代码不多,这里贴上 JavaScript
文件的代码。代码即文档,若难以理解,请结合代码中的注释去学习。
(function() {
let canvas = document.getElementById('canvas'); // 画布
let ctx = canvas.getContext('2d'); // 画笔
let width = canvas.width = window.innerWidth; // 设置 canvas 的大小,然后赋值给 width,方便后面的计算
let height = canvas.height = window.innerHeight;
let font = 12;
let cols = 0;
let dys = []; // 垂直距离的移动距离数组
let matrix = '';
let matrixSize = 20; // 矩阵雨的随机数量
for(let i = 0; i < matrixSize; i = 1) {
matrix = Math.floor(Math.random() * 2);
}
initData();
// 初始化关键数据
function initData() {
// 列数据
cols = width / font;
// 随机生成 dy 垂直移动的距离
for(let i = 0; i < cols; i = 1) {
dys[i] = Math.floor(Math.random() * cols);
}
}
function draw(){
// ctx.clearRect(0, 0, width, height);
ctx.fillStyle = "rgba(0, 0, 0, 0.05)";
ctx.fillRect(0, 0, width, height); // 填充画布
ctx.fillStyle = "#00ff00";
ctx.font = `${font}px`;
for(let i = 0; i < cols; i = 1) {
let txt = matrix[Math.floor(Math.random() * matrixSize)];
ctx.fillText(txt, i * font, dys[i] * font);
if(dys[i] * font > height) {
dys[i] = Math.floor(Math.random() * cols);
}
dys[i] = 1; // 垂直距离的设置
}
requestAnimationFrame(draw); // 重新绘制
}
draw();
// 监听窗口更改
window.addEventListener('resize', () => {
// 重置画布的大小
width = canvas.width = window.innerWidth;
height = canvas.height = window.innerHeight;
// 重新初始化关键数据
initData();
});
})()
需要注意的是,draw()
函数中,不可添加 ctx.clearRect(0, 0, width, height);
代码,不然就是雪花飘落的效果了。读者可以放开该代码,自行验证。
clearRect 是清空画布的指定区域
疑问点