]> source.dussan.org Git - gwtquery.git/commitdiff
Implement animation Easing based on Bezier curves instead of using different algorith...
authorManuel Carrasco Moñino <manuel.carrasco.m@gmail.com>
Fri, 1 Nov 2013 12:49:53 +0000 (13:49 +0100)
committerManuel Carrasco Moñino <manuel.carrasco.m@gmail.com>
Fri, 1 Nov 2013 12:49:53 +0000 (13:49 +0100)
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Effects.java
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/Bezier.java [new file with mode: 0644]
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/widgets/TextBoxBaseWidgetFactory.java
gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEffectsTestGwt.java

index 7112f4c62abf30ebaa6636147cc6874f8aa8b684..44deecb5022bc3c232509098b14879367ac902b2 100755 (executable)
@@ -26,6 +26,7 @@ import com.google.gwt.query.client.plugins.effects.ClipAnimation.Direction;
 import com.google.gwt.query.client.plugins.effects.Fx;
 import com.google.gwt.query.client.plugins.effects.PropertiesAnimation;
 import com.google.gwt.query.client.plugins.effects.PropertiesAnimation.Easing;
+import com.google.gwt.query.client.plugins.effects.PropertiesAnimation.EasingCurve;
 
 /**
  * Effects plugin for Gwt Query.
@@ -119,9 +120,9 @@ public class Effects extends QueuePlugin<Effects> {
    * <pre class="code">
    *  //move the element from its original position to the position top:500px and left:500px for 400ms.
    *  //use a swing easing function for the transition
-   *  $("#foo").animate(Properties.create("{top:'500px',left:'500px'}"), 400, Easing.SWING);
+   *  $("#foo").animate(Properties.create("{top:'500px',left:'500px'}"), 400, EasingCurve.swing);
    *  // Change the width and border attributes of a table
-   *  $("table").animate(Properties.create("{$width: '500', $border: '10'}"), 400, Easing.LINEAR);
+   *  $("table").animate(Properties.create("{$width: '500', $border: '10'}"), 400, EasingCurve.linear);
    * </pre>
    *
    * In addition to numeric values, each property can take the strings 'show',
@@ -145,8 +146,8 @@ public class Effects extends QueuePlugin<Effects> {
    * Example:
    *
    * <pre class="code">
-   *  $("#foo").animate("backgroundColor:'red', color:'#ffffff', borderColor:'rgb(129, 0, 70)'", 400, Easing.SWING);
-   *  $("#foo").animate($$("{backgroundColor:'red', color:'#ffffff', borderColor:'rgb(129, 0, 70)'}"), 400, Easing.SWING);
+   *  $("#foo").animate("backgroundColor:'red', color:'#ffffff', borderColor:'rgb(129, 0, 70)'", 400, EasingCurve.swing);
+   *  $("#foo").animate($$("{backgroundColor:'red', color:'#ffffff', borderColor:'rgb(129, 0, 70)'}"), 400, EasingCurve.swing);
    * </pre>
    *
    * @param p a {@link Properties} object containing css properties to animate.
@@ -185,7 +186,7 @@ public class Effects extends QueuePlugin<Effects> {
    *  //move the element from its original position to left:500px for 500ms
    *  $("#foo").animate("left:'500'");
    *  // Change the width attribute of a table
-   *  $("table").animate("$width:'500'"), 400, Easing.LINEAR);
+   *  $("table").animate("$width:'500'"), 400, EasingCurve.swing);
    * </pre>
    *
    * In addition to numeric values, each property can take the strings 'show',
@@ -284,7 +285,7 @@ public class Effects extends QueuePlugin<Effects> {
    * @param duration the duration in milliseconds of the animation
    */
   public Effects animate(Object stringOrProperties, int duration, Function... funcs) {
-    return animate(stringOrProperties, duration, Easing.LINEAR, funcs);
+    return animate(stringOrProperties, duration, EasingCurve.linear, funcs);
   }
 
   /**
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/Bezier.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/Bezier.java
new file mode 100644 (file)
index 0000000..7b098a6
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * 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;
+
+
+/**
+ * Bezier curve for transition easing functions.
+ * 
+ * Inspired in KeySpline.js from Gaetan Renaudeau [1] which
+ * is based in nsSMILKeySpline.cpp from mozilla.
+ * 
+ * [1] https://gist.github.com/gre/1926947
+ * [2] http://dxr.mozilla.org/mozilla-central/source/content/smil/nsSMILKeySpline.cpp
+ */
+public class Bezier {
+                  
+  private double x1, y1 , x2, y2;
+  
+  public Bezier(double x1, double y1, double x2, double y2) {
+    this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2;
+  }
+  
+  private double A(double a1, double a2) {
+    return 1.0 - 3.0 * a2 + 3.0 * a1;
+  }
+  private double B(double a1, double a2) {
+    return 3.0 * a2 - 6.0 * a1;
+  }
+  private double C(double a1){
+    return 3.0 * a1;
+  }
+  
+  private double calcBezier(double t, double a1, double a2) {
+    return ((A(a1, a2)*t + B(a1, a2))*t + C(a1))*t;
+  }
+  
+  private double calcSlope(double t, double a1, double a2) {
+    return 3.0 * A(a1, a2)*t*t + 2.0 * B(a1, a2) * t + C(a1);
+  }
+  
+  private double getTForX(double x) {
+    double t = x;
+    for (double i = 0; i < 4; ++i) {
+      double currentSlope = calcSlope(t, x1, x2);
+      if (currentSlope == 0.0) return t;
+      double currentX = calcBezier(t, x1, x2) - x;
+      t -= currentX / currentSlope;
+    }
+    return t;
+  }
+  
+  public double f (double x) {
+    return calcBezier(getTForX(x), y1, y2);
+  }
+  
+  public String toString() {
+    return x1 + "," + y1 + "," + x2 + "," + y2;
+  }
+
+}
index 92386f5e766618bd1429c76c06945eea79ae904b..acd2c127b5827b0476c0b1f94f86306be5d2a89e 100755 (executable)
@@ -36,19 +36,90 @@ public class PropertiesAnimation extends GQAnimation {
    */
   public static interface Easing {
     public double interpolate(double progress);
-
-    public Easing LINEAR = new Easing() {
-      public double interpolate(double progress) {
-        return progress;
-      }
-    };
-
-    public Easing SWING = new Easing() {
-      public double interpolate(double progress) {
-        return (1 + Math.cos(Math.PI + progress * Math.PI)) / 2;
-      }
-    };
+    /**
+     * @deprecated use EasingCurve.linear instead
+     */
+    public Easing LINEAR = EasingCurve.linear;
+
+    /**
+     * @deprecated use EasingCurve.swing instead
+     */
+    public Easing SWING = EasingCurve.swing;
   }
+  
+  /**
+   * This is a collection of most popular curves used in web animations
+   * implemented using Bezier Curve instead of a different formula per
+   * animation. 
+   * 
+   * The toString() method returns the string parameter which can be used
+   * for CSS3 transition-timing-function properties, example:
+   * <pre>
+
+   transition-timing-function: ease;
+   transition-timing-function: cubic-bezier(0, 0, 1, 1);
+     
+   * </pre>
+   */
+  public static enum EasingCurve implements Easing {
+      linear (0, 0, 1, 1) {
+        public double interpolate(double p){return p;}
+        public String toString() {return "linear";}
+      },
+      ease (0.25, 0.1, 0.25, 1) {
+        public String toString() {return "ease";}
+      },
+      easeIn (0.42, 0, 1, 1) {
+        public String toString() {return "ease-in";}
+      },
+      easeOut (0, 0, 0.58, 1) {
+        public String toString() {return "ease-out";}
+      },
+      easeInOut (0.42, 0, 0.58, 1) {
+        public String toString() {return "ease-in-out";}
+      },
+      snap (0,1,.5,1),
+      swing (.02,.01,.47,1),
+      easeInCubic (.550,.055,.675,.190),
+      easeOutCubic (.215,.61,.355,1),
+      easeInOutCubic (.645,.045,.355,1),
+      easeInCirc (.6,.04,.98,.335),
+      easeOutCirc (.075,.82,.165,1),
+      easeInOutCirc (.785,.135,.15,.86),
+      easeInExpo (.95,.05,.795,.035),
+      easeOutExpo (.19,1,.22,1),
+      easeInOutExpo (1,0,0,1),
+      easeInQuad (.55,.085,.68,.53),
+      easeOutQuad (.25,.46,.45,.94),
+      easeInOutQuad (.455,.03,.515,.955),
+      easeInQuart (.895,.03,.685,.22),
+      easeOutQuart (.165,.84,.44,1),
+      easeInOutQuart (.77,0,.175,1),
+      easeInQuint (.755,.05,.855,.06),
+      easeOutQuint (.23,1,.32,1),
+      easeInOutQuint (.86,0,.07,1),
+      easeInSine (.47,0,.745,.715),
+      easeOutSine (.39,.575,.565,1),
+      easeInOutSine (.445,.05,.55,.95),
+      easeInBack (.6,-.28,.735,.045),
+      easeOutBack (.175, .885,.32,1.275),
+      easeInOutBack (.68,-.55,.265,1.55),
+      custom(0, 0, 1, 1);
+     
+     private Bezier c = new Bezier(0, 0, 1, 1);
+     EasingCurve(double x1, double y1, double x2, double y2) {
+       with(x1, y1, x2, y2);
+     }
+     public void with(double x1, double y1, double x2, double y2) {
+       c = new Bezier(x1, y1, x2, y2);
+     }
+     public double interpolate(double progress) {
+       return c.f(progress);
+     }
+     public String toString() {
+      return "cubic-bezier(" + c + ")";
+     }
+   }
 
   private static final String[] ATTRS_TO_SAVE = new String[]{
       "overflow"};
@@ -190,7 +261,7 @@ public class PropertiesAnimation extends GQAnimation {
     return new Fx(key, val, start, end, unit, rkey);
   }
 
-  private Easing easing = Easing.SWING;
+  private Easing easing = EasingCurve.linear;
   private JsObjectArray<Fx> effects = JsObjectArray.create();
   private Function[] funcs;
 
index a3190a956ab192c5a9c58abbd1c1c59e581b03c4..9a7f22eb3d3b6428119b4851f492f8be092ff50c 100644 (file)
@@ -17,7 +17,6 @@ package com.google.gwt.query.client.plugins.widgets;
 
 import com.google.gwt.dom.client.Element;
 import com.google.gwt.dom.client.InputElement;
-import com.google.gwt.query.client.GQuery;
 import com.google.gwt.user.client.ui.TextBoxBase;
 
 /**
index 2dcefa3ae32362c25219ddf85bd010edcd0ac129..8cf497db3c411ec47cd710d429955e24347475ea 100644 (file)
 package com.google.gwt.query.client;
 
 import static com.google.gwt.query.client.GQuery.*;
+
 import com.google.gwt.core.client.Scheduler;
 import com.google.gwt.core.client.Scheduler.RepeatingCommand;
 import com.google.gwt.dom.client.Element;
 import com.google.gwt.junit.client.GWTTestCase;
 import com.google.gwt.query.client.GQuery.Offset;
-import com.google.gwt.query.client.plugins.effects.Bezier.EasingCurve;
 import com.google.gwt.query.client.plugins.effects.Fx.ColorFx;
 import com.google.gwt.query.client.plugins.effects.PropertiesAnimation;
-import com.google.gwt.query.client.plugins.effects.PropertiesAnimation.Easing;
+import com.google.gwt.query.client.plugins.effects.PropertiesAnimation.EasingCurve;
 import com.google.gwt.user.client.Timer;
 import com.google.gwt.user.client.ui.HTML;
 import com.google.gwt.user.client.ui.Label;
@@ -118,10 +118,10 @@ public class GQueryEffectsTestGwt extends GWTTestCase {
 
     final int duration = 1000;
     g.as(Effects).
-        animate($$("left: '+=100'"), duration, Easing.LINEAR).
-        animate($$("top: '+=100'"), duration, Easing.LINEAR).
-        animate($$("left: '-=100'"), duration, Easing.LINEAR).
-        animate($$("top: '-=100'"), duration, Easing.LINEAR);
+        animate($$("left: '+=100'"), duration, EasingCurve.linear).
+        animate($$("top: '+=100'"), duration, EasingCurve.linear).
+        animate($$("left: '-=100'"), duration, EasingCurve.linear).
+        animate($$("top: '-=100'"), duration, EasingCurve.linear);
 
     // Configure the max duration for this test
     delayTestFinish(duration * 4);
@@ -246,7 +246,7 @@ public class GQueryEffectsTestGwt extends GWTTestCase {
             .toString());
 
     prop1 = GQuery.$$("marginTop: '-110px', marginLeft: '-110px', top: '50%', left: '50%', width: '174px', height: '174px', padding: '20px'");
-    PropertiesAnimation an = new PropertiesAnimation(EasingCurve.SWING, g.get(0), prop1);
+    PropertiesAnimation an = new PropertiesAnimation(EasingCurve.swing, g.get(0), prop1);
     an.onStart();
     an.onComplete();
 
@@ -272,7 +272,7 @@ public class GQueryEffectsTestGwt extends GWTTestCase {
             .toString());
 
     prop1 = GQuery.$$("marginTop: '0', marginLeft: '0', top: '0%', left: '0%', width: '100px', height: '100px', padding: '5px'");
-    an = new PropertiesAnimation(Easing.SWING, g.get(0), prop1);
+    an = new PropertiesAnimation(EasingCurve.swing, g.get(0), prop1);
     an.onStart();
     an.onComplete();
 
@@ -358,7 +358,7 @@ public class GQueryEffectsTestGwt extends GWTTestCase {
     delayTestFinish(duration * 3);
 
     g.as(Effects).
-        animate($$("$width: +=100; $border: +=4"), duration, Easing.LINEAR);
+        animate($$("$width: +=100; $border: +=4"), duration, EasingCurve.linear);
 
     final Timer timer = new Timer() {
       public void run() {