You can grab the code from here.
GWT-FX provides an effects framework for users of the Google Web Toolkit (GWT). It harnesses the key benefits of
GWT and modern effect approaches (based on Cascading Style Sheets), providing the following benefits over other existing approaches:
- Large reductions in size of code sent to browser:
- Send only the code needed for the browser used
- Send only the code for effects actually used
- Reduce trips to server for code
- Use CSS to change how effects look, without changing code
Let's quantify the first 2 points. If you use Scriptaculous in your application, you need at least 4 trips to the server, to download 3 scriptaculous
files totaling some 168K* plus whatever application code size you have. This application requires just 2 trips to server (one for
code and one for a style sheet) and is just over 130K for the whole application code (excluding the code highlighting script). Better stil, using the
forthcomming ability of GWT for deferred loading of components (GWT.runAsync()) gets the initial payload of this application down to around 87K.
(We're not knocking the excellent Scriptaculous here at all, just highlighting the benefit of GWT's aggressive approach!)
Even better, the less of gwt-fx you use, the smaller the code becomes, since GWT prunes away unused code: for example, using gwt-fx just to
add a reflection to an image that fades into view, adds around only 12K of JavaScript code.
Using CSS to describe effects adds great flexibility, but you don't need to be a CSS expert to use GWT-FX as we provide a number of standard effects
out of the box, e.g. Fade, Move, Resize, etc.
The library is the result of some other work I am busy with and is made available in the interest of sharing; it is hopefully bug-free, but if you find issue, please raise them in the bug tracker - however, as this is driven by other projects, you're bugs might not have the same criticality as mine (of course, the source is available and any offers of fixing found issues is most welcome!)
* scriptaculous v1.8.1 itself requires : scriptaculous.js (4K), effects.js (40K) and prototype.js (124K)).
(
Jump to advanced information on using CSS to drive effects)
There are a few fundamentals to GWT-FX, but not many! The main objects you will use on
a day to day basis are
- NEffectPanel - a panel to which widgets and effects are added; the effects the apply to those widgets in the panel.
- NEffectPanelCollection - handles a collection of panels as one entity (can be used to make the library less obtrusive)
- NEffect - the definition of an effect, though you will not use the Effect class directly
- Transition Physics - alter how an effect progresses
- NEffectHandler - an interface that can be implemented to allow actions to take place pre and post the event, as well as if the event is interrupted
Let's start with a really simple example that fades an image - go on, click on the image....
The code to achieve that is below:
NEffectPanel example1EP = new NEffectPanel();
Fade theFade = new Fade();
Image img = new Image("ski.png");
example1EP.add(img);
example1EP.addEffect(theFade);
RootPanel.get().add(example1EP);
All that is done is to create an EffectPanel (line 1) and create a new Fade effect object (line 2). Fade is a predefined effect that extends the Effect
class to provide the ability to alter the CSS visibility property on the panel, fading it from fully visible to invisible. We add a created image to the
EffectPanel in line 4 - just as you would adding a widget to a normal GWT panel -so we have something to watch fade away. Finally, in line 5, we have added
the effect to the panel so it is already to go.
Kicking off the effect is as simple as saying the following:
example1EP.playEffects();
(in this page we have wrapped that call up into a ClickHandler (GWT 1.6) attached to the image so that when you click the image the playEffects method on the panel is called).
The above code is quite intrusive, i.e. the user explicitly has to create an NEffectPanel, put the widget in it and place the panel onto the DOM. We can make the code a little less
intrusive by (ab)using an NEffectPanelCollection.
// Create a normal Image widget and add to DOM
Image img = new Image("ski.png");
RootPanel.get().add(img);
// Create an N EffectPanelCollection
NEffectPanelCollection effectController = new NEffectPanelCollection();
//Add the Image unobtrusively to the controller
// (the controller will detach the widget from DOM, wrap in an NEffectPanel, and attach the NEffectPanel in the DOM
// at the correct place)
effectController.add(img);
// Create and add a Fade effect
Fade theFade = new Fade();
effectController.addEffect(theFade);
// Fade the image
effectController.playEffects();
Control of an effect is generally performed through the EffectPanel. The most used control method is playEffects() which comes in two
variants: a simple version that takes no parameters and plays the effects on the panel from their start to their end, as we have just used; and a second variant that
plays the effect between provided start and end points (which take values between 0 and 1). So,
example1EP.playEffects(0.0, 0.5);
would play the effect from the start until the middle - try it....
You can also play the effect in reverse - try clicking this....
to do this, we just played between near the end point of the Fade effect (0.8) to the start point (0.0)
example1EP.playEffects(0.8, 0.0);
Two additional methods are available that allow us to play an effect forwards or backwards from its current position.
These are
resumeEffectsForwards and
resumeEffectsBackwards. You might want to use these if you have, for example, an effect
to be played on mouseEnter and mouseLeave. Try the image below - putting the mouse into it will start the fade effect, taking the mouse out will
return full visiblity to the image.
Duration can also be changed for all effects on the panel - try typing in new times below and clicking the image again.
You can set the duration for all the effects on a panel using the following code
example1EP.setEffectsLength(5.0);
Transition Physics is the name we give to working out how the effect should progress. Up
to now effects have progressed linearly, i.e they have kept a constant speed.
GWT-FX provides 6 default transition physics, which you can play with above. To set in your own code just use:
example1EP.setEffectsTransitionType(new EaseInOutTransitionPhysics());
- Linear - progresses at a constant pace
- EaseIn - starts slow and then speeds up to the end
- EaseOut - slows down to the end
- EaseInOut - starts and ends slow but speeds up to the middle
- Bounce - progresses like a ball bouncing
- Elastic - goes past the end point and then oscillates backwards and forwards to the end
Some of the transition physics can take parameters, e.g. the Elastic effect can take parameters in its constructor
allowing the number of oscillations and dampening to be controlled:
new ElasticTransitionPhysics(numb_oscillations, dampening);
It is also possible to chain transition physics together allowing simple compositions to be made. Rather than creating
classes for every type you might need, sometimes existing ones can be combined together. Say, for example, we want a
Bounce transition physics to also have EaseInOut - simple, just do the following:
ElasticTransitionPhysics tp = new ElasticTransitionPhysics(numb_oscillations, dampening);
tp.chainTransitionPhysicsBefore(new EaseInOutTransitionPhysics);
with the above, first the EaseInOut transition physics is applied, followed by the Elastic one - this actually is what you
are seeing in the example above for the Elastic.
Effects themselves give a lower granularity of control, allowing you
to set their own duration (remember if you set the duration on the Panel, then all effects on the panel
get that duration). There are often various properties you may wish to set for an effect, and these
are available through the effect's properties object.
For example, if you wish to set the final percentage height of Resize to 250%, you would write:
Resize theResize = new Resize();
theResize.getProperties().setEndHeightPercentage(250);
were we create the effect in line 1, and then in line 2 use the getProperties() method to return access to the
properties object on which we then execute the setEndHeightPercentage() method with the value 5 as the parameter.
The current set of effects provided with GWT-FX version 3 is listed below, but in the next section we go through
the most powerful part of GWT-FX and look at how you can build almost any effect you want without going near the
code - by using CSS Style Sheets.
- Blind - down, up, left and right
- Wipe - down, up, left and right
- Slide - down, up, left and right
- BoxOutCentre / BoxInCentre
- ChangeColor
- Collapse - Horizontally and Vertically
- Fade
- Show
- Highlight
- Resize
- Move
- Puff
- ReflectImage
Cascading Style Sheets are the magic that drives GWT-FX version 2. Almost all effects
can be thought of as the progression from one style definition to another. For example, the fades we have seen above are
just a progression of values supplied to the visibility property. To some extent we could have provided two CSS style definitions
.start{
visibility: 100;
}
.end{
visibility: 0;
}
to capture our wishes, and the require the effect to move that visibilty property from 100 to 0. And, in fact, that is exactly what
GWT-FX version 3 does. Effects, such as Fade are really provided for brevity and to some extent backwards compatibility with GWT-FX
version 1. Version 3 provides a very powerful NMorphStyle() effect, which you have already perhaps seen in action. The logo at the top
of this page is driven by CSS; actually the following:
.logo1{
top: 0px;
left: 0px;
background-color: #ffff00;
width: 5px;
height: 25px;}
.logo2{top: 0px; left: 400px; background-color: #0000ff; width: 150px; height: 25px;}
.logo3{top: 70px; left: 390px; background-color: #956600; width: 330px; height: 110px;}
.logo4{top: 80px; left: 398px; font-size: 2pt; color: #ff6666; border: 0px;}
.logo5{top: 80px; left: 398px; font-size: 60pt; color: #ffffff;}
.logo6{top: 15px; font-weight: normal; letter-spacing: 20px; opacity: 0; width: 695px;right: 490px; font-size: 60pt; color: #ff0000; text-align: right; }
.logo7{
top: 155px;
font-weight: bold;
letter-spacing: 2px;
opacity: 100;
width: 695px;
right: 0px;
font-size: 10pt;
color: #000000;
text-align: right;}
Lines 1 to 8 control the coloured box that move, grows and eventually stays in place, 9 and 10 control the growing "GWT" text and finally lines 11 and 21 control
the "GWT, Just fancier" tag line. Click on the area below to broadly see this all in action again:
The box grows and changes colours as we say that the effect implemented moves from the style defined in .logo1 to that defined in .logo2 and the onto that defined in
.logo3. Have a look at the CSS, you can see the positional elements (top and left) and the colour (background-color) followed by the dimensions (width and height).
These are fed into GWT by creating a new MorphStyle effect as follows:
NMorphStyle morph1 = new NMorphStyle(new Selector(".logo1"), new Selector(".logo2"));
using this, GWT-FX will crawl the active Cascading Style Sheet to find a CSS rule that matches the selectors. Upon finding them it will construct a set of effects
to transition each individual property in the rules from the start to the end (if no start can be found, GWT-FX will attempt to determine the computed style by
interrogating the browser (but note that it cannot handle styles that are found to have a value of "auto" - if that turns out to be the case, GWT-FX will suggest you
explicitly set the start value).
The real benefit of this CSS approach is twofold: first you can change the effect without having to recompile the code, and secondly, you are not constrained by having
to write new effect code - if you need something that is not provided (e.g. Fade) then just throw together the CSS definition of what you want, and off you go with a
new NMorphStyle() effect.
//END
This section is a quick start guide to using GWT-FX, there are a couple of steps you need to do for set up....
- Download a copy of the library's JAR file
- Add the JAR file to your application's classpath (in both the shell and compile scripts - and according to your IDE manual if your using an IDE, e.g. Eclipse)
- Add the following to your application's XML configuration file (application.gwt.xml:
With everything set up, you create an NEffectPanel
NEffectPanel thePanel = new NEffectPanel();
add whatever widgets you want to it, for example, an image:
thePanel.add(new Image("someimageURL.png"));
Then decide if you're using the set of built in effects, or if you are going to use Cascading Style Sheet definitions. As this is a get going guide,
we'll use the built in Resize effect
thePanel.addEffect(new Resize());
Add your panel to your application, for example the RootPanel
RootPanel.get().add(thePanel);
...and play the effect
thePanel.playEffects();
More details on transition styles, effects, timings, and using the more interesting Cascading Style Sheets can be found in the Tutorial.
Enjoy!