java循环卡住,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?

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)

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;

}

Does not load, crashes browser window

解决方案

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.)

Draw once:

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 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);

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);

(Fun fact: crypto.getRandomValues is faster than this in practice, but not a good choice.)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值