单步执行时{J}行为会发生变化

时间:2016-02-18 23:12:34

标签: javascript html5-canvas

如果我单步执行以下js代码(在OS X上使用Firefox 44),我会得到所需的结果:执行context.setTransform(...)并将图像放大2。

correct result obtained only when single stepping

如果另一方面我通过简单地加载页面来运行FF中的代码,就好像永远不会应用转换一样。 (结果与注释context.setTransform(...)行相同。)

otherwise an incorrect output is obtained

罪魁祸首似乎是context.save() / context.restore()对。评论这两行将直接产生预期的结果。但最好用保存/恢复来包装图形代码以隔离上下文,尤其是当前的转换。

您可以使用convert -size 100x100 plasma:fractal plasma_fractal1.jpg generate身边的finicky图片。

我知道设置img.src的顺序是enter image description here,但我注意到了正确的,多浏览器安全的订单。

发生了什么事?

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();
}

2 个答案:

答案 0 :(得分:2)

你正面临一场比赛&#39;两个异步函数之间的问题(实际执行drawImage和myDrawingFunction函数的Image.onload上挂起的匿名函数)。
在调试的情况下,图像有时间加载,因此onload立即触发并执行您想要的操作 在您只是定期加载页面的情况下,在加载图像之前设置/取消设置上下文:当图像加载时,它太晚(上下文被恢复)并且图像以1:1的比例绘制。

对这些事情进行编码的正确方法是分离关注点并等待dom和所有图像在执行任何操作之前加载。

答案 1 :(得分:0)

这是完全正常和预期的行为。

您正在混合同步和异步调用。

同步调用将按书面顺序逐个进行,而异步调用应堆叠在要执行的操作之上。

所以代码的一步一步是:

  1. 抓取myfrac.js
  2. 定义myDrawImage函数和myDrawingFunction函数*
  3. 致电myDrawingFunction
  4. 定义canvasctx变量
  5. 清除上下文(如果之前没有绘制任何内容则无用,如果有什么内容,则应在此处进行以前的var定义)
  6. 保存上下文属性
  7. 致电myDrawImage
  8. 定义img
  9. 设置其onload事件处理程序(此处理程序将堆叠)
  10. 设置img的{​​{1}}
  11. 恢复上下文属性(尚未绘制任何内容)
  12. 如果有任何其他脚本
  13. ,还有其他任何事情要做

    <强> 12 + X。调用img onload handler = drawImage()

    如您所见,在调用src处理程序时,您已经恢复了上下文的属性,并重置了上下文的矩阵。

    * 无法保证这两者的顺序