模拟电影《黑客帝国》里数据传输的动图
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Binary Matrix Rain</title>
<style>
body, html {
margin: 0;
padding: 0;
overflow: hidden;
background-color: black;
}
canvas {
display: block;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var width = window.innerWidth;
var height = window.innerHeight;
canvas.width = width;
canvas.height = height;
var drops = [];
var dropCount = Math.floor(width / 4); // 每4个像素一个字符
// 初始化流
for (var i = 0; i < dropCount; i++) {
drops[i] = {
x: Math.random() * width, // 随机x坐标
y: Math.random() * height, // 随机y坐标
value: Math.floor(Math.random() * 2).toString(), // 随机二进制值(0或1)
speed: 10 + Math.random() * 10, // 随机速度
width: Math.random() * 8 + 8, // 随机字符宽度(8到16像素之间)
num: 4 + Math.floor(Math.random() * 10),//随机位数
fontNum: Math.random(), // 随机字体大小
};
}
function draw() {
ctx.clearRect(0, 0, width, height);
ctx.fillStyle = 'rgba(0, 255, 0, 0.01)'; // 设置绿色填充色和透明度
ctx.fillRect(0, 0, width, height); // 填充整个画布为绿色背景
ctx.fillStyle = '#0f0'; // 设置字符颜色为绿色
for (var i = 0; i < dropCount; i++) {
var drop = drops[i];
ctx.font = 'bold ' + (drop.fontNum * 10 + 12) + 'px monospace'; // 随机字体大小
// 绘制字符
//ctx.fillText(drop.value, drop.x, drop.y);
var zum = Math.floor(drop.x + drop.num + drop.speed + drop.width);
var zum2 = zum.toString(2);
for(var j = 0; j < drop.num; j++)
{
ctx.fillText(zum2[Math.floor(j % zum2.length)], drop.x, drop.y+drop.width*1.3*j);
}
// 更新字符位置
drop.y -= drop.speed;
// 如果字符超出底部,则重置到顶部并随机更改值
if (drop.y < -drop.width*1.3*drop.num) {//drop.y > height) {
drop.y = height;//-ctx.measureText(drop.value).width - drop.width; // 重置y坐标到顶部上方
drop.value = Math.floor(Math.random() * 2).toString(); // 随机新值
drop.x = Math.random() * width; // 随机新x坐标(可选,保持原位置也可以)
drop.num = 4 + Math.floor(Math.random() * 30);
}
}
//setTimeout(() => {
//requestAnimationFrame(draw);
//}, 100);
requestAnimationFrame(draw); // 递归调用draw函数实现动画
}
draw(); // 开始动画
// 窗口大小改变时调整画布大小
<!-- window.addEventListener('resize', function() { -->
<!-- width = window.innerWidth; -->
<!-- height = window.innerHeight; -->
<!-- canvas.width = width; -->
<!-- canvas.height = height; -->
<!-- dropCount = Math.floor(width / 5); // 重新计算字符数量 -->
<!-- drops = []; // 清空drops数组 -->
<!-- // 重新初始化流(可选,也可以只调整已有字符的位置和速度) -->
<!-- <!-- for (var i = 0; i < dropCount; i++) { --> -->
<!-- <!-- drops[i] = { --> -->
<!-- <!-- x: Math.random() * width, --> -->
<!-- <!-- y: Math.random() * height, --> -->
<!-- <!-- value: Math.floor(Math.random() * 2).toString(), --> -->
<!-- <!-- speed: 1 + Math.random() * 2, --> -->
<!-- <!-- width: Math.random() * 8 + 8, --> -->
<!-- <!-- }; --> -->
<!-- <!-- } --> -->
<!-- for (var i = 0; i < dropCount; i++) { -->
<!-- drops[i] = { -->
<!-- x: Math.random() * width, // 随机x坐标 -->
<!-- y: Math.random() * height, // 随机y坐标 -->
<!-- value: Math.floor(Math.random() * 2).toString(), // 随机二进制值(0或1) -->
<!-- speed: 10 + Math.random() * 10, // 随机速度 -->
<!-- width: Math.random() * 8 + 8, // 随机字符宽度(8到16像素之间) -->
<!-- num: 4 + Math.floor(Math.random() * 10),//随机位数 -->
<!-- fontNum: Math.random(), // 随机字体大小 -->
<!-- }; -->
<!-- } -->
<!-- }); -->
</script>
</body>
</html>
运行效果