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

p5.js中DIFFERENCE混合模式致画面闪烁的原因及解决方法

问题分析与解决

闪烁原因

  1. 坐标系累积偏移:draw()函数每秒会执行约60次,每次执行都调用translate(width / 2, height / 2),但没有重置坐标系。这导致画布原点每次都会在之前的基础上再次向中心偏移,正方形的位置不断变化,直接引发视觉闪烁。
  2. 未清空画布+混合模式叠加:draw()开头没有调用background()清空画布,每次绘制的新正方形会和之前的画面通过DIFFERENCE混合模式叠加,颜色持续变化,进一步加剧闪烁效果。

解决方法

修改后的代码如下:

let size = 50;
let c = ["red", "green", "blue"];

function setup() {
  createCanvas(windowWidth, windowHeight);
}

function draw() {
  background(255); // 每次绘制前清空画布,消除画面叠加
  push(); // 先保存原始坐标系状态
  translate(width / 2, height / 2); // 在新状态中执行平移
  blendMode(DIFFERENCE);
  for (let i = 10; i > 0; i--) {
    fill(c[i % 3]);
    rect(0 - (i * size) / 2, 0 - (i * size) / 2, size * i, size * i);
  }
  pop(); // 恢复到原始坐标系,避免平移累积
}

核心改动:

  • 添加background(255):每次绘制前清空画布,阻止新旧画面的混合叠加。
  • 调整push()位置:将push()移到translate之前,确保pop()能恢复原始坐标系,避免每次draw()的平移操作累积偏移,让正方形固定在中心位置绘制。

当前示例中push()和pop()的作用

当前代码里的push()和pop()几乎没有实际作用:

  • push()是在translate之后调用的,保存的是已经偏移后的坐标系状态;pop()只是将状态恢复到本次translate后的状态,但下一次draw()又会再次执行translate,导致坐标系持续累积偏移。
  • 虽然pop()会把blendMode恢复到默认值,但这部分作用被坐标系偏移的问题完全掩盖,无法解决闪烁问题。

内容的提问来源于stack exchange,提问作者shasherazi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 09:10:00