Reputation: 63
I'm trying to fill a portion of a circle with a colour. For example, having a circle with 2/3 red and 1/3 empty.
The Raphael JS documentation doesn't help much. What is the best way to approach this?
Some examples can be seen at below picture:
var paper = new Raphael(document.getElementById('shape_container'), 400, 100);
var circle = paper.circle(50, 50, 30);
circle.attr (
{
fill: '#F00'
}
);
With the code above, I can draw a circle with full of red.. I could not find any way for how to fill 2/3 red..
Upvotes: 4
Views: 1976
Reputation: 31
I wrote a RaphaelJS custom attribute for this very purpose. It can be animated, so you can control the rotation/size of the slice and create donut or partial donut shapes too.
paper.customAttributes.filledArc = function(e,t,n,r,i,s){var o=360;if(o==i){i-=.001}i+=s;var u=(90-s)*Math.PI/180,a=e+n*Math.cos(u),f=t-n*Math.sin(u),l=e+(n-r)*Math.cos(u),c=t-(n-r)*Math.sin(u);var h=(90-i)*Math.PI/180,p=e+n*Math.cos(h),d=t-n*Math.sin(h),v=e+(n-r)*Math.cos(h),m=t-(n-r)*Math.sin(h);return{path:[["M",l,c],["L",a,f],["A",n,n,0,+(i>180+s),1,p,d],["L",v,m],["A",n-r,n-r,1,+(i>180+s),0,l,c]]}}
And then:
paper.path().attr( {
filledArc: [x,y,radius,width,degrees,rotation]
fill: mapit_red,
stroke: mapit_black
} );
Upvotes: 3
Reputation: 4433
Welcome, Alperen. I believe what you actually want is an arc path rather than a circle. Take a look at this:
function arcpath( canvas, x, y, r, ratio )
{
if ( ratio >= 1.0 ) return canvas.circle( x, y, r );
var degrees = 360 * ratio; // we use this to determine whether to use the large-sweep-flag or not
var radians = ( Math.PI * 2 * ratio ) - Math.PI / 2; // this is actually the angle of the terminal point on the circle's circumference -- up is Math.PI / 2, so we need to subtract that out.
var pathparts =
[
"M" + x + "," + y,
"v" + ( 0 - r ),
"A" + r + "," + r + " " + degrees + " " + ( degrees >= 180 ? "1" : "0" ) + " 1 " + ( x + ( r * Math.cos( radians ) ) ) + "," + ( y + ( r * Math.sin( radians ) ) ),
"z"
];
return canvas.path( pathparts );
}
var partial_circle = arcpath( canvas, 250, 350, 100, 0.75 ).attr( { fill: mapit_red, stroke: mapit_black } );
The geometry in the arcpath function is reasonably straightforward (though I had to look up the reference for large-sweep-flag, which was decidedly non-obvious). I'm sure this could be optimized substantially, but it's a functional first step.
Upvotes: 4