You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 15:39:01