我刚刚开始玩HTML5画布,我希望用它制作一些游戏。然而,一旦我开始将鼠标坐标渲染到它,它就会磨成近乎停止的状态:
http://jsfiddle.net/mnpenner/zHpgV/
我所做的只是呈现38行和一些文本,它应该能够处理,不是吗?
我做错了吗?我希望能够以低于30 FPS的速度渲染,但对于这样的东西,我希望它可以绘制1000次。
或者我只是使用错误的工具来完成工作? WebGL是否可以胜任这项任务?为什么一个人比另一个慢得多?
String.prototype.format = function() {
var args = arguments;
return this.replace(/\{(\d+)\}/g, function(m, n) {
return args[n];
});
};
var $canvas = $('#canvas');
var c = $canvas[0].getContext('2d');
var scale = 20;
var xMult = $canvas.width() / scale;
var yMult = $canvas.height() / scale;
var mouseX = 0;
var mouseY = 0;
c.scale(xMult, yMult);
c.lineWidth = 1 / scale;
c.font = '1pt Calibri';
function render() {
c.fillStyle = '#dcb25c';
c.fillRect(0, 0, scale, scale);
c.fillStyle = '#544423';
c.lineCap = 'square';
for (var i = 0; i <= 19; ++i) {
var j = 0.5 + i;
c.moveTo(j, 0.5);
c.lineTo(j, 19.5);
c.stroke();
c.moveTo(0.5, j);
c.lineTo(19.5, j);
c.stroke();
}
c.fillStyle = '#ffffff';
c.fillText('{0}, {1}'.format(mouseX, mouseY), 0.5, 1.5);
}
render();
$canvas.mousemove(function(e) {
mouseX = e.clientX;
mouseY = e.clientY;
render();
});
&#13;
<canvas id="canvas" width="570" height="570"></canvas>
&#13;
答案 0 :(得分:9)
正如我在评论中所说,我对这段代码的缓慢感到惊讶,因为我用非常快的动画绘制了更复杂的东西,甚至没有打扰双缓冲。
所以我看了一下,发现了一个预期的错误。
主要问题是绘图路径的累积。
每次绘制一条路径时添加c.beginPath();
。
这是一个fast rendering of the same thing,以证明它现在过得很快。
画布绘制 快,可用于制作动画。
答案 1 :(得分:8)
这里的代码做得更好。
以下是我改变后应该考虑的事项的细分:
beginPath
创建新路径。这是迄今为止最大的性能杀手。你最终会得到一条路径,里面有成千上万的行记录永远无法清除。render
内部唯一需要调用的是stroke
。您不需要再次呼叫lineTo/moveTo
,当然也不会连续呼叫。见注1。注1:如果您计划在应用程序中有多个路径,那么您应该缓存这样的路径,因为它们永远不会更改。我有一个关于如何做到这一点的教程here。
当然,如果你只是做一个背景,那么它应该保存为png,你应该使用CSS背景图像。
像这样:http://jsfiddle.net/zHpgV/4/
然后突然你的渲染程序很小:
function render() {
c.clearRect(0, 0, scale, scale);
c.fillText('{0}, {1}'.format(mouseX, mouseY), 0.5, 1.5);
}
答案 2 :(得分:7)
您不必在每个动画帧中绘制整个网格。将它放在另一个底层画布上(通常将它们称为“图层”,但它们只是单独的画布元素),因此您只能重绘坐标。
<div id="canv">
<canvas id="bgLayer" width="500" height="500" style="z-index: 0"></canvas>
<canvas id="fgLayer" width="500" height="500" style="z-index: 1"></canvas>
</div>
这是the example我一直在玩分层画布。在底部画布上绘制的表格,球在顶部画布上绘制。它只是一个游乐场,所以有很多东西需要修复和优化,例如在另一个隐藏的画布上只绘制一次球,并使用getImageData/putImageData来提高性能。
此外,建议使用requestAnimationFrame更新画布。您的示例会依赖于每次鼠标移动,这需要更多时间(当鼠标移动时)。