import com.google.gwt.animation.client.Animation;\r
import com.google.gwt.dom.client.Element;\r
import com.google.gwt.dom.client.NodeList;\r
+import com.google.gwt.core.client.Duration;\r
+import com.google.gwt.user.client.Timer;\r
\r
/**\r
* Effects plugin for Gwt Query.\r
GQuery.registerPlugin(Effects.class, new EffectsPlugin());\r
}\r
\r
+ public enum Easing {\r
+\r
+ LINEAR {\r
+ public double ease(double p, double n, double firstNum, double diff) {\r
+ return firstNum + diff * p;\r
+ }\r
+ }, SWING {\r
+ public double ease(double p, double n, double firstNum, double diff) {\r
+ return ((-Math.cos(p * Math.PI) / 2) + 0.5) * diff + firstNum;\r
+ }\r
+ };\r
+\r
+ public abstract double ease(double p, double n, double firstNum,\r
+ double diff);\r
+ }\r
+\r
+ public enum Speed {\r
+\r
+ SLOW(600), FAST(200), DEFAULT(400);\r
+\r
+ public int getDuration() {\r
+ return duration;\r
+ }\r
+\r
+ private final int duration;\r
+\r
+ Speed(int dur) {\r
+ this.duration = dur;\r
+ }\r
+ }\r
+\r
+ protected class PropFx {\r
+\r
+ public SpeedOpts opt;\r
+\r
+ public Element elem;\r
+\r
+ public String prop;\r
+\r
+ private double startTime;\r
+\r
+ private double start;\r
+\r
+ private double end;\r
+\r
+ private String unit;\r
+\r
+ private double now;\r
+\r
+ private double pos;\r
+\r
+ private double state;\r
+\r
+ public double cur(boolean force) {\r
+ if (elem.getPropertyString(prop) != null && (elem.getStyle() == null\r
+ || elem.getStyle().getProperty(prop) == null)) {\r
+ return elem.getPropertyDouble(prop);\r
+ }\r
+ double r = Double.parseDouble(GQuery.curCSS(elem, prop, force));\r
+ return !Double.isNaN(r) && r > -10000 ? r\r
+ : Double.parseDouble(GQuery.curCSS(elem, prop, false));\r
+ }\r
+\r
+ public void show() {\r
+ opt.cache.put(prop, elem.getStyle().getProperty(prop));\r
+ opt.show = true;\r
+ custom("width".equals("width") || "height".equals(prop) ? 1 : 0,\r
+ cur(false));\r
+ }\r
+\r
+ private boolean step(boolean gotoEnd) {\r
+ double t = Duration.currentTimeMillis();\r
+\r
+ if (gotoEnd || t >= opt.duration + startTime) {\r
+ now = end;\r
+ pos = start = 1;\r
+ update();\r
+ opt.curAnim.set(prop, "true");\r
+ boolean done = true;\r
+ for (String key : opt.curAnim.keys()) {\r
+ if (!"true".equals(opt.curAnim.get(key))) {\r
+ done = false;\r
+ }\r
+ }\r
+ if (done) {\r
+ if (opt.display != null) {\r
+ elem.getStyle().setProperty("overflow", opt.overflow);\r
+ elem.getStyle().setProperty("display", opt.display);\r
+ if ("none".equals(GQuery.curCSS(elem, "display", false))) {\r
+ elem.getStyle().setProperty("display", "block");\r
+ }\r
+ }\r
+ if (opt.hide) {\r
+ $(elem).hide();\r
+ }\r
+ if (opt.hide || opt.show) {\r
+ for (String key : opt.curAnim.keys()) {\r
+ elem.getStyle().setProperty(key, opt.cache.getString(key));\r
+ }\r
+ }\r
+ opt.complete(elem);\r
+ }\r
+ return false;\r
+ } else {\r
+ double n = t - startTime;\r
+ state = n / opt.duration;\r
+ pos = opt.easing.ease(this.state, n, 0, 1);\r
+ update();\r
+ return true;\r
+ }\r
+ }\r
+\r
+ public void update() {\r
+ (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );\r
+\r
+ // Set display property to block for height/width animations\r
+ if ( ( this.prop == "height" || this.prop == "width" ) && this.elem.style )\r
+ this.elem.style.display = "block";\r
+ }\r
+\r
+ public void hide() {\r
+ opt.cache.put(prop, elem.getStyle().getProperty(prop));\r
+ opt.hide = true;\r
+ custom(cur(false), 0);\r
+ }\r
+\r
+ private void custom(double from, double to) {\r
+ custom(from, to, "px");\r
+ }\r
+\r
+ private void custom(double from, double to, String unit) {\r
+ startTime = Duration.currentTimeMillis();\r
+ start = from;\r
+ end = to;\r
+ now = start;\r
+\r
+ Timer t = new Timer() {\r
+ @Override\r
+ public void run() {\r
+ step(false);\r
+ }\r
+ };\r
+ }\r
+ }\r
+\r
+ private class SpeedOpts {\r
+\r
+ private Properties properties;\r
+\r
+ private int duration;\r
+\r
+ private Effects.Easing easing;\r
+\r
+ private Function complete;\r
+\r
+ private boolean queue = true;\r
+\r
+ public String display;\r
+\r
+ public String overflow;\r
+\r
+ public Properties curAnim;\r
+\r
+ public boolean hide;\r
+\r
+ private GQuery.DataCache cache = DataCache.createObject().cast();\r
+\r
+ public boolean show;\r
+\r
+ public boolean isQueue() {\r
+ return queue;\r
+ }\r
+\r
+ public void setQueue(boolean queue) {\r
+ this.queue = queue;\r
+ }\r
+\r
+ protected SpeedOpts(int speed, Easing easing, Function complete) {\r
+ this.complete = complete;\r
+ this.easing = easing;\r
+ this.duration = speed;\r
+ }\r
+\r
+ public Function getComplete() {\r
+ return complete;\r
+ }\r
+\r
+ public void setComplete(Function complete) {\r
+ this.complete = complete;\r
+ }\r
+\r
+ public int getDuration() {\r
+ return duration;\r
+ }\r
+\r
+ public void setDuration(int duration) {\r
+ this.duration = duration;\r
+ }\r
+\r
+ public Easing getEasing() {\r
+ return easing;\r
+ }\r
+\r
+ public void setEasing(Easing easing) {\r
+ this.easing = easing;\r
+ }\r
+\r
+ public Properties getProperties() {\r
+ return properties;\r
+ }\r
+\r
+ public void setProperties(Properties properties) {\r
+ this.properties = properties;\r
+ }\r
+\r
+ protected SpeedOpts(Speed speed, Easing easing, Function complete) {\r
+ this.complete = complete;\r
+ this.easing = easing;\r
+ this.duration = speed.getDuration();\r
+ }\r
+\r
+ public void complete(Element elem) {\r
+ if (queue) {\r
+ $(elem).dequeue();\r
+ }\r
+ if (complete != null) {\r
+ complete.f(elem);\r
+ }\r
+ }\r
+ }\r
+\r
public Effects(Element element) {\r
super(element);\r
}\r
super(list);\r
}\r
\r
+ public Effects animate(final Properties properties, final Speed speed,\r
+ final Easing easing, final Function complete) {\r
+ if (properties.get("queue") != null) {\r
+ queue(new Function() {\r
+ final SpeedOpts optall = new SpeedOpts(speed, easing, complete);\r
+\r
+ @Override\r
+ public void f(Element e) {\r
+ boolean hidden = !$(e).visible();\r
+ for (String key : properties.keys()) {\r
+ String prop = properties.get(key);\r
+ if ("hide".equals(prop) && hidden\r
+ || "show".equals(prop) && !hidden) {\r
+ optall.complete(e);\r
+ return;\r
+ }\r
+ if ("height".equals(key)\r
+ || "width".equals(key) && e.getStyle() != null) {\r
+ optall.display = $(e).css("display");\r
+ optall.overflow = e.getStyle().getProperty("overflow");\r
+ }\r
+ }\r
+ if (optall.overflow != null) {\r
+ e.getStyle().setProperty("overflow", "hidden");\r
+ }\r
+ optall.curAnim = properties.cloneProps();\r
+ for (String key : properties.keys()) {\r
+ PropFx fx = new PropFx();\r
+ String val = properties.get(key);\r
+ fx.elem = e;\r
+ fx.opt = optall;\r
+ fx.prop = key;\r
+ if ("toggle".equals(val)) {\r
+ if (hidden) {\r
+ fx.show();\r
+ } else {\r
+ fx.hide();\r
+ }\r
+ } else if ("show".equals(val)) {\r
+ fx.show();\r
+ } else if ("hide".equals(val)) {\r
+ fx.hide();\r
+ } else {\r
+ JSArray parts = new Regexp("^([+-]=)?([0-9+-.]+)(.*)$")\r
+ .match(val);\r
+ double start = fx.cur(true);\r
+\r
+ if (parts != null) {\r
+ double end = Double.parseDouble(parts.getStr(2));\r
+ String unit = parts.getStr(3);\r
+ if (unit == null) {\r
+ unit = "px";\r
+ }\r
+ if (!"px".equals(unit)) {\r
+ e.getStyle().setProperty(key, (end != 0 ? end : 1) + unit);\r
+ start = (end != 0 ? end : 1) / fx.cur(true) * start;\r
+ e.getStyle().setProperty(key, start + unit);\r
+ }\r
+ if (parts.getStr(1) != null) {\r
+ end = (("-=".equals(parts.getStr(1)) ? -1 : 1) * end) + start;\r
+ }\r
+ fx.custom(start, end, unit);\r
+ } else {\r
+ fx.custom(start, Double.parseDouble(val), "");\r
+ }\r
+ }\r
+ }\r
+ }\r
+ });\r
+ }\r
+ return this;\r
+ }\r
+\r
+// jQuery.each( prop, function(name, val){\r
+// var e = new jQuery.fx( self, opt, name );\r
+//\r
+// if ( /toggle|show|hide/.test(val) )\r
+// e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );\r
+// else {\r
+// var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),\r
+// start = e.cur(true) || 0;\r
+//\r
+// if ( parts ) {\r
+// var end = parseFloat(parts[2]),\r
+// unit = parts[3] || "px";\r
+//\r
+// // We need to compute starting value\r
+// if ( unit != "px" ) {\r
+// self.style[ name ] = (end || 1) + unit;\r
+// start = ((end || 1) / e.cur(true)) * start;\r
+// self.style[ name ] = start + unit;\r
+// }\r
+//\r
+// // If a +=/-= token was provided, we're doing a relative animation\r
+// if ( parts[1] )\r
+// end = ((parts[1] == "-=" ? -1 : 1) * end) + start;\r
+//\r
+// e.custom( start, end, unit );\r
+// } else\r
+// e.custom( start, val, "" );\r
+// }\r
+// });\r
+//\r
+// // For JS strict compliance\r
+// return true;\r
+// });\r
+// }, \r
+// }\r
+\r
public Effects fadeIn() {\r
Animation a = new Animation() {\r
\r
}\r
\r
public Effects hide() {\r
- this.css("display", "none");\r
+ for (Element e : elements()) {\r
+ GQuery q = $(e);\r
+ String old = (String) q.data("olddisplay");\r
+ if (old != null && !"none".equals(old)) {\r
+ q.data("olddisplay", GQuery.curCSS(e, "display", false));\r
+ e.getStyle().setProperty("display", "none");\r
+ }\r
+ }\r
return this;\r
}\r
\r
+ private DataCache elemDisplay = DataCache.createObject().cast();\r
+\r
public Effects show() {\r
- this.css("display", "");\r
+ for (Element e : elements()) {\r
+ GQuery q = $(e);\r
+ String old = (String) q.data("olddisplay");\r
+ e.getStyle().setProperty("display", SelectorEngine.or(old, ""));\r
+ if ("none".equals(GQuery.curCSS(e, "display", false))) {\r
+ String tagName = e.getTagName();\r
+ String display = "";\r
+ if (elemDisplay.getString(tagName) != null) {\r
+ display = elemDisplay.getString(tagName);\r
+ } else {\r
+ Element elem = $("<" + tagName + ">").appendTo($("body")).get(0);\r
+ display = GQuery.curCSS(elem, "display", false);\r
+ if ("none".equals(display)) {\r
+ display = "block";\r
+ }\r
+ }\r
+ e.getStyle().setProperty("display", display);\r
+ q.data("olddisplay", display);\r
+ }\r
+ }\r
return this;\r
}\r
\r