2011-11-23 6 views
5

Vorrei che il mio widget GWT venisse avvisato quando il suo CSS animation è finito.Come aggiungere il gestore di eventi CSS AnimationEnd al widget GWT?

in semplice HTML/Javascript Questo è fatto facilmente registrando un gestore di eventi in questo modo:

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

Come posso fare questo in GWT?

Questo tipo di evento è sconosciuto a DOMImpl classi di GWT, quindi continuo a ricevere un errore "Cercando di affondare sconosciuto tipo di evento webkitAnimationEnd".

Grazie!

risposta

1

si può sempre scrivere alcuni dei nativi (JavaScript) Codice da soli:

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); 
    } 
} 

Non ho provato il codice di cui sopra. Fammi sapere se funziona come previsto.


È possibile utilizzare la classe di GWT Animation per ottenere lo stesso effetto. Ad esempio,

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

Interessante, io non lo sapevo. Ma farlo in questo modo si tradurrà in un'animazione con script, non in un'animazione CSS, giusto? GWT ancora non conosce l'evento. Le animazioni con script hanno alcuni inconvenienti quando si tratta di uniformità delle prestazioni sotto carico pesante o su alcuni dispositivi mobili. –

+0

Sì, ciò comporterà un'animazione con script, che potrebbe non essere efficiente come CPU come pura animazione CSS. –

+1

@Kev Sarebbe stato meglio tenere separate queste due risposte ... I commenti sopra si riferiscono alla sezione sotto la linea (la soluzione con script). La risposta accettata è solo la parte superiore sopra la linea, che descrive un approccio totalmente diverso. –

4

in base alla risposta Darthenius' e Clay Lenhart's Blog, ho finalmente risolta per questa soluzione:

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 
    } 
}-*/; 

Il CbAnimationEndHandlerIF è una semplice interfaccia personalizzata EventHandler:

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

Opere come un fascino! Grazie Darthenius!

Se qualcuno può individuare una debolezza in questo, ovviamente sarei felice di sapere.

+0

Prego. A proposito, bella astrazione per 'callback'. –

+0

Ho appena modificato il mio codice sopra per escludere MSIE, perché MSIE non può realizzare animazioni di fotogrammi chiave CSS (almeno fino alla versione 9) e richiederebbe anche una sintassi diversa per aggiungere il listener. –

0

Ho ampliato un po 'la soluzione di Darthenius. Questo codice include anche un meccanismo per rimuovere il gestore eventi al termine. Questo è ciò di cui avevo bisogno per la mia applicazione, ma potrebbe non essere quello che vuoi in tutti i contesti. YMMV!

Il mio codice finale è simile al seguente:

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); 
    } 
}