将图像绘制到画布上会为每个绘制的新图像返回InvalidStateError,然后成功

布莱恩·阿什利(Bryan Ashley)

情况

我有144个(90px x 90px)图像(12x12)可以旋转的网格状无序列表。我的最终目标是拍摄144个图像网格并将其另存为1个图像。

当前解决方案

我当前的解决方案是按照以下步骤操作:

  1. 创建一个图像宽度x 12宽和一个图像高度x 12高的画布。这是代表最终产品的图像。
  2. 遍历列表项(图像),从项中提取图像src并将其绘制到自己的画布上,该画布是图像的大小。
  3. 旋转新的小画布,但是其图像已在网格上旋转。
  4. 在当前指针的x和y处,将新的小画布绘制到最终结果画布上。

注意事项

当我遍历图像时,我会跟踪一个指针(我当前在画布上的位置)。我通过保持一行和一个列号来做到这一点。它们代表了我正在绘制的图像的当前行和列。我用它们乘以单个图像的宽度和高度来获得画布上确切的x和y坐标以绘制下一个图像。

当前问题

当我调用该函数来创建,绘制和生成画布的base64时,会收到以下错误消息:“ InvalidStateError:试图使用一个不可用或不再可用的对象。” 如果此错误发生的可能性为100%,则我将其假定为是因为我要绘制到画布上的图像尚未加载或根本没有加载,但是我只收到一次此错误,原因是我加载的每个新图像。例如,如果我有一个144图像网格,即2个不同的图像,每个图像绘制72次,则我将收到两次InvalidStateError,然后第三次调用该函数,它将成功。

当前代码

请记住,这只是简单的秒杀代码,可以测试保存图像,我知道需要进行一些重构。

generateThumbnail: function(){
  var builder = this,
      canvas = document.createElement('canvas'),
      content,
      row = 0,
      col = 0;

  // width is single image width (90) x number of tiles wide (usually 12)
  canvas.width = 90 * builder.grid[0];
  // height is single image height (90) x number of tiles high (usually 12)
  canvas.height = 90 * builder.grid[1];
  // get 2d context of new canvas
  context = canvas.getContext("2d");

  // loop through all of the images on the grid
  $.each($(".pattern-grid li"), function(i, tile) {
    var $tile = $(tile),
        image = new Image(),
        src = $tile.find("img").attr("src"),
        width,
        height,
        buffer,
        bufferctx,
        x,
        y;

    // set crossOrigin of image to anonymous as these images are loaded via CORS
    image.crossOrigin = "Anonymous";
  
    // increase row number by 1 if it has reached the end of the row and its not the first image being drawn
    if(i % builder.grid[0] == 0 && i != 0){
      row++;
    }
    // Set Column to 0 if it is a new row, otherwise increase column by 1 (unless it is the first image being drawn)
    if(col == builder.grid[0]-1){
      col = 0;
    }else if(i != 0){
      col++;
    }

    // determine if there was no image drawn at this location
    if(src != undefined){
      image.src = src;
      // get the width and height the image, to be used for the small canvas and where to draw it
      width = image.width;
      height = image.height;
      // create a new buffer canvas to draw the image to, this will be used to apply any rotations that may exist
      buffer = document.createElement("canvas");
      //set width and height of the buffer to the current images width and height
      buffer.width = width;
      buffer.height = height;
      bufferctx = buffer.getContext("2d");
      //Determine x and y coordinates to draw the small canvas using row and column numbers
      x = col*width;
      y = row*height;
      //Save current state of buffer canvas
      bufferctx.save();
      //translate and then rotate the buffer canvas by the image's rotation
      bufferctx.translate(width/2, height/2);
      bufferctx.rotate($tile.find("img").data("rotation")*Math.PI/180);
      bufferctx.translate(width/2*-1, height/2*-1);
      //draw image to buffer canvas and restore its context
      bufferctx.drawImage(image, 0, 0);
      bufferctx.restore();
      //draw the buffer canvas to the main canvas at predetermined x and y
      context.drawImage(buffer, x, y, width, height);
    }
  });
  return canvas.toDataURL();
}
布莱恩·阿什利(Bryan Ashley)

我可以将@abiessu的建议与onload一起使用,并与闭包配对以保存函数的状态。我有效的解决方案是:

generateThumbnail: function(){
  var builder = this,
      canvas = document.createElement('canvas'),
      content,
      row = 0,
      col = 0;
  // width is single image width (90) x number of tiles wide (usually 12)
  canvas.width = 90 * builder.grid[0];
  // height is single image height (90) x number of tiles high (usually 12)
  canvas.height = 90 * builder.grid[1];
  context = canvas.getContext("2d");
  // loop through all of the images on the grid
  $.each($(".pattern-grid li"), function(i, tile) {
    var $tile = $(tile),
        image = new Image(),
        src = $tile.find("img").attr("src");
     // set crossOrigin of image to anonymous as these images are loaded via CORS
    image.crossOrigin = "Anonymous";
    // increase row number by 1 if it has reached the end of the row and its not the first image being drawn
    if(i % builder.grid[0] == 0 && i != 0){
      row++;
    }
    // increase row number by 1 if it has reached the end of the row and its not the first image being drawn
    if(col == builder.grid[0]-1){
      col = 0;
    }else if(i != 0){
      col++;
    }
    image.onload = function(row, col){
      return function(){
        // determine if there was no image drawn at this location
        if(src != undefined){
          var width = image.width,
              height = image.height,
              buffer = document.createElement("canvas"),
              bufferctx,
              x,
              y;
          buffer.width = width;
          buffer.height = height;
          bufferctx = buffer.getContext("2d");
          x = col*width;
          y = row*height;
          bufferctx.save();
          bufferctx.translate(width/2, height/2);
          bufferctx.rotate($tile.find("img").data("rotation")*Math.PI/180);
          bufferctx.translate(width/2*-1, height/2*-1);
          bufferctx.drawImage(image, 0, 0);
          bufferctx.restore();
          context.drawImage(buffer, x, y, width, height);
        }
      }
    }(row, col);
    image.src = $tile.find("img").attr("src");
  });
  window.canvas = canvas;
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用img.crossOrigin =“ Anonymous”将图像绘制到画布上不起作用

来自分类Dev

html画布可以绘制上传的图像吗?

来自分类Dev

画布未绘制图像

来自分类Dev

javascript在画布上绘制图像

来自分类Dev

绘制到html画布中的png图像质量不佳

来自分类Dev

飞镖画布未绘制图像

来自分类Dev

在画布内绘制图像

来自分类Dev

使用回调将图像绘制到画布的Javascript

来自分类Dev

javascript画布不会绘制图像

来自分类Dev

画布-从原型中绘制图像

来自分类Dev

使用JCrop裁剪图像绘制到画布中

来自分类Dev

如果图像来自其他站点,将图像绘制到画布上会被描述为热链接吗?

来自分类Dev

画布上的文字未绘制在图像上

来自分类Dev

多个画布未绘制图像

来自分类Dev

在画布上绘制2点图像

来自分类Dev

将Svg绘制到画布上,包括嵌入到svg中的图像

来自分类Dev

将位图绘制到另一个上会产生失真的图像

来自分类Dev

将两个图像的差异绘制到画布

来自分类Dev

尝试将base64图像绘制到画布时出现HTTP错误431

来自分类Dev

在画布上绘制许多新图像时发生内存泄漏

来自分类Dev

将图像保存到画布,然后绘制更多

来自分类Dev

使用JCrop裁剪绘制到画布中的图像

来自分类Dev

用JavaScript加载并绘制平铺图像到画布

来自分类Dev

用图像而非颜色填充对象(将图像绘制到画布上)

来自分类Dev

在画布中绘制方形图像

来自分类Dev

将位图绘制到另一个上会产生失真的图像

来自分类Dev

在画布上绘制图像并作为纹理返回

来自分类Dev

如何将画布绘制到新的HTML页面

来自分类Dev

为什么我必须使用 window.onload 将图像绘制到画布上

Related 相关文章

热门标签

归档