我想为 Canvas 中的每个像素随机生成一种颜色,但是我的循环似乎使浏览器崩溃,我不知道为什么?
我尝试将循环减少到静态数(X = 10 x Y=100),它似乎有效。然而,结果需要几秒钟的时间才能显示在屏幕上(尽管我的测试显示运行时间为 10 毫秒)
我是 javascript/html 的新手,所以这可能是一个明显的解决方案,但是非常感谢任何帮助。
//"use strict";
// SELECT THE CANVAS ELEMENT FROM THE HTML PAGE AND NAME IT 'WORLD'
let world = document.querySelector("canvas");
// SET THE CANVAS HEIGHT/WIDTH TO THE WINDOW INNER X/Y
world.width = window.innerWidth;
world.height = window.innerHeight;
let context = world.getContext("2d");
// GET PERFORMANCE TEST VALUE BEFORE LOOP
let t0 = performance.now();
let x=0;
let y=0;
// LOOP THROUGH THE CANVAS STARTING AT FIRST PIXEL OF TOP ROW MOVING TO THE LAST PIXEL OF THE TOP ROW AND FILL, THEN MOVE TO THE NEXT LINE AND REPEAT FILL FOR EACH ROW UNTIL CANVAS IS COLORED
for (y=0; y < world.height; y++)
{
//TODO: ADD RANDOM RGB COLOR TO STROKE
context.lineTo(x,y);
context.stroke();
for (x=0; x < 10; x++){
//TODO: ADD RANDOM RGB COLOR TO STROKE
context.lineTo(x,y);
context.stroke();
}
}
// GET PERFORMANCE TEST VALUE AFTER LOOP
let t1 = performance.now();
// LOG THE TOTAL MILLISECONDS OF THE LOOP
console.log("Total Time" + (t1-t0) + " milliseconds");
// GENERATE A RANDOM NUMBER BASED ON THE WINDOW INNER WIDTH
function getRandomX(){
return Math.random() * window.innerWidth;
}
// GENERATE A RANDOM NUMBER BASED ON THE WINDOW INNER HEIGHT
function getRandomY(){
return Math.random() * window.innerHeight;
}
// GENERATE A RANDOM NUMBER BETWEEN 0 - 255
function getRandomRGB(){
return Math.Random() * 255;
}
<canvas></canvas>
无法加载,浏览器窗口崩溃
最佳答案
每次向路径添加线条时,都会重新绘制路径。这是二次的,而且没有必要。 (当您有 20,000 多条线时,二次就会出现问题。)
绘制一次:
let x = 0;
for (let y = 0; y < world.height; y++) {
context.lineTo(x, y);
for (x = 0; x < 10; x++) {
context.lineTo(x, y);
}
}
context.stroke();
当您想用多种颜色绘制时,请为每行开始一条新路径:
let x = 0;
for (let y = 0; y < world.height; y++) {
//TODO: ADD RANDOM RGB COLOR TO STROKE
context.lineTo(x, y);
context.stroke();
context.beginPath();
context.moveTo(x, y);
for (x = 0; x < 10; x++) {
//TODO: ADD RANDOM RGB COLOR TO STROKE
context.lineTo(x, y);
context.stroke();
context.beginPath();
context.moveTo(x, y);
}
}
不过, fillRect
似乎是 Canvas 方法绘制像素的更好选择:
const getRandomColor = () =>
'#' + (Math.random() * 0x1000000 >>> 0).toString(16);
const world = document.getElementById('canvas');
const context = world.getContext('2d');
const start = performance.now();
for (let y = 0; y < world.height; y++) {
for (let x = 0; x < world.width; x++) {
context.fillStyle = getRandomColor();
context.fillRect(x, y, 1, 1);
}
}
console.log(performance.now() - start);
<canvas id="canvas"></canvas>
最后,放入图像数据可能会提供最佳性能。
const world = document.getElementById('canvas');
const context = world.getContext('2d');
const start = performance.now();
const {width, height} = world;
const random32 = new Uint32Array(width * height);
for (let i = 0; i < random32.length; i++) {
random32[i] = Math.random() * 0x100000000 >>> 0;
}
const randomRGBA = new Uint8ClampedArray(random32.buffer);
for (let i = 3; i < randomRGBA.length; i += 4) {
randomRGBA[i] = 255;
}
const imageData = new ImageData(randomRGBA, width, height);
context.putImageData(imageData, 0, 0);
console.log(performance.now() - start);
<canvas id="canvas"></canvas>
(有趣的事实:crypto.getRandomValues
在实践中比这更快,但不是一个好的选择。)
关于javascript - Javascript 中的 For 循环在另一个 for 循环中崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56696807/