无法在 'CanvasRenderingContext2D' 上执行 'createPattern':图像参数是宽度或高度为 0 的 canvas 元素
Failed to execute 'createPattern' on 'CanvasRenderingContext2D': The image argument is a canvas element with a width or height of 0
我正在尝试为 canvas 项目制作放大镜,并且我正在尝试制作一个图案,其中涉及将包含图像副本的 canvas 的一部分复制到第二个,更小,canvas。我让 运行 进入错误状态:
"Failed to execute 'createPattern' on 'CanvasRenderingContext2D': The image argument is
a canvas element with a width or height of 0."
代码示例如下:
HTML:
<canvas id="tCanvas" width=240 height=240 style="background-color:aqua;">
</canvas>
<canvas id="canvas1" width=240 height=240 style="background-color:#808080;">
</canvas>
<p></p>
<button id="download" onclick="magnify();">Zoom</button>
JS:
var canvas = document.getElementById("canvas1");
var ctx = canvas.getContext('2d')
var base64 = canvas.toDataURL('image/png', 0);
drawing = new Image();
drawing.src = base64; // can also be a remote URL e.g. http://
var canvas1 = document.getElementById("tCanvas");
var ctx1 = canvas1.getContext('2d');
ctx1.drawImage(drawing, 0, 0);
let w = drawing.naturalWidth
let h = drawing.naturalHeight
let size = w / 4 // Size (radius) of magnifying glass
let magnification = 2
let r = size / magnification // Radius of part we want to magnify
let px = w / 3.5
let py = h / 4
let tileCanvas = document.getElementById("tCanvas")
tileCanvas.width = 2 * size
tileCanvas.height = 2 * size
tileCanvas.getContext('2d').drawImage(canvas, px - r, py - r, 2 * r, 2 * r, 0, 0, 2 * size, 2 * size)
let pattern = ctx.createPattern(tileCanvas, "repeat")
ctx.fillStyle = pattern
ctx.translate(px - size, py - size)
ctx.beginPath()
ctx.arc(size, size, size, 0, 2 * Math.PI)
ctx.fill()
ctx.strokeStyle = "orangered"
ctx.lineWidth = 12
ctx.stroke()
};
这是一个比较经典的问题,由图片加载'asynchronous nature'引起。我们看一下报错信息:
"Failed to execute 'createPattern' on 'CanvasRenderingContext2D': The
image argument is a canvas element with a width or height of 0."
它说发送到 createPattern()
方法的对象的高度或宽度为零,但为什么会发生这种情况?
让我们稍微回顾一下您的代码。
有问题的对象是 tileCanvas
,它的宽度和高度在这里确定:
tileCanvas.width = 2 * size
tileCanvas.height = 2 * size
那么size
的价值是多少?再往后退一步就会发现
let size = w / 4
和w
依次是
let w = drawing.naturalWidth
这是问题的症结所在。 naturalWidth
是图像对象的 属性 - 在您的例子中是 drawing
。问题是您在填充 .src
属性 后立即调用它。此时图像可能尚未完全加载,因此它 returns 为零。
您必须等待图像完全加载,才能查询其属性。这是通过监听 onload
事件来完成的。
这是一个例子:
var canvas = document.getElementById("canvas1");
var ctx = canvas.getContext('2d')
var base64 = canvas.toDataURL('image/png', 0);
drawing = new Image();
drawing.onload = () => {
var canvas1 = document.getElementById("tCanvas");
var ctx1 = canvas1.getContext('2d');
ctx1.drawImage(drawing, 0, 0);
let w = drawing.naturalWidth
let h = drawing.naturalHeight
let size = w / 4 // Size (radius) of magnifying glass
let magnification = 2
let r = size / magnification // Radius of part we want to magnify
let px = w / 3.5
let py = h / 4
let tileCanvas = document.getElementById("tCanvas")
tileCanvas.width = 2 * size
tileCanvas.height = 2 * size
tileCanvas.getContext('2d').drawImage(canvas, px - r, py - r, 2 * r, 2 * r, 0, 0, 2 * size, 2 * size)
let pattern = ctx.createPattern(tileCanvas, "repeat")
ctx.fillStyle = pattern
ctx.translate(px - size, py - size)
ctx.beginPath()
ctx.arc(size, size, size, 0, 2 * Math.PI)
ctx.fill()
ctx.strokeStyle = "orangered"
ctx.lineWidth = 12
ctx.stroke()
}
drawing.src = base64; // can also be a remote URL e.g. http://
<canvas id="tCanvas" width=240 height=240 style="background-color:aqua;">
</canvas>
<canvas id="canvas1" width=240 height=240 style="background-color:#808080;">
</canvas>
<p></p>
<button id="download" onclick="magnify();">Zoom</button>
我正在尝试为 canvas 项目制作放大镜,并且我正在尝试制作一个图案,其中涉及将包含图像副本的 canvas 的一部分复制到第二个,更小,canvas。我让 运行 进入错误状态:
"Failed to execute 'createPattern' on 'CanvasRenderingContext2D': The image argument is
a canvas element with a width or height of 0."
代码示例如下:
HTML:
<canvas id="tCanvas" width=240 height=240 style="background-color:aqua;">
</canvas>
<canvas id="canvas1" width=240 height=240 style="background-color:#808080;">
</canvas>
<p></p>
<button id="download" onclick="magnify();">Zoom</button>
JS:
var canvas = document.getElementById("canvas1");
var ctx = canvas.getContext('2d')
var base64 = canvas.toDataURL('image/png', 0);
drawing = new Image();
drawing.src = base64; // can also be a remote URL e.g. http://
var canvas1 = document.getElementById("tCanvas");
var ctx1 = canvas1.getContext('2d');
ctx1.drawImage(drawing, 0, 0);
let w = drawing.naturalWidth
let h = drawing.naturalHeight
let size = w / 4 // Size (radius) of magnifying glass
let magnification = 2
let r = size / magnification // Radius of part we want to magnify
let px = w / 3.5
let py = h / 4
let tileCanvas = document.getElementById("tCanvas")
tileCanvas.width = 2 * size
tileCanvas.height = 2 * size
tileCanvas.getContext('2d').drawImage(canvas, px - r, py - r, 2 * r, 2 * r, 0, 0, 2 * size, 2 * size)
let pattern = ctx.createPattern(tileCanvas, "repeat")
ctx.fillStyle = pattern
ctx.translate(px - size, py - size)
ctx.beginPath()
ctx.arc(size, size, size, 0, 2 * Math.PI)
ctx.fill()
ctx.strokeStyle = "orangered"
ctx.lineWidth = 12
ctx.stroke()
};
这是一个比较经典的问题,由图片加载'asynchronous nature'引起。我们看一下报错信息:
"Failed to execute 'createPattern' on 'CanvasRenderingContext2D': The image argument is a canvas element with a width or height of 0."
它说发送到 createPattern()
方法的对象的高度或宽度为零,但为什么会发生这种情况?
让我们稍微回顾一下您的代码。
有问题的对象是 tileCanvas
,它的宽度和高度在这里确定:
tileCanvas.width = 2 * size
tileCanvas.height = 2 * size
那么size
的价值是多少?再往后退一步就会发现
let size = w / 4
和w
依次是
let w = drawing.naturalWidth
这是问题的症结所在。 naturalWidth
是图像对象的 属性 - 在您的例子中是 drawing
。问题是您在填充 .src
属性 后立即调用它。此时图像可能尚未完全加载,因此它 returns 为零。
您必须等待图像完全加载,才能查询其属性。这是通过监听 onload
事件来完成的。
这是一个例子:
var canvas = document.getElementById("canvas1");
var ctx = canvas.getContext('2d')
var base64 = canvas.toDataURL('image/png', 0);
drawing = new Image();
drawing.onload = () => {
var canvas1 = document.getElementById("tCanvas");
var ctx1 = canvas1.getContext('2d');
ctx1.drawImage(drawing, 0, 0);
let w = drawing.naturalWidth
let h = drawing.naturalHeight
let size = w / 4 // Size (radius) of magnifying glass
let magnification = 2
let r = size / magnification // Radius of part we want to magnify
let px = w / 3.5
let py = h / 4
let tileCanvas = document.getElementById("tCanvas")
tileCanvas.width = 2 * size
tileCanvas.height = 2 * size
tileCanvas.getContext('2d').drawImage(canvas, px - r, py - r, 2 * r, 2 * r, 0, 0, 2 * size, 2 * size)
let pattern = ctx.createPattern(tileCanvas, "repeat")
ctx.fillStyle = pattern
ctx.translate(px - size, py - size)
ctx.beginPath()
ctx.arc(size, size, size, 0, 2 * Math.PI)
ctx.fill()
ctx.strokeStyle = "orangered"
ctx.lineWidth = 12
ctx.stroke()
}
drawing.src = base64; // can also be a remote URL e.g. http://
<canvas id="tCanvas" width=240 height=240 style="background-color:aqua;">
</canvas>
<canvas id="canvas1" width=240 height=240 style="background-color:#808080;">
</canvas>
<p></p>
<button id="download" onclick="magnify();">Zoom</button>