设置画布大小时,图像不会出现

时间:2017-09-12 23:31:43

标签: javascript html5 canvas

我有一个for循环,动态创建spanimg元素,具体取决于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)

1 个答案:

答案 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