Firefox从保存的base64恢复时绘制空白画布

时间:2016-04-04 15:39:01

标签: javascript html5 firefox canvas base64

我正在使用单个画布,允许用户单击窗口图像中的窗口窗格。想法是显示用户点击的位置。然后修改图像(通过在窗口上绘制格栅),然后保存为JPEG。我在点击功能之前保存了画布图像,因为我不希望选择框显示在最终图像中。但是,在恢复IE和Chrome没有的画布时,Firefox通常会显示空白画布。这在Chrome和IE中完美运行。有什么建议? Firefox是否有toDataURL()的问题?也许有些异步问题在这里发生?我也知道以这种方式保存画布是内存密集型的,可能有更好的方法来做到这一点,但我正在使用我所拥有的。

代码:

    /**
     * Restores canvas from drawingView.canvasRestorePoint if there are any restores saved
     */
    restoreCanvas:function()
    {
      var inverseScale = (1/drawingView.scaleFactor);
      var canvas = document.getElementById("drawPop.canvasOne");
      var c = canvas.getContext("2d");
      if (drawingView.canvasRestorePoint[0]!=null)
      {
        c.clearRect(0,0,canvas.width,canvas.height);
        var img = new Image();
        img.src = drawingView.canvasRestorePoint.pop();
        c.scale(inverseScale,inverseScale);
        c.drawImage(img, 0, 0);
        c.scale(drawingView.scaleFactor, drawingView.scaleFactor);
     }
    },
    /**
     * Pushes canvas into drawingView.canvasRestorePoint
     */
    saveCanvas:function()
    {
       var canvas = document.getElementById("drawPop.canvasOne");
       var urlData = canvas.toDataURL();
       drawingView.canvasRestorePoint.push(urlData);
    },

使用示例:

    readGrillInputs:function()
    {
        var glassNum = ir.get("drawPop.grillGlassNum").value;
        var panelNum = ir.get("drawPop.grillPanelNum").value;

        drawingView.restoreCanvas();
        drawEngine.drawGrill(glassNum, panelNum,null);
        drawingView.saveCanvas();
    },
    sortClick:function(event)
    {
      ..... //Sorts where user has clicked and generates panel/glass num
      ..... 
      drawingView.showClick(panelNum, glassNum);
    },
    showClick:function(panelNum, glassNum)
    {
       var glass = item.panels[panelNum].glasses[glassNum];
       var c = drawEngine.context;
       drawingView.restoreCanvas();
       drawingView.saveCanvas();
       c.strokeStyle = "red";
       c.strokeRect(glass.x, glass.y, glass.w, glass.h);
    },

1 个答案:

答案 0 :(得分:2)

By just looking at the code setting the img.src is an async action to retrieve the image, so when you try to draw it 2 lines later to the canvas, it probably hasn't been loaded yet (having it in cache will make it return fast enough that it might work).

You should instead use an img.onload function to draw the image when it has loaded.

restoreCanvas:function()
{
  var inverseScale = (1/drawingView.scaleFactor);
  var canvas = document.getElementById("drawPop.canvasOne");
  var c = canvas.getContext("2d");
  if (drawingView.canvasRestorePoint[0]!=null)
  {
    c.clearRect(0,0,canvas.width,canvas.height);
    var img = new Image();
    img.onload = function() {
      c.scale(inverseScale,inverseScale);
      c.drawImage(img, 0, 0);
      c.scale(drawingView.scaleFactor, drawingView.scaleFactor);
    };
    img.src = drawingView.canvasRestorePoint.pop();
 }
},