complex.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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.fx.ext-dojo.complex"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojox.fx.ext-dojo.complex"] = true;
  8. dojo.provide("dojox.fx.ext-dojo.complex");
  9. (function(){
  10. var da = dojo.animateProperty;
  11. dojo.animateProperty = function(options){
  12. // summary:
  13. // An extension of dojo.animateProperty which adds functionality
  14. // that animates a "complex property". The primary example is the
  15. // clip style: rect(10px 30px 10px 50px).
  16. // Note this can also be used with (and is actually intended for)
  17. // CSS3 properties, such as transform:
  18. // transform: rotate(10deg) translateX(0px)
  19. //
  20. // description:
  21. // The standard animation doesn't know what to do with something like
  22. // rect(...). This class identifies complex properties by they being a
  23. // string and having parenthesis. If so, that property is made into a
  24. // dojox.fx._Complex object and the getValue() is obtained from
  25. // there.
  26. //
  27. // example:
  28. // | var ani = dojo.animateProperty({
  29. // | node:dojo.byId("myDiv"),
  30. // | duration:600,
  31. // | properties:{
  32. // | clip:{start:'rect(0px 50px 50px 0px)', end:'rect(10px 30px 30px 10px)'}
  33. // | }
  34. // | }).play();
  35. //
  36. var d = dojo;
  37. var ani = da(options);
  38. dojo.connect(ani, "beforeBegin", function(){
  39. // dojo.Animate original still invokes and still
  40. // works. We're appending this functionality to
  41. // modify targeted properties.
  42. ani.curve.getValue = function(r){
  43. // Overwriting dojo.Animate's curve.getValue
  44. // This is mostly duplicate code, except it looks
  45. // for an instance of dojox.fx._Complex.
  46. var ret = {};
  47. for(var p in this._properties){
  48. var prop = this._properties[p],
  49. start = prop.start;
  50. if(start instanceof d.Color){
  51. ret[p] = d.blendColors(start, prop.end, r, prop.tempColor).toCss();
  52. }else if(start instanceof dojox.fx._Complex){
  53. ret[p] = start.getValue(r);
  54. }else if(!d.isArray(start)){
  55. ret[p] = ((prop.end - start) * r) + start + (p != "opacity" ? prop.units || "px" : 0);
  56. }
  57. }
  58. return ret;
  59. };
  60. // this.properties has already been set, as has this.curve._properties.
  61. // We're fixing the props in curve which will have NaN attributes from
  62. // our string property.
  63. var pm = {};
  64. for(var p in this.properties){
  65. var o = this.properties[p];
  66. if(typeof(o.start) == "string" && /\(/.test(o.start)){
  67. this.curve._properties[p].start = new dojox.fx._Complex(o);
  68. }
  69. }
  70. });
  71. return ani; // dojo.Animation
  72. }
  73. })();
  74. dojo.declare("dojox.fx._Complex", null, {
  75. // summary:
  76. // A class that takes a complex property such as
  77. // clip style: rect(10px 30px 10px 50px), and breaks it
  78. // into seperate animatable units. The object has a getValue()
  79. // that will return a string with the modified units.
  80. //
  81. PROP: /\([+-]?[\w|,|#|\.|\s]*\)/g,
  82. constructor: function(options){
  83. var beg = options.start.match(this.PROP);
  84. var end = options.end.match(this.PROP);
  85. var begProps = dojo.map(beg, this.getProps, this);
  86. var endProps = dojo.map(end, this.getProps, this);
  87. this._properties = {};
  88. this.strProp = options.start;
  89. dojo.forEach(begProps, function(prop, i){
  90. dojo.forEach(prop, function(p, j){
  91. this.strProp = this.strProp.replace(p, "PROP_"+i+""+j);
  92. this._properties["PROP_"+i+""+j] = this.makePropObject(p, endProps[i][j])
  93. },this);
  94. },this);
  95. },
  96. getValue: function(/*Float*/r){
  97. // summary:
  98. // Returns a string with teh same integrity as the
  99. // original star and end, but with the modified units.
  100. var str = this.strProp, u;
  101. for(var nm in this._properties){
  102. var v, o = this._properties[nm];
  103. if(o.units == "isColor"){
  104. v = dojo.blendColors(o.beg, o.end, r).toCss(false);
  105. u = "";
  106. }else{
  107. v = ((o.end - o.beg) * r) + o.beg;
  108. u = o.units;
  109. }
  110. str = str.replace(nm, v + u);
  111. }
  112. return str; // String
  113. },
  114. makePropObject: function(/* String */beg, /* String */end){
  115. // summary:
  116. // Returns an object that stores the numeric value and
  117. // units of the beggining and ending properties.
  118. //
  119. var b = this.getNumAndUnits(beg);
  120. var e = this.getNumAndUnits(end);
  121. return {
  122. beg:b.num,
  123. end:e.num,
  124. units:b.units
  125. }; // Object
  126. },
  127. getProps: function(/* String */str){
  128. // summary:
  129. // Helper function that splits a stringified set of properties
  130. // into individual units.
  131. //
  132. str = str.substring(1, str.length-1);
  133. var s;
  134. if(/,/.test(str)){
  135. str = str.replace(/\s/g, "");
  136. s = str.split(",");
  137. }else{
  138. str = str.replace(/\s{2,}/g, " ");
  139. s = str.split(" ");
  140. }
  141. return s; // String
  142. },
  143. getNumAndUnits: function(prop){
  144. // summary:
  145. // Helper function that returns the numeric verion of the string
  146. // property (or dojo.Color object) and the unit in which it was
  147. // defined.
  148. //
  149. if(!prop){ return {}; }
  150. if(/#/.test(prop)){
  151. return {
  152. num: new dojo.Color(prop),
  153. units:"isColor"
  154. }; // Object
  155. }
  156. var o = {
  157. num:parseFloat(/-*[\d\.\d|\d]{1,}/.exec(prop).join(""))
  158. };
  159. o.units = /[a-z]{1,}/.exec(prop);//.join("");
  160. o.units = o.units && o.units.length ? o.units.join("") : "";
  161. return o; // Object
  162. }
  163. });
  164. }