Creating a custom GWT animation

Post to Twitter

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.

Post to Twitter

This entry was posted in GWT, Java, Open Source. Bookmark the permalink.

2 Responses to Creating a custom GWT animation

  1. Mike Miller says:

    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.

  2. john says:

    Thanks so much for this. Was looking for a way to animate panels without using the layoutpanels and it’s absolute positions

Comments are closed.