Layout your GWT apps part 2 – Animations

| 0 comments

Example use of animations.One thing that is commonly achieved with Javascript are animations for panels, menus and other standard UI elements. In this post, we show you how you can animate arbitrary DIVs with GWT.

As an example, we use the feedback slider from the picture above. You can see a working example here. The feedback slider is basically an absolutely positioned DIV. Most of the DIV is hidden beyond the browser window. When the DIV is clicked, the DIV is moved into the page until all of it is revealed to the browser window.

The key to moving the DIV is simple. Firstly, we position it absolutely via CSS. Secondly, we manipulate the left, right, top, or bottom CSS-properties via Javascript. In the example, we have a DIV containing the feedback panel. This feedback-DIV is positioned absolutely based on the HTML-body element. The DIV is 630px wide. Its left-property is set to -600px, thus only the 30 right-most pixels are showing. Using a timer we continuously increase the left-property. Adding a pixel any other tenth of a second creates a seemingly smooth motion. This motion is the animation we want.

All the layout is done with HTML and CSS. To create the animation we only need two pieces of Javascript (or in our case GWT). Firstly, we need to catch the click event caused when a user clickes on the feedback-DIV. On this event we want to start the animation. Secondly, we need to implement the timer that realizes the animation. Here is how both things are done in GWT:

Event.addNativePreviewHandler(new NativePreviewHandler() {
  @Override
  public void onPreviewNativeEvent(NativePreviewEvent preview) {
    NativeEvent event = preview.getNativeEvent();
    Element target = event.getEventTarget().cast();
    if (event.getType().equalsIgnoreCase("click")) {
      if (target == FeedbackContainer.this.getElement()) {
        onOpenCloseClick(null);
      }
    }
  }
});

This piece adds a native event handler. This is the GWT way to catch all browser events. We catch all events and then look if we have the event we want. In our case we look for click events targeted for the feedback-DIV. The feedbackDiv variable holds an HTMLPanel that represents the feedback-DIV. Of course you can also work with DOM-elements directly.

private void onOpenCloseClick(ClickEvent e) {
  Animation animation = new Animation() {
    @Override
    protected void onUpdate(double progress) {
      if (isOpen) {
        DOM.setStyleAttribute(FeedbackContainer.this.getElement(), "left", 
            (int)(-600*(progress)) + "px");
      } else {
        DOM.setStyleAttribute(FeedbackContainer.this.getElement(), "left", 
            (int)(-600*(1-progress)) + "px");
      }
    }
 
    @Override
    protected void onComplete() {
      super.onComplete();
      isOpen = !isOpen;
    }
  };
  animation.run(1000);
}

Every time the feedback-DIV is clicked, we call the above method. It uses a GWT-Animation. The Animation class provides us with an abstraction for the needed timer.  We need to implement two methods: onUpdate(double) and onComplete(). Once we run the animation, onUpdate(double) is called on regular increments of time. The parameter ranges between 0 and 1 and tells us, how far in the animation we are. The other method onComplete() is called once, when the animation is over. We can run and animation with run(int). The int parameter tells the animation how long it shall run in milliseconds. Choosing the right time increment and scheduling the necessary timers is done by the animation class. We use the member variable isOpen to determine whether the animation opens or closes the slider.

Thats all. I am sure you can adopt this technique to animate your UI-panels.

Leave a Reply

Required fields are marked *.