JS:为什么我必须点击 canvas-resizing-button 两次?

JS: Why do I have to click my canvas-resizing-button twice?

我有一个大小为 392x392 的 HTML5 canvas,我在其中画了一些东西。 我正在尝试将 canvas 的内容调整为另一个 canvas,大小为 28x28 像素。

除了我必须点击 "resize image" 按钮两次之外,以下方法工作正常 - 为什么会这样,我该如何解决?

function resize() {
  //get the base64 string of the Image
  var dataURL = canvas.toDataURL();
  //draw the base64 string into a 28x28 canvas (for resizing)
  var img = new Image();
  img.src = dataURL;
  resizedCtx.drawImage(img, 0, 0, 28, 28);
}
<canvas id="canvas" width="392" height="392" style="border:1px solid;"></canvas>
<br>
<br>
<input type="button" value="resize image" id="btn" size="30" onclick="resize()">
<br>
<br>
<canvas id="resizedCanvas" width="28" height="28" style="border:1px solid;"></canvas>

<script>
  canvas = document.getElementById('canvas');
  ctx = canvas.getContext("2d");

  resizedCanvas = document.getElementById('resizedCanvas');
  resizedCtx = resizedCanvas.getContext('2d');
    
  ctx.fillStyle = "red";
  ctx.fillRect(20, 20, 280, 280);
</script>

code in jsfiddle.net

提前致谢!

function resize() {
  //get the base64 string of the Image
  var dataURL = canvas.toDataURL();
  //draw the base64 string into a 28x28 canvas (for resizing)
  var img = new Image();
  img.onload = function() {
    resizedCtx.drawImage(img, 0, 0, 28, 28);
  };
  img.src = dataURL;
}
<canvas id="canvas" width="392" height="392" style="border:1px solid;"></canvas>
<br>
<br>
<input type="button" value="resize image" id="btn" size="30" onclick="resize()">
<br>
<br>
<canvas id="resizedCanvas" width="28" height="28" style="border:1px solid;"></canvas>

<script>
  canvas = document.getElementById('canvas');
  ctx = canvas.getContext("2d");
  resizedCanvas = document.getElementById('resizedCanvas');
  resizedCtx = resizedCanvas.getContext('2d');
  ctx.fillStyle = "red";
  ctx.fillRect(20, 20, 280, 280);
</script>

只需将 resizedCanvas 和 resizedCtx 行放在调整大小函数中。

在您尝试 drawImage 时,您的 Image 对象尚未完成其内容的加载。您必须等到图像触发 load 事件。在该事件触发之前,图像不会渲染为任何东西,因为它尚未完成从 src URL.

加载数据

您的代码在第二次点击后工作,因为浏览器在第一次点击后缓存了与该特定 src 关联的图像数据,因此它准备好在第二次点击时立即呈现。

只需将您的 resizedCtx.drawImage(...) 调用放在一个回调函数中,该函数不会 运行 直到 imgload 事件按时间顺序触发。

function resize() {
  //get the base64 string of the Image
  var dataURL = canvas.toDataURL();
  //draw the base64 string into a 28x28 canvas (for resizing)
  var img = new Image();
  img.src = dataURL;
  img.addEventListener("load", function() {
      resizedCtx.drawImage(img, 0, 0, 28, 28);
  });
}

function resize() {
//get the base64 string of the Image
var dataURL = canvas.toDataURL();
//draw the base64 string into a 28x28 canvas (for resizing)
var img = new Image();
  img.src = dataURL;
  img.addEventListener("load", function() {
    resizedCtx.drawImage(img, 0, 0, 28, 28);
  });
}
<canvas id="canvas" width="392" height="392" style="border:1px solid;"></canvas>
<br><br>
<input type="button" value="resize image" id="btn" size="30" onclick="resize()">
<br><br>
<canvas id="resizedCanvas" width="28" height="28" style="border:1px solid;"></canvas>
<script>
  canvas = document.getElementById('canvas');
  ctx = canvas.getContext("2d");
  resizedCanvas = document.getElementById('resizedCanvas');
  resizedCtx = resizedCanvas.getContext('2d');
  ctx.fillStyle = "red";
  ctx.fillRect(20, 20, 280, 280);

</script>

你可以用这个替换你的JS代码

function resize() {
    var myCanvas = document.getElementById('resizedCanvas');
    var ctx = myCanvas.getContext('2d');
    var img = document.getElementById('canvas');
    ctx.drawImage(img,0,0);
}

Canvas 将接受另一个 canvas 内容。您现在所能做的就是操纵变量图像来改变它的位置,然后就可以了。

你可以在other中使用img.onload加载图片,然后执行函数 function resize() { //get the base64 string of the Image var dataURL = canvas.toDataURL(); //draw the base64 string into a 28x28 canvas (for resizing) var img = new Image(); img.src = dataURL; img.onload = function () { resizedCtx.drawImage(img, 0, 0, 28, 28); } }

只需将输入标签替换为此处的标签即可解决问题。

function resize() {
  //get the base64 string of the Image
  var dataURL = canvas.toDataURL();
  //draw the base64 string into a 28x28 canvas (for resizing)
  var img = new Image();
  img.src = dataURL;
  img.onload = function () { 
  resizedCtx.drawImage(img, 0, 0, 28, 28);
    }
}
<canvas id="canvas" width="392" height="392" style="border:1px solid;"></canvas>
<br>
<br>
<input type="button" value="resize image" id="btn" size="30" onclick="resize()">
<br>
<br>
<canvas id="resizedCanvas" width="28" height="28" style="border:1px solid;"></canvas>

<script>
 canvas = document.getElementById('canvas');
  ctx = canvas.getContext("2d");

  resizedCanvas = document.getElementById('resizedCanvas');
  resizedCtx = resizedCanvas.getContext('2d');
    
  ctx.fillStyle = "red";
  ctx.fillRect(20, 20, 280, 280);
</script>