我用 p5js 库用 javascript 制作了一个名为"pixel paint"的项目,但是当我运行它时,该项目运行得太慢了。我不知道为什么以及如何让它运行得更快。这是我的代码:
let h = 40, w = 64;
let checkbox;
let scl = 10;
let painting = new Array(h);
let brush = [0, 0, 0];
for(let i = 0; i < h; i++) {
painting[i] = new Array(w);
for(let j = 0; j < w; j++) {
painting[i][j] = [255, 255, 255];
}
}
function setup() {
createCanvas(w * scl, h * scl);
checkbox = createCheckbox('Show gird line', true);
checkbox.changed(onChange);
}
function draw() {
background(220);
for(let y = 0; y < h; y++) {
for(let x = 0; x < w; x++) {
fill(painting[y][x]);
rect(x * scl, y * scl, scl, scl);
}
}
if(mouseIsPressed) {
paint();
}
}
function onChange() {
if (checkbox.checked()) {
stroke(0);
} else {
noStroke();
}
}
function paint() {
if(mouseX < w * scl && mouseY < h * scl) {
let x = floor(mouseX / scl);
let y = floor(mouseY / scl);
painting[y][x] = brush;
}
}
<!--Include-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.min.js"></script>
有没有解决方案可以让我的项目运行得更快?
您拥有的代码易于阅读。
在这个阶段可能不值得优化,因为它会使代码在未来可能不必要地更加复杂/更难阅读和更改。
如果你想了解实现相同目标的不同方法,我可以提供一些想法,但是,对于您的特定用例,性能方面可能不会产生太大影响:
- 您可以使用平面
[w * h]
数组并使用单个for
循环而不是嵌套的 for 循环,而不是将painting
用作嵌套的[w][h]
数组。这有点类似于使用pixels[]
.(您可以将 x,y 转换为索引 (index = x + (y * width)
),反之亦然(x = index % width, y = floor(index / width)
) - 理论上,您可以使用
p5.Image
,访问pixels[]
来绘制并使用image()
进行渲染(理想情况下,如果浏览器支持,您将获得对WebGL渲染器的较低级别访问权限以启用抗锯齿)。网格本身可以是四边形的texture()
,您可以使用vertex()
不仅指定 x,y 几何位置,还指定与textureWrap(REPEAT)
串联的 u、v 纹理坐标。(我发布了一个较旧的重复处理示例:逻辑相同,语法几乎相同) - 与
p5.Image
思路类似,您可以使用createGraphics()
缓存绘图:例如,仅在拖动鼠标时更新p5.Graphics
实例,否则渲染缓存的绘图。此外,您可以使用noLoop()
/loop()
来控制p5的画布何时更新(例如loop()
mousePressed()
,更新图形mouseMoved()
,noLoop()
mouseReleased()
)
可能还有其他方法。
虽然了解优化代码的技术是件好事, 我强烈建议在您需要之前不要进行优化;当你这样做时 使用探查器(DevTools 有)只关注最慢的位 而不是在优化的部分代码上浪费时间和代码可读性 不会真正产生影响。