Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GWT Animation final value is not respected

I have a FlowPanel that I'm trying to animate back and forth like an iphone nav. (See this post for my original question on how to do this)

So I have it "working" with the code shown below. I say working in quotes because I'm finding that my final position of my scroller is not precise and always changes when scrolling.

The GWT.log always says the actual values I'm looking for, so for instance with the call below to scrollTo, my GWT.log says:

ScrollStart: 0 scrollStop: -246

But when I actually analyze the element in fireBug, its css, left position is never exactly -246px. Sometimes it's off by as much as 10px so my panel has just stopped scrolling before being finished.

The worst part is that this nav animates back and forth, so subsequent clicks can really throw it off, and I need pixel perfect positioning otherwise the whole things looks off.

I don't even know where to start with debugging this other than what I've already done. Any tips are appreciated.

EDIT: Additional logging information:
Logging inside the onUpdate shows this:

Updating: progress: 0.09319577524960648 position: -22.926160711403195
Updating: progress: 0.1328387452821571 position: -32.67833133941065
Updating: progress: 0.609071620698271 position: -149.83161869177468
Updating: progress: 0.7269952498697734 position: -178.84083146796425
Updating: progress: 0.9852532367342712 position: -242.37229623663072
AnimationComplete: final scrollStart/scrollStop: 0/-246

Why does it end at 0.98 % ???

Code to call animation

scroller = new Scroller();
scroller.scrollTo(-246,400);

Animation Code

public class Scroller extends Animation {

    private FlowPanel scroller;
    private final Element e;

    public Scroller(){
        scroller = new FlowPanel();
        e = scroller.getElement();
    }

    public void scrollTo(int position, int milliseconds) {

        scrollStart = e.getOffsetLeft();
        scrollStop = position;

        GWT.log("ScrollStart: " + scrollStart + " scrollStop: " + scrollStop);
        run(milliseconds);
    }

    @Override
    protected void onUpdate(double progress) {
        double position = scrollStart + (progress * (scrollStop - scrollStart));
        e.getStyle().setLeft(position, Style.Unit.PX);
    }
}
like image 218
brad Avatar asked Apr 19 '10 16:04

brad


1 Answers

onComplete gets called when the animation is finished (and onStart gets called before it starts), so override that if you want to take an action when the animation is 100% done:

public class Scroller extends Animation {
      ...

      @Override
      protected void onComplete() {
        e.getStyle().setLeft(scrollStop, Style.Unit.PX);
      }
}

Edit As brad notes, the docs aren't very clear that onComplete is what's called when the animation is finished. The Javadoc says Animation.onUpdate is:

Called when the animation should be updated. The value of progress is between 0.0 and 1.0 inclusively (unless you override the interpolate(double) method to provide a wider range of values). You can override onStart() and onComplete() to perform setup and tear down procedures.

The code that calls these methods is the only thing that makes clear that onUpdate is only called when the animation has started but not yet finished - that is, when the progress value is > 0 but < 1.

like image 149
aem Avatar answered Sep 25 '22 22:09

aem