Sunday, July 22, 2018

Rolling Gradient

Aloha,

Last week I've stumbled upon an old blogpost from 2011 where I implemented an animated progressbar in Java Swing. At that time I was fascinated by the animated progressbar in OS X.
And when I saw the animated gradient I thought by myself why not do that in JavaFX???
In Swing we have immediate mode rendering which makes these kind of animated gradients easy because you do the whole rendering on your own. In JavaFX where we have retained mode rendering (so the rendering is managed by JavaFX) you have to find a way to update the gradient fill for a node for each animation step.
My approach is as follows, the RollingGradient uses an AnimationTimer to calculate the gradient and on each modification it fires an UpdateEvent which can be used to fill a shape with the gradient. The gradient is part of the event.
If you simply would like to fill a JavaFX shape you can also set the shape in the RollingGradient and it will be filled from there.

So you could either use the event as follows:

Rectangle       rectangle = new Rectangle(200, 20);
RollingGradient gradient  = RollingGradientBuilder.create()
                                                  .firstColor(Color.rgb(250, 0, 0))
                                                  .secondColor(Color.rgb(180, 0, 0))
                                                  .smoothGradient(true)
                                                  .direction(Direction.LEFT)
                                                  .interval(Speed.NORMAL.getInterval())
                                                  .period(5)
                                                  .onUpdateEvent(e -> rectangle.setFill(e.getGradient()))
                                                  .start()
                                                  .build();

Or you can set the shape in the RollingGradient and let it do the fill as follows:


Rectangle       rectangle = new Rectangle(200, 20);
RollingGradient gradient  = RollingGradientBuilder.create()
                                                  .firstColor(Color.rgb(250, 0, 0))
                                                  .secondColor(Color.rgb(180, 0, 0))
                                                  .smoothGradient(true)
                                                  .direction(Direction.LEFT)
                                                  .interval(Speed.NORMAL.getInterval())
                                                  .shape(rect)
                                                  .period(5)
                                                  .start()
                                                  .build();

Both approaches will lead to the following output:


As you can see from the code there are some properties you can use to modify the gradient:

  • firstColor (set first color of gradient)
  • endColor (set second color of gradient)
  • smoothGradient
  • direction (rolling to left or right)
  • interval (defines the time in nanoseconds for the animation speed)
  • shape (a given shape that will be filled with the gradient)
  • period (defines the width for one color change)
  • start (when called will start the rolling gradient)

In the next example I've changed some parameters to give you an idea of what you can do:


Rectangle       rectangle = new Rectangle(200, 20);
RollingGradient gradient  = RollingGradientBuilder.create()
                                                  .firstColor(Color.rgb(88, 154, 227))
                                                  .secondColor(Color.rgb(50, 130, 222))
                                                  .smoothGradient(false)
                                                  .direction(Direction.RIGHT)
                                                  .interval(Speed.FAST.getInterval())
                                                  .shape(rect)
                                                  .period(15)
                                                  .start()
                                                  .build();

With this settings the gradient will look like follows:


And because images are boring I've recorded a short video for you that shows the rolling gradient in action...



Well that's it for today and as always you can find the source code on github.

So keep coding...

Tuesday, July 17, 2018

Anchor Selector control

Aloha,

Another control that I saw in Adobe Fireworks and other drawing programs is a control that is used to select an anchor. One can use it to select the origin or to define the position in a layout etc.
Here is a little screenshot of the control in Adobe Fireworks:


The original control is not very big which explains the blurry screenshot, so here is my version of that control implemented in JavaFX:


It's not very fancy that's for sure but sometimes you might need exactly such a control and then you know where to find it :)

The method getSelectedAnchor() will return a Pos object that you can use for whatever you need it.

Here is also a little video that shows the control in action...




In principle that's it and as always you can find the source code at github.

Keep coding...

Saturday, July 14, 2018

GradientPicker reloaded...

Aloha,

Because I worked a lot with Adobe Fireworks over the last 10 years I was using it's gradient tool very often. It is a handy tool to create color gradients where you can simply add new gradient stops and set the color and opacity for each stop either with a slider or by typing in the value.
This is how the Adobe Fireworks gradient tool looks like:



The functionality of the upper handles is to adjust the opacity of the selected stop where the lower handle is to set the color of the stop.
In 2013 I've already created a gradient picker in JavaFX but it was not a separate control but more part of a screen color picker.
So far so good but I always wanted to redo the gradient picker I've created at that time.
Well...after some night hacks I finally finished that gradient picker and so you can now also use it if you like. Here is what the current result looks like:



In principle it has the same functionality as the gradient tool in Adobe Fireworks. I've created a little video that demonstrates it's functionality:



And that's it for today, as always you can find the source code at github.

I hope this control will be useful for one or the other of you and don't forget...keep coding...

Friday, July 6, 2018

Tiles 1.6.4

Aloha,

During the last days and nights I've found some time to add some stuff to TilesFX.
First of all I've modified the calculation of the color gradient that is used in the SparkLineTileSkin and GaugeSparkLineTileSkin.
Because the spark lines only show the line between the low and high value that was measured in the given range it might happen that the color gradient has to be adjusted to the visible range of values.
This now works as expected (at least expected by me).

The code to define the following tile is:

Tile tile = TileBuilder.create()
                       .skinType(SkinType.SPARK_LINE)
                       .prefSize(400, 400)
                       .title("CO2")
                       .unit("ppm")
                       .minValue(400)
                       .maxValue(60000)
                       .decimals(0)
                       .tickLabelDecimals(0)
                       .time(ZonedDateTime.now(ZoneId.of("Europe/Berlin")))
                       .gradientStops(new Stop(0, Color.web("#1CAF4D")),
                                      new Stop(0.0075, Color.web("#1CAF4D")),
                                      new Stop(0.00751, Color.web("#91CA40")),
                                      new Stop(0.01166, Color.web("#91CA40")),
                                      new Stop(0.01167, Color.web("#F8C610")),
                                      new Stop(0.01666, Color.web("#F8C610")),
                                      new Stop(0.01667, Color.web("#F29222")),
                                      new Stop(0.025, Color.web("#F29222")),
                                      new Stop(0.02501, Color.web("#EC1D24")),
                                      new Stop(1.0, Color.web("#EC1D24")))
                       .strokeWithGradient(true)
                       .averagingPeriod(96)
                       .smoothing(true)

                       .build();

And the result when using TilesFX < 1.6.4 looks as follows:


As you can see the gradient used to color the spark line was just a linear gradient from the color calculated for the low value (here 400) to the high value (here 1036). There are no other colors in between even if the gradient stops in the builder contain more stops.
When using the same tile in TilesFX >= 1.6.4 the result will look as follows:


Based on the gradient stops defined in the builder we now see all levels for the different zones we defined.
Meaning to say the color gradient used to stroke the spark line will now always dynamically calculated dependent on the low and high value.
In addition I've added a  new skin named BarGaugeTileSkin which is another gauge visualization that you often can find in dashboards. It looks as follows...



As you can see it shows the current value, a bar with the min and max value and a threshold indicator with a text.
The color of the bar can be customized by

  • bar color property
  • sections
  • gradient stops

So if you would just simply change the color of the bar you just set the bar color by calling

setBarColor(YOUR COLOR) or .barColor(YOUR COLOR) in the TileBuilder.

If you would like to set the bar color dependent on sections (e.g. color the bar red if the value is higher than 80) you might want to define sections and enable them as follows:

Tile tile = TileBuilder.create()
                       .skinType(SkinType.BAR_GAUGE)
                       .prefSize(200, 200)
                       .minValue(0)
                       .maxValue(100)
                       .sectionsVisible(true)
                       .sections(new Section(80, 100, Color.RED))
                       .build();

And if you would like to set the bar color along a defined color gradient you have to define the gradient stops and enable them as follows:

Tile tile = TileBuilder.create()
                       .skinType(SkinType.BAR_GAUGE)
                       .prefSize(200, 200)
                       .minValue(0)
                       .maxValue(100)
                       .strokeWithGradient(true)
                       .gradientStops(new Stop(0.0, Bright.BLUE),
                                      new Stop(0.5, Bright.GREEN),
                                      new Stop(1.0, Bright.RED))
                       .build();

In principle that's all I did but I thought it was worth a new release, so as always please find the latest version here:

Source: github

Binary: bintray

Maven Central

That's it for today...so keep coding... :)

Thursday, July 5, 2018

TilesFX colors...

Aloha,

When working on my little dashboard at home I've figured out that I needed more colors to visualize some data. Because I've added already a color scheme (Bright) to TilesFX a while ago I decided to add more colors.
So in TilesFX 1.6.3 you will find 4 different color schemes, because I often need the same color at different brightness levels I've decided to add a Medium and Dark scheme to the lib. 
Here is a little table that shows the Bright, Medium and Dark scheme with their available color definitions:

The usage is pretty simple, let's assume you would like to make use of the color green from the medium scheme you simple type:

Medium.GREEN and you will get the color #32a539

So I hope these colors are as useful to you as they are to me :)

As always you can find the latest version of TilesFX here

Source: github

Binary: bintray

Maven Central

That's it for today...and do not forget to keep coding...