4

I would like to obtain a radial gradient effect on an image (alpha = 1 in the middle and transparent on the edges).

Do you have any ideeas on how I could do that?

pimvdb
  • 151,816
  • 78
  • 307
  • 352
gabitzish
  • 9,535
  • 7
  • 44
  • 65
  • take a look at this post maybe it will help you: http://stackoverflow.com/questions/5525874/createradialgradient-and-transparency – Tim Jun 21 '11 at 11:59
  • I can make radial gradients on circles, but I need it on images. – gabitzish Jun 21 '11 at 12:33

1 Answers1

7

If I'm not mistaking what you want to do is:

  1. Draw the image
  2. Draw a radial gradient over it, where the borders are transparent and the middle is opaque and using the globalCompositeOperation setting on the context to blend the transparency gradient with the image.

You can rather easily translate this into code: http://jsfiddle.net/W8Ywp/1/.

var ctx = $('#cv').get(0).getContext('2d');

var img = new Image();

img.src = 'http://www.netstate.com/states/'
        + 'symb/flowers/images/oklahoma_rose.jpg';

img.onload = function() {
    ctx.drawImage(img, 0, 0, 300, 300); // Draw image

    // Create gradient, from middle to borders
    var gradient = ctx.createRadialGradient(150, 150, 0,
                                            150, 150, 150);

    // Opaque white in the middle
    gradient.addColorStop(0, 'rgba(255,255,255,0)');

    // Transparent white at the borders
    gradient.addColorStop(1, 'rgba(255,255,255,1)');

    ctx.globalCompositeOperation = 'destination-out';
    ctx.fillStyle = gradient;
    ctx.fillRect(0, 0, 300, 300); // Fill rectangle over image with the gradient
};
Alnitak
  • 334,560
  • 70
  • 407
  • 495
pimvdb
  • 151,816
  • 78
  • 307
  • 352
  • This is not the solution I want. I want to add the image over another image, so it blends smoothly. If I make the gradient from white tranparent to white opaque, the image will have the gradient, but it will not be transparent on the edges, it will be white. – gabitzish Jun 21 '11 at 13:02
  • 5
    @gabitzish playing with http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation the `ctx.globalCompositeOperation` setting might fix that. – Alnitak Jun 21 '11 at 13:07
  • @Alnitak: You ought to post this as an answer so that it can be accepted. – pimvdb Jun 21 '11 at 14:51
  • @pimvdb - no matter, I've hit the rep cap for today anyway. In any event, I couldn't figure out from the docs just which value would actually work! Why don't you fix yours instead? ;-) – Alnitak Jun 21 '11 at 14:52
  • @Alnitak: Because it was your idea and I didn't want to steal it :) I will update it in a while. – pimvdb Jun 21 '11 at 15:28
  • I believe @Alnitak's idea is incorrect. The global compositing operation does not allow you to apply a gradient to an image. See http://stackoverflow.com/questions/3320417/is-it-possible-to-make-a-gradient-transparent-layer-masking-image-using-canvas in which one answer had to resort to pixel-by-pixel manipulation of the canvas to achieve the requested effect. – Nathan Feb 25 '15 at 16:25
  • @Nathan perhaps - all I know is that the OP said it was what he needed. – Alnitak Feb 25 '15 at 16:27
  • @Nathan setting the `globalCompositeOperation` to `destination-out` allows this to work exactly as the OP requested - see `http://jsfiddle.net/alnitak/jtexo5es/ the image becomes more and more transparent (showing the green div underneath) towards the edges. – Alnitak Feb 25 '15 at 16:48
  • @Alnitak No. You're adding a solid color on top of the image. The OP explicitly states in the first comment on this very answer that he/she wants to add one image on top of another. That's not what your fiddle does, nor can I see how `globalCompositeOperation` can accomplish that in general. – Nathan Feb 25 '15 at 20:42
  • no, the image is on top of the color, that in this case happens to be solid, but is in the div underneath. That div could contain anything. See http://jsfiddle.net/jtexo5es/3/ for a new one where the rose is overlayed with a gradient transparency on top of another flower. – Alnitak Feb 25 '15 at 20:57
  • @Nathan care to take back your incorrect assertions, yet? – Alnitak Feb 27 '15 at 15:18
  • @Alnitak No need to be testy, I just want an answer to the OP's question. I definitely take back my claim that you were putting color **on** the image; you're right, it's the other way around. But I **still** claim you haven't answered the question. You've just put an empty canvas on top of a background image, then put one image on the canvas. The OP wants (and I want) a method for putting an image with a transparent gradient on a nonempty canvas. If I try to adapt your solution to do so, I don't see how...here's my attempt for you to work with: http://jsfiddle.net/rfdjoh31/1/ – Nathan Feb 27 '15 at 19:02
  • @Nathan Not sure that's what this OP wanted, but in practise I think it would be necessary to create an off-screen canvas to create the "top" image modulated by the gradient alpha channel, and then composite the image data from that onto the (on-screen) canvas that already has the "bottom" image on it. Something like this: http://jsfiddle.net/alnitak/rfdjoh31/4/ – Alnitak Feb 27 '15 at 23:29
  • 2
    Excellent @Alnitak thank you! That should be the marked-correct answer on this post and on http://stackoverflow.com/questions/3320417/is-it-possible-to-make-a-gradient-transparent-layer-masking-image-using-canvas/11757560?noredirect=1#comment45736276_11757560 as well. I love it, thanks! – Nathan Feb 28 '15 at 03:39
  • @Nathan I've added this is an answer to the other question. – Alnitak Feb 28 '15 at 08:56
  • 2
    @Alnitak I up-voted it and commented on the accepted answer that people should look at yours since it's faster and simpler. Thanks again for it! – Nathan Feb 28 '15 at 14:07