Java中另一个for循环内的for循环崩溃 [英] For loop inside another for loop crashes in Javascript
问题描述
我想为画布中的每个像素随机生成一种颜色,但是我的循环似乎使浏览器崩溃,我不知道为什么?
I want to randomly generate a color for each pixel in the canvas however my loop seems to crash the browser and I cannot figure out why?
我尝试缩小循环到一个静态数(X = 10 x Y = 100),它似乎起作用了。但是要花几秒钟的时间才能在屏幕上显示结果(尽管我的测试显示运行时间为10ms)
I have tried reducing the loop to a static number (X = 10 x Y=100) and it seems to work. However it takes a few seconds for the result to be shown on the screen (despite my tests showing a run time of 10ms)
我是javascript / html的新手,所以这可能是一个显而易见的解决方案,但是可以提供任何帮助。
I am new to javascript/html so this could be an obvious solution, however any help is greatly appreciated.
//"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>
不加载,崩溃浏览器窗口
Does not load, crashes browser window
推荐答案
您每次在其中添加一行时都会重新绘制路径。这是二次方的,不是必须的。 (当您有20,000条以上的行时,二次方是一个问题。)
You’re redrawing the path every time you add a line to it. That’s quadratic and not necessary. (Quadratic is a problem when you have 20,000+ lines.)
绘制一次:
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();
当您想绘制多种颜色时,请为每行开始一条新路径:
And when you want to draw in multiple colours, start a new path every for each line:
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 $ c不过,$ c>似乎是画布方法绘制像素的更好选择:
fillRect
seems like a better choice for a canvas method to draw a pixel, though:
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>
最后,放置图像数据可能会提供最佳性能。
And finally, putting image data probably gives the best performance.
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
在实践中比这要快,但是效果不是很好)选择。)
(Fun fact: crypto.getRandomValues
is faster than this in practice, but not a good choice.)
这篇关于Java中另一个for循环内的for循环崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!