diff options
author | Ray Cromwell <cromwellian@gmail.com> | 2009-05-06 01:04:40 +0000 |
---|---|---|
committer | Ray Cromwell <cromwellian@gmail.com> | 2009-05-06 01:04:40 +0000 |
commit | d14966331f3de57473e8ff5857e719f26a84dc58 (patch) | |
tree | dfb396a5455665938a3de900c1142636481b9be1 /gwtquery-core/src | |
parent | 2020aa708fca88b683ff19438de72aa08b268d2d (diff) | |
download | gwtquery-d14966331f3de57473e8ff5857e719f26a84dc58.tar.gz gwtquery-d14966331f3de57473e8ff5857e719f26a84dc58.zip |
Effects/Animation work
Diffstat (limited to 'gwtquery-core/src')
3 files changed, 394 insertions, 6 deletions
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/Effects.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/Effects.java index 38c904ea..a15948c7 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/Effects.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/Effects.java @@ -18,6 +18,8 @@ package com.google.gwt.query.client; import com.google.gwt.animation.client.Animation;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NodeList;
+import com.google.gwt.core.client.Duration;
+import com.google.gwt.user.client.Timer;
/**
* Effects plugin for Gwt Query.
@@ -40,6 +42,237 @@ public class Effects extends GQuery { GQuery.registerPlugin(Effects.class, new EffectsPlugin());
}
+ public enum Easing {
+
+ LINEAR {
+ public double ease(double p, double n, double firstNum, double diff) {
+ return firstNum + diff * p;
+ }
+ }, SWING {
+ public double ease(double p, double n, double firstNum, double diff) {
+ return ((-Math.cos(p * Math.PI) / 2) + 0.5) * diff + firstNum;
+ }
+ };
+
+ public abstract double ease(double p, double n, double firstNum,
+ double diff);
+ }
+
+ public enum Speed {
+
+ SLOW(600), FAST(200), DEFAULT(400);
+
+ public int getDuration() {
+ return duration;
+ }
+
+ private final int duration;
+
+ Speed(int dur) {
+ this.duration = dur;
+ }
+ }
+
+ protected class PropFx {
+
+ public SpeedOpts opt;
+
+ public Element elem;
+
+ public String prop;
+
+ private double startTime;
+
+ private double start;
+
+ private double end;
+
+ private String unit;
+
+ private double now;
+
+ private double pos;
+
+ private double state;
+
+ public double cur(boolean force) {
+ if (elem.getPropertyString(prop) != null && (elem.getStyle() == null
+ || elem.getStyle().getProperty(prop) == null)) {
+ return elem.getPropertyDouble(prop);
+ }
+ double r = Double.parseDouble(GQuery.curCSS(elem, prop, force));
+ return !Double.isNaN(r) && r > -10000 ? r
+ : Double.parseDouble(GQuery.curCSS(elem, prop, false));
+ }
+
+ public void show() {
+ opt.cache.put(prop, elem.getStyle().getProperty(prop));
+ opt.show = true;
+ custom("width".equals("width") || "height".equals(prop) ? 1 : 0,
+ cur(false));
+ }
+
+ private boolean step(boolean gotoEnd) {
+ double t = Duration.currentTimeMillis();
+
+ if (gotoEnd || t >= opt.duration + startTime) {
+ now = end;
+ pos = start = 1;
+ update();
+ opt.curAnim.set(prop, "true");
+ boolean done = true;
+ for (String key : opt.curAnim.keys()) {
+ if (!"true".equals(opt.curAnim.get(key))) {
+ done = false;
+ }
+ }
+ if (done) {
+ if (opt.display != null) {
+ elem.getStyle().setProperty("overflow", opt.overflow);
+ elem.getStyle().setProperty("display", opt.display);
+ if ("none".equals(GQuery.curCSS(elem, "display", false))) {
+ elem.getStyle().setProperty("display", "block");
+ }
+ }
+ if (opt.hide) {
+ $(elem).hide();
+ }
+ if (opt.hide || opt.show) {
+ for (String key : opt.curAnim.keys()) {
+ elem.getStyle().setProperty(key, opt.cache.getString(key));
+ }
+ }
+ opt.complete(elem);
+ }
+ return false;
+ } else {
+ double n = t - startTime;
+ state = n / opt.duration;
+ pos = opt.easing.ease(this.state, n, 0, 1);
+ update();
+ return true;
+ }
+ }
+
+ public void update() {
+ (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
+
+ // Set display property to block for height/width animations
+ if ( ( this.prop == "height" || this.prop == "width" ) && this.elem.style )
+ this.elem.style.display = "block";
+ }
+
+ public void hide() {
+ opt.cache.put(prop, elem.getStyle().getProperty(prop));
+ opt.hide = true;
+ custom(cur(false), 0);
+ }
+
+ private void custom(double from, double to) {
+ custom(from, to, "px");
+ }
+
+ private void custom(double from, double to, String unit) {
+ startTime = Duration.currentTimeMillis();
+ start = from;
+ end = to;
+ now = start;
+
+ Timer t = new Timer() {
+ @Override
+ public void run() {
+ step(false);
+ }
+ };
+ }
+ }
+
+ private class SpeedOpts {
+
+ private Properties properties;
+
+ private int duration;
+
+ private Effects.Easing easing;
+
+ private Function complete;
+
+ private boolean queue = true;
+
+ public String display;
+
+ public String overflow;
+
+ public Properties curAnim;
+
+ public boolean hide;
+
+ private GQuery.DataCache cache = DataCache.createObject().cast();
+
+ public boolean show;
+
+ public boolean isQueue() {
+ return queue;
+ }
+
+ public void setQueue(boolean queue) {
+ this.queue = queue;
+ }
+
+ protected SpeedOpts(int speed, Easing easing, Function complete) {
+ this.complete = complete;
+ this.easing = easing;
+ this.duration = speed;
+ }
+
+ public Function getComplete() {
+ return complete;
+ }
+
+ public void setComplete(Function complete) {
+ this.complete = complete;
+ }
+
+ public int getDuration() {
+ return duration;
+ }
+
+ public void setDuration(int duration) {
+ this.duration = duration;
+ }
+
+ public Easing getEasing() {
+ return easing;
+ }
+
+ public void setEasing(Easing easing) {
+ this.easing = easing;
+ }
+
+ public Properties getProperties() {
+ return properties;
+ }
+
+ public void setProperties(Properties properties) {
+ this.properties = properties;
+ }
+
+ protected SpeedOpts(Speed speed, Easing easing, Function complete) {
+ this.complete = complete;
+ this.easing = easing;
+ this.duration = speed.getDuration();
+ }
+
+ public void complete(Element elem) {
+ if (queue) {
+ $(elem).dequeue();
+ }
+ if (complete != null) {
+ complete.f(elem);
+ }
+ }
+ }
+
public Effects(Element element) {
super(element);
}
@@ -52,6 +285,115 @@ public class Effects extends GQuery { super(list);
}
+ public Effects animate(final Properties properties, final Speed speed,
+ final Easing easing, final Function complete) {
+ if (properties.get("queue") != null) {
+ queue(new Function() {
+ final SpeedOpts optall = new SpeedOpts(speed, easing, complete);
+
+ @Override
+ public void f(Element e) {
+ boolean hidden = !$(e).visible();
+ for (String key : properties.keys()) {
+ String prop = properties.get(key);
+ if ("hide".equals(prop) && hidden
+ || "show".equals(prop) && !hidden) {
+ optall.complete(e);
+ return;
+ }
+ if ("height".equals(key)
+ || "width".equals(key) && e.getStyle() != null) {
+ optall.display = $(e).css("display");
+ optall.overflow = e.getStyle().getProperty("overflow");
+ }
+ }
+ if (optall.overflow != null) {
+ e.getStyle().setProperty("overflow", "hidden");
+ }
+ optall.curAnim = properties.cloneProps();
+ for (String key : properties.keys()) {
+ PropFx fx = new PropFx();
+ String val = properties.get(key);
+ fx.elem = e;
+ fx.opt = optall;
+ fx.prop = key;
+ if ("toggle".equals(val)) {
+ if (hidden) {
+ fx.show();
+ } else {
+ fx.hide();
+ }
+ } else if ("show".equals(val)) {
+ fx.show();
+ } else if ("hide".equals(val)) {
+ fx.hide();
+ } else {
+ JSArray parts = new Regexp("^([+-]=)?([0-9+-.]+)(.*)$")
+ .match(val);
+ double start = fx.cur(true);
+
+ if (parts != null) {
+ double end = Double.parseDouble(parts.getStr(2));
+ String unit = parts.getStr(3);
+ if (unit == null) {
+ unit = "px";
+ }
+ if (!"px".equals(unit)) {
+ e.getStyle().setProperty(key, (end != 0 ? end : 1) + unit);
+ start = (end != 0 ? end : 1) / fx.cur(true) * start;
+ e.getStyle().setProperty(key, start + unit);
+ }
+ if (parts.getStr(1) != null) {
+ end = (("-=".equals(parts.getStr(1)) ? -1 : 1) * end) + start;
+ }
+ fx.custom(start, end, unit);
+ } else {
+ fx.custom(start, Double.parseDouble(val), "");
+ }
+ }
+ }
+ }
+ });
+ }
+ return this;
+ }
+
+// jQuery.each( prop, function(name, val){
+// var e = new jQuery.fx( self, opt, name );
+//
+// if ( /toggle|show|hide/.test(val) )
+// e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
+// else {
+// var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
+// start = e.cur(true) || 0;
+//
+// if ( parts ) {
+// var end = parseFloat(parts[2]),
+// unit = parts[3] || "px";
+//
+// // We need to compute starting value
+// if ( unit != "px" ) {
+// self.style[ name ] = (end || 1) + unit;
+// start = ((end || 1) / e.cur(true)) * start;
+// self.style[ name ] = start + unit;
+// }
+//
+// // If a +=/-= token was provided, we're doing a relative animation
+// if ( parts[1] )
+// end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
+//
+// e.custom( start, end, unit );
+// } else
+// e.custom( start, val, "" );
+// }
+// });
+//
+// // For JS strict compliance
+// return true;
+// });
+// },
+// }
+
public Effects fadeIn() {
Animation a = new Animation() {
@@ -103,12 +445,40 @@ public class Effects extends GQuery { }
public Effects hide() {
- this.css("display", "none");
+ for (Element e : elements()) {
+ GQuery q = $(e);
+ String old = (String) q.data("olddisplay");
+ if (old != null && !"none".equals(old)) {
+ q.data("olddisplay", GQuery.curCSS(e, "display", false));
+ e.getStyle().setProperty("display", "none");
+ }
+ }
return this;
}
+ private DataCache elemDisplay = DataCache.createObject().cast();
+
public Effects show() {
- this.css("display", "");
+ for (Element e : elements()) {
+ GQuery q = $(e);
+ String old = (String) q.data("olddisplay");
+ e.getStyle().setProperty("display", SelectorEngine.or(old, ""));
+ if ("none".equals(GQuery.curCSS(e, "display", false))) {
+ String tagName = e.getTagName();
+ String display = "";
+ if (elemDisplay.getString(tagName) != null) {
+ display = elemDisplay.getString(tagName);
+ } else {
+ Element elem = $("<" + tagName + ">").appendTo($("body")).get(0);
+ display = GQuery.curCSS(elem, "display", false);
+ if ("none".equals(display)) {
+ display = "block";
+ }
+ }
+ e.getStyle().setProperty("display", display);
+ q.data("olddisplay", display);
+ }
+ }
return this;
}
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java index 574ab8c7..2c9c354e 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java @@ -62,7 +62,7 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> { }
}
- private static final class DataCache extends JavaScriptObject {
+ static final class DataCache extends JavaScriptObject {
protected DataCache() {
}
@@ -375,12 +375,18 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> { }
private static String curCSS(Element elem, String name) {
+ return curCSS(elem, name, false);
+ }
+
+ public static String curCSS(Element elem, String name, boolean force) {
Style s = elem.getStyle();
ensureStyleImpl();
- name = styleImpl.getPropertyName(name);
+ if (!force) {
+ name = styleImpl.getPropertyName(name);
- if (SelectorEngine.truth(s.getProperty(name))) {
- return s.getProperty(name);
+ if (SelectorEngine.truth(s.getProperty(name))) {
+ return s.getProperty(name);
+ }
}
return styleImpl.getCurrentStyle(elem, name);
}
@@ -760,6 +766,7 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> { // return this;
// }
+
/**
* Return a style property on the first matched element.
*/
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/Properties.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/Properties.java index ab14f610..56e24a7b 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/Properties.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/Properties.java @@ -63,4 +63,15 @@ public class Properties extends JavaScriptObject { }
return keys;
}-*/;
+
+ public native Properties cloneProps() /*-{
+ var props = {};
+ for(p in this) {
+ props[p] = this[p];
+ }
+ }-*/;
+
+ public native void set(String key, String val) /*-{
+ this[key]=val;
+ }-*/;
}
|