inside div animate gwt animation jquery-animate

div - Suave animación tipo jQuery en GWT



jquery parent (3)

Estoy jugando con la clase de animación de GWT como un ejercicio. Mi objetivo no es crear otra biblioteca de widget / animación para GWT. Además, soy muy consciente de que hay muchas bibliotecas que hacen esto. Lo que estoy tratando de hacer es aprender cómo se puede hacer esto, no cómo usar alguna biblioteca. Esto es sólo con fines educativos....

Dicho esto, he implementado una clase simple que realiza 4 animaciones diferentes en algún widget: atenuar, desvanecer, deslizar y deslizar (siguiendo el modelo de animación de jQuery). Vea el código a continuación para saber cómo lo he implementado.

DEMO EN VIVO: http://www.rodrigo-silveira.com/gwt-custom-animation/

Mi pregunta: ¿Cómo puedo [y con éxito] detener una animación tan pronto como se active otra, y continuar con la animación actual donde quedó la anterior?

Por ejemplo, si la slideIn () está a mitad de camino cuando se llama a slideOut (), ¿cómo puedo comenzar a deslizarse fuera de la altura natural del widget del 50%? Intenté mantener una variable miembro que siempre hace un seguimiento del progreso actual para poder usar eso en una nueva animación, pero parece que no puedo hacerlo bien. ¿Algunas ideas?

import com.google.gwt.animation.client.Animation; import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.user.client.Element; public class RokkoAnim extends Animation { private Element element; private int currentOp; private final static int FADE_OUT = 0; private final static int FADE_IN = 1; private final static int SLIDE_IN = 2; private final static int SLIDE_OUT = 3; public RokkoAnim(Element element) { this.element = element; } public void fadeOut(int durationMilli) { cancel(); currentOp = RokkoAnim.FADE_OUT; run(durationMilli); } public void fadeIn(int durationMilli) { cancel(); currentOp = RokkoAnim.FADE_IN; run(durationMilli); } public void slideIn(int durationMilli) { cancel(); currentOp = RokkoAnim.SLIDE_IN; run(durationMilli); } public void slideOut(int durationMilli) { cancel(); currentOp = RokkoAnim.SLIDE_OUT; run(durationMilli); } @Override protected void onUpdate(double progress) { switch (currentOp) { case RokkoAnim.FADE_IN: doFadeIn(progress); break; case RokkoAnim.FADE_OUT: doFadeOut(progress); break; case RokkoAnim.SLIDE_IN: doSlideIn(progress); break; case RokkoAnim.SLIDE_OUT: doSlideOut(progress); break; } } private void doFadeOut(double progress) { element.getStyle().setOpacity(1.0d - progress); } private void doFadeIn(double progress) { element.getStyle().setOpacity(progress); } private void doSlideIn(double progress) { double height = element.getScrollHeight(); element.getStyle().setHeight(height * (1.0d - progress), Unit.PX); } private void doSlideOut(double progress) { // Hard coded value. How can I find out what // the element''s max natural height is if it''s // currently set to height: 0 ? element.getStyle().setHeight(200 * progress, Unit.PX); } }

Uso

// 1. Get some widget FlowPanel div = new FlowPanel(); // 2. Instantiate the animation, passing the widget RokkoAnim anim = new RokkoAnim(div.getElement()); // 3. Perform the animation // >> inside mouseover event of some widget: anim.fadeIn(1500); // >> inside mouseout event of some widget: anim.fadeOut(1500);


  1. Agregue un método de instancia bool cancelado a su clase de animación
  2. Sólo ejecute la animación si no se cancela.
  3. Agregue un método cancelAnnimation y llame a este método cada vez que comience la nueva animación.

    private bool canceled = false; public void cancelAnnimation() { canceled = true; } private void doFadeOut(double progress) { if(!canceled) { element.getStyle().setOpacity(1.0d - progress); } } ... etc.

Así que esa es la forma en que se puede detener la animación. Pero ahora, necesitas comenzar la nueva animación desde el punto actual. Así que lo mejor fue modificar la clase de nuevo.

  1. agregar dos variables de instancia currentProgress y offset (doble)
  2. Añadir un doble desplazamiento al constructor.
  3. devuelve currentProgress cuando cancele la animación.
  4. iniciar la nueva animación con el desplazamiento de la primera animación.

    private bool canceled = false; private double currentProgress = 0; private double offset = 0; public RokkoAnim(Element element, double offset) { this.element = element; this.offset = offset; } public double cancelAnimation() { canceled = true; return currentProgress; } private void doFadeOut(double progress) { if(!canceled && ((progress + offset) <= 1)) { element.getStyle().setOpacity(1.0d - (progress+offset)); currentProgress = progress+offset; } } ... etc. double offset = anim1.cancelAnimation(); RokkoAnim anim2 = new RokkoAnim(div.getElement(), offset);


Debe actualizar la opacidad en función del valor actual (equivalente a += o -= asignaciones):

private void doFadeOut(double progress) { double opacity = element.getStyle().getOpacity(); element.getStyle().setOpacity(opacity - 1.0d - progress); } private void doFadeIn(double progress) { double opacity = element.getStyle().getOpacity(); element.getStyle().setOpacity(opacity + progress); }


para entrar y salir he modificado su clase para usar las coordenadas de la pantalla del widget:

public class WidgetAnimation extends Animation { private Element element; private int currentOp; private int startX=-1; private int finalX=-1; private final static int FADE_OUT = 0; private final static int FADE_IN = 1; private final static int SLIDE_IN = 2; private final static int SLIDE_OUT = 3; public WidgetAnimation(Element element) { this.element = element; } public void fadeOut(int durationMilli) { cancel(); currentOp = WidgetAnimation.FADE_OUT; run(durationMilli); } public void fadeIn(int durationMilli) { cancel(); currentOp = WidgetAnimation.FADE_IN; run(durationMilli); } public void slideIn(int durationMilli) { cancel(); currentOp = WidgetAnimation.SLIDE_IN; run(durationMilli); } public void slideOut(int durationMilli) { cancel(); currentOp = WidgetAnimation.SLIDE_OUT; run(durationMilli); } @Override protected void onUpdate(double progress) { switch (currentOp) { case WidgetAnimation.FADE_IN: doFadeIn(progress); break; case WidgetAnimation.FADE_OUT: doFadeOut(progress); break; case WidgetAnimation.SLIDE_IN: doSlideIn(progress); break; case WidgetAnimation.SLIDE_OUT: doSlideOut(progress); break; } } private void doFadeOut(double progress) { element.getStyle().setOpacity(1.0d - progress); } private void doFadeIn(double progress) { element.getStyle().setOpacity(progress); } private void doSlideIn(double progress) { if(startX==-1){ finalX = element.getAbsoluteLeft(); startX = - Window.getClientWidth(); } int positionX = (int) (startX + (progress * (this.finalX - startX))); this.element.getStyle().setLeft(positionX, Unit.PX); } private void doSlideOut(double progress) { if(startX==-1){ startX = element.getAbsoluteLeft(); finalX = - Window.getClientWidth(); } int positionX = (int) (startX + (progress * (this.finalX - startX))); GWT.log("StartX:" + startX); GWT.log("finalX:" + finalX); GWT.log("positionX:" + positionX); GWT.log("progress:" + progress); this.element.getStyle().setLeft(positionX, Unit.PX); }

}

Me estoy deslizando hacia afuera y en horizontal, pero puede modificar el código.

Espero que eso ayude.