Java中另一个for循环内的for循环崩溃 [英] For loop inside another for loop crashes in Javascript

查看:129
本文介绍了Java中另一个for循环内的for循环崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为画布中的每个像素随机生成一种颜色,但是我的循环似乎使浏览器崩溃,我不知道为什么?

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 似乎是画布方法绘制像素的更好选择:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆