单步执行时Javascript行为会发生变化

单步执行时Javascript行为会发生变化,javascript,html5-canvas,Javascript,Html5 Canvas,如果我单步执行下面的js代码(在OSX上使用Firefox44),我会得到想要的结果:执行context.setTransform(…),图像放大2 另一方面,如果我通过加载页面在FF中运行代码,就好像从未应用转换一样。(结果与注释掉context.setTransform(…)行相同。) 罪魁祸首似乎是context.save()/context.restore()对。将这两行注释掉会直接产生期望的结果。但最好使用save/restore包装图形代码,以隔离上下文,尤其是当前转换 您可以使

如果我单步执行下面的js代码(在OSX上使用Firefox44),我会得到想要的结果:执行
context.setTransform(…)
,图像放大2

另一方面,如果我通过加载页面在FF中运行代码,就好像从未应用转换一样。(结果与注释掉
context.setTransform(…)
行相同。)

罪魁祸首似乎是
context.save()
/
context.restore()
对。将这两行注释掉会直接产生期望的结果。但最好使用save/restore包装图形代码,以隔离上下文,尤其是当前转换

您可以使用
convert-size 100x100 plasma:fractal plasma\u fractal 1.jpg
在您的一侧显示图像

我知道设置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>

您正面临两个异步函数(挂接在Image.onload上的匿名函数,实际执行drawImage和myDrawingFunction函数)之间的“竞争”问题。
在调试情况下,映像有时间加载,因此onload会立即触发并执行您想要的操作。
在您只是定期加载页面的情况下,在加载图像之前设置/取消设置上下文:加载图像时为时已晚(上下文已恢复),并且图像以1:1的比例绘制


对这些事情进行编码的正确方法是分离关注点,等待dom和所有图像加载,然后再执行任何操作

您正面临两个异步函数(挂接在Image.onload上的匿名函数,实际执行drawImage和myDrawingFunction函数)之间的“竞争”问题。
在调试情况下,映像有时间加载,因此onload会立即触发并执行您想要的操作。
在您只是定期加载页面的情况下,在加载图像之前设置/取消设置上下文:加载图像时为时已晚(上下文已恢复),并且图像以1:1的比例绘制


对这些事情进行编码的正确方法是分离关注点,等待dom和所有图像加载,然后再执行任何操作

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

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

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

因此,您的代码的一步一步是:


  • 获取
    myfrac.js
  • 定义
    myDrawImage
    函数和
    myDrawingFunction
    函数*
  • 调用myDrawingFunction
  • 定义
    canvas
    ctx
    变量
  • 清除上下文(如果之前没有绘制任何内容,则无用;如果之前有绘制内容,则应在此列出以前的var定义)
  • 保存上下文属性
  • 调用
    myDrawImage
  • 定义
    img
  • 设置其
    onload
    事件处理程序(此处理程序将被堆叠)
  • 设置
    img
    src
  • 还原上下文属性(尚未在其上绘制任何内容)
  • 如果有其他脚本,则必须执行其他任何操作
  • 12.+x。调用img onload handler=drawImage()


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


    *这两种行为的顺序无法确定,这是完全正常和预期的行为

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

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

    因此,您的代码的一步一步是:


  • 获取
    myfrac.js
  • 定义
    myDrawImage
    函数和
    myDrawingFunction
    函数*
  • 调用myDrawingFunction
  • 定义
    canvas
    ctx
    变量
  • 清除上下文(如果之前没有绘制任何内容,则无用;如果之前有绘制内容,则应在此列出以前的var定义)
  • 保存上下文属性
  • 调用
    myDrawImage
  • 定义
    img
  • 设置其
    onload
    事件处理程序(此处理程序将被堆叠)
  • 设置
    img
    src
  • 还原上下文属性(尚未在其上绘制任何内容)
  • 如果有其他脚本,则必须执行其他任何操作
  • 12.+x。调用img onload handler=drawImage()


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


    *这两种代码的顺序无法确定

    何时调用js代码?您是否在等待先读取文档?我可以想象您的图像正在加载,您对其进行转换,然后dom被回流。如果您正在使用调试程序,那么您可能正在dom流动后运行代码。如果您有jQuery,请尝试使用“$(document).ready(myDrawingFunction);”包装对draw函数的调用@bhspencer用“$(文档).ready(myDrawingFunction);”包装没有帮助。单步执行仍然会产生不同的结果。是否使用
    window.onload
    事件,如
    window.onload=myDrawingFunction
    ?何时调用js代码?您是否在等待先读取文档?我可以想象您的图像正在加载,您对其进行转换,然后dom被回流。在那里,好像您正在使用调试程序
    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();
    }