GWT allows you to extend the animation class and create your own custom animations. I was reading this post earlier today and decided to take that code a little further and put it all together into a workable GWT project in Eclipse.
I used Eclipse 3.6 (Helios) along with the Plug-in for Eclipse using the GWT SDK (2.0.4).
Create a new GWT Project:
With the default files generated we need to delete some that won’t be of any use to us. Delete the files you don’t see in this screenshot:
Go into the GWTCustomAnimation.java file and edit it so its down to the bare bones:
package com.giantflyingsaucer.client;
import com.google.gwt.core.client.EntryPoint;
public class GWTCustomAnimation implements EntryPoint
{
public void onModuleLoad()
{
}
}
Now go into the GWTAnimation.html file (in the web-inf folder) and between the body tags insert this code overwriting anything currently in there.
<!-- OPTIONAL: include this if you want history support -->
<iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>
<!-- RECOMMENDED if your web app will not function without JavaScript enabled -->
<noscript>
<div style="width: 22em; position: absolute; left: 50%; margin-left: -11em; color: red; background-color: white; border: 1px solid red; padding: 4px; font-family: sans-serif">
Your web browser must have JavaScript enabled
in order for this application to display correctly.
</div>
</noscript>
<div id="mainDiv"></div>
With the project trimmed down we can start to add in what is needed. Right-click on the src folder and create a new package:
Inside the new package add some sort of image.
Right-click on the “com.giantflyingsaucer.client” package and select: New -> ClientBundle
This class will allow us to grab the image easily from our code. Here is the code for the newly create class that you’ll need:
package com.giantflyingsaucer.client;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.ImageResource;
public interface Resources extends ClientBundle
{
public static final Resources INSTANCE = GWT.create(Resources.class);
@Source("images/gwt-logo.png")
ImageResource gwtLogo();
}
Right-click on the “com.giantflyingsaucer.client” again but this time add a new class.
Add the following code:
package com.giantflyingsaucer.client;
import com.google.gwt.animation.client.Animation;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style;
public class CustomAnimation extends Animation
{
private final Element element;
private int startX;
private int startY;
private int finalX;
private int finalY;
public CustomAnimation(Element element)
{
this.element = element;
}
public void scrollTo(int x, int y, int milliseconds)
{
this.finalX = x;
this.finalY = y;
startX = element.getOffsetLeft();
startY = element.getOffsetTop();
run(milliseconds);
}
@Override
protected void onUpdate(double progress)
{
double positionX = startX + (progress * (this.finalX - startX));
double positionY = startY + (progress * (this.finalY - startY));
this.element.getStyle().setLeft(positionX, Style.Unit.PX);
this.element.getStyle().setTop(positionY, Style.Unit.PX);
}
@Override
protected void onComplete()
{
super.onComplete();
this.element.getStyle().setLeft(this.finalX, Style.Unit.PX);
this.element.getStyle().setTop(this.finalY, Style.Unit.PX);
}
}
Go back to the GWTCustomAnimation.java file now and add the following code:
package com.giantflyingsaucer.client;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.RootPanel;
public class GWTCustomAnimation implements EntryPoint
{
private AbsolutePanel absolutePanel = null;
public void onModuleLoad()
{
final Button runButton = new Button("Run");
runButton.addStyleName("runButton");
absolutePanel = new AbsolutePanel();
absolutePanel.setSize("350px", "350px");
absolutePanel.getElement().setId("cwAbsolutePanel");
absolutePanel.addStyleName("absolutePanel");
final Image img = new Image(Resources.INSTANCE.gwtLogo());
absolutePanel.add(img, 10, 10);
runButton.addClickHandler(new ClickHandler()
{
public void onClick(ClickEvent event)
{
CustomAnimation animation = new CustomAnimation(img.getElement());
animation.scrollTo(100, 200, 2000);
}
});
HorizontalPanel mainLayout = new HorizontalPanel();
mainLayout.setSpacing(10);
mainLayout.add(runButton);
mainLayout.add(absolutePanel);
RootPanel.get("mainDiv").add(mainLayout);
}
}
A couple final things, modify your web.xml to look like this (I took out the default servlets that were generated and which we already removed from the project):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<!-- Servlets -->
<!-- Default page to serve -->
<welcome-file-list>
<welcome-file>GWTCustomAnimation.html</welcome-file>
</welcome-file-list>
</web-app>
Modify the GWTCustomAnimation.css file (located in web-inf) to this:
/** Add css rules here for your application. */
.runButton {
display: block;
font-size: 16pt;
}
.absolutePanel {
background-color: #eee;
}
We are ready to run this now. Go ahead and once its up and running click on the “Run” button and if all goes well you should see some nice x, y based animation! All the source code is available here.











As written, this animation will show ease-in/ease-out easing (slow at start, fast in middle, slow at finish). The progress sent to onUpdate is first run through interpolate, which returns an eased progress value. To create a linear animation or one with a different type of easing, you need to override the interpolate function.
Thanks so much for this. Was looking for a way to animate panels without using the layoutpanels and it’s absolute positions