[483] | 1 | define(["dojo/_base/lang", "./_base", "./matrix", "dojo/_base/Color", "dojo/_base/array", "dojo/_base/fx", "dojo/_base/connect", "dojo/sniff"], |
---|
| 2 | function(lang, g, m, Color, arr, fx, Hub, has){ |
---|
| 3 | var fxg = g.fx = {}; |
---|
| 4 | |
---|
| 5 | // Generic interpolators. Should they be moved to dojox.fx? |
---|
| 6 | |
---|
| 7 | function InterpolNumber(start, end){ |
---|
| 8 | this.start = start, this.end = end; |
---|
| 9 | } |
---|
| 10 | InterpolNumber.prototype.getValue = function(r){ |
---|
| 11 | return (this.end - this.start) * r + this.start; |
---|
| 12 | }; |
---|
| 13 | |
---|
| 14 | function InterpolUnit(start, end, units){ |
---|
| 15 | this.start = start, this.end = end; |
---|
| 16 | this.units = units; |
---|
| 17 | } |
---|
| 18 | InterpolUnit.prototype.getValue = function(r){ |
---|
| 19 | return (this.end - this.start) * r + this.start + this.units; |
---|
| 20 | }; |
---|
| 21 | |
---|
| 22 | function InterpolColor(start, end){ |
---|
| 23 | this.start = start, this.end = end; |
---|
| 24 | this.temp = new Color(); |
---|
| 25 | } |
---|
| 26 | InterpolColor.prototype.getValue = function(r){ |
---|
| 27 | return Color.blendColors(this.start, this.end, r, this.temp); |
---|
| 28 | }; |
---|
| 29 | |
---|
| 30 | function InterpolValues(values){ |
---|
| 31 | this.values = values; |
---|
| 32 | this.length = values.length; |
---|
| 33 | } |
---|
| 34 | InterpolValues.prototype.getValue = function(r){ |
---|
| 35 | return this.values[Math.min(Math.floor(r * this.length), this.length - 1)]; |
---|
| 36 | }; |
---|
| 37 | |
---|
| 38 | function InterpolObject(values, def){ |
---|
| 39 | this.values = values; |
---|
| 40 | this.def = def ? def : {}; |
---|
| 41 | } |
---|
| 42 | InterpolObject.prototype.getValue = function(r){ |
---|
| 43 | var ret = lang.clone(this.def); |
---|
| 44 | for(var i in this.values){ |
---|
| 45 | ret[i] = this.values[i].getValue(r); |
---|
| 46 | } |
---|
| 47 | return ret; |
---|
| 48 | }; |
---|
| 49 | |
---|
| 50 | function InterpolTransform(stack, original){ |
---|
| 51 | this.stack = stack; |
---|
| 52 | this.original = original; |
---|
| 53 | } |
---|
| 54 | InterpolTransform.prototype.getValue = function(r){ |
---|
| 55 | var ret = []; |
---|
| 56 | arr.forEach(this.stack, function(t){ |
---|
| 57 | if(t instanceof m.Matrix2D){ |
---|
| 58 | ret.push(t); |
---|
| 59 | return; |
---|
| 60 | } |
---|
| 61 | if(t.name == "original" && this.original){ |
---|
| 62 | ret.push(this.original); |
---|
| 63 | return; |
---|
| 64 | } |
---|
| 65 | // Adding support for custom matrices |
---|
| 66 | if(t.name == "matrix"){ |
---|
| 67 | if((t.start instanceof m.Matrix2D) && (t.end instanceof m.Matrix2D)){ |
---|
| 68 | var transfMatrix = new m.Matrix2D(); |
---|
| 69 | for(var p in t.start) { |
---|
| 70 | transfMatrix[p] = (t.end[p] - t.start[p])*r + t.start[p]; |
---|
| 71 | } |
---|
| 72 | ret.push(transfMatrix); |
---|
| 73 | } |
---|
| 74 | return; |
---|
| 75 | } |
---|
| 76 | if(!(t.name in m)){ return; } |
---|
| 77 | var f = m[t.name]; |
---|
| 78 | if(typeof f != "function"){ |
---|
| 79 | // constant |
---|
| 80 | ret.push(f); |
---|
| 81 | return; |
---|
| 82 | } |
---|
| 83 | var val = arr.map(t.start, function(v, i){ |
---|
| 84 | return (t.end[i] - v) * r + v; |
---|
| 85 | }), |
---|
| 86 | matrix = f.apply(m, val); |
---|
| 87 | if(matrix instanceof m.Matrix2D){ |
---|
| 88 | ret.push(matrix); |
---|
| 89 | } |
---|
| 90 | }, this); |
---|
| 91 | return ret; |
---|
| 92 | }; |
---|
| 93 | |
---|
| 94 | var transparent = new Color(0, 0, 0, 0); |
---|
| 95 | |
---|
| 96 | function getColorInterpol(prop, obj, name, def){ |
---|
| 97 | if(prop.values){ |
---|
| 98 | return new InterpolValues(prop.values); |
---|
| 99 | } |
---|
| 100 | var value, start, end; |
---|
| 101 | if(prop.start){ |
---|
| 102 | start = g.normalizeColor(prop.start); |
---|
| 103 | }else{ |
---|
| 104 | start = value = obj ? (name ? obj[name] : obj) : def; |
---|
| 105 | } |
---|
| 106 | if(prop.end){ |
---|
| 107 | end = g.normalizeColor(prop.end); |
---|
| 108 | }else{ |
---|
| 109 | if(!value){ |
---|
| 110 | value = obj ? (name ? obj[name] : obj) : def; |
---|
| 111 | } |
---|
| 112 | end = value; |
---|
| 113 | } |
---|
| 114 | return new InterpolColor(start, end); |
---|
| 115 | } |
---|
| 116 | |
---|
| 117 | function getNumberInterpol(prop, obj, name, def){ |
---|
| 118 | if(prop.values){ |
---|
| 119 | return new InterpolValues(prop.values); |
---|
| 120 | } |
---|
| 121 | var value, start, end; |
---|
| 122 | if(prop.start){ |
---|
| 123 | start = prop.start; |
---|
| 124 | }else{ |
---|
| 125 | start = value = obj ? obj[name] : def; |
---|
| 126 | } |
---|
| 127 | if(prop.end){ |
---|
| 128 | end = prop.end; |
---|
| 129 | }else{ |
---|
| 130 | if(typeof value != "number"){ |
---|
| 131 | value = obj ? obj[name] : def; |
---|
| 132 | } |
---|
| 133 | end = value; |
---|
| 134 | } |
---|
| 135 | return new InterpolNumber(start, end); |
---|
| 136 | } |
---|
| 137 | |
---|
| 138 | fxg.animateStroke = function(/*Object*/ args){ |
---|
| 139 | // summary: |
---|
| 140 | // Returns an animation which will change stroke properties over time. |
---|
| 141 | // args: |
---|
| 142 | // an object defining the animation setting. |
---|
| 143 | // example: |
---|
| 144 | // | fxg.animateStroke{{ |
---|
| 145 | // | shape: shape, |
---|
| 146 | // | duration: 500, |
---|
| 147 | // | color: {start: "red", end: "green"}, |
---|
| 148 | // | width: {end: 15}, |
---|
| 149 | // | join: {values: ["miter", "bevel", "round"]} |
---|
| 150 | // | }).play(); |
---|
| 151 | if(!args.easing){ args.easing = fx._defaultEasing; } |
---|
| 152 | var anim = new fx.Animation(args), shape = args.shape, stroke; |
---|
| 153 | Hub.connect(anim, "beforeBegin", anim, function(){ |
---|
| 154 | stroke = shape.getStroke(); |
---|
| 155 | var prop = args.color, values = {}, value, start, end; |
---|
| 156 | if(prop){ |
---|
| 157 | values.color = getColorInterpol(prop, stroke, "color", transparent); |
---|
| 158 | } |
---|
| 159 | prop = args.style; |
---|
| 160 | if(prop && prop.values){ |
---|
| 161 | values.style = new InterpolValues(prop.values); |
---|
| 162 | } |
---|
| 163 | prop = args.width; |
---|
| 164 | if(prop){ |
---|
| 165 | values.width = getNumberInterpol(prop, stroke, "width", 1); |
---|
| 166 | } |
---|
| 167 | prop = args.cap; |
---|
| 168 | if(prop && prop.values){ |
---|
| 169 | values.cap = new InterpolValues(prop.values); |
---|
| 170 | } |
---|
| 171 | prop = args.join; |
---|
| 172 | if(prop){ |
---|
| 173 | if(prop.values){ |
---|
| 174 | values.join = new InterpolValues(prop.values); |
---|
| 175 | }else{ |
---|
| 176 | start = prop.start ? prop.start : (stroke && stroke.join || 0); |
---|
| 177 | end = prop.end ? prop.end : (stroke && stroke.join || 0); |
---|
| 178 | if(typeof start == "number" && typeof end == "number"){ |
---|
| 179 | values.join = new InterpolNumber(start, end); |
---|
| 180 | } |
---|
| 181 | } |
---|
| 182 | } |
---|
| 183 | this.curve = new InterpolObject(values, stroke); |
---|
| 184 | }); |
---|
| 185 | Hub.connect(anim, "onAnimate", shape, "setStroke"); |
---|
| 186 | return anim; // dojo.Animation |
---|
| 187 | }; |
---|
| 188 | |
---|
| 189 | fxg.animateFill = function(/*Object*/ args){ |
---|
| 190 | // summary: |
---|
| 191 | // Returns an animation which will change fill color over time. |
---|
| 192 | // Only solid fill color is supported at the moment |
---|
| 193 | // args: |
---|
| 194 | // an object defining the animation setting. |
---|
| 195 | // example: |
---|
| 196 | // | gfx.animateFill{{ |
---|
| 197 | // | shape: shape, |
---|
| 198 | // | duration: 500, |
---|
| 199 | // | color: {start: "red", end: "green"} |
---|
| 200 | // | }).play(); |
---|
| 201 | if(!args.easing){ args.easing = fx._defaultEasing; } |
---|
| 202 | var anim = new fx.Animation(args), shape = args.shape, fill; |
---|
| 203 | Hub.connect(anim, "beforeBegin", anim, function(){ |
---|
| 204 | fill = shape.getFill(); |
---|
| 205 | var prop = args.color, values = {}; |
---|
| 206 | if(prop){ |
---|
| 207 | this.curve = getColorInterpol(prop, fill, "", transparent); |
---|
| 208 | } |
---|
| 209 | }); |
---|
| 210 | Hub.connect(anim, "onAnimate", shape, "setFill"); |
---|
| 211 | return anim; // dojo.Animation |
---|
| 212 | }; |
---|
| 213 | |
---|
| 214 | fxg.animateFont = function(/*Object*/ args){ |
---|
| 215 | // summary: |
---|
| 216 | // Returns an animation which will change font properties over time. |
---|
| 217 | // args: |
---|
| 218 | // an object defining the animation setting. |
---|
| 219 | // example: |
---|
| 220 | // | gfx.animateFont{{ |
---|
| 221 | // | shape: shape, |
---|
| 222 | // | duration: 500, |
---|
| 223 | // | variant: {values: ["normal", "small-caps"]}, |
---|
| 224 | // | size: {end: 10, units: "pt"} |
---|
| 225 | // | }).play(); |
---|
| 226 | if(!args.easing){ args.easing = fx._defaultEasing; } |
---|
| 227 | var anim = new fx.Animation(args), shape = args.shape, font; |
---|
| 228 | Hub.connect(anim, "beforeBegin", anim, function(){ |
---|
| 229 | font = shape.getFont(); |
---|
| 230 | var prop = args.style, values = {}, value, start, end; |
---|
| 231 | if(prop && prop.values){ |
---|
| 232 | values.style = new InterpolValues(prop.values); |
---|
| 233 | } |
---|
| 234 | prop = args.variant; |
---|
| 235 | if(prop && prop.values){ |
---|
| 236 | values.variant = new InterpolValues(prop.values); |
---|
| 237 | } |
---|
| 238 | prop = args.weight; |
---|
| 239 | if(prop && prop.values){ |
---|
| 240 | values.weight = new InterpolValues(prop.values); |
---|
| 241 | } |
---|
| 242 | prop = args.family; |
---|
| 243 | if(prop && prop.values){ |
---|
| 244 | values.family = new InterpolValues(prop.values); |
---|
| 245 | } |
---|
| 246 | prop = args.size; |
---|
| 247 | if(prop && prop.units){ |
---|
| 248 | start = parseFloat(prop.start ? prop.start : (shape.font && shape.font.size || "0")); |
---|
| 249 | end = parseFloat(prop.end ? prop.end : (shape.font && shape.font.size || "0")); |
---|
| 250 | values.size = new InterpolUnit(start, end, prop.units); |
---|
| 251 | } |
---|
| 252 | this.curve = new InterpolObject(values, font); |
---|
| 253 | }); |
---|
| 254 | Hub.connect(anim, "onAnimate", shape, "setFont"); |
---|
| 255 | return anim; // dojo.Animation |
---|
| 256 | }; |
---|
| 257 | |
---|
| 258 | fxg.animateTransform = function(/*Object*/ args){ |
---|
| 259 | // summary: |
---|
| 260 | // Returns an animation which will change transformation over time. |
---|
| 261 | // args: |
---|
| 262 | // an object defining the animation setting. |
---|
| 263 | // example: |
---|
| 264 | // | gfx.animateTransform{{ |
---|
| 265 | // | shape: shape, |
---|
| 266 | // | duration: 500, |
---|
| 267 | // | transform: [ |
---|
| 268 | // | {name: "translate", start: [0, 0], end: [200, 200]}, |
---|
| 269 | // | {name: "original"} |
---|
| 270 | // | ] |
---|
| 271 | // | }).play(); |
---|
| 272 | if(!args.easing){ args.easing = fx._defaultEasing; } |
---|
| 273 | var anim = new fx.Animation(args), shape = args.shape, original; |
---|
| 274 | Hub.connect(anim, "beforeBegin", anim, function(){ |
---|
| 275 | original = shape.getTransform(); |
---|
| 276 | this.curve = new InterpolTransform(args.transform, original); |
---|
| 277 | }); |
---|
| 278 | Hub.connect(anim, "onAnimate", shape, "setTransform"); |
---|
| 279 | if(g.renderer === "svg" && has("ie") >= 10){ |
---|
| 280 | // fix http://bugs.dojotoolkit.org/ticket/16879 |
---|
| 281 | var handlers = [ |
---|
| 282 | Hub.connect(anim, "onBegin", anim, function(){ |
---|
| 283 | var parent = shape.getParent(); |
---|
| 284 | while(parent && parent.getParent){ |
---|
| 285 | parent = parent.getParent(); |
---|
| 286 | } |
---|
| 287 | if(parent){ |
---|
| 288 | shape.__svgContainer = parent.rawNode.parentNode; |
---|
| 289 | } |
---|
| 290 | }), |
---|
| 291 | Hub.connect(anim, "onAnimate", anim, function(){ |
---|
| 292 | try{ |
---|
| 293 | if(shape.__svgContainer){ |
---|
| 294 | var ov = shape.__svgContainer.style.visibility; |
---|
| 295 | shape.__svgContainer.style.visibility = "visible"; |
---|
| 296 | var pokeNode = shape.__svgContainer.offsetHeight; |
---|
| 297 | shape.__svgContainer.style.visibility = ov; |
---|
| 298 | } |
---|
| 299 | }catch(e){} |
---|
| 300 | }), |
---|
| 301 | Hub.connect(anim, "onEnd", anim, function(){ |
---|
| 302 | arr.forEach(handlers, Hub.disconnect); |
---|
| 303 | if(shape.__svgContainer){ |
---|
| 304 | var ov = shape.__svgContainer.style.visibility; |
---|
| 305 | var sn = shape.__svgContainer; |
---|
| 306 | shape.__svgContainer.style.visibility = "visible"; |
---|
| 307 | setTimeout(function(){ |
---|
| 308 | try{ |
---|
| 309 | sn.style.visibility = ov; |
---|
| 310 | sn = null; |
---|
| 311 | }catch(e){} |
---|
| 312 | },100); |
---|
| 313 | } |
---|
| 314 | delete shape.__svgContainer; |
---|
| 315 | }) |
---|
| 316 | ]; |
---|
| 317 | } |
---|
| 318 | return anim; // dojo.Animation |
---|
| 319 | }; |
---|
| 320 | |
---|
| 321 | return fxg; |
---|
| 322 | }); |
---|