]> source.dussan.org Git - gwtquery.git/commitdiff
Adding a TransitionsAnimation class whish is like PropertiesAnimation but using CSS3
authorManuel Carrasco Moñino <manuel.carrasco.m@gmail.com>
Sat, 9 Nov 2013 14:21:27 +0000 (15:21 +0100)
committerManuel Carrasco Moñino <manuel.carrasco.m@gmail.com>
Sat, 9 Nov 2013 14:21:27 +0000 (15:21 +0100)
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/Fx.java
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/PropertiesAnimation.java
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/Transitions.java
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/TransitionsAnimation.java [new file with mode: 0755]

index 03ed86b090ee86ba7c63afba1fb809f59361ee9c..426c408dd0ec6a2de112b619b26b7b31d1cd2f70 100644 (file)
@@ -18,6 +18,29 @@ public class Fx {
    */
   public static boolean off = false;
 
+  /**
+   * A pojo to store color transition values.
+   */
+  public static class TransitFx extends Fx {
+    public String transitEnd;
+    public String transitStart;
+
+    TransitFx() {
+    }
+
+    TransitFx(String attr, String value, String start, String end, String unit) {
+      this.cssprop = attr;
+      this.value = value;
+      this.transitStart = start;
+      this.transitEnd = end;
+      this.unit = unit;
+    }
+
+    public String toString() {
+      return super.toString() + " transitStart=" + transitStart + " transitEnd=" + transitEnd; 
+    }
+  }
+
   /**
    * A pojo to store color effect values.
    */
index f91f05574e57b144cb9472e8d3f74a110bb903d5..d9404e2201b13a7cee1fdcbc3d39999e916684f4 100755 (executable)
@@ -15,6 +15,8 @@
  */
 package com.google.gwt.query.client.plugins.effects;
 
+import static com.google.gwt.query.client.GQuery.$;
+
 import com.google.gwt.dom.client.Element;
 import com.google.gwt.query.client.Function;
 import com.google.gwt.query.client.GQuery;
@@ -131,13 +133,13 @@ public class PropertiesAnimation extends GQAnimation {
      }
    }
 
-  private static final String[] ATTRS_TO_SAVE = new String[]{"overflow"};
+  protected static final String[] ATTRS_TO_SAVE = new String[]{"overflow"};
   
   private static final RegExp REGEX_NUMBER_UNIT = RegExp.compile("^([0-9+-.]+)(.*)?$");
 
-  private static final RegExp REGEX_SYMBOL_NUMBER_UNIT = RegExp.compile("^([+-]=)?([0-9+-.]+)(.*)?$");
+  protected static final RegExp REGEX_SYMBOL_NUMBER_UNIT = RegExp.compile("^([+-]=)?([0-9+-.]+)(.*)?$");
 
-  private static final RegExp REGEX_NON_PIXEL_ATTRS = 
+  protected static final RegExp REGEX_NON_PIXEL_ATTRS = 
       RegExp.compile("z-?index|font-?weight|opacity|zoom|line-?height|^\\$", "i");
 
   private static final RegExp REGEX_COLOR_ATTR = RegExp.compile(".*color$", "i");
@@ -266,21 +268,19 @@ public class PropertiesAnimation extends GQAnimation {
     return new Fx(key, val, start, end, unit, rkey);
   }
 
-  private Easing easing = EasingCurve.linear;
-  private JsObjectArray<Fx> effects = JsObjectArray.create();
-  private Function[] funcs;
+  protected Easing easing;
+  protected JsObjectArray<Fx> effects = JsObjectArray.create();
+  protected Function[] funcs;
+  protected Properties prps;
 
   private Effects g;
 
-  private Properties prps;
-
-  public PropertiesAnimation(Easing easing, Element elem, Properties p,
-      Function... funcs) {
-    this.easing = easing;
+  public PropertiesAnimation(Easing easing, Element elem, Properties p, Function... funcs) {
+    this.easing = easing != null ? easing : EasingCurve.linear;
     this.e = elem;
     this.funcs = funcs;
     this.prps = p;
-    g = Effects.$(e).as(Effects.Effects);
+    g = $(e).as(Effects.Effects);
   }
 
   @Override
@@ -346,11 +346,7 @@ public class PropertiesAnimation extends GQAnimation {
 
   @Override
   protected double interpolate(double progress) {
-    if (easing != null) {
-      return easing.interpolate(progress);
-    }
-    // maybe return super.interpolate() instead ?
-    return progress;
+    return easing.interpolate(progress);
   }
 
 }
index b4cb8f2c9815097d272eced0552ecf7edc1952cd..9a290753ddcbc2a87a35c33ae3d371da42351374 100644 (file)
@@ -45,10 +45,10 @@ import com.google.gwt.user.client.DOM;
      .promise().done(new Function(){public void f() {
         g1.transition("{x: +100}", 2000, "linear", 0);
      }});
-     
+
     $("#bar")
      .transition("{ opacity: 0.1, scale: 2, x: 50, y: 50 }", 5000, EasingCurve.easeInBack)
-     .transition("{x: +100, width: +40px}", 2000, EasingCurve.easeOut);     
+     .transition("{x: +100, width: +40px}", 2000, EasingCurve.easeOut);
 
  * </pre>
  */
@@ -156,7 +156,7 @@ public class Transitions extends GQuery {
   private static final String TRANSFORM = "_t_";
   private static final String transformOrigin = getVendorPropertyName("transformOrigin");
   
-  private static final RegExp transformRegex = RegExp.compile("^(scale|translate|rotate([XY]|3d)?|perspective|skew[XY]|x|y)$");
+  protected static final RegExp transformRegex = RegExp.compile("^(scale|translate|rotate([XY]|3d)?|perspective|skew[XY]|x|y)$");
   private static final String transition = getVendorPropertyName("transition");
   
   private static final String transitionDelay = getVendorPropertyName("transitionDelay");
@@ -270,16 +270,26 @@ public class Transitions extends GQuery {
   }
   
   /**
-   * Works like GQuery.animate(), but uses CSS transitions.
+   * The transition() method allows you to create animation effects on any numeric HTML Attribute,
+   * CSS property, or color using CSS3 transformations and transitions.
    * 
-   * It allows chaining like:
+   * It works similar to animate(), supports chainning and queueing and an extra parameter for
+   * delaying the animation.
+   *
+   * Example:
    * <pre>
-    $("#foo")
-      .transition("{ opacity: 0.1, scale: 2, x: 50, y: 50 }", 5000, EasingCurve.easeInBack)
-      .transition("{x: +100, width: +40px}", 2000, EasingCurve.easeOut);
+     $("#foo").transition("{ opacity: 0.1, scale: 2, x: 50, y: 50 }", 5000, EasingCurve.easeInBack);
+
+     $("#bar")
+       .transition("{ opacity: 0.1, scale: 2, x: 50, y: 50 }", 5000, EasingCurve.easeInBack)
+       .transition("{x: +100, width: +40px}", 2000, EasingCurve.easeOut);
    * </pre>
    */
   public Transitions transition(Object stringOrProperties, int duration, Easing easing, int delay, final Function... funcs) {
+    if (isEmpty()) {
+      return this;
+    }
+    
     final Properties p = (stringOrProperties instanceof String) ? $$((String) stringOrProperties) : (Properties) stringOrProperties;
 
     final String oldTransitions = css(transition);
@@ -295,28 +305,45 @@ public class Transitions extends GQuery {
       value += (value.isEmpty() ? "" : ", ") + s + " " + attribs;
     }
     
-    // Use gQuery queue, so as we can chain transitions
     final String transitionValue = value;
+
+    // Use gQuery queue, so as we can chain transitions, animations etc.
     delay(0, new Function(){public void f() {
-      // Configure animation using transition property
-      css(transition, transitionValue);
-      // Set all css properties for this transition 
-      css(p);
-      // prevent memory leak
-      removeData(TRANSFORM);
+      // This is called once per element
+      $(this)
+        // Configure animation using transition property
+        .css(transition, transitionValue)
+        // Set all css properties for this transition using the css method in this class 
+        .as(Transitions).css(p)
+        // prevent memory leak
+        .removeData(TRANSFORM);
     }});
     
     // restore oldTransitions in the element, and use the queue to prevent more effects being run.
     // TODO: Use transitionEnd events once GQuery supports non-bit events
     delay(duration + delay, new Function(){public void f() {
-      css(transition, oldTransitions);
-      each(funcs);
+      // This is called once per element
+      $(this).as(Transitions)
+        .css(transition, oldTransitions)
+        .each(funcs);
     }});
     
     return this;
   }
 
+  /**
+   * The transition() method allows you to create animation effects on any numeric HTML Attribute,
+   * CSS property, or color using CSS3 transformations and transitions.
+   *
+   * It works similar to animate() but has an extra parameter for delaying the animation.
+   *
+   * Example animate an element within 2 seconds:
+   * $("#foo")
+   *   .transition("{ opacity: 0.1, scale: 2, x: 50, y: 50 }", 5000, EasingCurve.easeInBack, 2000);
+   *
+   */
   public Transitions transition(Object stringOrProperties, int duration, String easing, int delay) {
     return transition(stringOrProperties, duration, EasingCurve.valueOf(easing), delay);
   }
+
 }
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/TransitionsAnimation.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/TransitionsAnimation.java
new file mode 100755 (executable)
index 0000000..3d0479e
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2013, The gwtquery team.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.query.client.plugins.effects;
+
+import static com.google.gwt.query.client.GQuery.*;
+
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.query.client.Function;
+import com.google.gwt.query.client.Properties;
+import com.google.gwt.query.client.js.JsObjectArray;
+import com.google.gwt.query.client.plugins.effects.Fx.TransitFx;
+import com.google.gwt.regexp.shared.MatchResult;
+
+/**
+ * Animation effects on any numeric CSS3 property or transformation
+ * using CSS3 transitions
+ */
+public class TransitionsAnimation extends PropertiesAnimation {
+  
+  public static Fx computeFxProp(Element e, String key, String val, boolean hidden) {
+    Transitions g = $(e).as(Transitions.Transitions);
+    String unit = "";
+    if ("toggle".equals(val)) {
+      val = hidden ? "show" : "hide";
+    }
+
+    if (("show".equals(val) && !hidden) || ("hide").equals(val) && hidden) {
+      return null;
+    }
+
+    if (hidden) {
+      g.show();
+    }
+
+    String cur = g.css(key, true);
+    String trsStart = cur, trsEnd = trsStart;
+    
+    if ("show".equals(val)) {
+      g.saveCssAttrs(key);
+      trsStart = "0";
+    } else if ("hide".equals(val)) {
+      if (hidden) {
+        return null;
+      }
+      g.saveCssAttrs(key);
+      trsEnd = "0";
+    } else {
+      MatchResult parts = REGEX_SYMBOL_NUMBER_UNIT.exec(val);
+      if (parts != null) {
+        unit = REGEX_NON_PIXEL_ATTRS.test(key) || Transitions.transformRegex.test(key) ? "" : "px";
+        
+        String $1 = parts.getGroup(1);
+        String $2 = parts.getGroup(2);
+        String $3 = parts.getGroup(3);
+        trsEnd = "" + Double.parseDouble($2);
+        
+        if (unit.isEmpty() && $3 != null) {
+          unit = $3;
+        }
+        if (trsStart.isEmpty()) {
+          trsStart = "0";
+        }
+        
+        if (!trsStart.endsWith(unit)) {
+          trsStart += unit;
+        }
+
+        if ($1 != null && !$1.isEmpty()) {
+          double n = "-=".equals($1) ? -1 : 1;
+          double st = Double.parseDouble(trsStart);
+          double en = Double.parseDouble(trsEnd);
+          trsEnd = "" + (st + (n*en));
+        }
+      } else {
+        trsStart = trsEnd = val;
+      }
+    }
+    return new TransitFx(key, val, trsStart, trsEnd, unit);
+  }
+
+  private Transitions g;
+
+  public TransitionsAnimation(Easing easing, Element elem, Properties p, Function... funcs) {
+    super(easing, elem, p, funcs);
+    g = $(e).as(Transitions.Transitions);
+  }
+
+  private Properties getFxProperties(boolean isStart) {
+    Properties p = $$();
+    for (int i = 0; i < effects.length(); i++) {
+      TransitFx fx = (TransitFx)effects.get(i);
+      p.set(fx.cssprop, (isStart ? fx.transitStart : fx.transitEnd) + fx.unit);
+    }
+    return p;
+  }
+
+  @Override
+  public void onStart() {
+    effects = JsObjectArray.create();
+    boolean resize = false;
+    boolean move = false;
+    boolean hidden = !g.isVisible();
+    Fx fx;
+    for (String key : prps.keys()) {
+      String val = prps.getStr(key);
+      if ((fx = computeFxProp(e, key, val, hidden)) != null) {
+        effects.add(fx);
+        resize = resize || "height".equals(key) || "width".equals(key);
+        move = move || "top".equals(key) || "left".equals(key);
+      }
+      System.out.println(fx);
+    }
+    g.saveCssAttrs(ATTRS_TO_SAVE);
+    if (resize) {
+      g.css("overflow", "hidden");
+    }
+    if (move && !g.css("position", true).matches("absolute|relative|fixed")) {
+      g.css("position", "relative");
+    }
+  }
+
+  @Override
+  public void run(int duration) {
+    onStart();
+    Properties p = getFxProperties(true);
+    System.out.println(p.toJsonString());
+    g.css(p);
+    p = getFxProperties(false);
+    System.out.println(p.toJsonString());
+    g.transition(p, duration - 150, easing, 0, new Function(){public void f() {
+      onComplete();
+    }});
+  }
+}