p5.js代码卡顿排查:鼠标按压随动圆形一段时间后运动逐步减速
问题根因定位
- 逻辑设计缺陷带来的“减速”体感(非性能问题)
原代码仅在鼠标未按下时执行this.theta += 0.01的旋转增量逻辑,鼠标按住状态下theta值完全冻结,原本绕大圆圆周旋转的小圆会直接停转,这是视觉上最先感知到的“减速”来源,并非程序负载升高导致。 - 无限制数组累积+绘制逻辑错误带来的真实性能下降
- 鼠标按住时每帧无上限向
this.history数组push新的坐标对象,数组长度随按住时间线性增长,单帧遍历耗时、内存占用会逐步升高 - 轨迹绘制时错误将
endShape()写在for循环内部:beginShape()初始化后,每添加一个顶点就结束一次形状渲染,不仅无法绘制连续的运动轨迹,还会随着历史点数量增加,产生大量冗余的渲染函数调用,进一步拉低帧率。 - 由于旋转角度增量是按帧计算的(每帧固定加0.01弧度),帧率下降后单位时间内的角度总增量会随之减少,最终让原本持续旋转的大圆形也表现出越来越慢的视觉效果。
- 鼠标按住时每帧无上限向
- 缓动逻辑书写偏差
原代码中大圆形中心的更新公式存在冗余项,化简后实际仅能朝着固定方向漂移,完全没有实现“大圆形随鼠标位置跟随”的预期效果。
修正方案与代码实现
修正核心调整点:
- 无论鼠标是否按下,持续累加theta值,保证旋转臂上的小圆始终保持恒定转速
- 给轨迹历史数组设置长度上限(建议保留最近100个坐标点),避免无限累积
- 将
endShape()移到for循环外部,保证绘制连续运动轨迹,减少冗余渲染开销 - 修正随动逻辑,以鼠标坐标为大圆形的跟随目标,保证平滑移动效果
修正后的代码:
class Particle{ constructor(){ this.center = createVector(0,0); this.radius = 20; this.theta = 0; this.line = createVector(0,0); this.history = []; this.maxHistoryLength = 100; // 设置轨迹点上限 } render(){ translate(60,60); // 绘制大圆形 circle(this.center.x, this.center.y, this.radius); // 绘制旋转臂上的小圆 circle(this.line.x + this.center.x, this.line.y + this.center.y, 10); // 绘制连续运动轨迹 noFill(); beginShape(); for(let i=0;i < this.history.length; i++){ let pos = this.history[i]; vertex(pos.x, pos.y); } endShape(); } update(){ // 无论鼠标状态如何,持续旋转保证转速恒定 this.theta += 0.01; this.line.x = this.radius/2 * cos(this.theta); this.line.y = this.radius/2 * sin(this.theta); if (mouseIsPressed){ // 平滑跟随鼠标坐标的缓动逻辑 const targetX = mouseX - 60; // 抵消translate的偏移量 const targetY = mouseY - 60; this.center.x = (1-0.025)*this.center.x + 0.025*targetX; this.center.y = (1-0.025)*this.center.y + 0.025*targetY; // 记录轨迹点,超出上限时删除最早的点 this.history.push({x: this.center.x, y: this.center.y}); if(this.history.length > this.maxHistoryLength){ this.history.shift(); } } } } let particle; function setup() { createCanvas(windowWidth, windowHeight); particle = new Particle(); } function draw() { background(220); particle.render(); particle.update(); }
内容的提问来源于stack exchange,提问作者Harsha Satya Vardhan
相关产品推荐
相关产品推荐

