GWT Animation – small review

Since GWT 1.5 developers can use simple animated objects. Animation is a useful tool to change properties of widget  components in continuous way. (which seems to be more friendly to end-user, when using for rational purposes).

Animation is very easy to use, you just have to extend Animation class and override onUpdate() method. Let’s see how it works in simple example

Update 1013.10.11: If you would like to see more modern way to add animations to your project, read my post about Animations with GQuery

GWT Animation Use Example

To show how to use GWT Animation I’ve created simple application which consists of : label and button. After clicking on button, label will slowly change its width to reach width of size 300px .

public class AnimationTest implements EntryPoint {
    // how long animation will last
    private final int DURATION = 500;
    private int DESIRED_WIDGET_WIDTH = 300;
    private Widget resizedWidget;
    public class ResizeWidthAnimation  extends Animation {
        // initial size of widget
        private int startWidth = 0;
        // desired size of widget. Widget will have this size after animation will stop to run
        private int desiredWidth = 0;
       public ResizeWidthAnimation(int desiredWidth) {
            this.startWidth = resizedWidget.getOffsetWidth();
            this.desiredWidth = desiredWidth;
        }
        @Override
        protected void onUpdate(double progress) {
            double width = extractProportionalLength(progress) ;
            resizedWidget.setWidth( width + Unit.PX.getType());
        }
        private double extractProportionalLength(double progress) {
            double outWidth = startWidth - (startWidth - desiredWidth) * progress;
            return outWidth;
        }
    }
    public void onModuleLoad() {
        FlowPanel fp = new FlowPanel();
        resizedWidget = createLabel();
        fp.add(resizedWidget);
        final Button resizeButton = new Button("Click to Resize", new ClickHandler() {
           @Override
            public void onClick(ClickEvent event) {
                ResizeWidthAnimation resizeAnimation = new ResizeWidthAnimation(DESIRED_WIDGET_WIDTH);
                resizeAnimation.run(DURATION);
            }
        });
        fp.add(resizeButton);
        RootLayoutPanel.get().add(fp);
    }
    private Label createLabel() {
        final Label resizeMeLabel = new Label("Resize ME");
        resizeMeLabel.getElement().getStyle().setBackgroundColor("#5096a9");
        resizeMeLabel.setWidth("100" + Unit.PX.getType());
        return resizeMeLabel;
    }
}

I have created ResizeWidthAnimation class – which will change width of resizeMe Label. You can see this code working here: http://blog-demo.appspot.com/#animation . Lets take a closer look on the most important parts of this example.

onUpdate()

You can see that I have overridden onUpdate(double progress) method. This method will be run continuously every 25 milliseconds ( This value is indicated by Animation.DEFAULT_FRAME_DELAY) till the end of animation.  I have used progress  argument to calculate width of  label. Progress value will change continuously from 0 till 1. So every 25 milliseconds we will get a little bit bigger progress value.

run()

After creating an instance of ResizeWidthAnimation object we can launch it by calling run(int duration) method. Duration  is the duration of animation in milliseconds. The  bigger the duration the longer animation will last AND the smaller differences between each value of progress.

For  those who are really curious:
Actually, knowing the duration value, we can calculate how many times onUpdate method will be called . It will be

numberOfOnUpdateCalls  = duration/25

You may also think that you can calculate differences between each progress values.. which is actually truth but it is not so simple as :

progress(n+1) – progress(n) = 25/duration

I will describe How to calculate it in “What you can do more” chapter.

Small summary

As you can see you can very quickly create your own animation for every property of your widgets. For example in my applications “commons” I’ve created sets of Animations ( which are outer classes – not like the one from my simple example) which change different parameters of widgets. So I  can combine them together to create any effect I need:)

What can you do more?

The first example is the most easiest I could think of – just to “have something moving”.  As far as Animation is a very simple class there are some aspects of it which can be very handy while creating your own custom animations. So what can you do more?

Overridde: interpolate(double progress) method

If you have run the first example maybe you have noticed that width of the label first changes very slowly.. then very fast.. and in the end once again very slowly.  Looking at numbers it means that progress value isn’t changing in equal steps – it is not linear progress.

This is happening because the progress value which we get in onUpdate method is modified a little bit in another Animation method. It is interpolate method – which originally looks like this:

protected double interpolate(double progress) {
    return (1 + Math.cos(Math.PI + progress * Math.PI)) / 2;
}

So the progress we will receive in onUpdate method will change like this:

interpolation

Now if we need to we can override interpolate method to return any values we want. Creating any kind of progression we want.  For example you can try out this  calculation to have smooth come back effect:

return  progress*( 1.0 - progress )*4.0;

Run animations synchronously

You can create set of animation and then run them together or run one after another.  So e.g. you can create ResizeWidthAnimation and ResizeHeightAnimation and launch them like this:

ResizeWidthAnimation resizeAnimation = new ResizeWidthAnimation(resizedWidget, DESIRED_WIDGET_WIDTH);
resizeAnimation.run(DURATION);

ResizeHeightAnimation resizeHeight = new ResizeHeightAnimation(resizedWidget, DESIRED_WIDGET_HEIGHT);
double delay = 400.0;
resizeHeight.run(DURATION, Duration.currentTimeMillis() + delay);

Animation class will handle those both animations without conflicts so the effect will be as smooth as only one animation have been run. See how it works here : http://blog-demo.appspot.com/#ParaAnim

Override other Animation methods

Animation provides also other useful methods which you can override. Those are:

onStart() Called immediately before the animation starts.

onComplete() Called immediately after the animation completes.

onCancel() Called immediately after the animation is canceled.

Using this methods you can handle some init or end parameters. Using them is quite intuitive you should just remember about calling their super methods.

Summary

Links

gwt api reference http://google-web-toolkit.googlecode.com/svn/javadoc/2.0/index.html?overview-summary.html

gwt showcase  http://gwt.google.com/samples/Showcase/Showcase.html#!CwAnimation

animations with GQuery : https://fascynacja.wordpress.com/2013/10/11/gquery-animations-how-to-use-them/

Advertisements

9 Responses to GWT Animation – small review

  1. Pingback: GWT balloon widget in 5 minutes « My Fascinations

  2. Naveen Gudipally says:

    Hi,

    Great post. One question. What should we do to shrink the label back to its original size while animating.

    Thanks,
    Naveen

  3. Ronald Hughes says:

    Nice article. Keep it up…

  4. katta vijay says:

    Hi Agata ,
    Can you please help me on implementing marquee with animation in gwt or gwt .

    Thanks,
    Vijay katta

  5. Pingback: GQuery Animations – how to use them | My Fascinations

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: