如何在Canvas中实现页面加载后圆形按15px步长随机移动并带停留间隔
Canvas 圆形正交随机移动实现
核心逻辑
完全匹配要求的无冗余实现,没有复杂计算:
- 全局存储圆形当前坐标、固定步长、移动间隔,避免函数间传参混乱
- 每次重绘前清空画布,消除旧圆形的残影
- 仅从上下左右四个正交方向中随机选1个,叠加15px固定步长计算新坐标
- 用递归setTimeout做调度,保证每次移动到新位置后停留指定时长再触发下一次移动,速度不会过快
原代码中几个容易踩的坑:
- 没有全局存储圆形坐标,移动相关函数无法获取当前位置
- 坐标计算存在叠加偏差:
translate(x,y)做坐标偏移后,仍在(50,50)位置画圆,实际显示位置和传入坐标会差50px- 缺少画布清屏逻辑,连续绘制会留下拖影
- 移动方向逻辑未限定为四个正交方向,不符合步长要求
完整可运行代码
对应JS文件
"use strict"; let ctx; let canvas; // 核心固定参数 let ballX = 80; // 圆形初始圆心X坐标 let ballY = 80; // 圆形初始圆心Y坐标 const STEP = 15; // 固定移动步长15px const MOVE_WAIT = 300; // 每次移动后停留300ms,控制移动速度 function setup() { canvas = document.getElementById("myCanvas"); ctx = canvas.getContext("2d"); // 首次绘制初始位置的圆形 drawBall(ballX, ballY); // 启动循环移动 moveLoop(); } // 直接在目标坐标绘制红色圆形,无多余坐标偏移 function drawBall(x, y) { // 清空整个画布,消除旧圆残影 ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = "red"; ctx.beginPath(); // 以传入的x,y为圆心,画半径15的正圆 ctx.arc(x, y, 15, 0, 2 * Math.PI); ctx.fill(); } // 循环移动核心逻辑 function moveLoop() { // 四个正交方向的位移配置,每个方向步长固定15px const validDirections = [ {dx: 0, dy: -STEP}, // 向上 {dx: 0, dy: STEP}, // 向下 {dx: -STEP, dy: 0}, // 向左 {dx: STEP, dy: 0} // 向右 ]; // 随机选中一个方向 const pickedDir = validDirections[Math.floor(Math.random() * validDirections.length)]; // 更新圆形坐标 ballX += pickedDir.dx; ballY += pickedDir.dy; // 在新位置绘制圆形 drawBall(ballX, ballY); // 等待指定停留时长后,触发下一次移动 setTimeout(moveLoop, MOVE_WAIT); }
对应HTML文件
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>Run</title> <script src="script.js"></script> </head> <body onload="setup()"> <h1>Run</h1> <canvas id="myCanvas" height="400" width="400" style="border: 1px solid black"></canvas> </body> </html>
可调参数说明
- 想调整移动速度:修改
MOVE_WAIT的数值,数值越大停留时间越长,圆形移动越慢 - 想调整步长:修改
STEP的数值,当前固定为要求的15px - 想避免圆形移出画布看不见:可在更新坐标后加边界限制,比如用
ballX = Math.max(15, Math.min(canvas.width - 15, ballX))、ballY = Math.max(15, Math.min(canvas.height - 15, ballY))把坐标约束在画布范围内
内容的提问来源于stack exchange,提问作者Gustavo Diaz
相关产品推荐
相关产品推荐

