Thursday, January 27, 2011

Easy tweening...

Here we go again...
During my html5 canvas expedition i found this neat little library named tween.js which is a javascript implementation of the easing functions of Robert Penner.
Easing functions allow you to apply custom mathematical formulas to your animations. 
In the first version of the canvas steelseries gauges i used the trident.js library of Kirill Grouchnikov which is a nice animation lib that also supports easing.
Because i only needed the interpolation between two values over a specific time i was looking for something smaller which was the reason why i moved from trident.js to tween.js.


But i won't talk about html5 canvas and javascript again but more about java...
When i took a look at the 12kb small tween.js script i liked the approach and thought about porting this functionality to java.


Like i said i was looking for a small library that interpolates values nothing more and so i created the Easy lib.
I know that one should avoid reinventing the wheel over and over again but to better understand an animation library it was a good thing to do that.


So the Easy class takes the following parameters:

(optional) object (Object)   : the object that you would like to "animate"
(optional) property (String) : the property which setter you would like to use
(mandatory) start (double)   : the value where the interpolation should start
(mandatory) stop (double)    : the value where the interpolation should stop
(mandatory) duration (long)  : the time in [ms] the interpolation should take
(optional) easing (enum)     : the easing function it should use to interpolate

So there are the following constructors available in Easy.class Ease.class:

Ease(Object OBJECT, String PROPERTY)


Ease(double START, double STOP, long DURATION)
    
Ease(double START, double STOP, long DURATION, EasingFunction EASING_FUNCTION)
        
Ease(Object OBJECT, String PROPERTY, double START, double STOP, long DURATION)
    
Ease(Object OBJECT, String PROPERTY, double START, double STOP, long DURATION, EasingFunction EASING_FUNCTION)


Ease(Object OBJECT, String PROPERTY, double START, double STOP, long DURATION, Color START_COLOR, Color STOP_COLOR)



Ease(Object OBJECT, String PROPERTY, double START, double STOP, long DURATION, Color START_COLOR, Color STOP_COLOR, EasingFunction EASING_FUNCTION)

The following easing functions are available:



    EASE_BACK_IN
    EASE_BACK_OUT
    EASE_BOUNCE_IN
    EASE_BOUNCE_OUT
    EASE_BOUNCE_IN_OUT
    EASE_CIRCULAR_IN
    EASE_CIRCULAR_OUT
    EASE_CIRCULAR_IN_OUT
    EASE_CUBIC_IN
    EASE_CUBIC_OUT
    EASE_CUBIC_IN_OUT
    EASE_EXPONENTIAL_IN
    EASE_EXPONENTIAL_OUT
    EASE_EXPONENTIAL_IN_OUT
    EASE_LINEAR
    EASE_QUADRATIC_IN
    EASE_QUADRATIC_OUT
    EASE_QUADRATIC_IN_OUT (DEFAULT if nothing is provided)
    EASE_QUART_IN
    EASE_QUART_OUT
    EASE_QUART_IN_OUT
    EASE_QUINTIC_IN
    EASE_QUINTIC_OUT
    EASE_QUINTIC_IN_OUT
    EASE_SINE_IN
    EASE_SIN_OUT
    EASE_SIN_IN_OUT
    EASE_STRONG_IN,
    EASE_STRONG_OUT
    EASE_STRONG_IN_OUT

You will find them in eu.hansolo.easy.EasingFunction


UPDATE:
Please find here an easing function generator that will show you the graphs of the different functions and also gives you an idea how to create those functions.


How does it work...?


The Ease class fires EaseEvents and EaseColorEvents. To receive this events you could attach a EaseEventListener to the Ease class. Each EaseEvent provides a value, a state and a color.
So if you don't provide a object with it's property the Ease class will only interpolate between the start and stop value in the given time with the given easing function. If you would like to use the values calculated by the easing function you have to attach the EaseEventListener to the Ease class instance and handle the values in the easeEventPerformend() method of the handler.

Whereas if you provide a object with it's property the Ease class instance will invoke the setProperty() method of the object and set the interpolated value directly.


The Ease class will not take care about repaints of dirty areas etc. but only calculate the values and fire events...that's all.


Here is a simple example on how to use the Easy lib:



// The class with the property we would like to interpolate
public class InvokedClass
{
    private double value;


    public InvokedClass()
    {
        value = 0;
    }


    public double getValue()
    {
        return value;
    }


    public void setValue(double value)
    {
        this.value = value;
    }
}

// The class where the interpolation is defined and started from


public class EasyTest
{        
    public static void main(String[] args)
    {
        final InvokedClass invokeInstance = new InvokedClass();


        Ease ease = new Ease(invokeInstance, "value", 0, 25, 5000);
        ease.addEaseEventListener(new EaseEventListener()
        {
            @Override
            public void easeEventPerformed(EaseEvent event)
            {
                System.out.println(invokeInstance.getValue());
            }
        });
        ease.start();
    }
}



This simple example will output the values from 0 to 25 interpolated by a QUADRATIC_IN_OUT easing function (which is the default) within 5 sec.


This might not be the best implementation but for me it was fun and maybe it's of use for one or another...


See it in action here...


Please find the downloads here:


    The binary jar file
    The netbeans project


The files will change from time to time because i'm still adding features to the library.


Keep coding...

Monday, January 17, 2011

Canvas Steel...

And another one...

You know i'm not a JavaScript developer but as a user of mobile devices like Android or iOS based phones i did not like the fact that i could not use my SteelSeries library to visualize data on those kind of devices.
My first idea was to create an Android version of the library but in this case no iOS user would be able to use the library...bad idea...

Then after one of our JUG roundups i decided to take a look at HTML5 and in specific at the Canvas 2d api...what should i say...it's not so different from Java Swing as i first thought.

During a business trip to Paris at the end of last year i started to convert the swing drawing code to canvas drawing code and i was surprised that it tooks me around 6 hours only to convert the basic graphics of a radial gauge from swing to canvas.

Because i have to play with this things only in my spare time it tooks me some very early mornings and late nights to further improve the canvas version of the radial gauge and at the end of last week i decided it's time to show you the result of my work.

See this page in action...

I tried to implement all the features from the Java Swing version but right now it's still missing some parts (like min- and max measured value, lcd unit string etc.)

Because there's no conical gradient paint (that i used for the black-metal frame) in canvas i had to create the frame with a different technique, where i rotate a line which is changing it's color dependend on the rotation angle. The component is scalable and uses the same approach as the latest version of the steelseries (3.5.3) to visualize the four supported types of gauges.

Here is a list of the properties of the radial.js class:

String gaugeType : "type1", "type2", "type3", "type4"
Float minValue : 
Float maxValue :
Float threshold : 
Section section[] : Array of Sections (e.g.  new Section(30, 50, 'rgba(0, 220, 0, 0.3)'))
Section area[] : Array of Sections(e.g. new Section(75, 100, 'rgba(220, 0, 0, 0.3)'))
String title :
String unit :
String frameDesign : "metal", "brass", "steel", "blackMetal", "shinyMetal"
BackgroundColor backgroundColor : DARK_GRAY, SATIN_GRAY, LIGHT_GRAY, WHITE, BLACK, BEIGE
String pointerType : "type1", "type2"
Color pointerColor : RED, GREEN, BLUE, YELLOW, ORANGE, CYAN, MAGENTA
LcdColor lcdColor : BEIGE, BLUE, ORANGE, RED, YELLOW, WHITE, GRAY, BLACK, GREEN, BLUE_BLACK, BLUE_DARKBLUE, BLUE_GRAY, STANDARD, BLUE_BLUE
Boolean lcdVisible : true, false
LedColor ledColor : RED_LED, GREEN_LED, BLUE_LED, ORANGE_LED, YELLOW_LED, CYAN_LED, MAGENTA_LED
Boolean ledVisible : true, false

To realize a radial gauge you need two files, the radial.js for the gauge itself and the tools.js, where helper objects are defined like:

Section, BackgroundColor, Color, LcdColor and LedColor

To create a radial gauge you have to call it's constructor in your html file which looks like this:

var radial = new Radial('canvas', gaugeType, minValue, maxValue, threshold, section, area, title, unit, frameDesign, backgroundColor, pointerType, pointerColor, lcdColor, lcdVisible, ledColor, ledVisible);  

The 'canvas' string is the name of the canvas element in your html file that should be used to draw the gauge into.
After you created the radial gauge with it's constructor you could draw it using it's paintComponent() method (ups...looks a bit like swing...).

radial.paintComponent();

Well, i mentioned that i'm not a JavaScript programmer which means that i'm sure there's a lot of potential to improve the code (right now it might look a little bit java like).

To get a better impression on how to use the radial.js component you just have to take a look to the sourcecode of the Radial.html file.

There's one other file needed to make things work and that the trident.js which is a javascript version of the trident animation library from Kirill Grouchnikov.

Please find all the needed files here:

    radial.js
    tools.js
    trident.js


I will also port other gauges from the steelseries library to html5 canvas but it will take some time to realize it, so stay tuned, i'll anounce any news on twitter...

Update:
Now there's also a radialbargraph available as you can see here...

See this page in action...

I hope you enjoy the possibilities of the canvas as much as i do...

Keep coding...


FXG Converter update...

Aloha...
Due to my work on the html5 canvas version of the steelseries i had the same problem as a year ago where i started to create the java swing version of the steelseries library...converting graphics to code (it seems to be a never ending story).
After i made some progress converting the java swing code to html5 canvas, last week i decided to spend some time to add html5 canvas support to the fxg converter. I'm sure Adobe will add an export to canvas in future releases of Fireworks but today it's not possible to do that.

So here we go, the FXG converter now supports conversion from fxg to html5 canvas. It supports the FXG spec 2.0 except text (which will not be placed correctly in the converted canvas) and winding rules in paths (i only have one file where this leads to some drawing problems in canvas).

The workflow is the same as it is in the Java Swing version:

1. Create your drawing in Adobe Fireworks (or Adobe Illustrator):


2. Export the file to FXG.

3. Start the FXG converter and drag the fxg file to the converter.


4. Switch the button from java2d to canvas and press the Convert button.

5. The converter will create two files on your desktop that are named like the fxg file.



6. Simply open the html file in your favourite (html5 capable) browser and...enjoy


Like in the Java Swing version the converted "components" are fully scalable. 


An example of the converted JUG Muenster logo in different sizes could be found here. Another example of some converted fxg files could you find here.

If you have no possibility to create fxg files you might want to download the JUG Muenster logo as fxg file here.

Html5 Canvas is amazing because it seems to be the first real x-platform 2d api that one could use on all html5 capable browsers including iOS based devices, Android based devices, some setop boxes etc.


So enjoy converting your graphics to canvas and show it to the world...


Wednesday, January 12, 2011

Mavenized Steel...

A happy new year everybody...
During the last weeks i made some modifications to the steelseries library that i was asked for at Devoxx 2010 (yes Jan...you are the reason for this).

The question was if i could switch to maven as a build system...well i had no idea on what's coming up to me and agreed (there was a time when i thought this was a big mistake). Well switching to maven was not a big deal but that was only the first part of the story, the second part was how to publish the library in the maven central repo ???

I never thought that this could be so damn hard...well now i know but even with help from others and from the internet it was tough.

But long story short...it's done and the SteelSeries library should appear in the maven central repo and right now is available here.


A T T E N T I O N   P L E A S E 

THE NEW RELEASE (3.5.3) BREAKS COMPATIBILITY !!!


Ah, by the way i also made a lot of refactorings to the library which lead to a reduction in size about 120 kb...

I figured out that in principle i have four groups of gauges in my lib

- Radials 
  (Radial1, Radial1Lcd, Radial2, Radial2Lcd, Radial3, Radial3Lcd, Radial4, 
   Radial4Lcd)
- RadialBargraphs
  (RadialBargraph1, RadialBargraph1Lcd, RadialBargraph2, RadialBargraph2Lcd,
   RadialBargraph3, RadialBargraph3Lcd, RadialBargraph4, RadialBargraph3Lcd)
- Linears
  (Linear, LinearLcd)
- LinearBargraphs
  (LinearBargraph, LinearBargraphLcd)

and some others that do not fit into this scheme.

So i removed all these Radial1, Radial2, Radial4 etc. gauges and replaced them with the following new classes

- Radial
- RadialBargraph
- Linear
- LinearBargraph

To get the same results as before i added a enum named GaugeType that contains TYPE1, TYPE2, TYPE3, TYPE4.
Each of the new classes get a method setGaugeType() and getGaugeType() so that one could switch between the types of gauges.
In addition i added the lcd to each of the new components and one could now use setLcdVisible() to switch the lcd on or off.

Another modification was the new enum named FrameType which contains ROUND and SQUARE. This enum is used to switch the frame on the Radial and RadialBargraph components between the circular and the square one.
This little add on made it possible to remove the RadialSquareVertical component from the lib and now give you the ability to set a rectangular frame to all Radial components.



There are also two new frameDesigns available...brass and steel which looks like this...


The idea for these colors came to me when i was looking around in a watch store where i saw watches in these colors.

But that's not enough...i also extended the possibilities of the area feature. In the steelseries version 2 you could add one area but i figured out that this might not be enough so i now allow as much areas as you like...
That could lead to gauges that looks like this...



Looks funny right...

The sections that in version 2 have been placed on the inside of the gauge are now placed under the tickmarks, where also the track is placed. That means you could combine the track with the sections feature which could look like this...



As you can see the track which goes from 75 - 100 in the image above has not exactly the same size as the section and i might change this in the next version but i looks funny.

There's also another pointer available TYPE3 which looks like this...


This pointer might be useful if you have many values in you scaling and need a needle like pointer that is smaller than the standard one.

Unfortunately the Radial1Square component had some problems with negative values in the scale and to avoid problems i disabled the possibility to change the orientation of the gauge. So in this release you could only use the standard orientation. I might create a new version of the Radial1Square component that is easier to handle than the current one...just need more time...

There are some other projects i'm working on and which might be of interest for some of you...

You might hear about HTML5 Canvas...it's great...so i started fiddeling around with it and what should i say...i'm working on a canvas port of the steelseries lib.
To give you a little preview of my work i prepared a little gauge in swing and the same version in canvas...take a look...


It's amazing...isn't it...

The really fun part of it is that one could use it also on a mobile device like my android phone or an iPad...think about the possibilities...

One of the next steps will be the extension of the FXG converter so that it also will convert fxg files to html5 canvas.

I guess that's it for today...keep coding...