2011-11-23 16 views
5

Chciałbym, aby mój widget GWT był powiadamiany o zakończeniu jego CSS animation.Jak dodać obsługę zdarzeń CSS AnimationEnd do widżetu GWT?

W zwykłym HTML/Javascript to łatwo zrobić poprzez zarejestrowanie programu obsługi zdarzeń tak:

elem.addEventListener("webkitAnimationEnd", function(){ 
    // do something 
}, false); 
// add more for Mozilla etc. 

Jak mogę to zrobić w GWT?

Ten typ zdarzenia jest nieznany GWT za DOMImpl klas, więc wciąż otrzymuję błąd „Starając się zatopić nieznany typ zdarzenia webkitAnimationEnd”.

Dzięki!

Odpowiedz

1

Zawsze można napisać niektóre z rodzimych (JavaScript) kod siebie:

public class CssAnimation { 
    public static native void registerCssCallback(
     Element elem, AsyncCallback<Void> callback) /*-{ 
    elem.addEventListener("webkitAnimationEnd", function() { 
     $entry(@CssAnimation::cssCallback(Lcom/google/gwt/user/client/rpc/AsyncCallback;)(callback)); 
    }, false); 
    }-*/; 


    protected static void cssCallback(AsyncCallback<Void> callback) { 
    callback.onSuccess(null); 
    } 
} 

nie próbowałem powyższy kod. Daj mi znać, jeśli działa zgodnie z oczekiwaniami.


Możesz użyć klasy GWT Animation, aby uzyskać ten sam efekt. Na przykład,

new com.google.gwt.animation.client.Animation() { 
    final com.google.gwt.dom.client.Style es = widget.getElement().getStyle(); 

    @Override 
    protected void onUpdate(double progress) { 
     setOpacity(1 - interpolate(progress)); 
    } 

    private void setOpacity(double opacity) { 
     es.setProperty("opacity", Double.toString(opacity)); 
     es.setProperty("filter", "alpha(opacity=" + 100 * opacity + ")"); 
    } 

    @Override 
    protected void onComplete() { 
     /* ... run some code when animation completes ... */ 
    } 
    }.run(2000, 5000); 
+0

Ciekawe, nie wiedziałem o tym. Ale zrobienie tego w ten sposób spowoduje animację skryptową, a nie animację CSS, prawda? GWT wciąż nie zna tego wydarzenia. Skryptowane animacje mają pewne wady, jeśli chodzi o płynność działania przy dużym obciążeniu lub na niektórych urządzeniach mobilnych. –

+0

Tak, spowoduje to skryptową animację, która może nie być tak wydajna jak CPU, jak czysta animacja CSS. –

+1

@Kev Byłoby lepiej zachować te dwie odpowiedzi osobno ... Powyższe komentarze odnoszą się do sekcji poniżej linii (rozwiązanie skryptowe). Przyjęta odpowiedź to tylko górna część powyżej linii, która opisuje zupełnie inne podejście. –

4

podstawie odpowiedzi Darthenius' i Clay Lenhart's Blog, w końcu osiadł na to rozwiązanie:

private native void registerAnimationEndHandler(final Element pElement, 
    final CbAnimationEndHandlerIF pHandler) 
/*-{ 
    var callback = function(){ 
     [email protected]::onAnimationEnd()(); 
    } 
    if (navigator.userAgent.indexOf('MSIE') < 0) { // no MSIE support 
     pElement.addEventListener("webkitAnimationEnd", callback, false); // Webkit 
     pElement.addEventListener("animationend", callback, false); // Mozilla 
    } 
}-*/; 

CbAnimationEndHandlerIF jest prosty zwyczaj EventHandler interfejs:

public interface CbAnimationEndHandlerIF extends EventHandler 
{ 
    void onAnimationEnd(); 
} 

działa jak urok! Dzięki Darthenius!

Jeśli ktoś zauważy słabość, oczywiście z przyjemnością się dowiem.

+0

Nie ma za co. Ciekawa abstrakcja dla "callback", przy okazji. –

+0

Właśnie zmodyfikowałem powyższy kod, aby wykluczyć MSIE, ponieważ MSIE nie może wykonywać animacji klatek kluczowych CSS (przynajmniej do wersji 9), a także wymagałaby innej składni w celu dodania detektora. –

0

Rozszerzyłem nieco rozwiązania z Darthenius. Ten kod zawiera także mechanizm do usuwania programu obsługi zdarzeń po jego zakończeniu. To jest to, czego potrzebowałem do mojej aplikacji, ale może nie być tym, czego chcesz w każdym kontekście. YMMV!

Moja ostatnia kod wygląda następująco:

import com.google.gwt.dom.client.Element; 
import com.google.gwt.user.client.rpc.AsyncCallback; 

public class CssAnimation { 
    public static native void registerCssCallback(Element elem, AsyncCallback<Void> callback) /*-{ 
     var eventListener = function() { 
      $entry(@CssAnimation::cssCallback(Lcom/google/gwt/user/client/rpc/AsyncCallback;)(callback)); 
      elem.removeEventListener("webkitAnimationEnd", eventListener); 
     }; 

     elem.addEventListener("webkitAnimationEnd", eventListener, false); 
    }-*/; 

    protected static void cssCallback(AsyncCallback<Void> callback) { 
     callback.onSuccess(null); 
    } 
} 
Powiązane problemy