Это потому, что fillRect
довольно медленный по сравнению с другими методами.Вероятно, вы могли бы ускорить процесс, используя вместо этого ImageData
объекты.
Способ сделать это - отобразить все на холсте, получить соответствующий ImageData
, изменить его содержимое.и поместите его обратно на холст:
var ctx = canvas.getContext("2d");
// render stuff here
var imageData = ctx.getImageData(0,0,canvasWidth,canvasHeight);
for (let x=0;x<canvasWidth;x++){
for (let y=0;y<canvasHeight;y++){
let i = (x+y*canvasWidth)*4;
let alpha = calculateAlpha(x,y); // your method here (should result in a value between 0 and 1)
imageData.data[i] = (1-alpha)*imageData.data[i]+alpha*25;
imageData.data[i+1] = (1-alpha)*imageData.data[i+1]+alpha*25;
imageData.data[i+2] = (1-alpha)*imageData.data[i+2]+alpha*30;
imageData.data[i+3] = 1-(1-alpha)*(1-imageData.data[i+3]);
}
}
ctx.putImageData(imageData,0,0);
Это должно делать освещение для каждого пикселя, и намного быстрее, чем использовать clearRect
все время.Тем не менее, это все равно может замедлить работу, так как вы выполняете много вычислений в каждом кадре.В этом случае вы могли бы ускорить процесс, выполнив освещение на втором холсте, который расположен над вашим основным холстом, используя css:
<div id="container">
<canvas id="canvas"></canvas>
<canvas id="lightingCanvas"></canvas>
</div>
Css:
#container {
position: relative;
}
#canvas, #lightingCanvas {
position: absolute;
top: 0;
left: 0;
}
#container, #canvas, #lightingCanvas {
width: 480px;
height: 360px;
}
Javascript:
var canvas = document.getElementById("lightingCanvas")
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgb(25,25,30)";
ctx.fillRect(0,0,canvas.width,canvas.height);
var imageData = ctx.getImageData(0,0,canvasWidth,canvasHeight);
for (let x=0;x<canvasWidth;x++){
for (let y=0;y<canvasHeight;y++){
let i = (x+y*canvasWidth)*4;
let alpha = calculateAlpha(x,y); // your method here (should result in a value between 0 and 1)
imageData.data[i+3] = 255*alpha;
}
}
ctx.putImageData(imageData,0,0);
Таким образом, браузер позаботится о смешивании для вас, и вам просто нужно подключить правильные альфа-значения - так что рендеринг должен быть еще быстрее.
Это также позволит вамчтобы вернуть большие пиксели - просто используйте более низкое разрешение на втором холсте и используйте некоторый эффект CSS, такой как image-rendering
: -webkit-crisp-edges
, чтобы сделать пикселизированный холст при увеличении.