Friday, April 29, 2016

Friday Fun XXVIII

And another friday which means time for some fun again...
It's interesting but again I've found a control that looks simple when you see it for the first time but at a second look you will figure out that it's not so easy to implement.
So here it is...

Apart from that the white bar seems to be misaligned in the picture above, the control has a neat effect. First of all the semitransparent white ring in the background makes it possible to put that control on whatever color and because it is translucent the background color will shine through like on the picture above.
In addition it comes with some 3D effect that is produced by the drop shadow of this ring.
Exactly this drop shadow is the thing that looks easy to do but it's not and the reason is the following.
If you create a ring (e.g. using a JavaFX Arc object) you can give it a strokeLineWidth and a Color. Adding a DropShadow is a no-brainer in JavaFX and in principle that's all you have to do. But because the Arc is translucent we will see the DropShadow shine through which will make the Arc appear darker which exactly is the problem.
To give you an idea what I'm talking about, here is a little screenshot of the effect...

As you can see we have a nice DropShadow on the Arc but we also see it shine through the ring which makes it appear dark. If you take a look on the picture above you will see that the ring appears bright and translucent plus the how to achieve that???
Well the answer is trivial but the solution not... :)
First we need to draw an Arc with a DropShadow that will look as follows...

In the next step we have to create a mask that only contains the shadow without the ring, which we can do by creating two rings. Then we subtract the smaller ring from the bigger one like follows...

On the right side we now have our shape that we can use as a clipping mask which will only contain the DropShadow without the orange ring.
Now we can apply this clipping mask to the Arc that has the DropShadow and it will look similar to this (the white should be transparent)...

And in the last step we can draw the final Arc that will be filled with Color.rgb(255, 255, 255, 0.4) so that the background can shine through.
The code to realize this operation will look as follows...

Arc outerRing = new Arc(size * 0.5, size * 0.5,
                         size * 0.43125, size * 0.43125,
                         0, 360);
outerRing.setStrokeWidth(size * 0.3);

Arc innerRing = new Arc(size * 0.5, size * 0.5,
                        size * 0.43125, size * 0.43125,
                        0, 360);
innerRing.setStrokeWidth(size * 0.1375);

Shape shape = Shape.subtract(outerRing, innerRing);

backgroundRing.setRadiusX(size * 0.43125);
backgroundRing.setRadiusY(size * 0.43125);
backgroundRing.setStrokeWidth(size * 0.1375);

barBackground.setRadiusX(size * 0.43125);
barBackground.setRadiusY(size * 0.43125);
barBackground.setStrokeWidth(size * 0.1375);

And we have to do this clipping everytime the size of the control changed. The final result of this operations will then look like follows...

And this is exactly how it should look like :)
For the implementation I make use of the Medusa gauge so there is a dependency on the Medusa project.

If you would like to see the code you will find it on github as always.

That's it for today, so I wish you all a nice weekend and...keep coding...


  1. Google just brings me here.. Very interesting..I'm graphic designer not a coder but I think i should start somehow. Here's my work(vector)

    Since I couldn't find any volunteer to do the coding side, I should start somewhere and learn it. This is gonna work on my carpc. Canbus communication is okay though! =) Can you help me to start? No coding background. So 'Hello world' types of tutorials would be nice!

    1. Hi there,
      Well I don't do "Hello World" kind of examples but I could port one of your gauges (Power View) to Medusa as a skin or as a separate control if youvket me.
      For more info you might want to drop me a mail.