P5JS技术问题:如何保留背景同时实现无拖影动态抖动圆?
问题与解决方案
需求:实现带有多个背景椭圆的动态抖动圆,遇到以下矛盾:
- 生成背景椭圆的循环放
draw()里,会每帧重复生成椭圆,导致背景越来越密 - 循环放
setup()里,抖动圆会留下拖影 - 用
clear()会直接清除所有内容(包括背景椭圆)
解决方法
核心思路是用p5.js的createGraphics创建离屏缓存画布,把静态背景和动态元素分开绘制:
- 在
setup()中创建一个和主画布尺寸一致的离屏画布,把所有背景椭圆绘制到这个离屏画布上 - 在
draw()的最开头,将离屏画布绘制到主画布上——这相当于每帧重新铺一次静态背景,既保留了椭圆,又清除了上一帧的抖动圆痕迹 - 之后正常绘制动态抖动圆即可
修改后的完整代码
sketch.js
function setup() { createCanvas(600, 600); // 创建离屏画布用于存储静态背景 const backgroundCanvas = createGraphics(width, height); // 在离屏画布上绘制背景椭圆 backgroundCanvas.fill(255); for (let i = 0; i < 1000; i++){ backgroundCanvas.ellipse(random(width), random(height), 5, 5); } x = width/2; // 抖动圆圆心x坐标 y = height/2; // 抖动圆圆心y坐标 r = 100; // 基础半径 verts = 200; // 构成圆的顶点数 wobbleSlider = createSlider(0, 200, 100, 1); // 半径波动幅度 smthSlider = createSlider(1, 500, 70, 1); // 噪声平滑度(值越大越平滑) t = 1; // 将离屏画布挂载到全局,方便draw函数调用 this.backgroundCanvas = backgroundCanvas; } function draw() { // 每帧先绘制静态背景,清除上一帧的抖动圆 image(this.backgroundCanvas, 0, 0); let wobble = wobbleSlider.value() let smth = smthSlider.value(); t += 0.01 beginShape() for(let i = 0; i < verts; i++){ let f = noise(50*cos(i/verts*2*PI)/smth + t, 50*sin(i/verts*2*PI)/smth + t) vertex(x + (r+wobble*f) * cos( (i/verts) * 2 * PI ), y + (r+wobble*f) * sin( (i/verts) * 2 * PI ) ) } endShape(CLOSE) }
style.css(无修改)
html, body { margin: 0; padding: 0; } canvas { display: block; }
index.html(无修改)
<!DOCTYPE html> <html lang="en"> <head> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/addons/p5.sound.min.js"></script> <link rel="stylesheet" type="text/css" href="style.css"> <meta charset="utf-8" /> </head> <body> <script src="sketch.js"></script> </body> </html>
内容的提问来源于stack exchange,提问作者tmmbt
相关产品推荐
相关产品推荐

