如何在Canvas中实现多个带编号圆形单次左到右平移不重叠动画
实现思路
- 用数组统一管理所有圆形实例,每个实例独立保存自身的位置、速度、编号、颜色、激活状态、启动延迟等属性,避免全局变量冲突
- 动画帧内先清空画布,再遍历数组更新所有激活状态的圆形位置,超出右边界的直接从数组移除,自动实现消失效果
- 不同圆形配置不同的y轴坐标即可实现分行不重叠,配置delay属性即可实现延迟启动效果
完整实现代码
HTML部分
<canvas id="canvas"></canvas>
JS部分
const canvas = document.getElementById("canvas"); canvas.width = 300; canvas.height = 900; const ctx = canvas.getContext("2d"); const radius = 13; // 圆形移动速度可统一调整 const moveSpeed = 1; // 存储所有圆形实例的数组 let circles = []; // 生成单个圆形配置的工具函数 function createCircle(yOffset, delay = 0) { const randomNumber = Math.floor(Math.random() * 60) + 1; let strokeColor; if (randomNumber > 0 && randomNumber <= 10) { strokeColor = "#0b0bf1"; } else if (randomNumber > 10 && randomNumber <= 20) { strokeColor = "#f10b0b"; } else if (randomNumber > 20 && randomNumber <= 30) { strokeColor = "#0bf163"; } else if (randomNumber > 30 && randomNumber <= 40) { strokeColor = "#f1da0b"; } else if (randomNumber > 40 && randomNumber <= 50) { strokeColor = "#950bf1"; } else if (randomNumber > 50 && randomNumber <= 60) { strokeColor = "#0bf1e5"; } return { x: radius, // y坐标按传入的偏移量设置,避免重叠 y: radius + yOffset, number: randomNumber, color: strokeColor, // 延迟启动时间,单位毫秒 delay: delay, // 记录创建时间,用来判断是否到启动时间 createTime: Date.now(), active: true } } // 批量创建圆形,这里示例创建6个,每行行高30px,奇数行延迟500ms启动 for (let i = 0; i < 6; i++) { circles.push(createCircle(i * 30, i % 2 === 1 ? 500 : 0)); } function animate() { requestAnimationFrame(animate); ctx.clearRect(0, 0, 300, 900); // 过滤掉已经到达终点的圆形,剩下的更新位置绘制 circles = circles.filter(circle => { if (!circle.active) return false; // 还没到启动时间,暂不移动 if (Date.now() - circle.createTime < circle.delay) return true; circle.x += moveSpeed; // 到达右边界直接过滤,不再绘制实现消失效果 if (circle.x - radius > 300) return false; // 绘制当前圆形 ctx.strokeStyle = circle.color; ctx.beginPath(); ctx.arc(circle.x, circle.y, 12, 0, Math.PI * 2, false); ctx.stroke(); ctx.fillStyle = '#000'; ctx.fillText(circle.number, circle.x - 5, circle.y + 3); return true; }) } animate();
可调整参数说明
- 修改
for循环的次数即可调整同时运行的圆形数量 - 修改
createCircle第一个参数的计算规则可调整行间距,比如i * 40就是行高40px - 修改
createCircle第二个参数的配置可调整延迟启动规则,比如传i * 200就是所有圆按顺序每间隔200ms启动一个 - 修改
moveSpeed变量的值即可调整圆形移动速度
内容的提问来源于stack exchange,提问作者Pedro Fernandes
相关产品推荐
相关产品推荐

