This question has sort of been answered here: Combined area of overlapping circles
My problem is more specific though. I have an arbitrary number of arbitrarily sized circles inside other arbitrarily sized circles, to make a target-like image:
This image must have some amount of transparency. The transparency must be the same throughout the entire shape. Then, there's an arbitrary number of these shapes that can overlap, and it needs to look like this:
The transparency amount must stay the same no matter how much they overlap.
The only thing I can think of to pull this off is to iterate through every pixel on the canvas and calculate what color the pixel should be based on its distance from the center of each circle, but this takes too long. I want the circles to be draggable as well, so this needs to be pretty fast. Is there a better way to do this? (Sorry about my poor GIMP skills)
It is possible to do natively without using pixel manipulation or any library.
Provided the transparency is the same for all the circles it is pretty straight forward.
Solution
Circles on top of some random background
What you need to do is to:
Your circle function can look something like this:
The function takes the
x
andy
center point as well asradius
. But in addition it takes astep
value between 0 and 2 which determines which surface is being drawn. This will be important in the next steps.First we can define an array holding all the circles we want to draw:
From here you would drag them, offset x and y and then redraw them, but for demo's sake I'll animate them.
Before we draw we set the global alpha on the main canvas (the off-screen is kept solid):
And the animation loop:
The global alpha can be reset for each operation in case you want to draw other elements to the canvas - or use a second on-screen canvas to hold static content.
Demo
You must use a library like RaphaelJS. It is capable of more than what you ask for here.
Edit: You can apply alpha transparency through js by programmatically determining the distance between centres (D) and comparing it with the sum of the radii (S). If D < S, then they overlap so take care of red circles.
(http://raphaeljs.com/)