15

So I know that context.clearRect makes pixels transparent, but I'm wondering, is there a function to make pixels translucent?

For example, say I have a canvas with these colors (fourth one in each color is alpha):

#ffff #feef #abff
#5f6f #000f #ffff

Running clearRect would resolve into this (or something, just make them all transparent):

#fff0 #fee0 #abf0
#5f60 #0000 #fff0

I want to remove opacity, but not make it transparent (kind of like globalAlpha for clearRect), so that it can end up like this (lets say I set the globalAlpha equivalent to 0.5):

#fff8 #fee8 #abf8
#5f68 #0008 #fff8

Is this possible? Or would it be simpler just to draw everything on an off-screen canvas, then draw that canvas (with globalAlpha set) on an on-screen one?

Let me know if this isn't clear in any way.

MiJyn
  • 5,327
  • 4
  • 37
  • 64
  • You can use `context.fillColor = "rgba(0-255, 0-255, 0-255, 0-1)"` and use fillRect. The 4th parameter it's the alpha value. 0 is max transparent and 1 is totally opaque. – Gustavo Carvalho May 27 '13 at 16:02
  • @gfcarv yes, that is kind of what I want, but I don't want a color. I want to remove opacity (I'm using motion blur, and I need the background to be transparent) – MiJyn May 27 '13 at 16:11
  • 1
    Check this thread: http://stackoverflow.com/questions/5304199/html-canvas-motion-blur-with-transparent-background I think it would be simpler to use the off-screen canvas. You can use `getImageData` to change the pixel colors one by one and use `putImageData` to reflect the changes in canvas but you don't wanna do that since it's very inefficient. – Gustavo Carvalho May 27 '13 at 16:48

2 Answers2

28

The answer above gets the job done, however getImageData is super slow and if you have a lot of other stuff going on it will slow down your animation immensely. If you create a second off screen canvas element you can set its global alpha to .9 and shuffle them back and forth and get the same effect with much greater speed.

context2.clearRect(0,0,width,height);
context2.globalAlpha = .9;
context2.drawImage(canvas1,0,0);
context1.clearRect(0,0,width,height);
context1.drawImage(canvas2,0,0);
context1.the  rest of the drawing that you are doing goes here.
Michael Bromley
  • 4,792
  • 4
  • 35
  • 57
hartwellalex
  • 396
  • 3
  • 3
4

I just tried to figure this out too, and I've decided to count through the pixels, setting the alpha channel of each one manually. This is a bit more work, because I can't just cover the entire canvas with a rect, but it's working so far.

I'm doing this so that I can set a background image for the webpage and put my canvas animation over it, without having to draw the background in the canvas element.

var oldArray = context.getImageData(0,0,canvas.width,canvas.height);
//count through only the alpha pixels
for(var d=3;d<oldArray.data.length;d+=4){
    //dim it with some feedback, I'm using .9
    oldArray.data[d] = Math.floor(oldArray.data[d]*.9);
}
sw.context.putImageData(oldArray,0,0);
user2275231
  • 78
  • 1
  • 1
  • 5
  • Thanks, though @gustavo-carvalho gave me an alternative that I used, this one directly answers my question =) – MiJyn Jun 25 '13 at 07:42