*/
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.
*/
*/
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;
}
}
- 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");
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
@Override
protected double interpolate(double progress) {
- if (easing != null) {
- return easing.interpolate(progress);
- }
- // maybe return super.interpolate() instead ?
- return progress;
+ return easing.interpolate(progress);
}
}
.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>
*/
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");
}
/**
- * 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);
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);
}
+
}
--- /dev/null
+/*
+ * 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();
+ }});
+ }
+}