JS:为什么我必须单击我的“画布调整大小”按钮两次?

时间:2018-11-24 22:08:08

标签: javascript html5 canvas image-resizing double-click

我有一个392x392尺寸的HTML5画布,可以在其中绘制一些内容。 我正在尝试将该画布的内容调整为另一块尺寸为28x28像素的画布。

以下方法可以正常工作,除了必须两次单击“调整图像大小”按钮-为什么会这样,我该如何解决?

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

谢谢!

4 个答案:

答案 0 :(得分:2)

您尝试Image时,您的drawImage对象尚未完成其内容的加载。您必须等待,直到图像触发load事件。在该事件触发之前,该图像将不会呈现为任何图像,因为它尚未完成从其src URL加载数据的操作。

您的代码在第二次单击后即可工作,因为浏览器在第一次单击后已缓存与该特定src关联的图像数据,因此可以在第二次单击时立即呈现。

只需将resizedCtx.drawImage(...)调用放在回调函数中,该回调函数将在load发生img事件触发后按时间顺序运行。

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>

答案 1 :(得分:2)

您可以以此替换JS代码

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

画布将接受另一个画布内容。您现在所能做的就是操纵可变图像以更改其位置,然后就可以使用它。

答案 2 :(得分:0)

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行放在resize函数中。

答案 3 :(得分:0)

您可以在其他位置使用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>