Jeff
Jeff

Reputation: 14279

RaphaelJS with rgba gradient fill

I am trying to create a gradient fill with RaphaelJS that uses rgba colors. In other words, I want both the start and end points to have a degree of transparency. For instance, 20% black to 0% black. How is this done?

This fiddle is how I expect that this would be accomplished but as you can see, the bottom black is completely opaque. http://jsfiddle.net/4aPj2/

r.circle(50,50,50).attr({fill:'90-rgba(0,0,0,0)-rgba(0,0,0,0.2)',opacity:0})

Upvotes: 1

Views: 3431

Answers (2)

Shamasis Bhattacharya
Shamasis Bhattacharya

Reputation: 3502

There is a workaround, but that involves editing raphael.js

Locate the code block:

el.appendChild($("stop", {
    offset: dots[i].offset ? dots[i].offset : i ? "100%" : "0%",
        "stop-color": dots[i].color || "#fff"
}));

And replace it using:

el.appendChild($("stop", {
    offset: dots[i].offset ? dots[i].offset : i ? "100%" : "0%",
        "stop-color": dots[i].color || "#fff",
        "stop-opacity": R.is(dots[i].opacity, "undefined") ? 1 : dots[i].opacity
}));

Update: Later figured out that I had accidentally missed a one-line change from my patch.

Next, locate the following line within the function R._parseDots

par[2] && (dot.offset = par[2] + "%");

and replace it with

dot.opacity = dot.color.opacity;
par[2] && (dot.offset = par[2] + "%");

With the above code, you can easily use something like myRect.attr("fill", "90-rgba(255,0,0,0.25)-rgba(0,255,0,0.75)-rgba(0,0,255,0.25)"); But note that the solution is for SVG output, VML does not support this. VML only supports a single opacity on gradient at 0% position and optionally a second opacity for the last opacity at 100% position. There would be a few more code changes for VML that I am not including here.

The code can be seen in action in the fiddle http://jsfiddle.net/shamasis/SYdJW/

Upvotes: 0

Simon Kenyon Shepard
Simon Kenyon Shepard

Reputation: 869

Ok,

previous answer is a red herring for anyone looking at this question. I just spent half a day digging around through the raphaeljs source code. It's not this simple. So Raphaeljs actually already has some built in support for this and anything you try to modify like above won't work as the built in support will override it later. The support that Raphaeljs currently has allows you to set the transparency of the final color-stop using the opacity attribute and the fill-opacity, so for example this:

r.circle(50,50,50).attr({fill:'90-#000000-#0000ff',opacity:0})

would translate in the real world to a circle with 100% opacity in the first color stop(black) in the center and 0% opacity in the final stop(blue). Another example :

r.circle(50,50,50).attr({fill:'90-#000000-#ffffff',opacity:0.5})

would produce a real world circle with 100% opacity black in the center and 50% white opacity around the outer of the circle on the final stop.

There is no current way in Raphaeljs to support different opacities on both color stops but if you desperately needed to do this this source line you would need to modify would be here :

$(stops[stops.length - 1], {"stop-opacity": value});

It's located at 6265 in the current version of Raphaeljs (2.1.0). I hope this helps someone avoid the hours of debugging RaphealJS source code I just spent....

Upvotes: 7

Related Questions