fx.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*
  2. Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
  3. Available via Academic Free License >= 2.1 OR the modified BSD license.
  4. see: http://dojotoolkit.org/license for details
  5. */
  6. if(!dojo._hasResource["dojox.gfx.fx"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojox.gfx.fx"] = true;
  8. dojo.provide("dojox.gfx.fx");
  9. dojo.require("dojox.gfx.matrix");
  10. (function(){
  11. var d = dojo, g = dojox.gfx, m = g.matrix;
  12. // Generic interpolators. Should they be moved to dojox.fx?
  13. function InterpolNumber(start, end){
  14. this.start = start, this.end = end;
  15. }
  16. InterpolNumber.prototype.getValue = function(r){
  17. return (this.end - this.start) * r + this.start;
  18. };
  19. function InterpolUnit(start, end, units){
  20. this.start = start, this.end = end;
  21. this.units = units;
  22. }
  23. InterpolUnit.prototype.getValue = function(r){
  24. return (this.end - this.start) * r + this.start + this.units;
  25. };
  26. function InterpolColor(start, end){
  27. this.start = start, this.end = end;
  28. this.temp = new dojo.Color();
  29. }
  30. InterpolColor.prototype.getValue = function(r){
  31. return d.blendColors(this.start, this.end, r, this.temp);
  32. };
  33. function InterpolValues(values){
  34. this.values = values;
  35. this.length = values.length;
  36. }
  37. InterpolValues.prototype.getValue = function(r){
  38. return this.values[Math.min(Math.floor(r * this.length), this.length - 1)];
  39. };
  40. function InterpolObject(values, def){
  41. this.values = values;
  42. this.def = def ? def : {};
  43. }
  44. InterpolObject.prototype.getValue = function(r){
  45. var ret = dojo.clone(this.def);
  46. for(var i in this.values){
  47. ret[i] = this.values[i].getValue(r);
  48. }
  49. return ret;
  50. };
  51. function InterpolTransform(stack, original){
  52. this.stack = stack;
  53. this.original = original;
  54. }
  55. InterpolTransform.prototype.getValue = function(r){
  56. var ret = [];
  57. dojo.forEach(this.stack, function(t){
  58. if(t instanceof m.Matrix2D){
  59. ret.push(t);
  60. return;
  61. }
  62. if(t.name == "original" && this.original){
  63. ret.push(this.original);
  64. return;
  65. }
  66. if(!(t.name in m)){ return; }
  67. var f = m[t.name];
  68. if(typeof f != "function"){
  69. // constant
  70. ret.push(f);
  71. return;
  72. }
  73. var val = dojo.map(t.start, function(v, i){
  74. return (t.end[i] - v) * r + v;
  75. }),
  76. matrix = f.apply(m, val);
  77. if(matrix instanceof m.Matrix2D){
  78. ret.push(matrix);
  79. }
  80. }, this);
  81. return ret;
  82. };
  83. var transparent = new d.Color(0, 0, 0, 0);
  84. function getColorInterpol(prop, obj, name, def){
  85. if(prop.values){
  86. return new InterpolValues(prop.values);
  87. }
  88. var value, start, end;
  89. if(prop.start){
  90. start = g.normalizeColor(prop.start);
  91. }else{
  92. start = value = obj ? (name ? obj[name] : obj) : def;
  93. }
  94. if(prop.end){
  95. end = g.normalizeColor(prop.end);
  96. }else{
  97. if(!value){
  98. value = obj ? (name ? obj[name] : obj) : def;
  99. }
  100. end = value;
  101. }
  102. return new InterpolColor(start, end);
  103. }
  104. function getNumberInterpol(prop, obj, name, def){
  105. if(prop.values){
  106. return new InterpolValues(prop.values);
  107. }
  108. var value, start, end;
  109. if(prop.start){
  110. start = prop.start;
  111. }else{
  112. start = value = obj ? obj[name] : def;
  113. }
  114. if(prop.end){
  115. end = prop.end;
  116. }else{
  117. if(typeof value != "number"){
  118. value = obj ? obj[name] : def;
  119. }
  120. end = value;
  121. }
  122. return new InterpolNumber(start, end);
  123. }
  124. g.fx.animateStroke = function(/*Object*/ args){
  125. // summary:
  126. // Returns an animation which will change stroke properties over time
  127. // example:
  128. // | dojox.gfx.fx.animateStroke{{
  129. // | shape: shape,
  130. // | duration: 500,
  131. // | color: {start: "red", end: "green"},
  132. // | width: {end: 15},
  133. // | join: {values: ["miter", "bevel", "round"]}
  134. // | }).play();
  135. if(!args.easing){ args.easing = d._defaultEasing; }
  136. var anim = new d.Animation(args), shape = args.shape, stroke;
  137. d.connect(anim, "beforeBegin", anim, function(){
  138. stroke = shape.getStroke();
  139. var prop = args.color, values = {}, value, start, end;
  140. if(prop){
  141. values.color = getColorInterpol(prop, stroke, "color", transparent);
  142. }
  143. prop = args.style;
  144. if(prop && prop.values){
  145. values.style = new InterpolValues(prop.values);
  146. }
  147. prop = args.width;
  148. if(prop){
  149. values.width = getNumberInterpol(prop, stroke, "width", 1);
  150. }
  151. prop = args.cap;
  152. if(prop && prop.values){
  153. values.cap = new InterpolValues(prop.values);
  154. }
  155. prop = args.join;
  156. if(prop){
  157. if(prop.values){
  158. values.join = new InterpolValues(prop.values);
  159. }else{
  160. start = prop.start ? prop.start : (stroke && stroke.join || 0);
  161. end = prop.end ? prop.end : (stroke && stroke.join || 0);
  162. if(typeof start == "number" && typeof end == "number"){
  163. values.join = new InterpolNumber(start, end);
  164. }
  165. }
  166. }
  167. this.curve = new InterpolObject(values, stroke);
  168. });
  169. d.connect(anim, "onAnimate", shape, "setStroke");
  170. return anim; // dojo.Animation
  171. };
  172. g.fx.animateFill = function(/*Object*/ args){
  173. // summary:
  174. // Returns an animation which will change fill color over time.
  175. // Only solid fill color is supported at the moment
  176. // example:
  177. // | dojox.gfx.fx.animateFill{{
  178. // | shape: shape,
  179. // | duration: 500,
  180. // | color: {start: "red", end: "green"}
  181. // | }).play();
  182. if(!args.easing){ args.easing = d._defaultEasing; }
  183. var anim = new d.Animation(args), shape = args.shape, fill;
  184. d.connect(anim, "beforeBegin", anim, function(){
  185. fill = shape.getFill();
  186. var prop = args.color, values = {};
  187. if(prop){
  188. this.curve = getColorInterpol(prop, fill, "", transparent);
  189. }
  190. });
  191. d.connect(anim, "onAnimate", shape, "setFill");
  192. return anim; // dojo.Animation
  193. };
  194. g.fx.animateFont = function(/*Object*/ args){
  195. // summary:
  196. // Returns an animation which will change font properties over time
  197. // example:
  198. // | dojox.gfx.fx.animateFont{{
  199. // | shape: shape,
  200. // | duration: 500,
  201. // | variant: {values: ["normal", "small-caps"]},
  202. // | size: {end: 10, units: "pt"}
  203. // | }).play();
  204. if(!args.easing){ args.easing = d._defaultEasing; }
  205. var anim = new d.Animation(args), shape = args.shape, font;
  206. d.connect(anim, "beforeBegin", anim, function(){
  207. font = shape.getFont();
  208. var prop = args.style, values = {}, value, start, end;
  209. if(prop && prop.values){
  210. values.style = new InterpolValues(prop.values);
  211. }
  212. prop = args.variant;
  213. if(prop && prop.values){
  214. values.variant = new InterpolValues(prop.values);
  215. }
  216. prop = args.weight;
  217. if(prop && prop.values){
  218. values.weight = new InterpolValues(prop.values);
  219. }
  220. prop = args.family;
  221. if(prop && prop.values){
  222. values.family = new InterpolValues(prop.values);
  223. }
  224. prop = args.size;
  225. if(prop && prop.units){
  226. start = parseFloat(prop.start ? prop.start : (shape.font && shape.font.size || "0"));
  227. end = parseFloat(prop.end ? prop.end : (shape.font && shape.font.size || "0"));
  228. values.size = new InterpolUnit(start, end, prop.units);
  229. }
  230. this.curve = new InterpolObject(values, font);
  231. });
  232. d.connect(anim, "onAnimate", shape, "setFont");
  233. return anim; // dojo.Animation
  234. };
  235. g.fx.animateTransform = function(/*Object*/ args){
  236. // summary:
  237. // Returns an animation which will change transformation over time
  238. // example:
  239. // | dojox.gfx.fx.animateTransform{{
  240. // | shape: shape,
  241. // | duration: 500,
  242. // | transform: [
  243. // | {name: "translate", start: [0, 0], end: [200, 200]},
  244. // | {name: "original"}
  245. // | ]
  246. // | }).play();
  247. if(!args.easing){ args.easing = d._defaultEasing; }
  248. var anim = new d.Animation(args), shape = args.shape, original;
  249. d.connect(anim, "beforeBegin", anim, function(){
  250. original = shape.getTransform();
  251. this.curve = new InterpolTransform(args.transform, original);
  252. });
  253. d.connect(anim, "onAnimate", shape, "setTransform");
  254. return anim; // dojo.Animation
  255. };
  256. })();
  257. }