2011-11-23 7 views
5

Me gustaría que mi widget GWT sea notificado cuando se termine su CSS animation.Cómo agregar el controlador de eventos CSS AnimationEnd al widget GWT?

En la versión HTML/Javascript Esto se hace fácilmente mediante el registro de un controlador de eventos de este modo:

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

¿Cómo se puede hacer esto en GWT?

Este tipo de evento es desconocida para DOMImpl clases de GWT, así que deja de recibir un error "Tratar de hundir el tipo de evento desconocido webkitAnimationEnd".

Gracias!

Respuesta

1

siempre se puede escribir algunos de los nativos (JavaScript) código usted mismo:

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

No he probado el código de seguridad. Avísame si funciona como se espera.


Se puede utilizar la clase de GWT Animation para lograr el mismo efecto. Por ejemplo,

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

Interesante, yo no lo sabía. Pero hacerlo de esta manera dará como resultado una animación guionizada, no una animación CSS, ¿verdad? GWT todavía no conoce el evento. Las animaciones con guión tienen algunas desventajas cuando se trata de suavidad de rendimiento con cargas pesadas o en algunos dispositivos móviles. –

+0

Sí, esto dará como resultado una animación con guiones, que puede no ser tan eficiente en la CPU como la animación CSS pura. –

+1

@Kev Hubiera sido mejor mantener estas dos respuestas separadas ... Los comentarios anteriores se refieren a la sección debajo de la línea (la solución guionizada). La respuesta aceptada es solo la parte superior sobre la línea, que describe un enfoque totalmente diferente. –

4

Sobre la base de respuesta y Clay Lenhart's Blog Darthenius', que finalmente se conformaron con esta solución:

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

El CbAnimationEndHandlerIF es una sencilla interfaz personalizada EventHandler:

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

Obras como ¡un encanto! Gracias Darthenius!

Si alguien puede detectar una debilidad en esto, por supuesto que me gustaría saberlo.

+0

De nada. Buena abstracción para 'devolución de llamada', por cierto. –

+0

Acabo de modificar mi código anterior para excluir MSIE, porque MSIE no puede hacer animaciones de fotogramas CSS (al menos hasta la versión 9), y también requeriría una sintaxis diferente para agregar el oyente. –

0

Expandí un poco la solución de Darthenius. Este código también incluye un mecanismo para eliminar el controlador de eventos cuando finaliza. Esto es lo que necesitaba para mi aplicación, pero puede que no sea lo que desea en todos los contextos. YMMV!

Mi código final es el siguiente:

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