我有一个for循环,动态创建span
或img
元素,具体取决于div
中的内容,然后我将它放在画布上。画布的宽度应等于所有图像和文本的组合宽度。一切顺利,直到我使用canvas.width = prevX.
更改画布的宽度。当我使用它时,画布不输出任何内容。当我使用console.log(canvas.width)
时,它显示画布宽度正在增长,但图像不会打印。如何动态更改画布宽度?
let canvas = document.querySelector("#canvas")
let ctx = canvas.getContext("2d")
let imgDiv = document.querySelector(".images")
let imgEl = document.getElementsByTagName("img")
let spanEl = document.getElementsByTagName("span")
let divEl = imgDiv.hasChildNodes()
let prevX = 0
if (divEl){
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.imageSmoothingEnabled = false;
canvas.height = 34
for(var n=0; n<imgDiv.children.length; n++){
if (imgDiv.children[n].nodeName === "IMG"){
ctx.drawImage(imgDiv.children[n], prevX ,0);
}
else if(imgDiv.children[n].nodeName === "SPAN"){
ctx.font = window.getComputedStyle(spanEl[0]).fontSize + " Open Sans"
ctx.fillText(imgDiv.children[n].innerHTML, prevX ,parseInt(window.getComputedStyle(spanEl[0]).fontSize,10))
}
prevX += imgDiv.children[n].width
canvas.width = prevX
}
}
编辑:更改了代码以使用getImageData()
和putImageData()
。宽度和高度会发生变化,但图像不会显示。我可能会将putImageData()
插入错误的位置。
let canvas = document.querySelector("#canvas")
let ctx = canvas.getContext("2d")
let imgDiv = document.querySelector(".images")
let imgEl = document.getElementsByTagName("img")
let spanEl = document.getElementsByTagName("span")
let divEl = imgDiv.hasChildNodes()
let prevX = 0
canvas.height = 34
canvas.width = 32
var imagedata = ctx.getImageData(0,0,canvas.width,canvas.height)
ctx.putImageData(imagedata,0,0)
if (divEl){
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.imageSmoothingEnabled = false;
for(var n=0; n<imgDiv.children.length; n++){
if (imgDiv.children[n].nodeName === "IMG"){
ctx.drawImage(imgDiv.children[n], prevX ,0)
prevX += imgDiv.children[n].width
}
else if(imgDiv.children[n].nodeName === "SPAN"){
ctx.font = window.getComputedStyle(spanEl[0]).fontSize + " Open Sans"
ctx.fillText(imgDiv.children[n].innerHTML, prevX ,parseInt(window.getComputedStyle(spanEl[0]).fontSize,10))
prevX += imgDiv.children[n].width
}
canvas.width = prevX
}
}
console.log(canvas.width)
console.log(canvas.height)
console.log(imagedata)
答案 0 :(得分:1)
当您通过curl -H 'content-type: text/plain' localhost:8888/encrypt --data-raw 'your password'
(例如)设置宽度属性高度时,它实际上会清除画布的内容(至少在Chrome中),然后使其更大,更有效清空它。
你可以做的是在使用canvas.width = 500
调整大小之前存储图像数据,然后调整大小,然后使用getImageData()
重新绘制你的东西,如果新的更大的画布。
在适当调整画布大小的同时,一个接一个地工作和添加(cat)图片的代码示例:
<强> HTML 强>
putImageData()
JS
<canvas id="canvas"></canvas>
<div style="display:none;">
<img id="source" src="cat.png"
width="260" height="270">
</div>
<button>Click to duplicate</button>
编辑:有关使用var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var image = document.getElementById('source');
canvas.width = 260; //native image size is 260 * 270
canvas.height = 270;
ctx.drawImage(image, 0, 0, 260, 270);
var numberOfCats = 1;
$("button").on('click', () =>{
currentData = ctx.getImageData(0, 0, canvas.width, canvas.height);
canvas.height = (numberOfCats + 1) * 270 ;
ctx.putImageData(currentData, 0, 0);
ctx.drawImage(image, 0, numberOfCats * 270, 260, 270);
numberOfCats += 1;
})
现在我考虑一下:getImageData()
是一个方便但有时令人讨厌的使用功能,因为它很容易触发交叉原始错误,即getImageData()
错误。
什么是受污染的画布?
虽然您可以使用没有CORS的图像 在你的画布上批准,这样做会污染画布。一旦画布有 被污染了,你再也无法将数据拉回画布。对于 例如,您不能再使用canvas toBlob(),toDataURL()或 getImageData()方法;这样做会引发安全错误。
这可以防止用户使用图像暴露私有数据 未经许可从远程网站提取信息。 (source,我强调)
每当您的图像源来自与发出HTML字符串的源不同的来源时,就会发生这种情况(请注意,这包括您在本地工作并尝试包含同一文件夹中的图片的情况!)。解决此问题的几种方法:
设置一个小型本地Web服务器(节点js示例:运行The canvas has been tainted by cross-origin data.
然后npm
install http-server -g
将启动
localhost上的服务器:9600)
如果您有权访问托管图片的远程服务器,则可以
将其http-server . -p 9600
标题设置为Access-Control-Allow-Origin
您可以停用安全参数(不建议这样做)
更多详细信息here