废话不多说,直接上代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body style="background-color: rgb(0, 0, 0);">
<title>爱心跳动粒子效果</title>
<div class="container">
<canvas id="myCanvas" width="1000px" height="1000px" style="background-color: black;"></canvas>
</div>
</body>
</html>
<script>
// 获取 canvas 元素并设置上下文
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
// 定义粒子的数组
var points = [];
// 粒子的属性
var particle_limit = 44;// 粒子界限
var particle_num = 50; // 单个点的粒子数量
var point_density = 0.1;// 点密度
var point_num = 0; // 点数量
var sw = canvas.width; // 画布的宽
var sh = canvas.height; // 画布的高
var throb = 0;
var dir = 0;
// 生成每个点的粒子参数
for (var t = 0; t <= 2 * Math.PI; t += point_density) {
var particles = []; // 创建一个空的行数组
for (var i = 0; i <= particle_num; i++) {
particles[i] = {
x: Math.random() * 2 * particle_limit - particle_limit,
y: Math.random() * 2 * particle_limit - particle_limit,
size: Math.random() * 2.5 + 0.1,
speedX: Math.random() * 3 - 1.5,
speedY: Math.random() * 3 - 1.5,
};
}
points.push(particles); // 将行数组添加到二维数组中
point_num += 1;
}
// 画一个点
function point(x, y, index) {
ctx.fillStyle = '#FF0000';
for (var i = 0; i < particle_num; i++) {
var p = points[index][i];
ctx.beginPath();
ctx.arc(p.x + x, p.y + y, p.size, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();
p.x += p.speedX;
p.y += p.speedY;
if (p.x + x < -particle_limit + x || p.x + x > particle_limit + x) {
p.speedX = -p.speedX;
}
if (p.y + y < -particle_limit + y || p.y + y > particle_limit + y) {
p.speedY = -p.speedY;
}
}
}
// 画爱心
function draw() {
// 清除画布内容
ctx.clearRect(0, 0, sw, sh);
var i = 0;
// 定义绘制爱心的公式
for (var t = 0; t <= 2 * Math.PI; t += point_density) {
var ix = (16 + throb) * Math.pow(Math.sin(t), 3);
var iy = -(
(13 + throb) * Math.cos(t) -
5 * Math.cos(2 * t) -
(2 + throb) * Math.cos(3 * t) -
Math.cos(4 * t)
);
ix *= 16; // 放大 x 坐标
iy *= 16; // 放大 y 坐标
// 将爱心的点绘制在 Canvas 上
point(sw / 2 + ix, sh / 2 + iy, i);
i += 1;
}
// 用 setTimeout 替换 requestAnimationFrame,以确保每秒调用一次
requestAnimationFrame(draw);
}
// 跳动
function performAction() {
if (dir == 0) {
throb += 0.15;
}
else {
throb -= 0.15;
}
if (throb <= 0) {
dir = 0;
}
if (throb >= 1.5) {
dir = 1;
}
setTimeout(performAction, 40);
}
performAction()
draw();
</script>
<style>
.container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
/* 设置容器高度为视口高度 */
}
</style>
效果:
当然,我只是截了一个图,实际是跳动的。