我正在尝试通过渲染单个正方形来将网格渲染到HTML画布(因为稍后在单元格上看起来不应该全部相同,而是具有各自的行为)。
我创建了一个最小的示例,该示例显示了我遇到的性能问题。运行该脚本几乎会冻结我的浏览器,直到它为我停止脚本为止,因为它检测到该脚本运行太慢。
我有一个运行Javascript框架p5.js的类似示例,并且在性能方面运行良好。 但是,我想在没有该框架的情况下转向基本Javascript。
这是引起性能问题的最小示例。我很高兴看到为什么它运行这么慢的任何建议...
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
const width = canvas.width;
const height = canvas.height;
let grid_width = 50;
let grid_height = grid_width;
let grid = [];
class Cell {
constructor(i,j) {
this.i = i;
this.j = j;
this.width = width / grid_width;
this.height = height / grid_height;
this.x = i*this.width;
this.y = j*this.height;
}
render(color) {
context.rect(this.x, this.y, this.width, this.height);
context.strokeStyle = '#000000';
context.lineWidth = .25;
if(color) {
context.fillStyle = color;
}
context.fillStyle = '#FFFFFF';
context.fill();
context.stroke();
}
}
for(let i = 0; i <= grid_width; i++) {
if(!(grid[i])) {
grid[i] = [];
}
for(let j = 0; j <= grid_height; j++) {
grid[i][j] = new Cell(i, j);
}
}
function draw() {
context.clearRect(0, 0, width, height);
grid.forEach(row => {
row.forEach(cell => {
cell.render();
});
});
requestAnimationFrame(draw);
}
// This call to draw will run very slowly!
// draw();
<!DOCTYPE html>
<html>
<head>
<!-- <script src="p5.js"></script> -->
</head>
<body>
<canvas id="canvas" width="800" height="800"></canvas><br>
<script src="sketch.js"></script>
</body>
</html>
请注意,我已注释掉对draw()的调用,因为我的脚本还破坏了该站点上的“运行代码段”按钮...
答案 0 :(得分:0)
注释了requestAnimationFrame(row)
函数调用。因为不存在这样的功能。现在,代码对我来说工作顺利。
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
const width = canvas.width;
const height = canvas.height;
let grid_width = 50;
let grid_height = grid_width;
let grid = [];
class Cell {
constructor(i,j) {
this.i = i;
this.j = j;
this.width = width / grid_width;
this.height = height / grid_height;
this.x = i*this.width;
this.y = j*this.height;
}
render(color) {
context.rect(this.x, this.y, this.width, this.height);
context.strokeStyle = '#000000';
context.lineWidth = .25;
if(color) {
context.fillStyle = color;
}
context.fillStyle = '#FFFFFF';
context.fill();
context.stroke();
}
}
for(let i = 0; i <= grid_width; i++) {
if(!(grid[i])) {
grid[i] = [];
}
for(let j = 0; j <= grid_height; j++) {
grid[i][j] = new Cell(i, j);
}
}
function draw() {
context.clearRect(0, 0, width, height);
grid.forEach(row => {
row.forEach(cell => {
cell.render();
});
});
//requestAnimationFrame(draw);
}
// This call to draw will run very slowly!
draw();
<!DOCTYPE html>
<html>
<head>
<!-- <script src="p5.js"></script> -->
</head>
<body>
<canvas id="canvas" width="800" height="800"></canvas><br>
<script src="sketch.js"></script>
</body>
</html>
答案 1 :(得分:0)
类似这样的事情。
简要说明。rect
是画布path command
。因此,fill
和stroke
用最新的beginPath()
和endPath
重绘了fillStyle
和strokeStyle
之间的所有路径。在这种情况下,循环首先仅绘制第一个矩形,然后再绘制第一个和第二个,依此类推。
是的,在方法中固定了if
语句后,您的颜色将始终应用于所有单元格。
所以我在这里使用了一些不同的代码。第一。我用立即应用的rect
和strokeRect
替换了fillRect
。第二。我删除了您的if
条件。
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
const width = canvas.width;
const height = canvas.height;
let grid_width = 50;
let grid_height = grid_width;
let grid = [];
class Cell {
constructor(i,j) {
this.i = i;
this.j = j;
this.width = width / grid_width;
this.height = height / grid_height;
this.x = i*this.width;
this.y = j*this.height;
}
render(color) {
context.strokeStyle = '#000000';
context.lineWidth = .25;
context.fillStyle = color || '#FFFFFF';
context.strokeRect(this.x, this.y, this.width, this.height);
context.fillRect(this.x, this.y, this.width, this.height);
}
}
for(let i = 0; i <= grid_width; i++) {
if(!(grid[i])) {
grid[i] = [];
}
for(let j = 0; j <= grid_height; j++) {
grid[i][j] = new Cell(i, j);
}
}
function draw() {
context.clearRect(0, 0, width, height);
grid.forEach(row => {
row.forEach(cell => {
cell.render(Math.random()>0.5?"#FF00FF":undefined);
});
});
//requestAnimationFrame(draw);
}
// This call to draw will run very slowly!
draw();
<!DOCTYPE html>
<html>
<head>
<!-- <script src="p5.js"></script> -->
</head>
<body>
<canvas id="canvas" width="800" height="800"></canvas><br>
<script src="sketch.js"></script>
</body>
</html>