Search code examples
htmlcanvashtml5-canvasdrawimage

Why does drawImage() change the canvas outside the destination box?


Based on the documentation of drawImage(), I'm trying to draw to a specific part of a canvas. However, areas outside of the destination box are being affected, namly having their alpha values zeroed.

I've created a JSFiddle demonstrating the issue.

canvas composition results

I copied the canvas on the left (full yellow) to the canvas on the right and the drew the middle canvas to the center of that same canvas using "destination-atop". You can see that it applied properly but at the same time cleared everything outside the draw area. Same happens with "copy". See the Fiddle for details.

Why does drawImage() affect pixels outside its destination?


Solution

  • For reasons unknown to me, the "destination box" (dx, dy, dWidth, dHeight) isn't actually a destination box. It's more like a "center" and "scale" because drawing extends out of this box as though there were transparent source pixels being applied to that outside area.

    The fix is to add a clipping rectangle before doing the drawing, as such:

    ctx.beginPath()
    ctx.rect(dx, dy, dWidth, dHeight)
    ctx.clip()
    ctx.drawImage(img, dx, dy, dWidth, dHeight)
    

    The resulting Fiddle now does what I expected, applying the mask in the middle to the center of the solid-color image on the left to get the image on the right:

    enter image description here