如果我单步执行以下js代码(在OS X上使用Firefox 44),我会得到所需的结果:执行context.setTransform(...)
并将图像放大2。
如果另一方面我通过简单地加载页面来运行FF中的代码,就好像永远不会应用转换一样。 (结果与注释context.setTransform(...)
行相同。)
罪魁祸首似乎是context.save()
/ context.restore()
对。评论这两行将直接产生预期的结果。但最好用保存/恢复来包装图形代码以隔离上下文,尤其是当前的转换。
您可以使用convert -size 100x100 plasma:fractal plasma_fractal1.jpg
generate身边的finicky图片。
我知道设置img.src的顺序是,但我注意到了正确的,多浏览器安全的订单。
发生了什么事?
myfrac.html
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<style>
div {
width: 600px;
height: 400px;
background: #BBBBBB;
margin: 20px;
padding: 15px;
}
#myCanvas {
background-color: white;
border: 2px solid black;
width: 400px;
height: 300px;
}
</style>
</head>
<body>
<div>
<canvas id="myCanvas">
<p>Canvas not available</p>
</canvas>
</div>
<script src="myfrac.js" type="text/javascript"></script>
<script>myDrawingFunction()</script>
</body>
</html>
myfrac.js
function myDrawImage(context, imageURI, x, y, w, h)
{
var img = new Image;
img.onload = function(){
context.drawImage(img, x, y, w, h);
};
img.src = imageURI;
}
function myDrawingFunction()
{
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
context.save();
context.setTransform(2, 0, 0, 2, 0, 0);
myDrawImage(context, "plasma_fractal1.jpg", 0, 0, 200, 200);
context.restore();
}
答案 0 :(得分:2)
你正面临一场比赛&#39;两个异步函数之间的问题(实际执行drawImage和myDrawingFunction函数的Image.onload上挂起的匿名函数)。
在调试的情况下,图像有时间加载,因此onload立即触发并执行您想要的操作
在您只是定期加载页面的情况下,在加载图像之前设置/取消设置上下文:当图像加载时,它太晚(上下文被恢复)并且图像以1:1的比例绘制。
对这些事情进行编码的正确方法是分离关注点并等待dom和所有图像在执行任何操作之前加载。
答案 1 :(得分:0)
这是完全正常和预期的行为。
您正在混合同步和异步调用。
同步调用将按书面顺序逐个进行,而异步调用应堆叠在要执行的操作之上。
所以代码的一步一步是:
myfrac.js
myDrawImage
函数和myDrawingFunction
函数* myDrawingFunction
canvas
和ctx
变量myDrawImage
img
onload
事件处理程序(此处理程序将堆叠) img
的{{1}} <强> 12 + X。调用img onload handler = drawImage()
如您所见,在调用src
处理程序时,您已经恢复了上下文的属性,并重置了上下文的矩阵。
* 无法保证这两者的顺序