我在玩宠物游戏时发现了一种奇怪的行为。我想在画布上绘制一些对象,其中一些需要旋转图像/图标。这是很常见的用例,通常的解决方案是使用上下文的rotate方法。随着我的使用translate,我也很好地将图像放在理想的位置。
这很好用,直到我在Windows笔记本电脑上尝试Chrome,并启用了硬件加速。图像开始闪烁并在屏幕上传送。我发现它与加速度有关(关闭加速图形修复问题),我最好的猜测是,当更新帧时,渲染器假定绘图调用是独立的并且可以并行执行。当发生上下文转换时,情况并非如此,因为上下文状态发生了变化。
不良行为的示例:使用ID为“屏幕”的canvas元素尝试以下操作:
var canvas = document.getElementById("screen"),
ctx = canvas.getContext("2d");
var drawrect = function () {
ctx.fillStyle = this.color;
ctx.translate(this.x+10, this.y+10);
ctx.rotate(this.rotation);
ctx.fillRect(-10, -10, 20, 20);
ctx.rotate(-this.rotation);
ctx.translate(-this.x-10, -this.y-10);
};
var red = {
x: 22,
y: 22,
rotation: 0,
color: "#ff0000",
draw: drawrect
};
var blu = {
x: 22,
y: 111,
rotation: 0,
color: "#0000ff",
draw: drawrect
};
function main_loop() {
ctx.clearRect(0, 0, 450, 450);
frameId = requestAnimationFrame(main_loop);
red.draw();
red.x += 1;
red.rotation +=0.1;
blu.draw();
blu.x += 1;
blu.rotation -=0.1;
}
main_loop();
工作示例:http://jsfiddle.net/1u2d7uhr/7/(在Chrome,Chromium,Firefox上测试;加速Chrome故障,其他人没有)
我能够通过删除翻译并将旋转元素渲染到单独的画布来“修复”这个画布,然后(在旋转之后)绘制到主画布上。这对我来说似乎很骇人听闻。
我的代码错误了吗?
在这种情况下,渲染旋转的正确方法是什么(也许这个问题我应该去做代码审查,但我不确定是不是这样)?
或者是浏览器方面的错误行为?我理解它背后的逻辑,但它对开发人员来说非常令人惊讶(并引起一些混乱)。或者我只有一个......