1/*! 2* EaselJS 3* Visit http://createjs.com/ for documentation, updates and examples. 4* 5* Copyright (c) 2010 gskinner.com, inc. 6* 7* Permission is hereby granted, free of charge, to any person 8* obtaining a copy of this software and associated documentation 9* files (the "Software"), to deal in the Software without 10* restriction, including without limitation the rights to use, 11* copy, modify, merge, publish, distribute, sublicense, and/or sell 12* copies of the Software, and to permit persons to whom the 13* Software is furnished to do so, subject to the following 14* conditions: 15* 16* The above copyright notice and this permission notice shall be 17* included in all copies or substantial portions of the Software. 18* 19* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26* OTHER DEALINGS IN THE SOFTWARE. 27*/ 28 29 30//############################################################################## 31// extend.js 32//############################################################################## 33 34this.createjs = this.createjs||{}; 35 36/** 37 * @class Utility Methods 38 */ 39 40/** 41 * Sets up the prototype chain and constructor property for a new class. 42 * 43 * This should be called right after creating the class constructor. 44 * 45 * function MySubClass() {} 46 * createjs.extend(MySubClass, MySuperClass); 47 * MySubClass.prototype.doSomething = function() { } 48 * 49 * var foo = new MySubClass(); 50 * console.log(foo instanceof MySuperClass); // true 51 * console.log(foo.prototype.constructor === MySubClass); // true 52 * 53 * @method extend 54 * @param {Function} subclass The subclass. 55 * @param {Function} superclass The superclass to extend. 56 * @return {Function} Returns the subclass's new prototype. 57 */ 58createjs.extend = function(subclass, superclass) { 59 "use strict"; 60 61 function o() { this.constructor = subclass; } 62 o.prototype = superclass.prototype; 63 return (subclass.prototype = new o()); 64}; 65 66//############################################################################## 67// promote.js 68//############################################################################## 69 70this.createjs = this.createjs||{}; 71 72/** 73 * @class Utility Methods 74 */ 75 76/** 77 * Promotes any methods on the super class that were overridden, by creating an alias in the format `prefix_methodName`. 78 * It is recommended to use the super class's name as the prefix. 79 * An alias to the super class's constructor is always added in the format `prefix_constructor`. 80 * This allows the subclass to call super class methods without using `function.call`, providing better performance. 81 * 82 * For example, if `MySubClass` extends `MySuperClass`, and both define a `draw` method, then calling `promote(MySubClass, "MySuperClass")` 83 * would add a `MySuperClass_constructor` method to MySubClass and promote the `draw` method on `MySuperClass` to the 84 * prototype of `MySubClass` as `MySuperClass_draw`. 85 * 86 * This should be called after the class's prototype is fully defined. 87 * 88 * function ClassA(name) { 89 * this.name = name; 90 * } 91 * ClassA.prototype.greet = function() { 92 * return "Hello "+this.name; 93 * } 94 * 95 * function ClassB(name, punctuation) { 96 * this.ClassA_constructor(name); 97 * this.punctuation = punctuation; 98 * } 99 * createjs.extend(ClassB, ClassA); 100 * ClassB.prototype.greet = function() { 101 * return this.ClassA_greet()+this.punctuation; 102 * } 103 * createjs.promote(ClassB, "ClassA"); 104 * 105 * var foo = new ClassB("World", "!?!"); 106 * console.log(foo.greet()); // Hello World!?! 107 * 108 * @method promote 109 * @param {Function} subclass The class to promote super class methods on. 110 * @param {String} prefix The prefix to add to the promoted method names. Usually the name of the superclass. 111 * @return {Function} Returns the subclass. 112 */ 113createjs.promote = function(subclass, prefix) { 114 "use strict"; 115 116 var subP = subclass.prototype, supP = (Object.getPrototypeOf&&Object.getPrototypeOf(subP))||subP.__proto__; 117 if (supP) { 118 subP[(prefix+="_") + "constructor"] = supP.constructor; // constructor is not always innumerable 119 for (var n in supP) { 120 if (subP.hasOwnProperty(n) && (typeof supP[n] == "function")) { subP[prefix + n] = supP[n]; } 121 } 122 } 123 return subclass; 124}; 125 126//############################################################################## 127// indexOf.js 128//############################################################################## 129 130this.createjs = this.createjs||{}; 131 132/** 133 * @class Utility Methods 134 */ 135 136/** 137 * Finds the first occurrence of a specified value searchElement in the passed in array, and returns the index of 138 * that value. Returns -1 if value is not found. 139 * 140 * var i = createjs.indexOf(myArray, myElementToFind); 141 * 142 * @method indexOf 143 * @param {Array} array Array to search for searchElement 144 * @param searchElement Element to find in array.
145 * @return {Number} The first index of searchElement in array. 146 */ 147createjs.indexOf = function (array, searchElement){ 148 "use strict"; 149 150 for (var i = 0,l=array.length; i < l; i++) { 151 if (searchElement === array[i]) { 152 return i; 153 } 154 } 155 return -1; 156}; 157 158//############################################################################## 159// Event.js 160//############################################################################## 161 162this.createjs = this.createjs||{}; 163 164(function() { 165 "use strict"; 166 167// constructor: 168 /** 169 * Contains properties and methods shared by all events for use with 170 * {{#crossLink "EventDispatcher"}}{{/crossLink}}. 171 * 172 * Note that Event objects are often reused, so you should never 173 * rely on an event object's state outside of the call stack it was received in. 174 * @class Event 175 * @param {String} type The event type. 176 * @param {Boolean} bubbles Indicates whether the event will bubble through the display list. 177 * @param {Boolean} cancelable Indicates whether the default behaviour of this event can be cancelled. 178 * @constructor 179 **/ 180 function Event(type, bubbles, cancelable) { 181 182 183 // public properties: 184 /** 185 * The type of event. 186 * @property type
187 * @type String 188 **/ 189 this.type = type; 190 191 /** 192 * The object that generated an event. 193 * @property target 194 * @type Object 195 * @default null 196 * @readonly 197 */ 198 this.target = null; 199 200 /** 201 * The current target that a bubbling event is being dispatched from. For non-bubbling events, this will 202 * always be the same as target. For example, if childObj.parent = parentObj, and a bubbling event 203 * is generated from childObj, then a listener on parentObj would receive the event with 204 * target=childObj (the original target) and currentTarget=parentObj (where the listener was added). 205 * @property currentTarget 206 * @type Object 207 * @default null 208 * @readonly 209 */ 210 this.currentTarget = null; 211 212 /** 213 * For bubbling events, this indicates the current event phase:<OL> 214 * <LI> capture phase: starting from the top parent to the target</LI> 215 * <LI> at target phase: currently being dispatched from the target</LI> 216 * <LI> bubbling phase: from the target to the top parent</LI> 217 * </OL> 218 * @property eventPhase 219 * @type Number 220 * @default 0 221 * @readonly 222 */ 223 this.eventPhase = 0; 224 225 /** 226 * Indicates whether the event will bubble through the display list. 227 * @property bubbles 228 * @type Boolean 229 * @default false 230 * @readonly 231 */ 232 this.bubbles = !!bubbles; 233 234 /** 235 * Indicates whether the default behaviour of this event can be cancelled via 236 * {{#crossLink "Event/preventDefault"}}{{/crossLink}}. This is set via the Event constructor. 237 * @property cancelable 238 * @type Boolean 239 * @default false 240 * @readonly 241 */ 242 this.cancelable = !!cancelable; 243 244 /** 245 * The epoch time at which this event was created. 246 * @property timeStamp 247 * @type Number 248 * @default 0 249 * @readonly 250 */ 251 this.timeStamp = (new Date()).getTime(); 252 253 /** 254 * Indicates if {{#crossLink "Event/preventDefault"}}{{/crossLink}} has been called 255 * on this event. 256 * @property defaultPrevented 257 * @type Boolean 258 * @default false 259 * @readonly 260 */ 261 this.defaultPrevented = false; 262 263 /** 264 * Indicates if {{#crossLink "Event/stopPropagation"}}{{/crossLink}} or 265 * {{#crossLink "Event/stopImmediatePropagation"}}{{/crossLink}} has been called on this event. 266 * @property propagationStopped 267 * @type Boolean 268 * @default false 269 * @readonly 270 */ 271 this.propagationStopped = false; 272 273 /** 274 * Indicates if {{#crossLink "Event/stopImmediatePropagation"}}{{/crossLink}} has been called 275 * on this event. 276 * @property immediatePropagationStopped 277 * @type Boolean 278 * @default false 279 * @readonly 280 */ 281 this.immediatePropagationStopped = false; 282 283 /** 284 * Indicates if {{#crossLink "Event/remove"}}{{/crossLink}} has been called on this event. 285 * @property removed 286 * @type Boolean 287 * @default false 288 * @readonly 289 */ 290 this.removed = false; 291 } 292 var p = Event.prototype; 293 294 /** 295 * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`. 296 * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}} 297 * for details. 298 * 299 * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance. 300 * 301 * @method initialize 302 * @protected 303 * @deprecated 304 */ 305 // p.initialize = function() {}; // searchable for devs wondering where it is. 306 307// public methods: 308 /** 309 * Sets {{#crossLink "Event/defaultPrevented"}}{{/crossLink}} to true if the event is cancelable. 310 * Mirrors the DOM level 2 event standard. In general, cancelable events that have `preventDefault()` called will 311 * cancel the default behaviour associated with the event. 312 * @method preventDefault 313 **/ 314 p.preventDefault = function() { 315 this.defaultPrevented = this.cancelable&&true; 316 }; 317 318 /** 319 * Sets {{#crossLink "Event/propagationStopped"}}{{/crossLink}} to true. 320 * Mirrors the DOM event standard. 321 * @method stopPropagation 322 **/ 323 p.stopPropagation = function() { 324 this.propagationStopped = true; 325 }; 326 327 /** 328 * Sets {{#crossLink "Event/propagationStopped"}}{{/crossLink}} and 329 * {{#crossLink "Event/immediatePropagationStopped"}}{{/crossLink}} to true. 330 * Mirrors the DOM event standard. 331 * @method stopImmediatePropagation 332 **/ 333 p.stopImmediatePropagation = function() {
334 this.immediatePropagationStopped = this.propagationStopped = true; 335 }; 336 337 /** 338 * Causes the active listener to be removed via removeEventListener(); 339 * 340 * myBtn.addEventListener("click", function(evt) { 341 * // do stuff... 342 * evt.remove(); // removes this listener. 343 * }); 344 * 345 * @method remove 346 **/ 347 p.remove = function() { 348 this.removed = true; 349 }; 350 351 /** 352 * Returns a clone of the Event instance. 353 * @method clone 354 * @return {Event} a clone of the Event instance. 355 **/ 356 p.clone = function() { 357 return new Event(this.type, this.bubbles, this.cancelable); 358 }; 359 360 /** 361 * Provides a chainable shortcut method for setting a number of properties on the instance. 362 * 363 * @method set 364 * @param {Object} props A generic object containing properties to copy to the instance. 365 * @return {Event} Returns the instance the method is called on (useful for chaining calls.) 366 * @chainable 367 */ 368 p.set = function(props) { 369 for (var n in props) { this[n] = props[n]; } 370 return this; 371 }; 372 373 /** 374 * Returns a string representation of this object. 375 * @method toString 376 * @return {String} a string representation of the instance. 377 **/ 378 p.toString = function() { 379 return "[Event (type="+this.type+")]"; 380 }; 381 382 createjs.Event = Event; 383}()); 384 385//############################################################################## 386// EventDispatcher.js 387//############################################################################## 388 389this.createjs = this.createjs||{}; 390 391(function() { 392 "use strict"; 393 394 395// constructor: 396 /** 397 * EventDispatcher provides methods for managing queues of event listeners and dispatching events. 398 * 399 * You can either extend EventDispatcher or mix its methods into an existing prototype or instance by using the 400 * EventDispatcher {{#crossLink "EventDispatcher/initialize"}}{{/crossLink}} method. 401 * 402 * Together with the CreateJS Event class, EventDispatcher provides an extended event model that is based on the 403 * DOM Level 2 event model, including addEventListener, removeEventListener, and dispatchEvent. It supports 404 * bubbling / capture, preventDefault, stopPropagation, stopImmediatePropagation, and handleEvent. 405 * 406 * EventDispatcher also exposes a {{#crossLink "EventDispatcher/on"}}{{/crossLink}} method, which makes it easier 407 * to create scoped listeners, listeners that only run once, and listeners with associated arbitrary data. The 408 * {{#crossLink "EventDispatcher/off"}}{{/crossLink}} method is merely an alias to 409 * {{#crossLink "EventDispatcher/removeEventListener"}}{{/crossLink}}. 410 * 411 * Another addition to the DOM Level 2 model is the {{#crossLink "EventDispatcher/removeAllEventListeners"}}{{/crossLink}} 412 * method, which can be used to listeners for all events, or listeners for a specific event. The Event object also 413 * includes a {{#crossLink "Event/remove"}}{{/crossLink}} method which removes the active listener. 414 * 415 * <h4>Example</h4> 416 * Add EventDispatcher capabilities to the "MyClass" class. 417 * 418 * EventDispatcher.initialize(MyClass.prototype); 419 * 420 * Add an event (see {{#crossLink "EventDispatcher/addEventListener"}}{{/crossLink}}). 421 * 422 * instance.addEventListener("eventName", handlerMethod); 423 * function handlerMethod(event) { 424 * console.log(event.target + " Was Clicked"); 425 * } 426 * 427 * <b>Maintaining proper scope</b><br /> 428 * Scope (ie. "this") can be be a challenge with events. Using the {{#crossLink "EventDispatcher/on"}}{{/crossLink}} 429 * method to subscribe to events simplifies this. 430 * 431 * instance.addEventListener("click", function(event) { 432 * console.log(instance == this); // false, scope is ambiguous. 433 * }); 434 * 435 * instance.on("click", function(event) { 436 * console.log(instance == this); // true, "on" uses dispatcher scope by default. 437 * }); 438 * 439 * If you want to use addEventListener instead, you may want to use function.bind() or a similar proxy to manage 440 * scope. 441 * 442 * <b>Browser support</b> 443 * The event model in CreateJS can be used separately from the suite in any project, however the inheritance model 444 * requires modern browsers (IE9+). 445 * 446 * 447 * @class EventDispatcher 448 * @constructor 449 **/ 450 function EventDispatcher() { 451 452 453 // private properties: 454 /** 455 * @protected 456 * @property _listeners 457 * @type Object 458 **/ 459 this._listeners = null; 460 461 /** 462 * @protected 463 * @property _captureListeners 464 * @type Object 465 **/ 466 this._captureListeners = null; 467 }
468 var p = EventDispatcher.prototype; 469 470 /** 471 * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`. 472 * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}} 473 * for details. 474 * 475 * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance. 476 * 477 * @method initialize 478 * @protected 479 * @deprecated 480 */ 481 // p.initialize = function() {}; // searchable for devs wondering where it is. 482 483 484// static public methods: 485 /** 486 * Static initializer to mix EventDispatcher methods into a target object or prototype. 487 * 488 * EventDispatcher.initialize(MyClass.prototype); // add to the prototype of the class 489 * EventDispatcher.initialize(myObject); // add to a specific instance 490 * 491 * @method initialize 492 * @static 493 * @param {Object} target The target object to inject EventDispatcher methods into. This can be an instance or a 494 * prototype. 495 **/ 496 EventDispatcher.initialize = function(target) { 497 target.addEventListener = p.addEventListener; 498 target.on = p.on; 499 target.removeEventListener = target.off = p.removeEventListener; 500 target.removeAllEventListeners = p.removeAllEventListeners; 501 target.hasEventListener = p.hasEventListener; 502 target.dispatchEvent = p.dispatchEvent; 503 target._dispatchEvent = p._dispatchEvent; 504 target.willTrigger = p.willTrigger; 505 }; 506 507 508// public methods: 509 /** 510 * Adds the specified event listener. Note that adding multiple listeners to the same function will result in 511 * multiple callbacks getting fired. 512 * 513 * <h4>Example</h4> 514 * 515 * displayObject.addEventListener("click", handleClick); 516 * function handleClick(event) { 517 * // Click happened. 518 * } 519 * 520 * @method addEventListener 521 * @param {String} type The string type of the event. 522 * @param {Function | Object} listener An object with a handleEvent method, or a function that will be called when 523 * the event is dispatched. 524 * @param {Boolean} [useCapture] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase. 525 * @return {Function | Object} Returns the listener for chaining or assignment. 526 **/ 527 p.addEventListener = function(type, listener, useCapture) { 528 var listeners; 529 if (useCapture) { 530 listeners = this._captureListeners = this._captureListeners||{}; 531 } else { 532 listeners = this._listeners = this._listeners||{}; 533 } 534 var arr = listeners[type]; 535 if (arr) { this.removeEventListener(type, listener, useCapture); } 536 arr = listeners[type]; // remove may have deleted the array 537 if (!arr) { listeners[type] = [listener]; } 538 else { arr.push(listener); } 539 return listener; 540 }; 541 542 /** 543 * A shortcut method for using addEventListener that makes it easier to specify an execution scope, have a listener 544 * only run once, associate arbitrary data with the listener, and remove the listener. 545 * 546 * This method works by creating an anonymous wrapper function and subscribing it with addEventListener. 547 * The wrapper function is returned for use with `removeEventListener` (or `off`). 548 * 549 * <b>IMPORTANT:</b> To remove a listener added with `on`, you must pass in the returned wrapper function as the listener, or use 550 * {{#crossLink "Event/remove"}}{{/crossLink}}. Likewise, each time you call `on` a NEW wrapper function is subscribed, so multiple calls 551 * to `on` with the same params will create multiple listeners. 552 * 553 * <h4>Example</h4> 554 * 555 * var listener = myBtn.on("click", handleClick, null, false, {count:3}); 556 * function handleClick(evt, data) { 557 * data.count -= 1; 558 * console.log(this == myBtn); // true - scope defaults to the dispatcher 559 * if (data.count == 0) { 560 * alert("clicked 3 times!"); 561 * myBtn.off("click", listener); 562 * // alternately: evt.remove(); 563 * } 564 * } 565 * 566 * @method on 567 * @param {String} type The string type of the event. 568 * @param {Function | Object} listener An object with a handleEvent method, or a function that will be called when 569 * the event is dispatched. 570 * @param {Object} [scope] The scope to execute the listener in. Defaults to the dispatcher/currentTarget for function listeners, and to the listener itself for object listeners (ie. using handleEvent). 571 * @param {Boolean} [once=false] If true, the listener will remove itself after the first time it is triggered. 572 * @param {*} [data] Arbitrary data that will be included as the second parameter when the listener is called. 573 * @param {Boolean} [useCapture=false] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase. 574 * @return {Function} Returns the anonymous function that was created and assigned as the listener. This is needed to remove the listener later using .removeEventListener. 575 **/ 576 p.on = function(type, listener, scope, once, data, useCapture) { 577 if (listener.handleEvent) { 578 scope = scope||listener; 579 listener = listener.handleEvent; 580 } 581 scope = scope||this; 582 return this.addEventListener(type, function(evt) { 583 listener.call(scope, evt, data); 584 once&&evt.remove(); 585 }, useCapture); 586 }; 587 588 /** 589 * Removes the specified event listener. 590 * 591 * <b>Important Note:</b> that you must pass the exact function reference used when the event was added. If a proxy 592 * function, or function closure is used as the callback, the proxy/closure reference must be used - a new proxy or 593 * closure will not work. 594 * 595 * <h4>Example</h4> 596 * 597 * displayObject.removeEventListener("click", handleClick); 598 * 599 * @method removeEventListener 600 * @param {String} type The string type of the event. 601 * @param {Function | Object} listener The listener function or object. 602 * @param {Boolean} [useCapture] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase. 603 **/ 604 p.removeEventListener = function(type, listener, useCapture) { 605 var listeners = useCapture ? this._captureListeners : this._listeners; 606 if (!listeners) { return; } 607 var arr = listeners[type]; 608 if (!arr) { return; } 609 for (var i=0,l=arr.length; i<l; i++) { 610 if (arr[i] == listener) { 611 if (l==1) { delete(listeners[type]); } // allows for faster checks. 612 else { arr.splice(i,1); } 613 break; 614 } 615 } 616 }; 617 618 /** 619 * A shortcut to the removeEventListener method, with the same parameters and return value. This is a companion to the 620 * .on method. 621 * 622 * <b>IMPORTANT:</b> To remove a listener added with `on`, you must pass in the returned wrapper function as the listener. See 623 * {{#crossLink "EventDispatcher/on"}}{{/crossLink}} for an example. 624 * 625 * @method off 626 * @param {String} type The string type of the event. 627 * @param {Function | Object} listener The listener function or object. 628 * @param {Boolean} [useCapture] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase. 629 **/ 630 p.off = p.removeEventListener; 631 632 /** 633 * Removes all listeners for the specified type, or all listeners of all types. 634 * 635 * <h4>Example</h4> 636 * 637 * // Remove all listeners 638 * displayObject.removeAllEventListeners(); 639 * 640 * // Remove all click listeners 641 * displayObject.removeAllEventListeners("click"); 642 * 643 * @method removeAllEventListeners 644 * @param {String} [type] The string type of the event. If omitted, all listeners for all types will be removed. 645 **/ 646 p.removeAllEventListeners = function(type) { 647 if (!type) { this._listeners = this._captureListeners = null; } 648 else { 649 if (this._listeners) { delete(this._listeners[type]); } 650 if (this._captureListeners) { delete(this._captureListeners[type]); } 651 } 652 }; 653 654 /** 655 * Dispatches the specified event to all listeners. 656 * 657 * <h4>Example</h4> 658 * 659 * // Use a string event 660 * this.dispatchEvent("complete"); 661 * 662 * // Use an Event instance 663 * var event = new createjs.Event("progress"); 664 * this.dispatchEvent(event); 665 * 666 * @method dispatchEvent 667 * @param {Object | String | Event} eventObj An object with a "type" property, or a string type. 668 * While a generic object will work, it is recommended to use a CreateJS Event instance. If a string is used, 669 * dispatchEvent will construct an Event instance if necessary with the specified type. This latter approach can 670 * be used to avoid event object instantiation for non-bubbling events that may not have any listeners. 671 * @param {Boolean} [bubbles] Specifies the `bubbles` value when a string was passed to eventObj. 672 * @param {Boolean} [cancelable] Specifies the `cancelable` value when a string was passed to eventObj. 673 * @return {Boolean} Returns false if `preventDefault()` was called on a cancelable event, true otherwise. 674 **/
675 p.dispatchEvent = function(eventObj, bubbles, cancelable) { 676 if (typeof eventObj == "string") { 677 // skip everything if there's no listeners and it doesn't bubble: 678 var listeners = this._listeners; 679 if (!bubbles && (!listeners || !listeners[eventObj])) { return true; } 680 eventObj = new createjs.Event(eventObj, bubbles, cancelable); 681 } else if (eventObj.target && eventObj.clone) { 682 // redispatching an active event object, so clone it: 683 eventObj = eventObj.clone(); 684 } 685 686 // TODO: it would be nice to eliminate this. Maybe in favour of evtObj instanceof Event? Or !!evtObj.createEvent 687 try { eventObj.target = this; } catch (e) {} // try/catch allows redispatching of native events 688 689 if (!eventObj.bubbles || !this.parent) { 690 this._dispatchEvent(eventObj, 2); 691 } else { 692 var top=this, list=[top]; 693 while (top.parent) { list.push(top = top.parent); } 694 var i, l=list.length; 695 696 // capture & atTarget 697 for (i=l-1; i>=0 && !eventObj.propagationStopped; i--) { 698 list[i]._dispatchEvent(eventObj, 1+(i==0)); 699 } 700 // bubbling 701 for (i=1; i<l && !eventObj.propagationStopped; i++) { 702 list[i]._dispatchEvent(eventObj, 3); 703 } 704 } 705 return !eventObj.defaultPrevented; 706 }; 707 708 /** 709 * Indicates whether there is at least one listener for the specified event type. 710 * @method hasEventListener 711 * @param {String} type The string type of the event. 712 * @return {Boolean} Returns true if there is at least one listener for the specified event. 713 **/ 714 p.hasEventListener = function(type) { 715 var listeners = this._listeners, captureListeners = this._captureListeners; 716 return !!((listeners && listeners[type]) || (captureListeners && captureListeners[type])); 717 }; 718 719 /** 720 * Indicates whether there is at least one listener for the specified event type on this object or any of its 721 * ancestors (parent, parent's parent, etc). A return value of true indicates that if a bubbling event of the 722 * specified type is dispatched from this object, it will trigger at least one listener. 723 * 724 * This is similar to {{#crossLink "EventDispatcher/hasEventListener"}}{{/crossLink}}, but it searches the entire 725 * event flow for a listener, not just this object. 726 * @method willTrigger 727 * @param {String} type The string type of the event. 728 * @return {Boolean} Returns `true` if there is at least one listener for the specified event. 729 **/ 730 p.willTrigger = function(type) { 731 var o = this; 732 while (o) { 733 if (o.hasEventListener(type)) { return true; } 734 o = o.parent; 735 } 736 return false; 737 }; 738 739 /** 740 * @method toString 741 * @return {String} a string representation of the instance. 742 **/ 743 p.toString = function() { 744 return "[EventDispatcher]"; 745 }; 746 747 748// private methods: 749 /** 750 * @method _dispatchEvent 751 * @param {Object | String | Event} eventObj 752 * @param {Object} eventPhase 753 * @protected 754 **/ 755 p._dispatchEvent = function(eventObj, eventPhase) { 756 var l, listeners = (eventPhase==1) ? this._captureListeners : this._listeners; 757 if (eventObj && listeners) { 758 var arr = listeners[eventObj.type]; 759 if (!arr||!(l=arr.length)) { return; } 760 try { eventObj.currentTarget = this; } catch (e) {} 761 try { eventObj.eventPhase = eventPhase; } catch (e) {} 762 eventObj.removed = false; 763 764 arr = arr.slice(); // to avoid issues with items being removed or added during the dispatch 765 for (var i=0; i<l && !eventObj.immediatePropagationStopped; i++) { 766 var o = arr[i]; 767 if (o.handleEvent) { o.handleEvent(eventObj); } 768 else { o(eventObj); } 769 if (eventObj.removed) { 770 this.off(eventObj.type, o, eventPhase==1); 771 eventObj.removed = false; 772 } 773 } 774 } 775 }; 776 777 778 createjs.EventDispatcher = EventDispatcher; 779}()); 780 781//############################################################################## 782// Ticker.js 783//############################################################################## 784 785this.createjs = this.createjs||{}; 786 787(function() { 788 "use strict"; 789 790 791// constructor: 792 /** 793 * The Ticker provides a centralized tick or heartbeat broadcast at a set interval. Listeners can subscribe to the tick 794 * event to be notified when a set time interval has elapsed. 795 *
796 * Note that the interval that the tick event is called is a target interval, and may be broadcast at a slower interval 797 * when under high CPU load. The Ticker class uses a static interface (ex. `Ticker.framerate = 30;`) and 798 * can not be instantiated. 799 * 800 * <h4>Example</h4> 801 * 802 * createjs.Ticker.addEventListener("tick", handleTick); 803 * function handleTick(event) { 804 * // Actions carried out each tick (aka frame) 805 * if (!event.paused) { 806 * // Actions carried out when the Ticker is not paused. 807 * } 808 * } 809 * 810 * @class Ticker 811 * @uses EventDispatcher 812 * @static 813 **/ 814 function Ticker() { 815 throw "Ticker cannot be instantiated."; 816 } 817 818 819// constants: 820 /** 821 * In this mode, Ticker uses the requestAnimationFrame API, but attempts to synch the ticks to target framerate. It 822 * uses a simple heuristic that compares the time of the RAF return to the target time for the current frame and 823 * dispatches the tick when the time is within a certain threshold. 824 * 825 * This mode has a higher variance for time between frames than {{#crossLink "Ticker/TIMEOUT:property"}}{{/crossLink}}, 826 * but does not require that content be time based as with {{#crossLink "Ticker/RAF:property"}}{{/crossLink}} while 827 * gaining the benefits of that API (screen synch, background throttling). 828 * 829 * Variance is usually lowest for framerates that are a divisor of the RAF frequency. This is usually 60, so 830 * framerates of 10, 12, 15, 20, and 30 work well. 831 * 832 * Falls back to {{#crossLink "Ticker/TIMEOUT:property"}}{{/crossLink}} if the requestAnimationFrame API is not 833 * supported. 834 * @property RAF_SYNCHED 835 * @static 836 * @type {String} 837 * @default "synched" 838 * @readonly 839 **/ 840 Ticker.RAF_SYNCHED = "synched"; 841 842 /** 843 * In this mode, Ticker passes through the requestAnimationFrame heartbeat, ignoring the target framerate completely. 844 * Because requestAnimationFrame frequency is not deterministic, any content using this mode should be time based. 845 * You can leverage {{#crossLink "Ticker/getTime"}}{{/crossLink}} and the {{#crossLink "Ticker/tick:event"}}{{/crossLink}} 846 * event object's "delta" properties to make this easier. 847 * 848 * Falls back on {{#crossLink "Ticker/TIMEOUT:property"}}{{/crossLink}} if the requestAnimationFrame API is not 849 * supported. 850 * @property RAF 851 * @static 852 * @type {String} 853 * @default "raf" 854 * @readonly 855 **/ 856 Ticker.RAF = "raf"; 857 858 /** 859 * In this mode, Ticker uses the setTimeout API. This provides predictable, adaptive frame timing, but does not 860 * provide the benefits of requestAnimationFrame (screen synch, background throttling). 861 * @property TIMEOUT 862 * @static 863 * @type {String} 864 * @default "timeout" 865 * @readonly 866 **/ 867 Ticker.TIMEOUT = "timeout"; 868 869 870// static events: 871 /** 872 * Dispatched each tick. The event will be dispatched to each listener even when the Ticker has been paused using 873 * {{#crossLink "Ticker/setPaused"}}{{/crossLink}}. 874 * 875 * <h4>Example</h4> 876 * 877 * createjs.Ticker.addEventListener("tick", handleTick); 878 * function handleTick(event) { 879 * console.log("Paused:", event.paused, event.delta); 880 * } 881 * 882 * @event tick 883 * @param {Object} target The object that dispatched the event. 884 * @param {String} type The event type. 885 * @param {Boolean} paused Indicates whether the ticker is currently paused. 886 * @param {Number} delta The time elapsed in ms since the last tick. 887 * @param {Number} time The total time in ms since Ticker was initialized. 888 * @param {Number} runTime The total time in ms that Ticker was not paused since it was initialized. For example, 889 * you could determine the amount of time that the Ticker has been paused since initialization with `time-runTime`. 890 * @since 0.6.0 891 */ 892 893 894// public static properties: 895 /** 896 * Deprecated in favour of {{#crossLink "Ticker/timingMode"}}{{/crossLink}}, and will be removed in a future version. If true, timingMode will 897 * use {{#crossLink "Ticker/RAF_SYNCHED"}}{{/crossLink}} by default. 898 * @deprecated Deprecated in favour of {{#crossLink "Ticker/timingMode"}}{{/crossLink}}. 899 * @property useRAF 900 * @static 901 * @type {Boolean} 902 * @default false 903 **/ 904 Ticker.useRAF = false;
905 906 /** 907 * Specifies the timing api (setTimeout or requestAnimationFrame) and mode to use. See 908 * {{#crossLink "Ticker/TIMEOUT"}}{{/crossLink}}, {{#crossLink "Ticker/RAF"}}{{/crossLink}}, and 909 * {{#crossLink "Ticker/RAF_SYNCHED"}}{{/crossLink}} for mode details. 910 * @property timingMode 911 * @static 912 * @type {String} 913 * @default Ticker.TIMEOUT 914 **/ 915 Ticker.timingMode = null; 916 917 /** 918 * Specifies a maximum value for the delta property in the tick event object. This is useful when building time 919 * based animations and systems to prevent issues caused by large time gaps caused by background tabs, system sleep, 920 * alert dialogs, or other blocking routines. Double the expected frame duration is often an effective value 921 * (ex. maxDelta=50 when running at 40fps). 922 * 923 * This does not impact any other values (ex. time, runTime, etc), so you may experience issues if you enable maxDelta 924 * when using both delta and other values. 925 * 926 * If 0, there is no maximum. 927 * @property maxDelta 928 * @static 929 * @type {number} 930 * @default 0 931 */ 932 Ticker.maxDelta = 0; 933 934 /** 935 * When the ticker is paused, all listeners will still receive a tick event, but the <code>paused</code> property 936 * of the event will be `true`. Also, while paused the `runTime` will not increase. See {{#crossLink "Ticker/tick:event"}}{{/crossLink}}, 937 * {{#crossLink "Ticker/getTime"}}{{/crossLink}}, and {{#crossLink "Ticker/getEventTime"}}{{/crossLink}} for more 938 * info. 939 * 940 * <h4>Example</h4> 941 * 942 * createjs.Ticker.addEventListener("tick", handleTick); 943 * createjs.Ticker.paused = true; 944 * function handleTick(event) { 945 * console.log(event.paused, 946 * createjs.Ticker.getTime(false), 947 * createjs.Ticker.getTime(true)); 948 * } 949 * 950 * @property paused 951 * @static 952 * @type {Boolean} 953 * @default false 954 **/ 955 Ticker.paused = false; 956 957 958// mix-ins: 959 // EventDispatcher methods: 960 Ticker.removeEventListener = null; 961 Ticker.removeAllEventListeners = null; 962 Ticker.dispatchEvent = null; 963 Ticker.hasEventListener = null; 964 Ticker._listeners = null; 965 createjs.EventDispatcher.initialize(Ticker); // inject EventDispatcher methods. 966 Ticker._addEventListener = Ticker.addEventListener; 967 Ticker.addEventListener = function() { 968 !Ticker._inited&&Ticker.init(); 969 return Ticker._addEventListener.apply(Ticker, arguments); 970 }; 971 972 973// private static properties: 974 /** 975 * @property _inited 976 * @static 977 * @type {Boolean} 978 * @protected 979 **/ 980 Ticker._inited = false; 981 982 /** 983 * @property _startTime 984 * @static 985 * @type {Number} 986 * @protected 987 **/ 988 Ticker._startTime = 0; 989 990 /** 991 * @property _pausedTime 992 * @static 993 * @type {Number} 994 * @protected 995 **/ 996 Ticker._pausedTime=0; 997 998 /** 999 * The number of ticks that have passed 1000 * @property _ticks 1001 * @static 1002 * @type {Number} 1003 * @protected 1004 **/ 1005 Ticker._ticks = 0; 1006 1007 /** 1008 * The number of ticks that have passed while Ticker has been paused 1009 * @property _pausedTicks 1010 * @static 1011 * @type {Number} 1012 * @protected 1013 **/ 1014 Ticker._pausedTicks = 0; 1015 1016 /** 1017 * @property _interval 1018 * @static 1019 * @type {Number} 1020 * @protected 1021 **/ 1022 Ticker._interval = 50; 1023 1024 /** 1025 * @property _lastTime 1026 * @static 1027 * @type {Number} 1028 * @protected 1029 **/ 1030 Ticker._lastTime = 0; 1031 1032 /** 1033 * @property _times 1034 * @static 1035 * @type {Array} 1036 * @protected 1037 **/ 1038 Ticker._times = null; 1039 1040 /** 1041 * @property _tickTimes 1042 * @static 1043 * @type {Array} 1044 * @protected 1045 **/ 1046 Ticker._tickTimes = null; 1047 1048 /** 1049 * Stores the timeout or requestAnimationFrame id. 1050 * @property _timerId 1051 * @static 1052 * @type {Number} 1053 * @protected 1054 **/ 1055 Ticker._timerId = null; 1056 1057 /** 1058 * True if currently using requestAnimationFrame, false if using setTimeout. This may be different than timingMode 1059 * if that property changed and a tick hasn't fired. 1060 * @property _raf 1061 * @static 1062 * @type {Boolean} 1063 * @protected 1064 **/ 1065 Ticker._raf = true; 1066 1067 1068// static getter / setters: 1069 /** 1070 * Use the {{#crossLink "Ticker/interval:property"}}{{/crossLink}} property instead. 1071 * @method setInterval 1072 * @static 1073 * @param {Number} interval 1074 * @deprecated 1075 **/ 1076 Ticker.setInterval = function(interval) { 1077 Ticker._interval = interval; 1078 if (!Ticker._inited) { return; } 1079 Ticker._setupTick(); 1080 }; 1081 1082 /** 1083 * Use the {{#crossLink "Ticker/interval:property"}}{{/crossLink}} property instead. 1084 * @method getInterval 1085 * @static 1086 * @return {Number} 1087 * @deprecated 1088 **/ 1089 Ticker.getInterval = function() { 1090 return Ticker._interval; 1091 }; 1092 1093 /** 1094 * Use the {{#crossLink "Ticker/framerate:property"}}{{/crossLink}} property instead. 1095 * @method setFPS 1096 * @static 1097 * @param {Number} value 1098 * @deprecated 1099 **/ 1100 Ticker.setFPS = function(value) { 1101 Ticker.setInterval(1000/value); 1102 }; 1103 1104 /** 1105 * Use the {{#crossLink "Ticker/framerate:property"}}{{/crossLink}} property instead. 1106 * @method getFPS 1107 * @static 1108 * @return {Number} 1109 * @deprecated 1110 **/ 1111 Ticker.getFPS = function() { 1112 return 1000/Ticker._interval; 1113 }; 1114 1115 /** 1116 * Indicates the target time (in milliseconds) between ticks. Default is 50 (20 FPS). 1117 * Note that actual time between ticks may be more than specified depending on CPU load. 1118 * This property is ignored if the ticker is using the `RAF` timing mode. 1119 * @property interval 1120 * @static 1121 * @type {Number} 1122 **/ 1123 1124 /** 1125 * Indicates the target frame rate in frames per second (FPS). Effe
1125ctively just a shortcut to `interval`, where 1126 * `framerate == 1000/interval`. 1127 * @property framerate 1128 * @static 1129 * @type {Number} 1130 **/ 1131 try { 1132 Object.defineProperties(Ticker, { 1133 interval: { get: Ticker.getInterval, set: Ticker.setInterval }, 1134 framerate: { get: Ticker.getFPS, set: Ticker.setFPS } 1135 }); 1136 } catch (e) { console.log(e); } 1137 1138 1139// public static methods: 1140 /** 1141 * Starts the tick. This is called automatically when the first listener is added. 1142 * @method init 1143 * @static 1144 **/ 1145 Ticker.init = function() { 1146 if (Ticker._inited) { return; } 1147 Ticker._inited = true; 1148 Ticker._times = []; 1149 Ticker._tickTimes = []; 1150 Ticker._startTime = Ticker._getTime(); 1151 Ticker._times.push(Ticker._lastTime = 0); 1152 Ticker.interval = Ticker._interval; 1153 }; 1154 1155 /** 1156 * Stops the Ticker and removes all listeners. Use init() to restart the Ticker. 1157 * @method reset 1158 * @static 1159 **/ 1160 Ticker.reset = function() { 1161 if (Ticker._raf) { 1162 var f = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.oCancelAnimationFrame || window.msCancelAnimationFrame; 1163 f&&f(Ticker._timerId); 1164 } else { 1165 clearTimeout(Ticker._timerId); 1166 } 1167 Ticker.removeAllEventListeners("tick"); 1168 Ticker._timerId = Ticker._times = Ticker._tickTimes = null; 1169 Ticker._startTime = Ticker._lastTime = Ticker._ticks = 0; 1170 Ticker._inited = false; 1171 }; 1172 1173 /** 1174 * Returns the average time spent within a tick. This can vary significantly from the value provided by getMeasuredFPS 1175 * because it only measures the time spent within the tick execution stack. 1176 * 1177 * Example 1: With a target FPS of 20, getMeasuredFPS() returns 20fps, which indicates an average of 50ms between 1178 * the end of one tick and the end of the next. However, getMeasuredTickTime() returns 15ms. This indicates that 1179 * there may be up to 35ms of "idle" time between the end of one tick and the start of the next. 1180 * 1181 * Example 2: With a target FPS of 30, getFPS() returns 10fps, which indicates an average of 100ms between the end of 1182 * one tick and the end of the next. However, getMeasuredTickTime() returns 20ms. This would indicate that something 1183 * other than the tick is using ~80ms (another script, DOM rendering, etc). 1184 * @method getMeasuredTickTime 1185 * @static 1186 * @param {Number} [ticks] The number of previous ticks over which to measure the average time spent in a tick. 1187 * Defaults to the number of ticks per second. To get only the last tick's time, pass in 1. 1188 * @return {Number} The average time spent in a tick in milliseconds. 1189 **/ 1190 Ticker.getMeasuredTickTime = function(ticks) { 1191 var ttl=0, times=Ticker._tickTimes; 1192 if (!times || times.length < 1) { return -1; } 1193 1194 // by default, calculate average for the past ~1 second: 1195 ticks = Math.min(times.length, ticks||(Ticker.getFPS()|0)); 1196 for (var i=0; i<ticks; i++) { ttl += times[i]; } 1197 return ttl/ticks; 1198 }; 1199 1200 /** 1201 * Returns the actual frames / ticks per second. 1202 * @method getMeasuredFPS 1203 * @static 1204 * @param {Number} [ticks] The number of previous ticks over which to measure the actual frames / ticks per second. 1205 * Defaults to the number of ticks per second. 1206 * @return {Number} The actual frames / ticks per second. Depending on performance, this may differ 1207 * from the target frames per second. 1208 **/ 1209 Ticker.getMeasuredFPS = function(ticks) { 1210 var times = Ticker._times; 1211 if (!times || times.length < 2) { return -1; } 1212 1213 // by default, calculate fps for the past ~1 second: 1214 ticks = Math.min(times.length-1, ticks||(Ticker.getFPS()|0)); 1215 return 1000/((times[0]-times[ticks])/ticks); 1216 }; 1217 1218 /** 1219 * Use the {{#crossLink "Ticker/paused:property"}}{{/crossLink}} property instead. 1220 * @method setPaused 1221 * @static 1222 * @param {Boolean} value 1223 * @deprecated 1224 **/ 1225 Ticker.setPaused = function(value) { 1226 // TODO: deprecated. 1227 Ticker.paused = value; 1228 }; 1229 1230 /** 1231 * Use the {{#crossLink "Ticker/paused:property"}}{{/crossLink}} property instead. 1232 * @method getPaused 1233 * @static 1234 * @return {Boolean} 1235 * @deprecated 1236 **/ 1237 Ticker.getPaused = function() { 1238 // TODO: deprecated. 1239 return Ticker.paused; 1240 }; 1241 1242 /** 1243 * Returns the number of milliseconds that have elapsed since Ticker was initialized via {{#crossLink "Ticker/init"}}. 1244 * Returns -1 if Ticker has not been initialized. For example, you could use 1245 * this in a time synchronized animation to determine the exact amount of time that has elapsed. 1246 * @method getTime 1247 * @static 1248 * @param {Boolean} [runTime=false] If true only time elapsed while Ticker was not paused will be returned. 1249 * If false, the value returned will be total time elapsed since the first tick event listener was added. 1250 * @return {Number} Number of milliseconds that have elapsed since Ticker was initialized or -1. 1251 **/ 1252 Ticker.getTime = function(runTime) { 1253 return Ticker._startTime ? Ticker._getTime() - (runTime ? Ticker._pausedTime : 0) : -1; 1254 }; 1255 1256 /** 1257 * Similar to the {{#crossLink "Ticker/getTime"}}{{/crossLink}} method, but returns the time on the most recent {{#crossLink "Ticker/tick:event"}}{{/crossLink}} 1258 * event object. 1259 * @method getEventTime 1260 * @static 1261 * @param runTime {Boolean} [runTime=false] If true, the runTime property will be returned instead of time. 1262 * @returns {number} The time or runTime property from the most recent tick event or -1. 1263 */ 1264 Ticker.getEventTime = function(runTime) { 1265 return Ticker._startTime ? (Ticker._lastTime || Ticker._startTime) - (runTime ? Ticker._pausedTime : 0) : -1; 1266 }; 1267 1268 /** 1269 * Returns the number of ticks that have been broadcast by Ticker. 1270 * @method getTicks 1271 * @static 1272 * @param {Boolean} pauseable Indicates whether to include ticks that would have been broadcast 1273 * while Ticker was paused. If true only tick events broadcast while Ticker is not paused will be returned. 1274 * If false, tick events that would have been broadcast while Ticker was paused will be included in the return 1275 * value. The default value is false. 1276 * @return {Number} of ticks that have been broadcast. 1277 **/ 1278 Ticker.getTicks = function(pauseable) { 1279 return Ticker._ticks - (pauseable ? Ticker._pausedTicks : 0); 1280 }; 1281 1282 1283// private static methods: 1284 /** 1285 * @method _handleSynch 1286 * @static 1287 * @protected 1288 **/ 1289 Ticker._handleSynch = function() { 1290 Ticker._timerId = null; 1291 Ticker._setupTick(); 1292 1293 // run if enough time has elapsed, with a little bit of flexibility to be early: 1294 if (Ticker._getTime() - Ticker._lastTime >= (Ticker._interval-1)*0.97) { 1295 Ticker._tick(); 1296 } 1297 }; 1298 1299 /** 1300 * @method _handleRAF 1301 * @static 1302 * @protected 1303 **/ 1304 Ticker._handleRAF = function() { 1305 Ticker._timerId = null; 1306 Ticker._setupTick(); 1307 Ticker._tick(); 1308 }; 1309 1310 /** 1311 * @method _handleTimeout 1312 * @static 1313 * @protected 1314 **/ 1315 Ticker._handleTimeout = function() { 1316 Ticker._timerId = null; 1317 Ticker._setupTick(); 1318 Ticker._tick(); 1319 }; 1320 1321 /** 1322 * @method _setupTick 1323 * @static 1324 * @protected 1325 **/ 1326 Ticker._setupTick = function() { 1327 if (Ticker._timerId != null) { return; } // avoid duplicates 1328 1329 var mode = Ticker.timingMode||(Ticker.useRAF&&Ticker.RAF_SYNCHED); 1330 if (mode == Ticker.RAF_SYNCHED || mode == Ticker.RAF) { 1331 var f = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame; 1332 if (f) { 1333 Ticker._timerId = f(mode == Ticker.RAF ? Ticker._handleRAF : Ticker._handleSynch); 1334 Ticker._raf = true; 1335 return; 1336 } 1337 } 1338 Ticker._raf = false;
1339 Ticker._timerId = setTimeout(Ticker._handleTimeout, Ticker._interval); 1340 }; 1341 1342 /** 1343 * @method _tick 1344 * @static 1345 * @protected 1346 **/ 1347 Ticker._tick = function() { 1348 var paused = Ticker.paused; 1349 var time = Ticker._getTime(); 1350 var elapsedTime = time-Ticker._lastTime; 1351 Ticker._lastTime = time; 1352 Ticker._ticks++; 1353 1354 if (paused) { 1355 Ticker._pausedTicks++; 1356 Ticker._pausedTime += elapsedTime; 1357 } 1358 1359 if (Ticker.hasEventListener("tick")) { 1360 var event = new createjs.Event("tick"); 1361 var maxDelta = Ticker.maxDelta; 1362 event.delta = (maxDelta && elapsedTime > maxDelta) ? maxDelta : elapsedTime; 1363 event.paused = paused; 1364 event.time = time; 1365 event.runTime = time-Ticker._pausedTime; 1366 Ticker.dispatchEvent(event); 1367 } 1368 1369 Ticker._tickTimes.unshift(Ticker._getTime()-time); 1370 while (Ticker._tickTimes.length > 100) { Ticker._tickTimes.pop(); } 1371 1372 Ticker._times.unshift(time); 1373 while (Ticker._times.length > 100) { Ticker._times.pop(); } 1374 }; 1375 1376 /** 1377 * @method _getTime 1378 * @static 1379 * @protected 1380 **/ 1381 var now = window.performance && (performance.now || performance.mozNow || performance.msNow || performance.oNow || performance.webkitNow); 1382 Ticker._getTime = function() { 1383 return ((now&&now.call(performance))||(new Date().getTime())) - Ticker._startTime; 1384 }; 1385 1386 1387 createjs.Ticker = Ticker; 1388}()); 1389 1390//############################################################################## 1391// UID.js 1392//############################################################################## 1393 1394this.createjs = this.createjs||{}; 1395 1396(function() { 1397 "use strict"; 1398 1399 1400// constructor: 1401 /** 1402 * Global utility for generating sequential unique ID numbers. The UID class uses a static interface (ex. <code>UID.get()</code>) 1403 * and should not be instantiated. 1404 * @class UID 1405 * @static 1406 **/ 1407 function UID() { 1408 throw "UID cannot be instantiated"; 1409 } 1410 1411 1412// private static properties: 1413 /** 1414 * @property _nextID 1415 * @type Number 1416 * @protected 1417 **/ 1418 UID._nextID = 0; 1419 1420 1421// public static methods: 1422 /** 1423 * Returns the next unique id. 1424 * @method get 1425 * @return {Number} The next unique id 1426 * @static 1427 **/ 1428 UID.get = function() { 1429 return UID._nextID++; 1430 }; 1431 1432 1433 createjs.UID = UID; 1434}()); 1435 1436//############################################################################## 1437// MouseEvent.js 1438//############################################################################## 1439 1440this.createjs = this.createjs||{}; 1441 1442(function() { 1443 "use strict"; 1444 1445 1446// constructor: 1447 /** 1448 * Passed as the parameter to all mouse/pointer/touch related events. For a listing of mouse events and their properties, 1449 * see the {{#crossLink "DisplayObject"}}{{/crossLink}} and {{#crossLink "Stage"}}{{/crossLink}} event listings. 1450 * @class MouseEvent 1451 * @param {String} type The event type. 1452 * @param {Boolean} bubbles Indicates whether the event will bubble through the display list. 1453 * @param {Boolean} cancelable Indicates whether the default behaviour of this event can be cancelled. 1454 * @param {Number} stageX The normalized x position relative to the stage. 1455 * @param {Number} stageY The normalized y position relative to the stage. 1456 * @param {MouseEvent} nativeEvent The native DOM event related to this mouse event. 1457 * @param {Number} pointerID The unique id for the pointer. 1458 * @param {Boolean} primary Indicates whether this is the primary pointer in a multitouch environment. 1459 * @param {Number} rawX The raw x position relative to the stage. 1460 * @param {Number} rawY The raw y position relative to the stage. 1461 * @param {DisplayObject} relatedTarget The secondary target for the event. 1462 * @extends Event 1463 * @constructor 1464 **/ 1465 function MouseEvent(type, bubbles, cancelable, stageX, stageY, nativeEvent, pointerID, primary, rawX, rawY, relatedTarget) { 1466 this.Event_constructor(type, bubbles, cancelable); 1467 1468 1469 // public properties: 1470 /** 1471 * The normalized x position on the stage. This will always be within the range 0 to stage width. 1472 * @property stageX 1473 * @type Number 1474 */ 1475 this.stageX = stageX; 1476 1477 /** 1478 * The normalized y position on the stage. This will always be within the range 0 to stage height. 1479 * @property stageY 1480 * @type Number 1481 **/ 1482 this.stageY = stageY; 1483 1484 /** 1485 * The raw x position relative to the stage. Normally this will be the same as the stageX value, unless 1486 * stage.mouseMoveOutside is true and the pointer is outside of the stage bounds. 1487 * @property rawX 1488 * @type Number 1489 */ 1490 this.rawX = (rawX==null)?stageX:rawX; 1491 1492 /** 1493 * The raw y position relative to the stage. Normally this will be the same as the stageY value, unless 1494 * stage.mouseMoveOutside is true and the pointer is outside of the stage bounds. 1495 * @property rawY 1496 * @type Number 1497 */ 1498 this.rawY = (rawY==null)?stageY:rawY; 1499 1500 /** 1501 * The native MouseEvent generated by the browser. The properties and API for this 1502 * event may differ between browsers. This property will be null if the 1503 * EaselJS property was not directly generated from a native MouseEvent. 1504 * @property nativeEvent 1505 * @type HtmlMouseEvent 1506 * @default null 1507 **/ 1508 this.nativeEvent = nativeEvent; 1509 1510 /** 1511 * The unique id for the pointer (touch point or cursor). This will be either -1 for the mouse, or the system 1512 * supplied id value. 1513 * @property pointerID 1514 * @type {Number} 1515 */ 1516 this.pointerID = pointerID; 1517 1518 /** 1519 * Indicates whether this is the primary pointer in a multitouch environment. This will always be true for the mouse. 1520 * For touch pointers, the first pointer in the current stack will be considered the primary pointer. 1521 * @property primary 1522 * @type {Boolean} 1523 */ 1524 this.primary = !!primary; 1525 1526 /** 1527 * The secondary target for the event, if applicable. This is used for mouseout/rollout 1528 * events to indicate the object that the mouse entered from, mouseover/rollover for the object the mouse exited, 1529 * and stagemousedown/stagemouseup events for the object that was the under the cursor, if any. 1530 * 1531 * Only valid interaction targets will be returned (ie. objects with mouse listeners or a cursor set). 1532 * @property relatedTarget 1533 * @type {DisplayObject} 1534 */ 1535 this.relatedTarget = relatedTarget; 1536 }
1537 var p = createjs.extend(MouseEvent, createjs.Event); 1538 1539 // TODO: deprecated 1540 // p.initialize = function() {}; // searchable for devs wondering where it is. REMOVED. See docs for details. 1541 1542 1543// getter / setters: 1544 /** 1545 * Returns the x position of the mouse in the local coordinate system of the current target (ie. the dispatcher). 1546 * @property localX 1547 * @type {Number} 1548 * @readonly 1549 */ 1550 p._get_localX = function() { 1551 return this.currentTarget.globalToLocal(this.rawX, this.rawY).x; 1552 }; 1553 1554 /** 1555 * Returns the y position of the mouse in the local coordinate system of the current target (ie. the dispatcher). 1556 * @property localY 1557 * @type {Number} 1558 * @readonly 1559 */ 1560 p._get_localY = function() { 1561 return this.currentTarget.globalToLocal(this.rawX, this.rawY).y; 1562 }; 1563 1564 /** 1565 * Indicates whether the event was generated by a touch input (versus a mouse input). 1566 * @property isTouch 1567 * @type {Boolean} 1568 * @readonly 1569 */ 1570 p._get_isTouch = function() { 1571 return this.pointerID !== -1; 1572 }; 1573 1574 1575 try { 1576 Object.defineProperties(p, { 1577 localX: { get: p._get_localX }, 1578 localY: { get: p._get_localY }, 1579 isTouch: { get: p._get_isTouch } 1580 }); 1581 } catch (e) {} // TODO: use Log 1582 1583 1584// public methods: 1585 /** 1586 * Returns a clone of the MouseEvent instance. 1587 * @method clone 1588 * @return {MouseEvent} a clone of the MouseEvent instance. 1589 **/ 1590 p.clone = function() { 1591 return new MouseEvent(this.type, this.bubbles, this.cancelable, this.stageX, this.stageY, this.nativeEvent, this.pointerID, this.primary, this.rawX, this.rawY); 1592 }; 1593 1594 /** 1595 * Returns a string representation of this object. 1596 * @method toString 1597 * @return {String} a string representation of the instance. 1598 **/ 1599 p.toString = function() { 1600 return "[MouseEvent (type="+this.type+" stageX="+this.stageX+" stageY="+this.stageY+")]"; 1601 }; 1602 1603 1604 createjs.MouseEvent = createjs.promote(MouseEvent, "Event"); 1605}()); 1606 1607//############################################################################## 1608// Matrix2D.js 1609//############################################################################## 1610 1611this.createjs = this.createjs||{}; 1612 1613(function() { 1614 "use strict"; 1615 1616 1617// constructor: 1618 /** 1619 * Represents an affine transformation matrix, and provides tools for constructing and concatenating matrices. 1620 * 1621 * This matrix can be visualized as: 1622 * 1623 * [ a c tx 1624 * b d ty 1625 * 0 0 1 ] 1626 * 1627 * Note the locations of b and c. 1628 * 1629 * @class Matrix2D 1630 * @param {Number} [a=1] Specifies the a property for the new matrix. 1631 * @param {Number} [b=0] Specifies the b property for the new matrix. 1632 * @param {Number} [c=0] Specifies the c property for the new matrix. 1633 * @param {Number} [d=1] Specifies the d property for the new matrix. 1634 * @param {Number} [tx=0] Specifies the tx property for the new matrix. 1635 * @param {Number} [ty=0] Specifies the ty property for the new matrix. 1636 * @constructor 1637 **/ 1638 function Matrix2D(a, b, c, d, tx, ty) { 1639 this.setValues(a,b,c,d,tx,ty); 1640 1641 // public properties: 1642 // assigned in the setValues method. 1643 /** 1644 * Position (0, 0) in a 3x3 affine transformation matrix. 1645 * @property a 1646 * @type Number 1647 **/ 1648 1649 /** 1650 * Position (0, 1) in a 3x3 affine transformation matrix. 1651 * @property b 1652 * @type Number 1653 **/ 1654 1655 /** 1656 * Position (1, 0) in a 3x3 affine transformation matrix. 1657 * @property c 1658 * @type Number 1659 **/ 1660 1661 /** 1662 * Position (1, 1) in a 3x3 affine transformation matrix. 1663 * @property d 1664 * @type Number 1665 **/ 1666 1667 /** 1668 * Position (2, 0) in a 3x3 affine transformation matrix. 1669 * @property tx 1670 * @type Number 1671 **/ 1672 1673 /** 1674 * Position (2, 1) in a 3x3 affine transformation matrix. 1675 * @property ty 1676 * @type Number 1677 **/ 1678 }
1679 var p = Matrix2D.prototype; 1680 1681 /** 1682 * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`. 1683 * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}} 1684 * for details. 1685 * 1686 * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance. 1687 * 1688 * @method initialize 1689 * @protected 1690 * @deprecated 1691 */ 1692 // p.initialize = function() {}; // searchable for devs wondering where it is. 1693 1694 1695// constants: 1696 /** 1697 * Multiplier for converting degrees to radians. Used internally by Matrix2D. 1698 * @property DEG_TO_RAD 1699 * @static 1700 * @final 1701 * @type Number 1702 * @readonly 1703 **/ 1704 Matrix2D.DEG_TO_RAD = Math.PI/180; 1705 1706 1707// static public properties: 1708 /** 1709 * An identity matrix, representing a null transformation. 1710 * @property identity 1711 * @static 1712 * @type Matrix2D 1713 * @readonly 1714 **/ 1715 Matrix2D.identity = null; // set at bottom of class definition. 1716 1717 1718// public methods: 1719 /** 1720 * Sets the specified values on this instance. 1721 * @method setValues 1722 * @param {Number} [a=1] Specifies the a property for the new matrix. 1723 * @param {Number} [b=0] Specifies the b property for the new matrix. 1724 * @param {Number} [c=0] Specifies the c property for the new matrix. 1725 * @param {Number} [d=1] Specifies the d property for the new matrix. 1726 * @param {Number} [tx=0] Specifies the tx property for the new matrix. 1727 * @param {Number} [ty=0] Specifies the ty property for the new matrix. 1728 * @return {Matrix2D} This instance. Useful for chaining method calls. 1729 */ 1730 p.setValues = function(a, b, c, d, tx, ty) { 1731 // don't forget to update docs in the constructor if these change: 1732 this.a = (a == null) ? 1 : a; 1733 this.b = b || 0; 1734 this.c = c || 0; 1735 this.d = (d == null) ? 1 : d; 1736 this.tx = tx || 0; 1737 this.ty = ty || 0; 1738 return this; 1739 }; 1740 1741 /** 1742 * Appends the specified matrix properties to this matrix. All parameters are required. 1743 * This is the equivalent of multiplying `(this matrix) * (specified matrix)`. 1744 * @method append 1745 * @param {Number} a 1746 * @param {Number} b 1747 * @param {Number} c 1748 * @param {Number} d 1749 * @param {Number} tx 1750 * @param {Number} ty 1751 * @return {Matrix2D} This matrix. Useful for chaining method calls. 1752 **/ 1753 p.append = function(a, b, c, d, tx, ty) { 1754 var a1 = this.a; 1755 var b1 = this.b; 1756 var c1 = this.c; 1757 var d1 = this.d; 1758 if (a != 1 || b != 0 || c != 0 || d != 1) { 1759 this.a = a1*a+c1*b; 1760 this.b = b1*a+d1*b; 1761 this.c = a1*c+c1*d; 1762 this.d = b1*c+d1*d; 1763 } 1764 this.tx = a1*tx+c1*ty+this.tx; 1765 this.ty = b1*tx+d1*ty+this.ty; 1766 return this; 1767 }; 1768 1769 /** 1770 * Prepends the specified matrix properties to this matrix. 1771 * This is the equivalent of multiplying `(specified matrix) * (this matrix)`. 1772 * All parameters are required. 1773 * @method prepend 1774 * @param {Number} a 1775 * @param {Number} b 1776 * @param {Number} c 1777 * @param {Number} d 1778 * @param {Number} tx 1779 * @param {Number} ty 1780 * @return {Matrix2D} This matrix. Useful for chaining method calls. 1781 **/ 1782 p.prepend = function(a, b, c, d, tx, ty) { 1783 var a1 = this.a; 1784 var c1 = this.c; 1785 var tx1 = this.tx; 1786 1787 this.a = a*a1+c*this.b; 1788 this.b = b*a1+d*this.b; 1789 this.c = a*c1+c*this.d; 1790 this.d = b*c1+d*this.d; 1791 this.tx = a*tx1+c*this.ty+tx; 1792 this.ty = b*tx1+d*this.ty+ty; 1793 return this; 1794 }; 1795 1796 /** 1797 * Appends the specified matrix to this matrix. 1798 * This is the equivalent of multiplying `(this matrix) * (specified matrix)`. 1799 * @method appendMatrix 1800 * @param {Matrix2D} matrix 1801 * @return {Matrix2D} This matrix. Useful for chaining method calls. 1802 **/ 1803 p.appendMatrix = function(matrix) { 1804 return this.append(matrix.a, matrix.b, matrix.c, matrix.d, matrix.tx, matrix.ty); 1805 }; 1806 1807 /** 1808 * Prepends the specified matrix to this matrix. 1809 * This is the equivalent of multiplying `(specified matrix) * (this matrix)`. 1810 * For example, you could calculate the combined transformation for a child object using: 1811 * 1812 * var o = myDisplayObject;
1813 * var mtx = o.getMatrix(); 1814 * while (o = o.parent) { 1815 * // prepend each parent's transformation in turn: 1816 * o.prependMatrix(o.getMatrix()); 1817 * } 1818 * @method prependMatrix 1819 * @param {Matrix2D} matrix 1820 * @return {Matrix2D} This matrix. Useful for chaining method calls. 1821 **/ 1822 p.prependMatrix = function(matrix) { 1823 return this.prepend(matrix.a, matrix.b, matrix.c, matrix.d, matrix.tx, matrix.ty); 1824 }; 1825 1826 /** 1827 * Generates matrix properties from the specified display object transform properties, and appends them to this matrix. 1828 * For example, you can use this to generate a matrix representing the transformations of a display object: 1829 * 1830 * var mtx = new createjs.Matrix2D(); 1831 * mtx.appendTransform(o.x, o.y, o.scaleX, o.scaleY, o.rotation); 1832 * @method appendTransform 1833 * @param {Number} x 1834 * @param {Number} y 1835 * @param {Number} scaleX 1836 * @param {Number} scaleY 1837 * @param {Number} rotation 1838 * @param {Number} skewX 1839 * @param {Number} skewY 1840 * @param {Number} regX Optional. 1841 * @param {Number} regY Optional. 1842 * @return {Matrix2D} This matrix. Useful for chaining method calls. 1843 **/ 1844 p.appendTransform = function(x, y, scaleX, scaleY, rotation, skewX, skewY, regX, regY) { 1845 if (rotation%360) { 1846 var r = rotation*Matrix2D.DEG_TO_RAD; 1847 var cos = Math.cos(r); 1848 var sin = Math.sin(r); 1849 } else { 1850 cos = 1; 1851 sin = 0; 1852 } 1853 1854 if (skewX || skewY) { 1855 // TODO: can this be combined into a single append operation? 1856 skewX *= Matrix2D.DEG_TO_RAD; 1857 skewY *= Matrix2D.DEG_TO_RAD; 1858 this.append(Math.cos(skewY), Math.sin(skewY), -Math.sin(skewX), Math.cos(skewX), x, y); 1859 this.append(cos*scaleX, sin*scaleX, -sin*scaleY, cos*scaleY, 0, 0); 1860 } else { 1861 this.append(cos*scaleX, sin*scaleX, -sin*scaleY, cos*scaleY, x, y); 1862 } 1863 1864 if (regX || regY) { 1865 // append the registration offset: 1866 this.tx -= regX*this.a+regY*this.c; 1867 this.ty -= regX*this.b+regY*this.d; 1868 } 1869 return this; 1870 }; 1871 1872 /** 1873 * Generates matrix properties from the specified display object transform properties, and prepends them to this matrix. 1874 * For example, you could calculate the combined transformation for a child object using: 1875 * 1876 * var o = myDisplayObject;
1877 * var mtx = new createjs.Matrix2D(); 1878 * do { 1879 * // prepend each parent's transformation in turn: 1880 * mtx.prependTransform(o.x, o.y, o.scaleX, o.scaleY, o.rotation, o.skewX, o.skewY, o.regX, o.regY); 1881 * } while (o = o.parent); 1882 * 1883 * Note that the above example would not account for {{#crossLink "DisplayObject/transformMatrix:property"}}{{/crossLink}} 1884 * values. See {{#crossLink "Matrix2D/prependMatrix"}}{{/crossLink}} for an example that does. 1885 * @method prependTransform 1886 * @param {Number} x 1887 * @param {Number} y 1888 * @param {Number} scaleX 1889 * @param {Number} scaleY 1890 * @param {Number} rotation 1891 * @param {Number} skewX 1892 * @param {Number} skewY 1893 * @param {Number} regX Optional. 1894 * @param {Number} regY Optional. 1895 * @return {Matrix2D} This matrix. Useful for chaining method calls. 1896 **/ 1897 p.prependTransform = function(x, y, scaleX, scaleY, rotation, skewX, skewY, regX, regY) { 1898 if (rotation%360) { 1899 var r = rotation*Matrix2D.DEG_TO_RAD; 1900 var cos = Math.cos(r); 1901 var sin = Math.sin(r); 1902 } else { 1903 cos = 1; 1904 sin = 0; 1905 } 1906 1907 if (regX || regY) { 1908 // prepend the registration offset: 1909 this.tx -= regX; this.ty -= regY; 1910 } 1911 if (skewX || skewY) { 1912 // TODO: can this be combined into a single prepend operation? 1913 skewX *= Matrix2D.DEG_TO_RAD; 1914 skewY *= Matrix2D.DEG_TO_RAD; 1915 this.prepend(cos*scaleX, sin*scaleX, -sin*scaleY, cos*scaleY, 0, 0); 1916 this.prepend(Math.cos(skewY), Math.sin(skewY), -Math.sin(skewX), Math.cos(skewX), x, y); 1917 } else { 1918 this.prepend(cos*scaleX, sin*scaleX, -sin*scaleY, cos*scaleY, x, y); 1919 } 1920 return this; 1921 }; 1922 1923 /** 1924 * Applies a clockwise rotation transformation to the matrix. 1925 * @method rotate 1926 * @param {Number} angle The angle to rotate by, in degrees. To use a value in radians, multiply it by `180/Math.PI`. 1927 * @return {Matrix2D} This matrix. Useful for chaining method calls. 1928 **/ 1929 p.rotate = function(angle) { 1930 angle = angle*Matrix2D.DEG_TO_RAD; 1931 var cos = Math.cos(angle); 1932 var sin = Math.sin(angle); 1933 1934 var a1 = this.a; 1935 var b1 = this.b; 1936 1937 this.a = a1*cos+this.c*sin; 1938 this.b = b1*cos+this.d*sin; 1939 this.c = -a1*sin+this.c*cos; 1940 this.d = -b1*sin+this.d*cos; 1941 return this; 1942 }; 1943 1944 /** 1945 * Applies a skew transformation to the matrix. 1946 * @method skew 1947 * @param {Number} skewX The amount to skew horizontally in degrees. To use a value in radians, multiply it by `180/Math.PI`. 1948 * @param {Number} skewY The amount to skew vertically in degrees. 1949 * @return {Matrix2D} This matrix. Useful for chaining method calls. 1950 */ 1951 p.skew = function(skewX, skewY) { 1952 skewX = skewX*Matrix2D.DEG_TO_RAD; 1953 skewY = skewY*Matrix2D.DEG_TO_RAD; 1954 this.append(Math.cos(skewY), Math.sin(skewY), -Math.sin(skewX), Math.cos(skewX), 0, 0); 1955 return this; 1956 }; 1957 1958 /** 1959 * Applies a scale transformation to the matrix. 1960 * @method scale 1961 * @param {Number} x The amount to scale horizontally. E.G. a value of 2 will double the size in the X direction, and 0.5 will halve it. 1962 * @param {Number} y The amount to scale vertically. 1963 * @return {Matrix2D} This matrix. Useful for chaining method calls. 1964 **/ 1965 p.scale = function(x, y) { 1966 this.a *= x; 1967 this.b *= x; 1968 this.c *= y; 1969 this.d *= y; 1970 //this.tx *= x; 1971 //this.ty *= y; 1972 return this; 1973 }; 1974 1975 /** 1976 * Translates the matrix on the x and y axes. 1977 * @method translate 1978 * @param {Number} x 1979 * @param {Number} y 1980 * @return {Matrix2D} This matrix. Useful for chaining method calls. 1981 **/ 1982 p.translate = function(x, y) { 1983 this.tx += this.a*x + this.c*y; 1984 this.ty += this.b*x + this.d*y; 1985 return this; 1986 }; 1987 1988 /** 1989 * Sets the properties of the matrix to those of an identity matrix (one that applies a null transformation). 1990 * @method identity 1991 * @return {Matrix2D} This matrix. Useful for chaining method calls. 1992 **/ 1993 p.identity = function() { 1994 this.a = this.d = 1; 1995 this.b = this.c = this.tx = this.ty = 0; 1996 return this; 1997 }; 1998 1999 /** 2000 * Inverts the matrix, causing it to perform the opposite transformation. 2001 * @method invert 2002 * @return {Matrix2D} This matrix. Useful for chaining method calls. 2003 **/ 2004 p.invert = function() { 2005 var a1 = this.a; 2006 var b1 = this.b; 2007 var c1 = this.c; 2008 var d1 = this.d; 2009 var tx1 = this.tx; 2010 var n = a1*d1-b1*c1; 2011 2012 this.a = d1/n; 2013 this.b = -b1/n; 2014 this.c = -c1/n; 2015 this.d = a1/n; 2016 this.tx = (c1*this.ty-d1*tx1)/n; 2017 this.ty = -(a1*this.ty-b1*tx1)/n; 2018 return this; 2019 }; 2020 2021 /**
2022 * Returns true if the matrix is an identity matrix. 2023 * @method isIdentity 2024 * @return {Boolean} 2025 **/ 2026 p.isIdentity = function() { 2027 return this.tx === 0 && this.ty === 0 && this.a === 1 && this.b === 0 && this.c === 0 && this.d === 1; 2028 }; 2029 2030 /** 2031 * Returns true if this matrix is equal to the specified matrix (all property values are equal). 2032 * @method equals 2033 * @param {Matrix2D} matrix The matrix to compare. 2034 * @return {Boolean} 2035 **/ 2036 p.equals = function(matrix) { 2037 return this.tx === matrix.tx && this.ty === matrix.ty && this.a === matrix.a && this.b === matrix.b && this.c === matrix.c && this.d === matrix.d; 2038 }; 2039 2040 /** 2041 * Transforms a point according to this matrix. 2042 * @method transformPoint 2043 * @param {Number} x The x component of the point to transform. 2044 * @param {Number} y The y component of the point to transform. 2045 * @param {Point | Object} [pt] An object to copy the result into. If omitted a generic object with x/y properties will be returned. 2046 * @return {Point} This matrix. Useful for chaining method calls. 2047 **/ 2048 p.transformPoint = function(x, y, pt) { 2049 pt = pt||{}; 2050 pt.x = x*this.a+y*this.c+this.tx; 2051 pt.y = x*this.b+y*this.d+this.ty; 2052 return pt; 2053 }; 2054 2055 /** 2056 * Decomposes the matrix into transform properties (x, y, scaleX, scaleY, and rotation). Note that these values 2057 * may not match the transform properties you used to generate the matrix, though they will produce the same visual 2058 * results. 2059 * @method decompose 2060 * @param {Object} target The object to apply the transform properties to. If null, then a new object will be returned. 2061 * @return {Object} The target, or a new generic object with the transform properties applied. 2062 */ 2063 p.decompose = function(target) { 2064 // TODO: it would be nice to be able to solve for whether the matrix can be decomposed into only scale/rotation even when scale is negative 2065 if (target == null) { target = {}; } 2066 target.x = this.tx; 2067 target.y = this.ty; 2068 target.scaleX = Math.sqrt(this.a * this.a + this.b * this.b); 2069 target.scaleY = Math.sqrt(this.c * this.c + this.d * this.d); 2070 2071 var skewX = Math.atan2(-this.c, this.d); 2072 var skewY = Math.atan2(this.b, this.a); 2073 2074 var delta = Math.abs(1-skewX/skewY); 2075 if (delta < 0.00001) { // effectively identical, can use rotation: 2076 target.rotation = skewY/Matrix2D.DEG_TO_RAD; 2077 if (this.a < 0 && this.d >= 0) { 2078 target.rotation += (target.rotation <= 0) ? 180 : -180; 2079 } 2080 target.skewX = target.skewY = 0; 2081 } else { 2082 target.skewX = skewX/Matrix2D.DEG_TO_RAD; 2083 target.skewY = skewY/Matrix2D.DEG_TO_RAD; 2084 } 2085 return target; 2086 }; 2087 2088 /** 2089 * Copies all properties from the specified matrix to this matrix. 2090 * @method copy 2091 * @param {Matrix2D} matrix The matrix to copy properties from. 2092 * @return {Matrix2D} This matrix. Useful for chaining method calls. 2093 */ 2094 p.copy = function(matrix) { 2095 return this.setValues(matrix.a, matrix.b, matrix.c, matrix.d, matrix.tx, matrix.ty); 2096 }; 2097 2098 /** 2099 * Returns a clone of the Matrix2D instance. 2100 * @method clone 2101 * @return {Matrix2D} a clone of the Matrix2D instance. 2102 **/ 2103 p.clone = function() { 2104 return new Matrix2D(this.a, this.b, this.c, this.d, this.tx, this.ty); 2105 }; 2106 2107 /** 2108 * Returns a string representation of this object. 2109 * @method toString 2110 * @return {String} a string representation of the instance. 2111 **/ 2112 p.toString = function() { 2113 return "[Matrix2D (a="+this.a+" b="+this.b+" c="+this.c+" d="+this.d+" tx="+this.tx+" ty="+this.ty+")]"; 2114 }; 2115 2116 // this has to be populated after the class is defined: 2117 Matrix2D.identity = new Matrix2D(); 2118 2119 2120 createjs.Matrix2D = Matrix2D; 2121}()); 2122 2123//############################################################################## 2124// DisplayProps.js 2125//############################################################################## 2126 2127this.createjs = this.createjs||{}; 2128 2129(function() { 2130 "use strict"; 2131 2132 /** 2133 * Used for calculating and encapsulating display related properties. 2134 * @class DisplayProps 2135 * @param {Number} [visible=true] Visible value. 2136 * @param {Number} [alpha=1] Alpha value. 2137 * @param {Number} [shadow=null] A Shadow instance or null. 2138 * @param {Number} [compositeOperation=null] A compositeOperation value or null. 2139 * @param {Number} [matrix] A transformation matrix. Defaults to a new identity matrix. 2140 * @constructor 2141 **/
2142 function DisplayProps(visible, alpha, shadow, compositeOperation, matrix) { 2143 this.setValues(visible, alpha, shadow, compositeOperation, matrix); 2144 2145 // public properties: 2146 // assigned in the setValues method. 2147 /** 2148 * Property representing the alpha that will be applied to a display object. 2149 * @property alpha 2150 * @type Number 2151 **/ 2152 2153 /** 2154 * Property representing the shadow that will be applied to a display object. 2155 * @property shadow 2156 * @type Shadow 2157 **/ 2158 2159 /** 2160 * Property representing the compositeOperation that will be applied to a display object. 2161 * You can find a list of valid composite operations at: 2162 * <a href="https://developer.mozilla.org/en/Canvas_tutorial/Compositing">https://developer.mozilla.org/en/Canvas_tutorial/Compositing</a> 2163 * @property compositeOperation 2164 * @type String 2165 **/ 2166 2167 /** 2168 * Property representing the value for visible that will be applied to a display object. 2169 * @property visible 2170 * @type Boolean 2171 **/ 2172 2173 /** 2174 * The transformation matrix that will be applied to a display object. 2175 * @property matrix 2176 * @type Matrix2D 2177 **/ 2178 }
2179 var p = DisplayProps.prototype; 2180 2181// initialization: 2182 /** 2183 * Reinitializes the instance with the specified values. 2184 * @method setValues 2185 * @param {Number} [visible=true] Visible value. 2186 * @param {Number} [alpha=1] Alpha value. 2187 * @param {Number} [shadow=null] A Shadow instance or null. 2188 * @param {Number} [compositeOperation=null] A compositeOperation value or null. 2189 * @param {Number} [matrix] A transformation matrix. Defaults to an identity matrix. 2190 * @return {DisplayProps} This instance. Useful for chaining method calls. 2191 * @chainable 2192 */ 2193 p.setValues = function (visible, alpha, shadow, compositeOperation, matrix) { 2194 this.visible = visible == null ? true : !!visible; 2195 this.alpha = alpha == null ? 1 : alpha; 2196 this.shadow = shadow; 2197 this.compositeOperation = compositeOperation; 2198 this.matrix = matrix || (this.matrix&&this.matrix.identity()) || new createjs.Matrix2D(); 2199 return this; 2200 }; 2201 2202// public methods: 2203 /** 2204 * Appends the specified display properties. This is generally used to apply a child's properties its parent's. 2205 * @method append 2206 * @param {Boolean} visible desired visible value 2207 * @param {Number} alpha desired alpha value 2208 * @param {Shadow} shadow desired shadow value 2209 * @param {String} compositeOperation desired composite operation value 2210 * @param {Matrix2D} [matrix] a Matrix2D instance 2211 * @return {DisplayProps} This instance. Useful for chaining method calls. 2212 * @chainable 2213 */ 2214 p.append = function(visible, alpha, shadow, compositeOperation, matrix) { 2215 this.alpha *= alpha; 2216 this.shadow = shadow || this.shadow; 2217 this.compositeOperation = compositeOperation || this.compositeOperation; 2218 this.visible = this.visible && visible; 2219 matrix&&this.matrix.appendMatrix(matrix); 2220 return this; 2221 }; 2222 2223 /** 2224 * Prepends the specified display properties. This is generally used to apply a parent's properties to a child's. 2225 * For example, to get the combined display properties that would be applied to a child, you could use: 2226 * 2227 * var o = myDisplayObject; 2228 * var props = new createjs.DisplayProps(); 2229 * do { 2230 * // prepend each parent's props in turn: 2231 * props.prepend(o.visible, o.alpha, o.shadow, o.compositeOperation, o.getMatrix()); 2232 * } while (o = o.parent); 2233 * 2234 * @method prepend 2235 * @param {Boolean} visible desired visible value 2236 * @param {Number} alpha desired alpha value 2237 * @param {Shadow} shadow desired shadow value 2238 * @param {String} compositeOperation desired composite operation value 2239 * @param {Matrix2D} [matrix] a Matrix2D instance 2240 * @return {DisplayProps} This instance. Useful for chaining method calls. 2241 * @chainable 2242 */ 2243 p.prepend = function(visible, alpha, shadow, compositeOperation, matrix) { 2244 this.alpha *= alpha; 2245 this.shadow = this.shadow || shadow; 2246 this.compositeOperation = this.compositeOperation || compositeOperation; 2247 this.visible = this.visible && visible; 2248 matrix&&this.matrix.prependMatrix(matrix); 2249 return this; 2250 }; 2251 2252 /** 2253 * Resets this instance and its matrix to default values. 2254 * @method identity 2255 * @return {DisplayProps} This instance. Useful for chaining method calls. 2256 * @chainable 2257 */ 2258 p.identity = function() { 2259 this.visible = true; 2260 this.alpha = 1; 2261 this.shadow = this.compositeOperation = null; 2262 this.matrix.identity(); 2263 return this; 2264 }; 2265 2266 /** 2267 * Returns a clone of the DisplayProps instance. Clones the associated matrix. 2268 * @method clone 2269 * @return {DisplayProps} a clone of the DisplayProps instance. 2270 **/ 2271 p.clone = function() { 2272 return new DisplayProps(this.alpha, this.shadow, this.compositeOperation, this.visible, this.matrix.clone()); 2273 }; 2274 2275// private methods: 2276 2277 createjs.DisplayProps = DisplayProps; 2278})(); 2279 2280//############################################################################## 2281// Point.js 2282//############################################################################## 2283 2284this.createjs = this.createjs||{}; 2285 2286(function() { 2287 "use strict"; 2288 2289 2290// constructor: 2291 /** 2292 * Represents a point on a 2 dimensional x / y coordinate system. 2293 * 2294 * <h4>Example</h4> 2295 * 2296 * var point = new createjs.Point(0, 100); 2297 * 2298 * @class Point 2299 * @param {Number} [x=0] X position. 2300 * @param {Number} [y=0] Y position. 2301 * @constructor 2302 **/ 2303 function Point(x, y) { 2304 this.setValues(x, y); 2305 2306 2307 // public properties: 2308 // assigned in the setValues method. 2309 /** 2310 * X position. 2311 * @property x 2312 * @type Number 2313 **/ 2314 2315 /** 2316 * Y position. 2317 * @property y 2318 * @type Number 2319 **/ 2320 }
2321 var p = Point.prototype; 2322 2323 /** 2324 * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`. 2325 * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}} 2326 * for details. 2327 * 2328 * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance. 2329 * 2330 * @method initialize 2331 * @protected 2332 * @deprecated 2333 */ 2334 // p.initialize = function() {}; // searchable for devs wondering where it is. 2335 2336 2337// public methods: 2338 /** 2339 * Sets the specified values on this instance. 2340 * @method setValues 2341 * @param {Number} [x=0] X position. 2342 * @param {Number} [y=0] Y position. 2343 * @return {Point} This instance. Useful for chaining method calls. 2344 * @chainable 2345 */ 2346 p.setValues = function(x, y) { 2347 this.x = x||0; 2348 this.y = y||0; 2349 return this; 2350 }; 2351 2352 /** 2353 * Copies all properties from the specified point to this point. 2354 * @method copy 2355 * @param {Point} point The point to copy properties from. 2356 * @return {Point} This point. Useful for chaining method calls. 2357 * @chainable 2358 */ 2359 p.copy = function(point) { 2360 this.x = point.x; 2361 this.y = point.y; 2362 return this; 2363 }; 2364 2365 /** 2366 * Returns a clone of the Point instance. 2367 * @method clone 2368 * @return {Point} a clone of the Point instance. 2369 **/ 2370 p.clone = function() { 2371 return new Point(this.x, this.y); 2372 }; 2373 2374 /** 2375 * Returns a string representation of this object. 2376 * @method toString 2377 * @return {String} a string representation of the instance. 2378 **/ 2379 p.toString = function() { 2380 return "[Point (x="+this.x+" y="+this.y+")]"; 2381 }; 2382 2383 2384 createjs.Point = Point; 2385}()); 2386 2387//############################################################################## 2388// Rectangle.js 2389//############################################################################## 2390 2391this.createjs = this.createjs||{}; 2392 2393(function() { 2394 "use strict"; 2395 2396 2397// constructor: 2398 /** 2399 * Represents a rectangle as defined by the points (x, y) and (x+width, y+height). 2400 * 2401 * <h4>Example</h4> 2402 * 2403 * var rect = new createjs.Rectangle(0, 0, 100, 100); 2404 * 2405 * @class Rectangle 2406 * @param {Number} [x=0] X position. 2407 * @param {Number} [y=0] Y position. 2408 * @param {Number} [width=0] The width of the Rectangle. 2409 * @param {Number} [height=0] The height of the Rectangle. 2410 * @constructor 2411 **/ 2412 function Rectangle(x, y, width, height) { 2413 this.setValues(x, y, width, height); 2414 2415 2416 // public properties: 2417 // assigned in the setValues method. 2418 /** 2419 * X position. 2420 * @property x 2421 * @type Number 2422 **/ 2423 2424 /** 2425 * Y position. 2426 * @property y 2427 * @type Number 2428 **/ 2429 2430 /** 2431 * Width. 2432 * @property width 2433 * @type Number 2434 **/ 2435 2436 /** 2437 * Height. 2438 * @property height 2439 * @type Number 2440 **/ 2441 }
2442 var p = Rectangle.prototype; 2443 2444 /** 2445 * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`. 2446 * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}} 2447 * for details. 2448 * 2449 * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance. 2450 * 2451 * @method initialize 2452 * @protected 2453 * @deprecated 2454 */ 2455 // p.initialize = function() {}; // searchable for devs wondering where it is. 2456 2457 2458// public methods: 2459 /** 2460 * Sets the specified values on this instance. 2461 * @method setValues 2462 * @param {Number} [x=0] X position. 2463 * @param {Number} [y=0] Y position. 2464 * @param {Number} [width=0] The width of the Rectangle. 2465 * @param {Number} [height=0] The height of the Rectangle. 2466 * @return {Rectangle} This instance. Useful for chaining method calls. 2467 * @chainable 2468 */ 2469 p.setValues = function(x, y, width, height) { 2470 // don't forget to update docs in the constructor if these change: 2471 this.x = x||0; 2472 this.y = y||0; 2473 this.width = width||0; 2474 this.height = height||0; 2475 return this; 2476 }; 2477 2478 /** 2479 * Extends the rectangle's bounds to include the described point or rectangle. 2480 * @method extend 2481 * @param {Number} x X position of the point or rectangle. 2482 * @param {Number} y Y position of the point or rectangle. 2483 * @param {Number} [width=0] The width of the rectangle. 2484 * @param {Number} [height=0] The height of the rectangle. 2485 * @return {Rectangle} This instance. Useful for chaining method calls. 2486 * @chainable 2487 */ 2488 p.extend = function(x, y, width, height) { 2489 width = width||0; 2490 height = height||0; 2491 if (x+width > this.x+this.width) { this.width = x+width-this.x; } 2492 if (y+height > this.y+this.height) { this.height = y+height-this.y; } 2493 if (x < this.x) { this.width += this.x-x; this.x = x; } 2494 if (y < this.y) { this.height += this.y-y; this.y = y; } 2495 return this; 2496 }; 2497 2498 /** 2499 * Adds the specified padding to the rectangle's bounds. 2500 * @method pad 2501 * @param {Number} top 2502 * @param {Number} left 2503 * @param {Number} right 2504 * @param {Number} bottom 2505 * @return {Rectangle} This instance. Useful for chaining method calls. 2506 * @chainable 2507 */ 2508 p.pad = function(top, left, bottom, right) { 2509 this.x -= left; 2510 this.y -= top; 2511 this.width += left+right; 2512 this.height += top+bottom; 2513 return this; 2514 }; 2515 2516 /** 2517 * Copies all properties from the specified rectangle to this rectangle. 2518 * @method copy 2519 * @param {Rectangle} rectangle The rectangle to copy properties from. 2520 * @return {Rectangle} This rectangle. Useful for chaining method calls. 2521 * @chainable 2522 */ 2523 p.copy = function(rectangle) { 2524 return this.setValues(rectangle.x, rectangle.y, rectangle.width, rectangle.height); 2525 }; 2526 2527 /** 2528 * Returns true if this rectangle fully encloses the described point or rectangle. 2529 * @method contains 2530 * @param {Number} x X position of the point or rectangle. 2531 * @param {Number} y Y position of the point or rectangle. 2532 * @param {Number} [width=0] The width of the rectangle. 2533 * @param {Number} [height=0] The height of the rectangle. 2534 * @return {Boolean} True if the described point or rectangle is contained within this rectangle. 2535 */ 2536 p.contains = function(x, y, width, height) { 2537 width = width||0; 2538 height = height||0; 2539 return (x >= this.x && x+width <= this.x+this.width && y >= this.y && y+height <= this.y+this.height); 2540 }; 2541 2542 /** 2543 * Returns a new rectangle which contains this rectangle and the specified rectangle. 2544 * @method union 2545 * @param {Rectangle} rect The rectangle to calculate a union with. 2546 * @return {Rectangle} A new rectangle describing the union. 2547 */ 2548 p.union = function(rect) { 2549 return this.clone().extend(rect.x, rect.y, rect.width, rect.height); 2550 }; 2551 2552 /** 2553 * Returns a new rectangle which describes the intersection (overlap) of this rectangle and the specified rectangle, 2554 * or null if they do not intersect. 2555 * @method intersection 2556 * @param {Rectangle} rect The rectangle to calculate an intersection with. 2557 * @return {Rectangle} A new rectangle describing the intersection or null. 2558 */ 2559 p.intersection = function(rect) {
2560 var x1 = rect.x, y1 = rect.y, x2 = x1+rect.width, y2 = y1+rect.height; 2561 if (this.x > x1) { x1 = this.x; } 2562 if (this.y > y1) { y1 = this.y; } 2563 if (this.x + this.width < x2) { x2 = this.x + this.width; } 2564 if (this.y + this.height < y2) { y2 = this.y + this.height; } 2565 return (x2 <= x1 || y2 <= y1) ? null : new Rectangle(x1, y1, x2-x1, y2-y1); 2566 }; 2567 2568 /** 2569 * Returns true if the specified rectangle intersects (has any overlap) with this rectangle. 2570 * @method intersects 2571 * @param {Rectangle} rect The rectangle to compare. 2572 * @return {Boolean} True if the rectangles intersect. 2573 */ 2574 p.intersects = function(rect) { 2575 return (rect.x <= this.x+this.width && this.x <= rect.x+rect.width && rect.y <= this.y+this.height && this.y <= rect.y + rect.height); 2576 }; 2577 2578 /** 2579 * Returns true if the width or height are equal or less than 0. 2580 * @method isEmpty 2581 * @return {Boolean} True if the rectangle is empty. 2582 */ 2583 p.isEmpty = function() { 2584 return this.width <= 0 || this.height <= 0; 2585 }; 2586 2587 /** 2588 * Returns a clone of the Rectangle instance. 2589 * @method clone 2590 * @return {Rectangle} a clone of the Rectangle instance. 2591 **/ 2592 p.clone = function() { 2593 return new Rectangle(this.x, this.y, this.width, this.height); 2594 }; 2595 2596 /** 2597 * Returns a string representation of this object. 2598 * @method toString 2599 * @return {String} a string representation of the instance. 2600 **/ 2601 p.toString = function() { 2602 return "[Rectangle (x="+this.x+" y="+this.y+" width="+this.width+" height="+this.height+")]"; 2603 }; 2604 2605 2606 createjs.Rectangle = Rectangle; 2607}()); 2608 2609//############################################################################## 2610// ButtonHelper.js 2611//############################################################################## 2612 2613this.createjs = this.createjs||{}; 2614 2615(function() { 2616 "use strict"; 2617 2618 2619// constructor: 2620 /** 2621 * The ButtonHelper is a helper class to create interactive buttons from {{#crossLink "MovieClip"}}{{/crossLink}} or 2622 * {{#crossLink "Sprite"}}{{/crossLink}} instances. This class will intercept mouse events from an object, and 2623 * automatically call {{#crossLink "Sprite/gotoAndStop"}}{{/crossLink}} or {{#crossLink "Sprite/gotoAndPlay"}}{{/crossLink}}, 2624 * to the respective animation labels, add a pointer cursor, and allows the user to define a hit state frame. 2625 * 2626 * The ButtonHelper instance does not need to be added to the stage, but a reference should be maintained to prevent 2627 * garbage collection. 2628 * 2629 * Note that over states will not work unless you call {{#crossLink "Stage/enableMouseOver"}}{{/crossLink}}. 2630 * 2631 * <h4>Example</h4> 2632 * 2633 * var helper = new createjs.ButtonHelper(myInstance, "out", "over", "down", false, myInstance, "hit"); 2634 * myInstance.addEventListener("click", handleClick); 2635 * function handleClick(event) { 2636 * // Click Happened. 2637 * } 2638 * 2639 * @class ButtonHelper 2640 * @param {Sprite|MovieClip} target The instance to manage. 2641 * @param {String} [outLabel="out"] The label or animation to go to when the user rolls out of the button. 2642 * @param {String} [overLabel="over"] The label or animation to go to when the user rolls over the button. 2643 * @param {String} [downLabel="down"] The label or animation to go to when the user presses the button. 2644 * @param {Boolean} [play=false] If the helper should call "gotoAndPlay" or "gotoAndStop" on the button when changing 2645 * states. 2646 * @param {DisplayObject} [hitArea] An optional item to use as the hit state for the button. If this is not defined, 2647 * then the button's visible states will be used instead. Note that the same instance as the "target" argument can be 2648 * used for the hitState. 2649 * @param {String} [hitLabel] The label or animation on the hitArea instance that defines the hitArea bounds. If this is 2650 * null, then the default state of the hitArea will be used. * 2651 * @constructor 2652 */ 2653 function ButtonHelper(target, outLabel, overLabel, downLabel, play, hitArea, hitLabel) { 2654 if (!target.addEventListener) { return; } 2655 2656 2657 // public properties: 2658 /** 2659 * The target for this button helper. 2660 * @property target 2661 * @type MovieClip | Sprite 2662 * @readonly 2663 **/ 2664 this.target = target; 2665 2666 /** 2667 * The label name or frame number to display when the user mouses out of the target. Defaults to "over". 2668 * @property overLabel
2669 * @type String | Number 2670 **/ 2671 this.overLabel = overLabel == null ? "over" : overLabel; 2672 2673 /** 2674 * The label name or frame number to display when the user mouses over the target. Defaults to "out". 2675 * @property outLabel 2676 * @type String | Number 2677 **/ 2678 this.outLabel = outLabel == null ? "out" : outLabel; 2679 2680 /** 2681 * The label name or frame number to display when the user presses on the target. Defaults to "down". 2682 * @property downLabel 2683 * @type String | Number 2684 **/ 2685 this.downLabel = downLabel == null ? "down" : downLabel; 2686 2687 /** 2688 * If true, then ButtonHelper will call gotoAndPlay, if false, it will use gotoAndStop. Default is false. 2689 * @property play 2690 * @default false 2691 * @type Boolean 2692 **/ 2693 this.play = play; 2694 2695 2696 // private properties 2697 /** 2698 * @property _isPressed 2699 * @type Boolean 2700 * @protected 2701 **/ 2702 this._isPressed = false; 2703 2704 /** 2705 * @property _isOver 2706 * @type Boolean 2707 * @protected 2708 **/ 2709 this._isOver = false; 2710 2711 /** 2712 * @property _enabled 2713 * @type Boolean 2714 * @protected 2715 **/ 2716 this._enabled = false; 2717 2718 // setup: 2719 target.mouseChildren = false; // prevents issues when children are removed from the display list when state changes. 2720 this.enabled = true; 2721 this.handleEvent({}); 2722 if (hitArea) { 2723 if (hitLabel) { 2724 hitArea.actionsEnabled = false; 2725 hitArea.gotoAndStop&&hitArea.gotoAndStop(hitLabel); 2726 } 2727 target.hitArea = hitArea; 2728 } 2729 } 2730 var p = ButtonHelper.prototype; 2731 2732 /** 2733 * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`. 2734 * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}} 2735 * for details. 2736 * 2737 * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance. 2738 * 2739 * @method initialize 2740 * @protected 2741 * @deprecated 2742 */ 2743 // p.initialize = function() {}; // searchable for devs wondering where it is. 2744 2745 2746// getter / setters: 2747 /** 2748 * Use the {{#crossLink "ButtonHelper/enabled:property"}}{{/crossLink}} property instead. 2749 * @method setEnabled 2750 * @param {Boolean} value 2751 * @deprecated 2752 **/ 2753 p.setEnabled = function(value) { // TODO: deprecated. 2754 if (value == this._enabled) { return; } 2755 var o = this.target; 2756 this._enabled = value; 2757 if (value) { 2758 o.cursor = "pointer"; 2759 o.addEventListener("rollover", this); 2760 o.addEventListener("rollout", this); 2761 o.addEventListener("mousedown", this); 2762 o.addEventListener("pressup", this); 2763 if (o._reset) { o.__reset = o._reset; o._reset = this._reset;} 2764 } else { 2765 o.cursor = null; 2766 o.removeEventListener("rollover", this); 2767 o.removeEventListener("rollout", this); 2768 o.removeEventListener("mousedown", this); 2769 o.removeEventListener("pressup", this); 2770 if (o.__reset) { o._reset = o.__reset; delete(o.__reset); } 2771 } 2772 }; 2773 /** 2774 * Use the {{#crossLink "ButtonHelper/enabled:property"}}{{/crossLink}} property instead. 2775 * @method getEnabled 2776 * @return {Boolean} 2777 * @deprecated 2778 **/ 2779 p.getEnabled = function() { 2780 return this._enabled; 2781 }; 2782 2783 /** 2784 * Enables or disables the button functionality on the target. 2785 * @property enabled 2786 * @type {Boolean} 2787 **/ 2788 try { 2789 Object.defineProperties(p, { 2790 enabled: { get: p.getEnabled, set: p.setEnabled } 2791 }); 2792 } catch (e) {} // TODO: use Log 2793 2794 2795// public methods: 2796 /** 2797 * Returns a string representation of this object. 2798 * @method toString 2799 * @return {String} a string representation of the instance. 2800 **/ 2801 p.toString = function() { 2802 return "[ButtonHelper]"; 2803 }; 2804 2805 2806// private methods: 2807 /** 2808 * @method handleEvent 2809 * @param {Object} evt The mouse event to handle. 2810 * @protected 2811 **/ 2812 p.handleEvent = function(evt) { 2813 var label, t = this.target, type = evt.type; 2814 if (type == "mousedown") { 2815 this._isPressed = true; 2816 label = this.downLabel; 2817 } else if (type == "pressup") { 2818 this._isPressed = false; 2819 label = this._isOver ? this.overLabel : this.outLabel; 2820 } else if (type == "rollover") { 2821 this._isOver = true; 2822 label = this._isPressed ? this.downLabel : this.overLabel; 2823 } else { // rollout and default 2824 this._isOver = false; 2825 label = this._isPressed ? this.overLabel : this.outLabel; 2826 } 2827 if (this.play) {
2828 t.gotoAndPlay&&t.gotoAndPlay(label); 2829 } else { 2830 t.gotoAndStop&&t.gotoAndStop(label); 2831 } 2832 }; 2833 2834 /** 2835 * Injected into target. Preserves the paused state through a reset. 2836 * @method _reset 2837 * @protected 2838 **/ 2839 p._reset = function() { 2840 // TODO: explore better ways to handle this issue. This is hacky & disrupts object signatures. 2841 var p = this.paused; 2842 this.__reset(); 2843 this.paused = p; 2844 }; 2845 2846 2847 createjs.ButtonHelper = ButtonHelper; 2848}()); 2849 2850//############################################################################## 2851// Shadow.js 2852//############################################################################## 2853 2854this.createjs = this.createjs||{}; 2855 2856(function() { 2857 "use strict"; 2858 2859 2860// constructor: 2861 /** 2862 * This class encapsulates the properties required to define a shadow to apply to a {{#crossLink "DisplayObject"}}{{/crossLink}} 2863 * via its <code>shadow</code> property. 2864 * 2865 * <h4>Example</h4> 2866 * 2867 * myImage.shadow = new createjs.Shadow("#000000", 5, 5, 10); 2868 * 2869 * @class Shadow 2870 * @constructor 2871 * @param {String} color The color of the shadow. This can be any valid CSS color value. 2872 * @param {Number} offsetX The x offset of the shadow in pixels. 2873 * @param {Number} offsetY The y offset of the shadow in pixels. 2874 * @param {Number} blur The size of the blurring effect. 2875 **/ 2876 function Shadow(color, offsetX, offsetY, blur) { 2877 2878 2879 // public properties: 2880 /** 2881 * The color of the shadow. This can be any valid CSS color value. 2882 * @property color
2883 * @type String 2884 * @default null 2885 */ 2886 this.color = color||"black"; 2887 2888 /** The x offset of the shadow. 2889 * @property offsetX 2890 * @type Number 2891 * @default 0 2892 */ 2893 this.offsetX = offsetX||0; 2894 2895 /** The y offset of the shadow. 2896 * @property offsetY 2897 * @type Number 2898 * @default 0 2899 */ 2900 this.offsetY = offsetY||0; 2901 2902 /** The blur of the shadow. 2903 * @property blur 2904 * @type Number 2905 * @default 0 2906 */ 2907 this.blur = blur||0; 2908 } 2909 var p = Shadow.prototype; 2910 2911 /** 2912 * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`. 2913 * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}} 2914 * for details. 2915 * 2916 * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance. 2917 * 2918 * @method initialize 2919 * @protected 2920 * @deprecated 2921 */ 2922 // p.initialize = function() {}; // searchable for devs wondering where it is. 2923 2924 2925// static public properties: 2926 /** 2927 * An identity shadow object (all properties are set to 0). 2928 * @property identity 2929 * @type Shadow 2930 * @static 2931 * @final 2932 * @readonly 2933 **/ 2934 Shadow.identity = new Shadow("transparent", 0, 0, 0); 2935 2936 2937// public methods: 2938 /** 2939 * Returns a string representation of this object. 2940 * @method toString 2941 * @return {String} a string representation of the instance. 2942 **/ 2943 p.toString = function() { 2944 return "[Shadow]"; 2945 }; 2946 2947 /** 2948 * Returns a clone of this Shadow instance. 2949 * @method clone 2950 * @return {Shadow} A clone of the current Shadow instance. 2951 **/ 2952 p.clone = function() { 2953 return new Shadow(this.color, this.offsetX, this.offsetY, this.blur); 2954 }; 2955 2956 2957 createjs.Shadow = Shadow; 2958}()); 2959 2960//############################################################################## 2961// SpriteSheet.js 2962//############################################################################## 2963 2964this.createjs = this.createjs||{}; 2965 2966(function() { 2967 "use strict"; 2968 2969 2970// constructor: 2971 /** 2972 * Encapsulates the properties and methods associated with a sprite sheet. A sprite sheet is a series of images (usually 2973 * animation frames) combined into a larger image (or images). For example, an animation consisting of eight 100x100 2974 * images could be combined into a single 400x200 sprite sheet (4 frames across by 2 high). 2975 * 2976 * The data passed to the SpriteSheet constructor defines: 2977 * <ol> 2978 * <li> The source image or images to use.</li> 2979 * <li> The positions of individual image frames.</li> 2980 * <li> Sequences of frames that form named animations. Optional.</li> 2981 * <li> The target playback framerate. Optional.</li> 2982 * </ol> 2983 * <h3>SpriteSheet Format</h3> 2984 * SpriteSheets are an object with two required properties (`images` and `frames`), and two optional properties 2985 * (`framerate` and `animations`). This makes them easy to define in javascript code, or in JSON. 2986 * 2987 * <h4>images</h4> 2988 * An array of source images. Images can be either an HTMlimage 2989 * instance, or a uri to an image. The former is recommended to control preloading. 2990 * 2991 * images: [image1, "path/to/image2.png"], 2992 * 2993 * <h4>frames</h4> 2994 * Defines the individual frames. There are two supported formats for frame data: 2995 * When all of the frames are the same size (in a grid), use an object with `width`, `height`, `regX`, `regY`, 2996 * and `count` properties. 2997 * 2998 * <ul> 2999 * <li>`width` & `height` are required and specify the dimensions of the frames</li> 3000 * <li>`regX` & `regY` indicate the registration point or "origin" of the frames</li> 3001 * <li>`spacing` indicate the spacing between frames</li> 3002 * <li>`margin` specify the margin around the image(s)</li> 3003 * <li>`count` allows you to specify the total number of frames in the spritesheet; if omitted, this will 3004 * be calculated based on the dimensions of the source images and the frames. Frames will be assigned 3005 * indexes based on their position in the source images (left to right, top to bottom).</li> 3006 * </ul> 3007 * 3008 * frames: {width:64, height:64, count:20, regX: 32, regY:64, spacing:0, margin:0} 3009 * 3010 * If the frames are of different sizes, use an array of frame definitions. Each definition is itself an array 3011 * with 4 required and 3 optional entries, in the order: 3012 * 3013 * <ul> 3014 * <li>The first four, `x`, `y`, `width`, and `height` are required and define the frame rectangle.</li> 3015 * <li>The fifth, `imageIndex`, specifies the index of the source image (defaults to 0)</li> 3016 * <li>The last two, `regX` and `regY` specify the registration point of the frame</li> 3017 * </ul> 3018 * 3019 * frames: [ 3020 * // x, y, width, height, imageIndex*, regX*, regY* 3021 * [64, 0, 96, 64], 3022 * [0, 0, 64, 64, 1, 32, 32] 3023 * // etc. 3024 * ] 3025 * 3026 * <h4>animations</h4> 3027 * Optional. An object defining sequences of frames to play as
3027named animations. Each property corresponds to an 3028 * animation of the same name. Each animation must specify the frames to play, and may 3029 * also include a relative playback `speed` (ex. 2 would playback at double speed, 0.5 at half), and 3030 * the name of the `next` animation to sequence to after it completes. 3031 * 3032 * There are three formats supported for defining the frames in an animation, which can be mixed and matched as appropriate: 3033 * <ol> 3034 * <li>for a single frame animation, you can simply specify the frame index 3035 * 3036 * animations: { 3037 * sit: 7 3038 * } 3039 * 3040 * </li> 3041 * <li> 3042 * for an animation of consecutive frames, you can use an array with two required, and two optional entries 3043 * in the order: `start`, `end`, `next`, and `speed`. This will play the frames from start to end inclusive. 3044 * 3045 * animations: { 3046 * // start, end, next*, speed* 3047 * run: [0, 8], 3048 * jump: [9, 12, "run", 2] 3049 * } 3050 * 3051 * </li> 3052 * <li> 3053 * for non-consecutive frames, you can use an object with a `frames` property defining an array of frame 3054 * indexes to play in order. The object can also specify `next` and `speed` properties. 3055 * 3056 * animations: { 3057 * walk: { 3058 * frames: [1,2,3,3,2,1] 3059 * }, 3060 * shoot: { 3061 * frames: [1,4,5,6], 3062 * next: "walk", 3063 * speed: 0.5 3064 * } 3065 * } 3066 * 3067 * </li> 3068 * </ol> 3069 * <strong>Note:</strong> the `speed` property was added in EaselJS 0.7.0. Earlier versions had a `frequency` 3070 * property instead, which was the inverse of `speed`. For example, a value of "4" would be 1/4 normal speed in 3071 * earlier versions, but is 4x normal speed in EaselJS 0.7.0+. 3072 * 3073 * <h4>framerate</h4> 3074 * Optional. Indicates the default framerate to play this spritesheet at in frames per second. See 3075 * {{#crossLink "SpriteSheet/framerate:property"}}{{/crossLink}} for more information. 3076 * 3077 * framerate: 20 3078 * 3079 * Note that the Sprite framerate will only work if the stage update method is provided with the {{#crossLink "Ticker/tick:event"}}{{/crossLink}} 3080 * event generated by the {{#crossLink "Ticker"}}{{/crossLink}}. 3081 * 3082 * createjs.Ticker.on("tick", handleTick); 3083 * function handleTick(event) { 3084 * stage.update(event); 3085 * } 3086 * 3087 * <h3>Example</h3> 3088 * To define a simple sprite sheet, with a single image "sprites.jpg" arranged in a regular 50x50 grid with three 3089 * animations: "stand" showing the first frame, "run" looping frame 1-5 inclusive, and "jump" playing frame 6-8 and 3090 * sequencing back to run. 3091 * 3092 * var data = { 3093 * images: ["sprites.jpg"], 3094 * frames: {width:50, height:50}, 3095 * animations: { 3096 * stand:0, 3097 * run:[1,5], 3098 * jump:[6,8,"run"] 3099 * } 3100 * }; 3101 * var spriteSheet = new createjs.SpriteSheet(data); 3102 * var animation = new createjs.Sprite(spriteSheet, "run"); 3103 * 3104 * <h3>Generating SpriteSheet Images</h3> 3105 * Spritesheets can be created manually by combining images in PhotoShop, and specifying the frame size or 3106 * coordinates manually, however there are a number of tools that facilitate this. 3107 * <ul> 3108 * <li>Exporting SpriteSheets or HTML5 content from Flash Pro supports the EaselJS SpriteSheet format.</li> 3109 * <li>The popular <a href="https://www.codeandweb.com/texturepacker/easeljs" target="_blank">Texture Packer</a> has 3110 * EaselJS support. 3111 * <li>SWF animations in Flash can be exported to SpriteSheets using <a href="http://createjs.com/zoe" target="_blank"></a></li> 3112 * </ul> 3113 * 3114 * <h3>Cross Origin Issues</h3> 3115 * <strong>Warning:</strong> Images loaded cross-origin will throw cross-origin security errors when interacted with 3116 * using: 3117 * <ul> 3118 * <li>a mouse</li> 3119 * <li>methods such as {{#crossLink "Container/getObjectUnderPoint"}}{{/crossLink}}</li> 3120 * <li>Filters (see {{#crossLink "Filter"}}{{/crossLink}})</li> 3121 * <li>caching (see {{#crossLink "DisplayObject/cache"}}{{/crossLink}})</li> 3122 * </ul> 3123 * You can get around this by setting `crossOrigin` property on your images before passing them to EaselJS, or 3124 * setting the `crossOrigin` property on PreloadJS' LoadQueue or LoadItems. 3125 * 3126 * var image = new Image(); 3127 * img.crossOrigin="Anonymous"; 3128 * img.src = "http://server-with-CORS-support.com/path/to/image.jpg"; 3129 * 3130 * If you pass string paths to SpriteSheets, they will not work cross-origin. The server that stores the image must 3131 * support cross-origin requests, or this will not work. For more information, check out 3132 * <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS" target="_blank">CORS overview on MDN</a>. 3133 * 3134 * @class SpriteSheet 3135 * @constructor 3136 * @param {Object} data An object describing the SpriteSheet data.
3137 * @extends EventDispatcher 3138 **/ 3139 function SpriteSheet(data) { 3140 this.EventDispatcher_constructor(); 3141 3142 3143 // public properties: 3144 /** 3145 * Indicates whether all images are finished loading. 3146 * @property complete 3147 * @type Boolean 3148 * @readonly 3149 **/ 3150 this.complete = true; 3151 3152 /** 3153 * Specifies the framerate to use by default for Sprite instances using the SpriteSheet. See the Sprite class 3154 * {{#crossLink "Sprite/framerate:property"}}{{/crossLink}} for more information. 3155 * @property framerate 3156 * @type Number 3157 **/ 3158 this.framerate = 0; 3159 3160 3161 // private properties: 3162 /** 3163 * @property _animations 3164 * @protected 3165 * @type Array 3166 **/ 3167 this._animations = null; 3168 3169 /** 3170 * @property _frames 3171 * @protected 3172 * @type Array 3173 **/ 3174 this._frames = null; 3175 3176 /** 3177 * @property _images 3178 * @protected 3179 * @type Array 3180 **/ 3181 this._images = null; 3182 3183 /** 3184 * @property _data 3185 * @protected 3186 * @type Object 3187 **/ 3188 this._data = null; 3189 3190 /** 3191 * @property _loadCount 3192 * @protected 3193 * @type Number 3194 **/ 3195 this._loadCount = 0; 3196 3197 // only used for simple frame defs: 3198 /** 3199 * @property _frameHeight 3200 * @protected 3201 * @type Number 3202 **/ 3203 this._frameHeight = 0; 3204 3205 /** 3206 * @property _frameWidth 3207 * @protected 3208 * @type Number 3209 **/ 3210 this._frameWidth = 0; 3211 3212 /** 3213 * @property _numFrames 3214 * @protected 3215 * @type Number 3216 **/ 3217 this._numFrames = 0; 3218 3219 /** 3220 * @property _regX 3221 * @protected 3222 * @type Number 3223 **/ 3224 this._regX = 0; 3225 3226 /** 3227 * @property _regY 3228 * @protected 3229 * @type Number 3230 **/ 3231 this._regY = 0; 3232 3233 /** 3234 * @property _spacing 3235 * @protected 3236 * @type Number 3237 **/ 3238 this._spacing = 0; 3239 3240 /** 3241 * @property _margin 3242 * @protected 3243 * @type Number 3244 **/ 3245 this._margin = 0; 3246 3247 // setup: 3248 this._parseData(data); 3249 } 3250 var p = createjs.extend(SpriteSheet, createjs.EventDispatcher); 3251 3252 // TODO: deprecated 3253 // p.initialize = function() {}; // searchable for devs wondering where it is. REMOVED. See docs for details. 3254 3255 3256// events: 3257 /** 3258 * Dispatched when all images are loaded. Note that this only fires if the images 3259 * were not fully loaded when the sprite sheet was initialized. You should check the complete property 3260 * to prior to adding a listener. Ex. 3261 * 3262 * var sheet = new createjs.SpriteSheet(data); 3263 * if (!sheet.complete) { 3264 * // not preloaded, listen for the complete event: 3265 * sheet.addEventListener("complete", handler); 3266 * } 3267 * 3268 * @event complete 3269 * @param {Object} target The object that dispatched the event. 3270 * @param {String} type The event type. 3271 * @since 0.6.0 3272 */ 3273 3274 /** 3275 * Dispatched when getFrame is called with a valid frame index. This is primarily intended for use by {{#crossLink "SpriteSheetBuilder"}}{{/crossLink}} 3276 * when doing on-demand rendering. 3277 * @event getframe 3278 * @param {Number} index The frame index. 3279 * @param {Object} frame The frame object that getFrame will return. 3280 */ 3281 3282 /** 3283 * Dispatched when an image encounters an error. A SpriteSheet will dispatch an error event for each image that 3284 * encounters an error, and will still dispatch a {{#crossLink "SpriteSheet/complete:event"}}{{/crossLink}} 3285 * event once all images are finished processing, even if an error is encountered. 3286 * @event error 3287 * @param {String} src The source of the image that failed to load. 3288 * @since 0.8.2 3289 */ 3290 3291 3292// getter / setters: 3293 /** 3294 * Use the {{#crossLink "SpriteSheet/animations:property"}}{{/crossLink}} property instead. 3295 * @method getAnimations 3296 * @return {Array} 3297 * @deprecated 3298 **/ 3299 p.getAnimations = function() { 3300 return this._animations.slice(); 3301 }; 3302 3303 /** 3304 * Returns an array of all available animation names available on this sprite sheet as strings. 3305 * @property animations 3306 * @type {Array} 3307 * @readonly 3308 **/ 3309 try { 3310 Object.defineProperties(p, { 3311 animations: { get: p.getAnimations } 3312 }); 3313 } catch (e) {} 3314 3315 3316// public methods: 3317 /** 3318 * Returns the total number of frames in the specified animation, or in the whole sprite 3319 * sheet if the animation param is omitted. Returns 0 if the spritesheet relies on calculated frame counts, and 3320 * the images have not been fully loaded. 3321 * @method getNumFrames 3322 * @param {String} animation The name of the animation to get a frame count for. 3323 * @return {Number} The number of frames in the animation, or in the entire sprite sheet if the animation param is omitted. 3324 */ 3325 p.getNumFrames = function(animation) { 3326 if (animation == null) { 3327 return this._frames ? this._frames.length : this._numFrames || 0; 3328 } else { 3329 var data = this._data[animation]; 3330 if (data == null) { return 0; } 3331 else { return data.frames.length; } 3332 } 3333 }; 3334 3335 /** 3336 * Returns an object defining the specified animation. The returned object c
3336ontains:<UL> 3337 * <li>frames: an array of the frame ids in the animation</li> 3338 * <li>speed: the playback speed for this animation</li> 3339 * <li>name: the name of the animation</li> 3340 * <li>next: the default animation to play next. If the animation loops, the name and next property will be the 3341 * same.</li> 3342 * </UL> 3343 * @method getAnimation 3344 * @param {String} name The name of the animation to get. 3345 * @return {Object} a generic object with frames, speed, name, and next properties. 3346 **/ 3347 p.getAnimation = function(name) { 3348 return this._data[name]; 3349 }; 3350 3351 /** 3352 * Returns an object specifying the image and source rect of the specified frame. The returned object has:<UL> 3353 * <li>an image property holding a reference to the image object in which the frame is found</li> 3354 * <li>a rect property containing a Rectangle instance which defines the boundaries for the frame within that 3355 * image.</li> 3356 * <li> A regX and regY property corresponding to the regX/Y values for the frame. 3357 * </UL> 3358 * @method getFrame 3359 * @param {Number} frameIndex The index of the frame. 3360 * @return {Object} a generic object with image and rect properties. Returns null if the frame does not exist. 3361 **/ 3362 p.getFrame = function(frameIndex) { 3363 var frame; 3364 if (this._frames && (frame=this._frames[frameIndex])) { return frame; } 3365 return null; 3366 }; 3367 3368 /** 3369 * Returns a {{#crossLink "Rectangle"}}{{/crossLink}} instance defining the bounds of the specified frame relative 3370 * to the origin. For example, a 90 x 70 frame with a regX of 50 and a regY of 40 would return: 3371 * 3372 * [x=-50, y=-40, width=90, height=70] 3373 * 3374 * @method getFrameBounds 3375 * @param {Number} frameIndex The index of the frame. 3376 * @param {Rectangle} [rectangle] A Rectangle instance to copy the values into. By default a new instance is created. 3377 * @return {Rectangle} A Rectangle instance. Returns null if the frame does not exist, or the image is not fully loaded. 3378 **/ 3379 p.getFrameBounds = function(frameIndex, rectangle) { 3380 var frame = this.getFrame(frameIndex); 3381 return frame ? (rectangle||new createjs.Rectangle()).setValues(-frame.regX, -frame.regY, frame.rect.width, frame.rect.height) : null; 3382 }; 3383 3384 /** 3385 * Returns a string representation of this object. 3386 * @method toString 3387 * @return {String} a string representation of the instance. 3388 **/ 3389 p.toString = function() { 3390 return "[SpriteSheet]"; 3391 }; 3392 3393 /** 3394 * SpriteSheet cannot be cloned. A SpriteSheet can be shared by multiple Sprite instances without cloning it. 3395 * @method clone 3396 **/ 3397 p.clone = function() { 3398 throw("SpriteSheet cannot be cloned.") 3399 }; 3400 3401// private methods: 3402 /** 3403 * @method _parseData 3404 * @param {Object} data An object describing the SpriteSheet data. 3405 * @protected 3406 **/ 3407 p._parseData = function(data) { 3408 var i,l,o,a; 3409 if (data == null) { return; } 3410 3411 this.framerate = data.framerate||0; 3412 3413 // parse images: 3414 if (data.images && (l=data.images.length) > 0) { 3415 a = this._images = []; 3416 for (i=0; i<l; i++) { 3417 var img = data.images[i]; 3418 if (typeof img == "string") { 3419 var src = img; 3420 img = document.createElement("img"); 3421 img.src = src; 3422 } 3423 a.push(img); 3424 if (!img.getContext && !img.naturalWidth) { 3425 this._loadCount++; 3426 this.complete = false; 3427 (function(o, src) { img.onload = function() { o._handleImageLoad(src); } })(this, src); 3428 (function(o, src) { img.onerror = function() { o._handleImageError(src); } })(this, src); 3429 } 3430 } 3431 } 3432 3433 // parse frames: 3434 if (data.frames == null) { // nothing 3435 } else if (Array.isArray(data.frames)) { 3436 this._frames = []; 3437 a = data.frames; 3438 for (i=0,l=a.length;i<l;i++) { 3439 var arr = a[i]; 3440 this._frames.push({image:this._images[arr[4]?arr[4]:0], rect:new createjs.Rectangle(arr[0],arr[1],arr[2],arr[3]), regX:arr[5]||0, regY:arr[6]||0 }); 3441 } 3442 } else { 3443 o = data.frames; 3444 this._frameWidth = o.width; 3445 this._frameHeight = o.height; 3446 this._regX = o.regX||0; 3447 this._regY = o.regY||0; 3448 this._spacing = o.spacing||0; 3449 this._margin = o.margin||0; 3450 this._numFrames = o.count; 3451 if (this._loadCount == 0) { this._calculateFrames(); } 3452 } 3453 3454 // parse animations: 3455 this._animations = []; 3456 if ((o=data.animations) != null) { 3457 this._data = {}; 3458 var name; 3459 for (name in o) { 3460 var anim = {name:name}; 3461 var obj = o[name]; 3462 if (typeof obj == "number") { // single frame 3463 a = anim.frames = [obj]; 3464 } else if (Array.isArray(obj)) { // simple 3465 if (obj.length == 1) { anim.frames = [obj[0]]; } 3466 else { 3467 anim.speed = obj[3]; 3468 anim.next = obj[2]; 3469 a = anim.frames = []; 3470 for (i=obj[0];i<=obj[1];i++) { 3471 a.push(i); 3472 } 3473 } 3474 } else { // complex 3475 anim.speed = obj.speed; 3476 anim.next = obj.next; 3477 var frames = obj.frames; 3478 a = anim.frames = (typeof frames == "number") ? [frames] : frames.slice(0); 3479 } 3480 if (anim.next === true || anim.next === undefined) { anim.next = name; } // loop 3481 if (anim.next === false || (a.length < 2 && anim.next == name)) { anim.next = null; } // stop 3482 if (!anim.speed) { anim.speed = 1; } 3483 this._animations.push(name); 3484 this._data[name] = anim; 3485 } 3486 } 3487 }; 3488 3489 /** 3490 * @method _handleImageLoad 3491 * @protected 3492 **/ 3493 p._handleImageLoad = function(src) { 3494 if (--this._loadCount == 0) { 3495 this._calculateFrames(); 3496 this.complete = true; 3497 this.dispatchEvent("complete"); 3498 } 3499 }; 3500 3501 /** 3502 * @method _handleImageError 3503 * @protected 3504 */ 3505 p._handleImageError = function (src) { 3506 var errorEvent = new createjs.Event("error"); 3507 errorEvent.src = src; 3508 this.dispatchEvent(errorEvent); 3509 3510 // Complete is still dispatched. 3511 if (--this._loadCount == 0) { 3512 this.dispatchEvent("complete"); 3513 } 3514 }; 3515 3516 /**
3517 * @method _calculateFrames 3518 * @protected 3519 **/ 3520 p._calculateFrames = function() { 3521 if (this._frames || this._frameWidth == 0) { return; } 3522 3523 this._frames = []; 3524 3525 var maxFrames = this._numFrames || 100000; // if we go over this, something is wrong. 3526 var frameCount = 0, frameWidth = this._frameWidth, frameHeight = this._frameHeight; 3527 var spacing = this._spacing, margin = this._margin; 3528 3529 imgLoop: 3530 for (var i=0, imgs=this._images; i<imgs.length; i++) { 3531 var img = imgs[i], imgW = img.width, imgH = img.height; 3532 3533 var y = margin; 3534 while (y <= imgH-margin-frameHeight) { 3535 var x = margin; 3536 while (x <= imgW-margin-frameWidth) { 3537 if (frameCount >= maxFrames) { break imgLoop; } 3538 frameCount++; 3539 this._frames.push({ 3540 image: img, 3541 rect: new createjs.Rectangle(x, y, frameWidth, frameHeight), 3542 regX: this._regX, 3543 regY: this._regY 3544 }); 3545 x += frameWidth+spacing; 3546 } 3547 y += frameHeight+spacing; 3548 } 3549 } 3550 this._numFrames = frameCount; 3551 }; 3552 3553 3554 createjs.SpriteSheet = createjs.promote(SpriteSheet, "EventDispatcher"); 3555}()); 3556 3557//############################################################################## 3558// Graphics.js 3559//############################################################################## 3560 3561this.createjs = this.createjs||{}; 3562 3563(function() { 3564 "use strict"; 3565 3566 3567// constructor: 3568 /** 3569 * The Graphics class exposes an easy to use API for generating vector drawing instructions and drawing them to a 3570 * specified context. Note that you can use Graphics without any dependency on the EaselJS framework by calling {{#crossLink "Graphics/draw"}}{{/crossLink}} 3571 * directly, or it can be used with the {{#crossLink "Shape"}}{{/crossLink}} object to draw vector graphics within the 3572 * context of an EaselJS display list. 3573 * 3574 * There are two approaches to working with Graphics object: calling methods on a Graphics instance (the "Graphics API"), or 3575 * instantiating Graphics command objects and adding them to the graphics queue via {{#crossLink "Graphics/append"}}{{/crossLink}}. 3576 * The former abstracts the latter, simplifying beginning and ending paths, fills, and strokes. 3577 * 3578 * var g = new createjs.Graphics(); 3579 * g.setStrokeStyle(1); 3580 * g.beginStroke("#000000"); 3581 * g.beginFill("red"); 3582 * g.drawCircle(0,0,30); 3583 * 3584 * All drawing methods in Graphics return the Graphics instance, so they can be chained together. For example, 3585 * the following line of code would generate the instructions to draw a rectangle with a red stroke and blue fill: 3586 * 3587 * myGraphics.beginStroke("red").beginFill("blue").drawRect(20, 20, 100, 50); 3588 * 3589 * Each graphics API call generates a command object (see below). The last command to be created can be accessed via 3590 * {{#crossLink "Graphics/command:property"}}{{/crossLink}}: 3591 * 3592 * var fillCommand = myGraphics.beginFill("red").command; 3593 * // ... later, update the fill style/color: 3594 * fillCommand.style = "blue"; 3595 * // or change it to a bitmap fill: 3596 * fillCommand.bitmap(myImage); 3597 * 3598 * For more direct control of rendering, you can instantiate and append command objects to the graphics queue directly. In this case, you 3599 * need to manage path creation manually, and ensure that fill/stroke is applied to a defined path: 3600 * 3601 * // start a new path. Graphics.beginCmd is a reusable BeginPath instance: 3602 * myGraphics.append(createjs.Graphics.beginCmd); 3603 * // we need to define the path before applying the fill: 3604 * var circle = new createjs.Graphics.Circle(0,0,30); 3605 * myGraphics.append(circle); 3606 * // fill the path we just defined: 3607 * var fill = new createjs.Graphics.Fill("red"); 3608 * myGraphics.append(fill); 3609 * 3610 * These approaches can be used together, for example to insert a custom command: 3611 * 3612 * myGraphics.beginFill("red"); 3613 * var customCommand = new CustomSpiralCommand(etc); 3614 * myGraphics.append(customCommand); 3615 * myGraphics.beginFill("blue"); 3616 * myGraphics.drawCircle(0, 0, 30); 3617 * 3618 * See {{#crossLink "Graphics/append"}}{{/crossLink}} for more info on creating custom commands. 3619 * 3620 * <h4>Tiny API</h4> 3621 * The Graphics class also includes a "tiny API", which is one or tw
3621o-letter methods that are shortcuts for all of the 3622 * Graphics methods. These methods are great for creating compact instructions, and is used by the Toolkit for CreateJS 3623 * to generate readable code. All tiny methods are marked as protected, so you can view them by enabling protected 3624 * descriptions in the docs. 3625 * 3626 * <table> 3627 * <tr><td><b>Tiny</b></td><td><b>Method</b></td><td><b>Tiny</b></td><td><b>Method</b></td></tr> 3628 * <tr><td>mt</td><td>{{#crossLink "Graphics/moveTo"}}{{/crossLink}} </td> 3629 * <td>lt</td> <td>{{#crossLink "Graphics/lineTo"}}{{/crossLink}}</td></tr> 3630 * <tr><td>a/at</td><td>{{#crossLink "Graphics/arc"}}{{/crossLink}} / {{#crossLink "Graphics/arcTo"}}{{/crossLink}} </td> 3631 * <td>bt</td><td>{{#crossLink "Graphics/bezierCurveTo"}}{{/crossLink}} </td></tr> 3632 * <tr><td>qt</td><td>{{#crossLink "Graphics/quadraticCurveTo"}}{{/crossLink}} (also curveTo)</td> 3633 * <td>r</td><td>{{#crossLink "Graphics/rect"}}{{/crossLink}} </td></tr> 3634 * <tr><td>cp</td><td>{{#crossLink "Graphics/closePath"}}{{/crossLink}} </td> 3635 * <td>c</td><td>{{#crossLink "Graphics/clear"}}{{/crossLink}} </td></tr> 3636 * <tr><td>f</td><td>{{#crossLink "Graphics/beginFill"}}{{/crossLink}} </td> 3637 * <td>lf</td><td>{{#crossLink "Graphics/beginLinearGradientFill"}}{{/crossLink}} </td></tr> 3638 * <tr><td>rf</td><td>{{#crossLink "Graphics/beginRadialGradientFill"}}{{/crossLink}} </td> 3639 * <td>bf</td><td>{{#crossLink "Graphics/beginBitmapFill"}}{{/crossLink}} </td></tr> 3640 * <tr><td>ef</td><td>{{#crossLink "Graphics/endFill"}}{{/crossLink}} </td> 3641 * <td>ss / sd</td><td>{{#crossLink "Graphics/setStrokeStyle"}}{{/crossLink}} / {{#crossLink "Graphics/setStrokeDash"}}{{/crossLink}} </td></tr> 3642 * <tr><td>s</td><td>{{#crossLink "Graphics/beginStroke"}}{{/crossLink}} </td> 3643 * <td>ls</td><td>{{#crossLink "Graphics/beginLinearGradientStroke"}}{{/crossLink}} </td></tr> 3644 * <tr><td>rs</td><td>{{#crossLink "Graphics/beginRadialGradientStroke"}}{{/crossLink}} </td> 3645 * <td>bs</td><td>{{#crossLink "Graphics/beginBitmapStroke"}}{{/crossLink}} </td></tr> 3646 * <tr><td>es</td><td>{{#crossLink "Graphics/endStroke"}}{{/crossLink}} </td> 3647 * <td>dr</td><td>{{#crossLink "Graphics/drawRect"}}{{/crossLink}} </td></tr> 3648 * <tr><td>rr</td><td>{{#crossLink "Graphics/drawRoundRect"}}{{/crossLink}} </td> 3649 * <td>rc</td><td>{{#crossLink "Graphics/drawRoundRectComplex"}}{{/crossLink}} </td></tr> 3650 * <tr><td>dc</td><td>{{#crossLink "Graphics/drawCircle"}}{{/crossLink}} </td> 3651 * <td>de</td><td>{{#crossLink "Graphics/drawEllipse"}}{{/crossLink}} </td></tr> 3652 * <tr><td>dp</td><td>{{#crossLink "Graphics/drawPolyStar"}}{{/crossLink}} </td> 3653 * <td>p</td><td>{{#crossLink "Graphics/decodePath"}}{{/crossLink}} </td></tr> 3654 * </table> 3655 * 3656 * Here is the above example, using the tiny API instead. 3657 * 3658 * myGraphics.s("red").f("blue").r(20, 20, 100, 50); 3659 * 3660 * @class Graphics 3661 * @constructor 3662 **/ 3663 function Graphics() { 3664 3665 3666 // public properties 3667 /** 3668 * Holds a reference to the last command that was created or appended. For example, you could retain a reference 3669 * to a Fill command in order to dynamically update the color later by using: 3670 * 3671 * var myFill = myGraphics.beginFill("red").command; 3672 * // update color later: 3673 * myFill.style = "yellow"; 3674 * 3675 * @property command 3676 * @type Object 3677 **/ 3678 this.command = null; 3679 3680 3681 // private properties 3682 /** 3683 * @property _stroke 3684 * @protected 3685 * @type {Stroke} 3686 **/ 3687 this._stroke = null; 3688 3689 /** 3690 * @property _strokeStyle 3691 * @protected 3692 * @type {StrokeStyle} 3693 **/ 3694 this._strokeStyle = null; 3695 3696 /** 3697 * @property _oldStrokeStyle 3698 * @protected 3699 * @type {StrokeStyle} 3700 **/ 3701 this._oldStrokeStyle = null; 3702 3703 /** 3704 * @property _strokeDash 3705 * @protected 3706 * @type {StrokeDash} 3707 **/ 3708 this._strokeDash = null; 3709 3710 /** 3711 * @property _oldStrokeDash 3712 * @protected 3713 * @type {StrokeDash} 3714 **/ 3715 this._oldStrokeDash = null; 3716 3717 /** 3718 * @property _strokeIgnoreScale 3719 * @protected 3720 * @type Boolean 3721 **/ 3722 this._strokeIgnoreScale = false;
3723 3724 /** 3725 * @property _fill 3726 * @protected 3727 * @type {Fill} 3728 **/ 3729 this._fill = null; 3730 3731 /** 3732 * @property _instructions 3733 * @protected 3734 * @type {Array} 3735 **/ 3736 this._instructions = []; 3737 3738 /** 3739 * Indicates the last instruction index that was committed. 3740 * @property _commitIndex 3741 * @protected 3742 * @type {Number} 3743 **/ 3744 this._commitIndex = 0; 3745 3746 /** 3747 * Uncommitted instructions. 3748 * @property _activeInstructions 3749 * @protected 3750 * @type {Array} 3751 **/ 3752 this._activeInstructions = []; 3753 3754 /** 3755 * This indicates that there have been changes to the activeInstruction list since the last updateInstructions call. 3756 * @property _dirty 3757 * @protected 3758 * @type {Boolean} 3759 * @default false 3760 **/ 3761 this._dirty = false; 3762 3763 /** 3764 * Index to draw from if a store operation has happened. 3765 * @property _storeIndex 3766 * @protected 3767 * @type {Number} 3768 * @default 0 3769 **/ 3770 this._storeIndex = 0; 3771 3772 // setup: 3773 this.clear(); 3774 } 3775 var p = Graphics.prototype; 3776 var G = Graphics; // shortcut 3777 3778 /** 3779 * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`. 3780 * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}} 3781 * for details. 3782 * 3783 * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance. 3784 * 3785 * @method initialize 3786 * @protected 3787 * @deprecated 3788 */ 3789 // p.initialize = function() {}; // searchable for devs wondering where it is. 3790 3791 3792// static public methods: 3793 /** 3794 * Returns a CSS compatible color string based on the specified RGB numeric color values in the format 3795 * "rgba(255,255,255,1.0)", or if alpha is null then in the format "rgb(255,255,255)". For example, 3796 * 3797 * createjs.Graphics.getRGB(50, 100, 150, 0.5); 3798 * // Returns "rgba(50,100,150,0.5)" 3799 * 3800 * It also supports passing a single hex color value as the first param, and an optional alpha value as the second 3801 * param. For example, 3802 * 3803 * createjs.Graphics.getRGB(0xFF00FF, 0.2); 3804 * // Returns "rgba(255,0,255,0.2)" 3805 * 3806 * @method getRGB 3807 * @static 3808 * @param {Number} r The red component for the color, between 0 and 0xFF (255). 3809 * @param {Number} g The green component for the color, between 0 and 0xFF (255). 3810 * @param {Number} b The blue component for the color, between 0 and 0xFF (255). 3811 * @param {Number} [alpha] The alpha component for the color where 0 is fully transparent and 1 is fully opaque. 3812 * @return {String} A CSS compatible color string based on the specified RGB numeric color values in the format 3813 * "rgba(255,255,255,1.0)", or if alpha is null then in the format "rgb(255,255,255)". 3814 **/ 3815 Graphics.getRGB = function(r, g, b, alpha) { 3816 if (r != null && b == null) { 3817 alpha = g; 3818 b = r&0xFF; 3819 g = r>>8&0xFF; 3820 r = r>>16&0xFF; 3821 } 3822 if (alpha == null) { 3823 return "rgb("+r+","+g+","+b+")"; 3824 } else { 3825 return "rgba("+r+","+g+","+b+","+alpha+")"; 3826 } 3827 }; 3828 3829 /** 3830 * Returns a CSS compatible color string based on the specified HSL numeric color values in the format "hsla(360,100,100,1.0)", 3831 * or if alpha is null then in the format "hsl(360,100,100)". 3832 * 3833 * createjs.Graphics.getHSL(150, 100, 70); 3834 * // Returns "hsl(150,100,70)" 3835 * 3836 * @method getHSL 3837 * @static 3838 * @param {Number} hue The hue component for the color, between 0 and 360. 3839 * @param {Number} saturation The saturation component for the color, between 0 and 100. 3840 * @param {Number} lightness The lightness component for the color, between 0 and 100. 3841 * @param {Number} [alpha] The alpha component for the color where 0 is fully transparent and 1 is fully opaque. 3842 * @return {String} A CSS compatible color string based on the specified HSL numeric color values in the format 3843 * "hsla(360,100,100,1.0)", or if alpha is null then in the format "hsl(360,100,100)". 3844 **/ 3845 Graphics.getHSL = function(hue, saturation, lightness, alpha) { 3846 if (alpha == null) { 3847 return "hsl("+(hue%360)+","+saturation+"%,"+lightness+"%)"; 3848 } else { 3849 return "hsla("+(hue%360)+","+saturation+"%,"+lightness+"%,"+alpha+")"; 3850 } 3851 }; 3852 3853 3854// static properties: 3855 /** 3856 * A reusable instance of {{#crossLink "Graphics/BeginPath"}}{{/crossLink}} to avoid 3857 * unnecessary instantiation. 3858 * @property beginCmd 3859 * @type {Graphics.BeginPath} 3860 * @static 3861 **/ 3862 // defined at the bottom of this file. 3863 3864 /** 3865 * Map of Base64 characters to values. Used by {{#crossLink "Graphics/decodePath"}}{{/crossLink}}. 3866 * @property BASE_64 3867 * @static 3868 * @final 3869 * @readonly 3870 * @type {Object} 3871 **/ 3872 Graphics.BASE_64 = {"A":0,"B":1,"C":2,"D":3,"E":4,"F":5,"G":6,"H":7,"I":8,"J":9,"K":10,"L":11,"M":12,"N":13,"O":14,"P":15,"Q":16,"R":17,"S":18,"T":19,"U":20,"V":21,"W":22,"X":23,"Y":24,"Z":25,"a":26,"b":27,"c":28,"d":29,"e":30,"f":31,"g":32,"h":33,"i":34,"j":35,"k":36,"l":37,"m":38,"n":39,"o":40,"p":41,"q":42,"r":43,"s":44,"t":45,"u":46,"v":47,"w":48,"x":49,"y":50,"z":51,"0":52,"1":53,"2":54,"3":55,"4":56,"5":57,"6":58,"7":59,"8":60,"9":61,"+":62,"/":63}; 3873 3874 /** 3875 * Maps numeric values for the caps parameter of {{#crossLink "Graphics/setStrokeStyle"}}{{/crossLink}} to 3876 * corresponding string values. This is primarily for use with the tiny API. The mappings are as follows: 0 to
3877 * "butt", 1 to "round", and 2 to "square". 3878 * For example, to set the line caps to "square": 3879 * 3880 * myGraphics.ss(16, 2); 3881 * 3882 * @property STROKE_CAPS_MAP 3883 * @static 3884 * @final 3885 * @readonly 3886 * @type {Array} 3887 **/ 3888 Graphics.STROKE_CAPS_MAP = ["butt", "round", "square"]; 3889 3890 /** 3891 * Maps numeric values for the joints parameter of {{#crossLink "Graphics/setStrokeStyle"}}{{/crossLink}} to 3892 * corresponding string values. This is primarily for use with the tiny API. The mappings are as follows: 0 to 3893 * "miter", 1 to "round", and 2 to "bevel". 3894 * For example, to set the line joints to "bevel": 3895 * 3896 * myGraphics.ss(16, 0, 2); 3897 * 3898 * @property STROKE_JOINTS_MAP 3899 * @static 3900 * @final 3901 * @readonly 3902 * @type {Array} 3903 **/ 3904 Graphics.STROKE_JOINTS_MAP = ["miter", "round", "bevel"]; 3905 3906 /** 3907 * @property _ctx 3908 * @static 3909 * @protected 3910 * @type {CanvasRenderingContext2D} 3911 **/ 3912 var canvas = (createjs.createCanvas?createjs.createCanvas():document.createElement("canvas")); 3913 if (canvas.getContext) { 3914 Graphics._ctx = canvas.getContext("2d"); 3915 canvas.width = canvas.height = 1; 3916 } 3917 3918 3919// getter / setters: 3920 /** 3921 * Use the {{#crossLink "Graphics/instructions:property"}}{{/crossLink}} property instead. 3922 * @method getInstructions 3923 * @return {Array} 3924 * @deprecated 3925 **/ 3926 p.getInstructions = function() { 3927 this._updateInstructions(); 3928 return this._instructions; 3929 }; 3930 3931 /** 3932 * Returns the graphics instructions array. Each entry is a graphics command object (ex. Graphics.Fill, Graphics.Rect) 3933 * Modifying the returned array directly is not recommended, and is likely to result in unexpected behaviour. 3934 * 3935 * This property is mainly intended for introspection of the instructions (ex. for graphics export). 3936 * @property instructions 3937 * @type {Array} 3938 * @readonly 3939 **/ 3940 try { 3941 Object.defineProperties(p, { 3942 instructions: { get: p.getInstructions } 3943 }); 3944 } catch (e) {} 3945 3946 3947// public methods: 3948 /** 3949 * Returns true if this Graphics instance has no drawing commands. 3950 * @method isEmpty 3951 * @return {Boolean} Returns true if this Graphics instance has no drawing commands. 3952 **/ 3953 p.isEmpty = function() { 3954 return !(this._instructions.length || this._activeInstructions.length); 3955 }; 3956 3957 /** 3958 * Draws the display object into the specified context ignoring its visible, alpha, shadow, and transform. 3959 * Returns true if the draw was handled (useful for overriding functionality). 3960 * 3961 * NOTE: This method is mainly for internal use, though it may be useful for advanced uses. 3962 * @method draw 3963 * @param {CanvasRenderingContext2D} ctx The canvas 2D context object to draw into. 3964 * @param {Object} data Optional data that is passed to graphics command exec methods. When called from a Shape instance, the shape passes itself as the data parameter. This can be used by custom graphic commands to insert contextual data. 3965 **/ 3966 p.draw = function(ctx, data) { 3967 this._updateInstructions(); 3968 var instr = this._instructions; 3969 for (var i=this._storeIndex, l=instr.length; i<l; i++) { 3970 instr[i].exec(ctx, data); 3971 } 3972 }; 3973 3974 /** 3975 * Draws only the path described for this Graphics instance, skipping any non-path instructions, including fill and 3976 * stroke descriptions. Used for <code>DisplayObject.mask</code> to draw the clipping path, for example. 3977 * 3978 * NOTE: This method is mainly for internal use, though it may be useful for advanced uses. 3979 * @method drawAsPath 3980 * @param {CanvasRenderingContext2D} ctx The canvas 2D context object to draw into. 3981 **/ 3982 p.drawAsPath = function(ctx) { 3983 this._updateInstructions(); 3984 var instr, instrs = this._instructions; 3985 for (var i=this._storeIndex, l=instrs.length; i<l; i++) { 3986 // the first command is always a beginPath command. 3987 if ((instr = instrs[i]).path !== false) { instr.exec(ctx); } 3988 } 3989 }; 3990 3991 3992// public methods that map directly to context 2D calls: 3993 /** 3994 * Moves the drawing point to the specified position. A tiny API method "mt" also exists. 3995 * @method moveTo 3996 * @param {Number} x The x coordinate the drawing point should move to. 3997 * @param {Number} y The y coordinate the drawing point should move to. 3998 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls). 3999 * @chainable 4000 **/ 4001 p.moveTo = function(x, y) { 4002 return this.append(new G.MoveTo(x,y), true); 4003 }; 4004 4005 /** 4006 * Draws a line from the current drawing point to the specified position, which become the new current drawing 4007 * point. Note that you *must* call {{#crossLink "Graphics/moveTo"}}{{/crossLink}} before the first `lineTo()`. 4008 * A tiny API method "lt" also exists. 4009 * 4010 * For detailed information, read the 4011 * <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#complex-shapes-(paths)"> 4012 * whatwg spec</a>. 4013 * @method lineTo 4014 * @param {Number} x The x coordinate the drawing point should draw to. 4015 * @param {Number} y The y coordinate the drawing point should draw to. 4016 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4017 * @chainable 4018 **/ 4019 p.lineTo = function(x, y) { 4020 return this.append(new G.LineTo(x,y)); 4021 }; 4022 4023 /** 4024 * Draws an arc with the specified control points and radius. For detailed information, read the 4025 * <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-arcto"> 4026 * whatwg spec</a>. A tiny API method "at" also exists. 4027 * @method arcTo 4028 * @param {Number} x1 4029 * @param {Number} y1 4030 * @param {Number} x2 4031 * @param {Number} y2 4032 * @param {Number} radius 4033 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4034 * @chainable 4035 **/ 4036 p.arcTo = function(x1, y1, x2, y2, radius) { 4037 return this.append(new G.ArcTo(x1, y1, x2, y2, radius)); 4038 }; 4039 4040 /** 4041 * Draws an arc defined by the radius, startAngle and endAngle arguments, centered at the position (x, y). For 4042 * example, to draw a full circle with a radius of 20 centered at (100, 100): 4043 * 4044 * arc(100, 100, 20, 0, Math.PI*2); 4045 * 4046 * For detailed information, read the 4047 * <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-arc">whatwg spec</a>. 4048 * A tiny API method "a" also exists. 4049 * @method arc 4050 * @param {Number} x 4051 * @param {Number} y 4052 * @param {Number} radius 4053 * @param {Number} startAngle Measured in radians. 4054 * @param {Number} endAngle Measured in radians. 4055 * @param {Boolean} anticlockwise 4056 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4057 * @chainable 4058 **/ 4059 p.arc = function(x, y, radius, startAngle, endAngle, anticlockwise) { 4060 return this.append(new G.Arc(x, y, radius, startAngle, endAngle, anticlockwise)); 4061 }; 4062 4063 /** 4064 * Draws a quadratic curve from the current drawing point to (x, y) using the control point (cpx, cpy). For detailed 4065 * information, read the <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-quadraticcurveto"> 4066 * whatwg spec</a>. A tiny API method "qt" also exists. 4067 * @method quadraticCurveTo 4068 * @param {Number} cpx 4069 * @param {Number} cpy 4070 * @param {Number} x 4071 * @param {Number} y 4072 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4073 * @chainable 4074 **/ 4075 p.quadraticCurveTo = function(cpx, cpy, x, y) { 4076 return this.append(new G.QuadraticCurveTo(cpx, cpy, x, y)); 4077 }; 4078 4079 /** 4080 * Draws a bezier curve from the current drawing point to (x, y) using the control points (cp1x, cp1y) and (cp2x, 4081 * cp2y). For detailed information, read the 4082 * <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-beziercurveto"> 4083 * whatwg spec</a>. A tiny API method "bt" also exists. 4084 * @method bezierCurveTo 4085 * @param {Number} cp1x 4086 * @param {Number} cp1y 4087 * @param {Number} cp2x 4088 * @param {Number} cp2y 4089 * @param {Number} x 4090 * @param {Number} y 4091 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4092 * @chainable 4093 **/ 4094 p.bezierCurveTo = function(cp1x, cp1y, cp2x, cp2y, x, y) { 4095 return this.append(new G.BezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)); 4096 }; 4097 4098 /** 4099 * Draws a rectangle at (x, y) with the specified width and height using the current fill and/or stroke. 4100 * For detailed information, read the 4101 * <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-rect">
4102 * whatwg spec</a>. A tiny API method "r" also exists. 4103 * @method rect 4104 * @param {Number} x 4105 * @param {Number} y 4106 * @param {Number} w Width of the rectangle 4107 * @param {Number} h Height of the rectangle 4108 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4109 * @chainable 4110 **/ 4111 p.rect = function(x, y, w, h) { 4112 return this.append(new G.Rect(x, y, w, h)); 4113 }; 4114 4115 /** 4116 * Closes the current path, effectively drawing a line from the current drawing point to the first drawing point specified 4117 * since the fill or stroke was last set. A tiny API method "cp" also exists. 4118 * @method closePath 4119 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4120 * @chainable 4121 **/ 4122 p.closePath = function() { 4123 return this._activeInstructions.length ? this.append(new G.ClosePath()) : this; 4124 }; 4125 4126 4127// public methods that roughly map to Flash graphics APIs: 4128 /** 4129 * Clears all drawing instructions, effectively resetting this Graphics instance. Any line and fill styles will need 4130 * to be redefined to draw shapes following a clear call. A tiny API method "c" also exists. 4131 * @method clear 4132 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4133 * @chainable 4134 **/ 4135 p.clear = function() { 4136 this._instructions.length = this._activeInstructions.length = this._commitIndex = 0; 4137 this._strokeStyle = this._oldStrokeStyle = this._stroke = this._fill = this._strokeDash = this._oldStrokeDash = null; 4138 this._dirty = this._strokeIgnoreScale = false; 4139 return this; 4140 }; 4141 4142 /** 4143 * Begins a fill with the specified color. This ends the current sub-path. A tiny API method "f" also exists. 4144 * @method beginFill 4145 * @param {String} color A CSS compatible color value (ex. "red", "#FF0000", or "rgba(255,0,0,0.5)"). Setting to 4146 * null will result in no fill. 4147 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4148 * @chainable 4149 **/ 4150 p.beginFill = function(color) { 4151 return this._setFill(color ? new G.Fill(color) : null); 4152 }; 4153 4154 /** 4155 * Begins a linear gradient fill defined by the line (x0, y0) to (x1, y1). This ends the current sub-path. For 4156 * example, the following code defines a black to white vertical gradient ranging from 20px to 120px, and draws a 4157 * square to display it: 4158 * 4159 * myGraphics.beginLinearGradientFill(["#000","#FFF"], [0, 1], 0, 20, 0, 120).drawRect(20, 20, 120, 120); 4160 * 4161 * A tiny API method "lf" also exists. 4162 * @method beginLinearGradientFill 4163 * @param {Array} colors An array of CSS compatible color values. For example, ["#F00","#00F"] would define a gradient 4164 * drawing from red to blue. 4165 * @param {Array} ratios An array of gradient positions which correspond to the colors. For example, [0.1, 0.9] would draw 4166 * the first color to 10% then interpolating to the second color at 90%. 4167 * @param {Number} x0 The position of the first point defining the line that defines the gradient direction and size. 4168 * @param {Number} y0 The position of the first point defining the line that defines the gradient direction and size. 4169 * @param {Number} x1 The position of the second point defining the line that defines the gradient direction and size. 4170 * @param {Number} y1 The position of the second point defining the line that defines the gradient direction and size. 4171 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4172 * @chainable 4173 **/ 4174 p.beginLinearGradientFill = function(colors, ratios, x0, y0, x1, y1) { 4175 return this._setFill(new G.Fill().linearGradient(colors, ratios, x0, y0, x1, y1)); 4176 }; 4177 4178 /** 4179 * Begins a radial gradient fill. This ends the current sub-path. For example, the following code defines a red to 4180 * blue radial gradient centered at (100, 100), with a radius of 50, and draws a circle to display it: 4181 * 4182 * myGraphics.beginRadialGradientFill(["#F00","#00F"], [0, 1], 100, 100, 0, 100, 100, 50).drawCircle(100, 100, 50); 4183 * 4184 * A tiny API method "rf" also exists. 4185 * @method beginRadialGradientFill 4186 * @param {Array} colors An array of CSS compatible color values. For example, ["#F00","#00F"] would define 4187 * a gradient drawing from red to blue. 4188 * @param {Array} ratios An array of gradient positions which correspond to the colors. For example, [0.1, 4189 * 0.9] would draw the first color to 10% then interpolating to the second color at 90%. 4190 * @param {Number} x0 Center position of the inner circle that defines the gradient. 4191 * @param {Number} y0 Center position of the inner circle that defines the gradient. 4192 * @param {Number} r0 Radius of the inner circle that defines the gradient. 4193 * @param {Number} x1 Center position of the outer circle that defines the gradient. 4194 * @param {Number} y1 Center position of the outer circle that defines the gradient. 4195 * @param {Number} r1 Radius of the outer circle that defines the gradient. 4196 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4197 * @chainable 4198 **/ 4199 p.beginRadialGradientFill = function(colors, ratios, x0, y0, r0, x1, y1, r1) { 4200 return this._setFill(new G.Fill().radialGradient(colors, ratios, x0, y0, r0, x1, y1, r1)); 4201 }; 4202 4203 /** 4204 * Begins a pattern fill using the specified image. This ends the current sub-path. A tiny API method "bf" also 4205 * exists. 4206 * @method beginBitmapFill 4207 * @param {HTMLImageElement | HTMLCanvasElement | HTMLVideoElement} image The Image, Canvas, or Video object to use 4208 * as the pattern. Must be loaded prior to creating a bitmap fill, or the fill will be empty. 4209 * @param {String} repetition Optional. Indicates whether to repeat the image in the fill area. One of "repeat", 4210 * "repeat-x", "repeat-y", or "no-repeat". Defaults to "repeat". Note that Firefox does not support "repeat-x" or 4211 * "repeat-y" (latest tests were in FF 20.0), and will default to "repeat". 4212 * @param {Matrix2D} matrix Optional. Specifies a transformation matrix for the bitmap fill. This transformation 4213 * will be applied relative to the parent transform. 4214 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4215 * @chainable 4216 **/ 4217 p.beginBitmapFill = function(image, repetition, matrix) { 4218 return this._setFill(new G.Fill(null,matrix).bitmap(image, repetition)); 4219 }; 4220 4221 /** 4222 * Ends the current sub-path, and begins a new one with no fill. Functionally identical to <code>beginFill(null)</code>. 4223 * A tiny API method "ef" also exists. 4224 * @method endFill 4225 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4226 * @chainable 4227 **/ 4228 p.endFill = function() { 4229 return this.beginFill(); 4230 }; 4231 4232 /** 4233 * Sets the stroke style. Like all drawing methods, this can be chained, so you can define 4234 * the stroke style and color in a single line of code like so: 4235 * 4236 * myGraphics.setStrokeStyle(8,"round").beginStroke("#F00"); 4237 * 4238 * A tiny API method "ss" also exists. 4239 * @method setStrokeStyle 4240 * @param {Number} thickness The width of the stroke. 4241 * @param {String | Number} [caps=0] Indicates the type of caps to use at the end of lines. One of butt, 4242 * round, or square. Defaults to "butt". Also accepts the values 0 (butt), 1 (round), and 2
4242(square) for use with 4243 * the tiny API. 4244 * @param {String | Number} [joints=0] Specifies the type of joints that should be used where two lines meet. 4245 * One of bevel, round, or miter. Defaults to "miter". Also accepts the values 0 (miter), 1 (round), and 2 (bevel) 4246 * for use with the tiny API. 4247 * @param {Number} [miterLimit=10] If joints is set to "miter", then you can specify a miter limit ratio which 4248 * controls at what point a mitered joint will be clipped. 4249 * @param {Boolean} [ignoreScale=false] If true, the stroke will be drawn at the specified thickness regardless 4250 * of active transformations. 4251 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4252 * @chainable 4253 **/ 4254 p.setStrokeStyle = function(thickness, caps, joints, miterLimit, ignoreScale) { 4255 this._updateInstructions(true); 4256 this._strokeStyle = this.command = new G.StrokeStyle(thickness, caps, joints, miterLimit, ignoreScale); 4257 4258 // ignoreScale lives on Stroke, not StrokeStyle, so we do a little trickery: 4259 if (this._stroke) { this._stroke.ignoreScale = ignoreScale; } 4260 this._strokeIgnoreScale = ignoreScale; 4261 return this; 4262 }; 4263 4264 /** 4265 * Sets or clears the stroke dash pattern. 4266 * 4267 * myGraphics.setStrokeDash([20, 10], 0); 4268 * 4269 * A tiny API method `sd` also exists. 4270 * @method setStrokeDash 4271 * @param {Array} [segments] An array specifying the dash pattern, alternating between line and gap. 4272 * For example, `[20,10]` would create a pattern of 20 pixel lines with 10 pixel gaps between them. 4273 * Passing null or an empty array will clear the existing stroke dash. 4274 * @param {Number} [offset=0] The offset of the dash pattern. For example, you could increment this value to create a "marching ants" effect. 4275 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4276 * @chainable 4277 **/ 4278 p.setStrokeDash = function(segments, offset) { 4279 this._updateInstructions(true); 4280 this._strokeDash = this.command = new G.StrokeDash(segments, offset); 4281 return this; 4282 }; 4283 4284 /** 4285 * Begins a stroke with the specified color. This ends the current sub-path. A tiny API method "s" also exists. 4286 * @method beginStroke 4287 * @param {String} color A CSS compatible color value (ex. "#FF0000", "red", or "rgba(255,0,0,0.5)"). Setting to 4288 * null will result in no stroke. 4289 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4290 * @chainable 4291 **/ 4292 p.beginStroke = function(color) { 4293 return this._setStroke(color ? new G.Stroke(color) : null); 4294 }; 4295 4296 /** 4297 * Begins a linear gradient stroke defined by the line (x0, y0) to (x1, y1). This ends the current sub-path. For 4298 * example, the following code defines a black to white vertical gradient ranging from 20px to 120px, and draws a 4299 * square to display it: 4300 * 4301 * myGraphics.setStrokeStyle(10). 4302 * beginLinearGradientStroke(["#000","#FFF"], [0, 1], 0, 20, 0, 120).drawRect(20, 20, 120, 120); 4303 * 4304 * A tiny API method "ls" also exists. 4305 * @method beginLinearGradientStroke 4306 * @param {Array} colors An array of CSS compatible color values. For example, ["#F00","#00F"] would define 4307 * a gradient drawing from red to blue. 4308 * @param {Array} ratios An array of gradient positions which correspond to the colors. For example, [0.1, 4309 * 0.9] would draw the first color to 10% then interpolating to the second color at 90%. 4310 * @param {Number} x0 The position of the first point defining the line that defines the gradient direction and size. 4311 * @param {Number} y0 The position of the first point defining the line that defines the gradient direction and size. 4312 * @param {Number} x1 The position of the second point defining the line that defines the gradient direction and size. 4313 * @param {Number} y1 The position of the second point defining the line that defines the gradient direction and size. 4314 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4315 * @chainable 4316 **/ 4317 p.beginLinearGradientStroke = function(colors, ratios, x0, y0, x1, y1) { 4318 return this._setStroke(new G.Stroke().linearGradient(colors, ratios, x0, y0, x1, y1)); 4319 }; 4320 4321 /** 4322 * Begins a radial gradient stroke. This ends the current sub-path. For example, the following code defines a red to 4323 * blue radial gradient centered at (100, 100), with a radius of 50, and draws a rectangle to display it: 4324 * 4325 * myGraphics.setStrokeStyle(10) 4326 * .beginRadialGradientStroke(["#F00","#00F"], [0, 1], 100, 100, 0, 100, 100, 50) 4327 * .drawRect(50, 90, 150, 110); 4328 * 4329 * A tiny API method "rs" also exists. 4330 * @method beginRadialGradientStroke 4331 * @param {Array} colors An array of CSS compatible color values. For example, ["#F00","#00F"] would define 4332 * a gradient drawing from red to blue. 4333 * @param {Array} ratios An array of gradient positions which correspond to the colors. For example, [0.1, 4334 * 0.9] would draw the first color to 10% then interpolating to the second color at 90%, then draw the second color 4335 * to 100%. 4336 * @param {Number} x0 Center position of the inner circle that defines the gradient. 4337 * @param {Number} y0 Center position of the inner circle that defines the gradient. 4338 * @param {Number} r0 Radius of the inner circle that defines the gradient. 4339 * @param {Number} x1 Center position of the outer circle that defines the gradient. 4340 * @param {Number} y1 Center position of the outer circle that defines the gradient. 4341 * @param {Number} r1 Radius of the outer circle that defines the gradient. 4342 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4343 * @chainable 4344 **/ 4345 p.beginRadialGradientStroke = function(colors, ratios, x0, y0, r0, x1, y1, r1) { 4346 return this._setStroke(new G.Stroke().radialGradient(colors, ratios, x0, y0, r0, x1, y1, r1)); 4347 }; 4348 4349 /** 4350 * Begins a pattern fill using the specified image. This ends the current sub-path. Note that unlike bitmap fills, 4351 * strokes do not currently support a matrix parameter due to limitations in the canvas API. A tiny API method "bs" 4352 * also exists. 4353 * @method beginBitmapStroke 4354 * @param {HTMLImageElement | HTMLCanvasElement | HTMLVideoElement} image The Image, Canvas, or Video object to use 4355 * as the pattern. Must be loaded prior to creating a bitmap fill, or the fill will be empty. 4356 * @param {String} [repetition=repeat] Optional. Indicates whether to repeat the image in the fill area. One of 4357 * "repeat", "repeat-x", "repeat-y", or "no-repeat". Defaults to "repeat". 4358 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4359 * @chainable 4360 **/ 4361 p.beginBitmapStroke = function(image, repetition) { 4362 // NOTE: matrix is not supported for stroke because transforms on strokes also affect the drawn stroke width. 4363 return this._setStroke(new G.Stroke().bitmap(image, repetition)); 4364 }; 4365 4366 /** 4367 * Ends the current sub-path, and begins a new one with no stroke. Functionally identical to <code>beginStroke(null)</code>. 4368 * A tiny API method "es" also exists. 4369 * @method endStroke 4370 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4371 * @chainable 4372 **/ 4373 p.endStroke = function() { 4374 return this.beginStroke(); 4375 }; 4376 4377 /** 4378 * Maps the familiar ActionScript <code>curveTo()</code> method to the functionally similar {{#crossLink "Graphics/quadraticCurveTo"}}{{/crossLink}} 4379 * method. 4380 * @method quadraticCurveTo 4381 * @param {Number} cpx 4382 * @param {Number} cpy 4383 * @param {Number} x 4384 * @param {Number} y 4385 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4386 * @chainable 4387 **/ 4388 p.curveTo = p.quadraticCurveTo; 4389 4390 /** 4391 * 4392 * Maps the familiar ActionScript <code>drawRect()</code> method to the functionally similar {{#crossLink "Graphics/rect"}}{{/crossLink}} 4393 * method. 4394 * @method drawRect 4395 * @param {Number} x 4396 * @param {Number} y 4397 * @param {Number} w Width of the rectangle 4398 * @param {Number} h Height of the rectangle 4399 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4400 * @chainable 4401 **/ 4402 p.drawRect = p.rect; 4403 4404 /** 4405 * Draws a rounded rectangle with all corners with the specified radius. 4406 * @method drawRoundRect 4407 * @param {Number} x 4408 * @param {Number} y 4409 * @param {Number} w 4410 * @param {Number} h 4411 * @param {Number} radius Corner radius. 4412 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4413 * @chainable 4414 **/ 4415 p.drawRoundRect = function(x, y, w, h, radius) { 4416 return this.drawRoundRectComplex(x, y, w, h, radius, radius, radius, radius); 4417 }; 4418 4419 /**
4420 * Draws a rounded rectangle with different corner radii. Supports positive and negative corner radii. A tiny API 4421 * method "rc" also exists. 4422 * @method drawRoundRectComplex 4423 * @param {Number} x The horizontal coordinate to draw the round rect. 4424 * @param {Number} y The vertical coordinate to draw the round rect. 4425 * @param {Number} w The width of the round rect. 4426 * @param {Number} h The height of the round rect. 4427 * @param {Number} radiusTL Top left corner radius. 4428 * @param {Number} radiusTR Top right corner radius. 4429 * @param {Number} radiusBR Bottom right corner radius. 4430 * @param {Number} radiusBL Bottom left corner radius. 4431 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4432 * @chainable 4433 **/ 4434 p.drawRoundRectComplex = function(x, y, w, h, radiusTL, radiusTR, radiusBR, radiusBL) { 4435 return this.append(new G.RoundRect(x, y, w, h, radiusTL, radiusTR, radiusBR, radiusBL)); 4436 }; 4437 4438 /** 4439 * Draws a circle with the specified radius at (x, y). 4440 * 4441 * var g = new createjs.Graphics(); 4442 * g.setStrokeStyle(1); 4443 * g.beginStroke(createjs.Graphics.getRGB(0,0,0)); 4444 * g.beginFill(createjs.Graphics.getRGB(255,0,0)); 4445 * g.drawCircle(0,0,3); 4446 * 4447 * var s = new createjs.Shape(g); 4448 * s.x = 100; 4449 * s.y = 100; 4450 * 4451 * stage.addChild(s); 4452 * stage.update(); 4453 * 4454 * A tiny API method "dc" also exists. 4455 * @method drawCircle 4456 * @param {Number} x x coordinate center point of circle. 4457 * @param {Number} y y coordinate center point of circle. 4458 * @param {Number} radius Radius of circle. 4459 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4460 * @chainable 4461 **/ 4462 p.drawCircle = function(x, y, radius) { 4463 return this.append(new G.Circle(x, y, radius)); 4464 }; 4465 4466 /** 4467 * Draws an ellipse (oval) with a specified width (w) and height (h). Similar to {{#crossLink "Graphics/drawCircle"}}{{/crossLink}}, 4468 * except the width and height can be different. A tiny API method "de" also exists. 4469 * @method drawEllipse 4470 * @param {Number} x The left coordinate point of the ellipse. Note that this is different from {{#crossLink "Graphics/drawCircle"}}{{/crossLink}} 4471 * which draws from center. 4472 * @param {Number} y The top coordinate point of the ellipse. Note that this is different from {{#crossLink "Graphics/drawCircle"}}{{/crossLink}} 4473 * which draws from the center. 4474 * @param {Number} w The height (horizontal diameter) of the ellipse. The horizontal radius will be half of this 4475 * number. 4476 * @param {Number} h The width (vertical diameter) of the ellipse. The vertical radius will be half of this number. 4477 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4478 * @chainable 4479 **/ 4480 p.drawEllipse = function(x, y, w, h) { 4481 return this.append(new G.Ellipse(x, y, w, h)); 4482 }; 4483 4484 /** 4485 * Draws a star if pointSize is greater than 0, or a regular polygon if pointSize is 0 with the specified number of 4486 * points. For example, the following code will draw a familiar 5 pointed star shape centered at 100, 100 and with a 4487 * radius of 50: 4488 * 4489 * myGraphics.beginFill("#FF0").drawPolyStar(100, 100, 50, 5, 0.6, -90); 4490 * // Note: -90 makes the first point vertical 4491 * 4492 * A tiny API method "dp" also exists. 4493 * 4494 * @method drawPolyStar 4495 * @param {Number} x Position of the center of the shape. 4496 * @param {Number} y Position of the center of the shape. 4497 * @param {Number} radius The outer radius of the shape. 4498 * @param {Number} sides The number of points on the star or sides on the polygon. 4499 * @param {Number} pointSize The depth or "pointy-ness" of the star points. A pointSize of 0 will draw a regular 4500 * polygon (no points), a pointSize of 1 will draw nothing because the points are infinitely pointy. 4501 * @param {Number} angle The angle of the first point / corner. For example a value of 0 will draw the first point 4502 * directly to the right of the center. 4503 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4504 * @chainable 4505 **/ 4506 p.drawPolyStar = function(x, y, radius, sides, pointSize, angle) { 4507 return this.append(new G.PolyStar(x, y, radius, sides, pointSize, angle)); 4508 }; 4509 4510 // TODO: deprecated. 4511 /** 4512 * Removed in favour of using custom command objects with {{#crossLink "Graphics/append"}}{{/crossLink}}. 4513 * @method inject 4514 * @deprecated 4515 **/ 4516 4517 /** 4518 * Appends a graphics command object to the graphics queue. Command objects expose an "exec" method 4519 * that accepts two parameters: the Context2D to operate on, and an arbitrary data object passed into 4520 * {{#crossLink "Graphics/draw"}}{{/crossLink}}. The latter will usually be the Shape instance that called draw. 4521 * 4522 * This method is used internally by Graphics methods, such as drawCircle, but can also be used directly to insert 4523 * built-in or custom graphics commands. For example: 4524 * 4525 * // attach data to our shape, so we can access it during the draw: 4526 * myShape.color = "red"; 4527 * 4528 * // append a Circle command object: 4529 * myShape.graphics.append(new createjs.Graphics.Circle(50, 50, 30)); 4530 * 4531 * // append a custom command object with an exec method that sets the fill style 4532 * // based on the shape's data, and then fills the circle. 4533 * myShape.graphics.append({exec:function(ctx, shape) { 4534 * ctx.fillStyle = shape.color; 4535 * ctx.fill(); 4536 * }}); 4537 * 4538 * @method append 4539 * @param {Object} command A graphics command object exposing an "exec" method. 4540 * @param {boolean} clean The clean param is primarily for internal use. A value of true indicates that a command does not generate a path that should be stroked or filled. 4541 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4542 * @chainable 4543 **/ 4544 p.append = function(command, clean) { 4545 this._activeInstructions.push(command); 4546 this.command = command; 4547 if (!clean) { this._dirty = true; } 4548 return this; 4549 }; 4550 4551 /** 4552 * Decodes a compact encoded path string into a series of draw instructions. 4553 * This format is not intended to be human readable, and is meant for use by authoring tools. 4554 * The format uses a base64 character set, with each character representing 6 bits, to define a series of draw 4555 * commands. 4556 * 4557 * Each command is comprised of a single "header" character followed by a variable number of alternating x and y 4558 * position values. Reading the header bits from left to right (most to least significant): bits 1 to 3 specify the 4559 * type of operation (0-moveTo, 1-lineTo, 2-quadraticCurveTo, 3-bezierCurveTo, 4-closePath, 5-7 unused). Bit 4
4560 * indicates whether position values use 12 bits (2 characters) or 18 bits (3 characters), with a one indicating the 4561 * latter. Bits 5 and 6 are currently unused. 4562 * 4563 * Following the header is a series of 0 (closePath), 2 (moveTo, lineTo), 4 (quadraticCurveTo), or 6 (bezierCurveTo) 4564 * parameters. These parameters are alternating x/y positions represented by 2 or 3 characters (as indicated by the 4565 * 4th bit in the command char). These characters consist of a 1 bit sign (1 is negative, 0 is positive), followed 4566 * by an 11 (2 char) or 17 (3 char) bit integer value. All position values are in tenths of a pixel. Except in the 4567 * case of move operations which are absolute, this value is a delta from the previous x or y position (as 4568 * appropriate). 4569 * 4570 * For example, the string "A3cAAMAu4AAA" represents a line starting at -150,0 and ending at 150,0. 4571 * <br />A - bits 000000. First 3 bits (000) indicate a moveTo operation. 4th bit (0) indicates 2 chars per 4572 * parameter. 4573 * <br />n0 - 110111011100. Absolute x position of -150.0px. First bit indicates a negative value, remaining bits 4574 * indicate 1500 tenths of a pixel. 4575 * <br />AA - 000000000000. Absolute y position of 0. 4576 * <br />I - 001100. First 3 bits (001) indicate a lineTo operation. 4th bit (1) indicates 3 chars per parameter. 4577 * <br />Au4 - 000000101110111000. An x delta of 300.0px, which is added to the previous x value of -150.0px to 4578 * provide an absolute position of +150.0px. 4579 * <br />AAA - 000000000000000000. A y delta value of 0. 4580 * 4581 * A tiny API method "p" also exists. 4582 * @method decodePath 4583 * @param {String} str The path string to decode. 4584 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4585 * @chainable 4586 **/ 4587 p.decodePath = function(str) { 4588 var instructions = [this.moveTo, this.lineTo, this.quadraticCurveTo, this.bezierCurveTo, this.closePath]; 4589 var paramCount = [2, 2, 4, 6, 0]; 4590 var i=0, l=str.length; 4591 var params = []; 4592 var x=0, y=0; 4593 var base64 = Graphics.BASE_64; 4594 4595 while (i<l) { 4596 var c = str.charAt(i); 4597 var n = base64[c]; 4598 var fi = n>>3; // highest order bits 1-3 code for operation. 4599 var f = instructions[fi]; 4600 // check that we have a valid instruction & that the unused bits are empty: 4601 if (!f || (n&3)) { throw("bad path data (@"+i+"): "+c); } 4602 var pl = paramCount[fi]; 4603 if (!fi) { x=y=0; } // move operations reset the position. 4604 params.length = 0; 4605 i++; 4606 var charCount = (n>>2&1)+2; // 4th header bit indicates number size for this operation. 4607 for (var p=0; p<pl; p++) { 4608 var num = base64[str.charAt(i)]; 4609 var sign = (num>>5) ? -1 : 1; 4610 num = ((num&31)<<6)|(base64[str.charAt(i+1)]); 4611 if (charCount == 3) { num = (num<<6)|(base64[str.charAt(i+2)]); } 4612 num = sign*num/10; 4613 if (p%2) { x = (num += x); } 4614 else { y = (num += y); } 4615 params[p] = num; 4616 i += charCount; 4617 } 4618 f.apply(this,params); 4619 } 4620 return this; 4621 }; 4622 4623 /** 4624 * Stores all graphics commands so they won't be executed in future draws. Calling store() a second time adds to 4625 * the existing store. This also affects `drawAsPath()`. 4626 * 4627 * This is useful in cases where you are creating vector graphics in an iterative manner (ex. generative art), so 4628 * that only new graphics need to be drawn (which can provide huge performance benefits), but you wish to retain all 4629 * of the vector instructions for later use (ex. scaling, modifying, or exporting). 4630 * 4631 * Note that calling store() will force the active path (if any) to be ended in a manner similar to changing 4632 * the fill or stroke. 4633 * 4634 * For example, consider a application where the user draws lines with the mouse. As each line segment (or collection of 4635 * segments) are added to a Shape, it can be rasterized using {{#crossLink "DisplayObject/updateCache"}}{{/crossLink}}, 4636 * and then stored, so that it can be redrawn at a different scale when the application is resized, or exported to SVG. 4637 * 4638 * // set up cache: 4639 * myShape.cache(0,0,500,500,scale); 4640 * 4641 * // when the user drags, draw a new line: 4642 * myShape.graphics.moveTo(oldX,oldY).lineTo(newX,newY); 4643 * // then draw it into the existing cache: 4644 * myShape.updateCache("source-over"); 4645 * // store the new line, so it isn't redrawn next time: 4646 * myShape.store(); 4647 * 4648 * // then, when the window resizes, we can re-render at a different scale: 4649 * // first, unstore all our lines: 4650 * myShape.unstore(); 4651 * // then cache using the new scale: 4652 * myShape.cache(0,0,500,500,newScale); 4653 * // finally, store the existing commands again: 4654 * myShape.store(); 4655 * 4656 * @method store 4657 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4658 * @chainable 4659 **/ 4660 p.store = function() { 4661 this._updateInstructions(true); 4662 this._storeIndex = this._instructions.length; 4663 return this; 4664 }; 4665 4666 /** 4667 * Unstores any graphics commands that were previously stored using {{#crossLink "Graphics/store"}}{{/crossLink}} 4668 * so that they will be executed in subsequent draw calls. 4669 * 4670 * @method unstore 4671 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4672 * @chainable 4673 **/ 4674 p.unstore = function() { 4675 this._storeIndex = 0; 4676 return this; 4677 }; 4678 4679 /** 4680 * Returns a clone of this Graphics instance. Note that the individual command objects are not cloned. 4681 * @method clone 4682 * @return {Graphics} A clone of the current Graphics instance. 4683 **/ 4684 p.clone = function() { 4685 var o = new Graphics(); 4686 o.command = this.command; 4687 o._stroke = this._stroke; 4688 o._strokeStyle = this._strokeStyle; 4689 o._strokeDash = this._strokeDash; 4690 o._strokeIgnoreScale = this._strokeIgnoreScale; 4691 o._fill = this._fill; 4692 o._instructions = this._instructions.slice(); 4693 o._commitIndex = this._commitIndex; 4694 o._activeInstructions = this._activeInstructions.slice(); 4695 o._dirty = this._dirty; 4696 o._storeIndex = this._storeIndex; 4697 return o; 4698 }; 4699 4700 /** 4701 * Returns a string representation of this object. 4702 * @method toString 4703 * @return {String} a string representation of the instance. 4704 **/ 4705 p.toString = function() { 4706 return "[Graphics]"; 4707 }; 4708 4709 4710// tiny API: 4711 /** 4712 * Shortcut to moveTo. 4713 * @method mt 4714 * @param {Number} x The x coordinate the drawing point should move to. 4715 * @param {Number} y The y coordinate the drawing point should move to. 4716 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls). 4717 * @chainable 4718 * @protected 4719 **/ 4720 p.mt = p.moveTo; 4721 4722 /** 4723 * Shortcut to lineTo. 4724 * @method lt 4725 * @param {Number} x The x coordinate the drawing point should draw to. 4726 * @param {Number} y The y coordinate the drawing point should draw to. 4727 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4728 * @chainable 4729 * @protected 4730 **/ 4731 p.lt = p.lineTo; 4732 4733 /** 4734 * Shortcut to arcTo. 4735 * @method at 4736 * @param {Number} x1 4737 * @param {Number} y1 4738 * @param {Number} x2 4739 * @param {Number} y2 4740 * @param {Number} radius 4741 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4742 * @chainable 4743 * @protected 4744 **/ 4745 p.at = p.arcTo; 4746 4747 /** 4748 * Shortcut to bezierCurveTo. 4749 * @method bt 4750 * @param {Number} cp1x 4751 * @param {Number} cp1y 4752 * @param {Number} cp2x 4753 * @param {Number} cp2y 4754 * @param {Number} x 4755 * @param {Number} y 4756 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4757 * @chainable 4758 * @protected 4759 **/ 4760 p.bt = p.bezierCurveTo; 4761 4762 /** 4763 * Shortcut to quadraticCurveTo / curveTo. 4764 * @method qt 4765 * @param {Number} cpx 4766 * @param {Number} cpy 4767 * @param {Number} x 4768 * @param {Number} y 4769 * @protected 4770 * @chainable 4771 **/ 4772 p.qt = p.quadraticCurveTo; 4773 4774 /** 4775 * Shortcut to arc. 4776 * @method a 4777 * @param {Number} x 4778 * @param {Number} y 4779 * @param {Number} radius 4780 * @param {Number} startAngle Measured in radians. 4781 * @param {Number} endAngle Measured in radians. 4782 * @param {Boolean} anticlockwise 4783 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4784 * @protected 4785 * @chainable 4786 **/ 4787 p.a = p.arc; 4788 4789 /** 4790 * Shortcut to rect. 4791 * @method r 4792 * @param {Number} x 4793 * @param {Number} y 4794 * @param {Number} w Width of the rectangle 4795 * @param {Number} h Height of the rectangle 4796 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4797 * @chainable 4798 * @protected 4799 **/ 4800 p.r = p.rect; 4801 4802 /** 4803 * Shortcut to closePath. 4804 * @method cp 4805 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4806 * @chainable 4807 * @protected 4808 **/ 4809 p.cp = p.closePath; 4810 4811 /** 4812 * Shortcut to clear. 4813 * @method c 4814 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4815 * @chainable 4816 * @protected 4817 **/ 4818 p.c = p.clear; 4819 4820 /** 4821 * Shortcut to beginFill. 4822 * @method f 4823 * @param {String} color A CSS compatible color value (ex. "red", "#FF0000", or "rgba(255,0,0,0.5)"). Setting to 4824 * null will result in no fill. 4825 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4826 * @chainable 4827 * @protected 4828 **/ 4829 p.f = p.beginFill; 4830 4831 /** 4832 * Shortcut to beginLinearGradientFill. 4833 * @method lf 4834 * @param {Array} colors An array of CSS compatible color values. For example, ["#F00","#00F"] would define a gradient 4835 * drawing from red to blue. 4836 * @param {Array} ratios An array of gradient positions which correspond to the colors. For example, [0.1, 0.9] would draw 4837 * the first color to 10% then interpolating to the second color at 90%. 4838 * @param {Number} x0 The position of the first point defining the line that defines the gradient direction and size. 4839 * @param {Number} y0 The position of the first point defining the line that defines the gradient direction and size. 4840 * @param {Number} x1 The position of the second point defining the line that defines the gradient direction and size. 4841 * @param {Number} y1 The position of the second point defining the line that defines the gradient direction and size. 4842 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4843 * @chainable 4844 * @protected 4845 **/ 4846 p.lf = p.beginLinearGradientFill; 4847 4848 /** 4849 * Shortcut to beginRadialGradientFill. 4850 * @method rf 4851 * @param {Array} colors An array of CSS compatible color values. For example, ["#F00","#00F"] would define 4852 * a gradient drawing from red to blue. 4853 * @param {Array} ratios An array of gradient positions which correspond to the colors. For example, [0.1, 4854 * 0.9] would draw the first color to 10% then interpolating to the second color at 90%. 4855 * @param {Number} x0 Center position of the inner circle that defines the gradient. 4856 * @param {Number} y0 Center position of the inner circle that defines the gradient. 4857 * @param {Number} r0 Radius of the inner circle that defines the gradient. 4858 * @param {Number} x1 Center position of the outer circle that defines the gradient. 4859 * @param {Number} y1 Center position of the outer circle that defines the gradient. 4860 * @param {Number} r1 Radius of the outer circle that defines the gradient. 4861 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4862 * @chainable 4863 * @protected 4864 **/ 4865 p.rf = p.beginRadialGradientFill; 4866 4867 /** 4868 * Shortcut to beginBitmapFill. 4869 * @method bf 4870 * @param {HTMLImageElement | HTMLCanvasElement | HTMLVideoElement} image The Image, Canvas, or Video object to use 4871 * as the pattern. 4872 * @param {String} repetition Optional. Indicates whether to repeat the image in the fill area. One of "repeat", 4873 * "repeat-x", "repeat-y", or "no-repeat". Defaults to "repeat". Note that Firefox does not support "repeat-x" or 4874 * "repeat-y" (latest tests were in FF 20.0), and will default to "repeat". 4875 * @param {Matrix2D} matrix Optional. Specifies a transformation matrix for the bitmap fill. This transformation 4876 * will be applied relative to the parent transform. 4877 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4878 * @chainable 4879 * @protected 4880 **/ 4881 p.bf = p.beginBitmapFill; 4882 4883 /** 4884 * Shortcut to endFill. 4885 * @method ef 4886 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4887 * @chainable 4888 * @protected 4889 **/ 4890 p.ef = p.endFill; 4891 4892 /** 4893 * Shortcut to setStrokeStyle. 4894 * @method ss 4895 * @param {Number} thickness The width of the stroke. 4896 * @param {String | Number} [caps=0] Indicates the type of caps to use at the end of lines. One of butt, 4897 * round, or square. Defaults to "butt". Also accepts the values 0 (butt), 1 (round), and 2
4897(square) for use with 4898 * the tiny API. 4899 * @param {String | Number} [joints=0] Specifies the type of joints that should be used where two lines meet. 4900 * One of bevel, round, or miter. Defaults to "miter". Also accepts the values 0 (miter), 1 (round), and 2 (bevel) 4901 * for use with the tiny API. 4902 * @param {Number} [miterLimit=10] If joints is set to "miter", then you can specify a miter limit ratio which 4903 * controls at what point a mitered joint will be clipped. 4904 * @param {Boolean} [ignoreScale=false] If true, the stroke will be drawn at the specified thickness regardless 4905 * of active transformations. 4906 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4907 * @chainable 4908 * @protected 4909 **/ 4910 p.ss = p.setStrokeStyle; 4911 4912 /** 4913 * Shortcut to setStrokeDash. 4914 * @method sd 4915 * @param {Array} [segments] An array specifying the dash pattern, alternating between line and gap. 4916 * For example, [20,10] would create a pattern of 20 pixel lines with 10 pixel gaps between them. 4917 * Passing null or an empty array will clear any existing dash. 4918 * @param {Number} [offset=0] The offset of the dash pattern. For example, you could increment this value to create a "marching ants" effect. 4919 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4920 * @chainable 4921 * @protected 4922 **/ 4923 p.sd = p.setStrokeDash; 4924 4925 /** 4926 * Shortcut to beginStroke. 4927 * @method s 4928 * @param {String} color A CSS compatible color value (ex. "#FF0000", "red", or "rgba(255,0,0,0.5)"). Setting to 4929 * null will result in no stroke. 4930 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4931 * @chainable 4932 * @protected 4933 **/ 4934 p.s = p.beginStroke; 4935 4936 /** 4937 * Shortcut to beginLinearGradientStroke. 4938 * @method ls 4939 * @param {Array} colors An array of CSS compatible color values. For example, ["#F00","#00F"] would define 4940 * a gradient drawing from red to blue. 4941 * @param {Array} ratios An array of gradient positions which correspond to the colors. For example, [0.1, 4942 * 0.9] would draw the first color to 10% then interpolating to the second color at 90%. 4943 * @param {Number} x0 The position of the first point defining the line that defines the gradient direction and size. 4944 * @param {Number} y0 The position of the first point defining the line that defines the gradient direction and size. 4945 * @param {Number} x1 The position of the second point defining the line that defines the gradient direction and size. 4946 * @param {Number} y1 The position of the second point defining the line that defines the gradient direction and size. 4947 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4948 * @chainable 4949 * @protected 4950 **/ 4951 p.ls = p.beginLinearGradientStroke; 4952 4953 /** 4954 * Shortcut to beginRadialGradientStroke. 4955 * @method rs 4956 * @param {Array} colors An array of CSS compatible color values. For example, ["#F00","#00F"] would define 4957 * a gradient drawing from red to blue. 4958 * @param {Array} ratios An array of gradient positions which correspond to the colors. For example, [0.1, 4959 * 0.9] would draw the first color to 10% then interpolating to the second color at 90%, then draw the second color 4960 * to 100%. 4961 * @param {Number} x0 Center position of the inner circle that defines the gradient. 4962 * @param {Number} y0 Center position of the inner circle that defines the gradient. 4963 * @param {Number} r0 Radius of the inner circle that defines the gradient. 4964 * @param {Number} x1 Center position of the outer circle that defines the gradient. 4965 * @param {Number} y1 Center position of the outer circle that defines the gradient. 4966 * @param {Number} r1 Radius of the outer circle that defines the gradient. 4967 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4968 * @chainable 4969 * @protected 4970 **/ 4971 p.rs = p.beginRadialGradientStroke; 4972 4973 /** 4974 * Shortcut to beginBitmapStroke. 4975 * @method bs 4976 * @param {HTMLImageElement | HTMLCanvasElement | HTMLVideoElement} image The Image, Canvas, or Video object to use 4977 * as the pattern. 4978 * @param {String} [repetition=repeat] Optional. Indicates whether to repeat the image in the fill area. One of 4979 * "repeat", "repeat-x", "repeat-y", or "no-repeat". Defaults to "repeat". 4980 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4981 * @chainable 4982 * @protected 4983 **/ 4984 p.bs = p.beginBitmapStroke; 4985 4986 /** 4987 * Shortcut to endStroke. 4988 * @method es 4989 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 4990 * @chainable 4991 * @protected 4992 **/ 4993 p.es = p.endStroke; 4994 4995 /** 4996 * Shortcut to drawRect. 4997 * @method dr 4998 * @param {Number} x 4999 * @param {Number} y 5000 * @param {Number} w Width of the rectangle 5001 * @param {Number} h Height of the rectangle 5002 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 5003 * @chainable 5004 * @protected 5005 **/ 5006 p.dr = p.drawRect; 5007 5008 /** 5009 * Shortcut to drawRoundRect. 5010 * @method rr 5011 * @param {Number} x 5012 * @param {Number} y 5013 * @param {Number} w 5014 * @param {Number} h 5015 * @param {Number} radius Corner radius. 5016 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 5017 * @chainable 5018 * @protected 5019 **/ 5020 p.rr = p.drawRoundRect; 5021 5022 /** 5023 * Shortcut to drawRoundRectComplex. 5024 * @method rc 5025 * @param {Number} x The horizontal coordinate to draw the round rect. 5026 * @param {Number} y The vertical coordinate to draw the round rect. 5027 * @param {Number} w The width of the round rect. 5028 * @param {Number} h The height of the round rect. 5029 * @param {Number} radiusTL Top left corner radius. 5030 * @param {Number} radiusTR Top right corner radius. 5031 * @param {Number} radiusBR Bottom right corner radius. 5032 * @param {Number} radiusBL Bottom left corner radius. 5033 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 5034 * @chainable 5035 * @protected 5036 **/ 5037 p.rc = p.drawRoundRectComplex; 5038 5039 /** 5040 * Shortcut to drawCircle. 5041 * @method dc 5042 * @param {Number} x x coordinate center point of circle. 5043 * @param {Number} y y coordinate center point of circle. 5044 * @param {Number} radius Radius of circle. 5045 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 5046 * @chainable 5047 * @protected 5048 **/ 5049 p.dc = p.drawCircle; 5050 5051 /** 5052 * Shortcut to drawEllipse. 5053 * @method de 5054 * @param {Number} x The left coordinate point of the ellipse. Note that this is different from {{#crossLink "Graphics/drawCircle"}}{{/crossLink}} 5055 * which draws from center. 5056 * @param {Number} y The top coordinate point of the ellipse. Note that this is different from {{#crossLink "Graphics/drawCircle"}}{{/crossLink}} 5057 * which draws from the center. 5058 * @param {Number} w The height (horizontal diameter) of the ellipse. The horizontal radius will be half of this 5059 * number. 5060 * @param {Number} h The width (vertical diameter) of the ellipse. The vertical radius will be half of this number. 5061 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 5062 * @chainable 5063 * @protected 5064 **/ 5065 p.de = p.drawEllipse; 5066 5067 /** 5068 * Shortcut to drawPolyStar. 5069 * @method dp 5070 * @param {Number} x Position of the center of the shape. 5071 * @param {Number} y Position of the center of the shape. 5072 * @param {Number} radius The outer radius of the shape. 5073 * @param {Number} sides The number of points on the star or sides on the polygon. 5074 * @param {Number} pointSize The depth or "pointy-ness" of the star points. A pointSize of 0 will draw a regular
5075 * polygon (no points), a pointSize of 1 will draw nothing because the points are infinitely pointy. 5076 * @param {Number} angle The angle of the first point / corner. For example a value of 0 will draw the first point 5077 * directly to the right of the center. 5078 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 5079 * @chainable 5080 * @protected 5081 **/ 5082 p.dp = p.drawPolyStar; 5083 5084 /** 5085 * Shortcut to decodePath. 5086 * @method p 5087 * @param {String} str The path string to decode. 5088 * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.) 5089 * @chainable 5090 * @protected 5091 **/ 5092 p.p = p.decodePath; 5093 5094 5095// private methods: 5096 /** 5097 * @method _updateInstructions 5098 * @param commit 5099 * @protected 5100 **/ 5101 p._updateInstructions = function(commit) { 5102 var instr = this._instructions, active = this._activeInstructions, commitIndex = this._commitIndex; 5103 5104 if (this._dirty && active.length) { 5105 instr.length = commitIndex; // remove old, uncommitted commands 5106 instr.push(Graphics.beginCmd); 5107 5108 var l = active.length, ll = instr.length; 5109 instr.length = ll+l; 5110 for (var i=0; i<l; i++) { instr[i+ll] = active[i]; } 5111 5112 if (this._fill) { instr.push(this._fill); } 5113 if (this._stroke) { 5114 // doesn't need to be re-applied if it hasn't changed. 5115 if (this._strokeDash !== this._oldStrokeDash) { 5116 this._oldStrokeDash = this._strokeDash; 5117 instr.push(this._strokeDash); 5118 } 5119 if (this._strokeStyle !== this._oldStrokeStyle) { 5120 this._oldStrokeStyle = this._strokeStyle; 5121 instr.push(this._strokeStyle); 5122 } 5123 instr.push(this._stroke); 5124 } 5125 5126 this._dirty = false; 5127 } 5128 5129 if (commit) { 5130 active.length = 0; 5131 this._commitIndex = instr.length; 5132 } 5133 }; 5134 5135 /** 5136 * @method _setFill 5137 * @param fill 5138 * @protected 5139 **/ 5140 p._setFill = function(fill) { 5141 this._updateInstructions(true); 5142 this.command = this._fill = fill; 5143 return this; 5144 }; 5145 5146 /** 5147 * @method _setStroke 5148 * @param stroke 5149 * @protected 5150 **/ 5151 p._setStroke = function(stroke) { 5152 this._updateInstructions(true); 5153 if (this.command = this._stroke = stroke) { 5154 stroke.ignoreScale = this._strokeIgnoreScale; 5155 } 5156 return this; 5157 }; 5158 5159// Command Objects: 5160 /** 5161 * @namespace Graphics 5162 */ 5163 /** 5164 * Graphics command object. See {{#crossLink "Graphics/lineTo"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information. See {{#crossLink "Graphics"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information. 5165 * @class LineTo 5166 * @constructor 5167 * @param {Number} x 5168 * @param {Number} y 5169 **/ 5170 /** 5171 * @property x 5172 * @type Number 5173 */ 5174 /** 5175 * @property y 5176 * @type Number 5177 */ 5178 /** 5179 * Execute the Graphics command in the provided Canvas context. 5180 * @method exec 5181 * @param {CanvasRenderingContext2D} ctx The canvas rendering context 5182 */ 5183 (G.LineTo = function(x, y) { 5184 this.x = x; this.y = y; 5185 }).prototype.exec = function(ctx) { ctx.lineTo(this.x,this.y); }; 5186 5187 /** 5188 * Graphics command object. See {{#crossLink "Graphics/moveTo"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information. 5189 * @class MoveTo 5190 * @constructor 5191 * @param {Number} x 5192 * @param {Number} y 5193 **/ 5194 /** 5195 * @property x 5196 * @type Number 5197 */ 5198 /** 5199 * @property y 5200 * @type Number 5201 */ 5202 /** 5203 * @method exec 5204 * @param {CanvasRenderingContext2D} ctx 5205 */ 5206 (G.MoveTo = function(x, y) { 5207 this.x = x; this.y = y; 5208 }).prototype.exec = function(ctx) { ctx.moveTo(this.x, this.y); }; 5209 5210 5211 /** 5212 * Graphics command object. See {{#crossLink "Graphics/arcTo"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information. 5213 * @class ArcTo 5214 * @constructor 5215 * @param {Number} x1 5216 * @param {Number} y1 5217 * @param {Number} x2 5218 * @param {Number} y2 5219 * @param {Number} radius 5220 **/ 5221 /** 5222 * @property x1 5223 * @type Number 5224 */ 5225 /** 5226 * @property y1 5227 * @type Number 5228 */ 5229 /** 5230 * @property x2 5231 * @type Number 5232 */ 5233 /** 5234 * @property y2 5235 * @type Number 5236 */ 5237 /** 5238 * @property radius 5239 * @type Number 5240 */ 5241 /** 5242 * Execute the Graphics command in the provided Canvas context. 5243 * @method exec 5244 * @param {CanvasRenderingContext2D} ctx The canvas rendering context 5245 */ 5246 (G.ArcTo = function(x1, y1, x2, y2, radius) { 5247 this.x1 = x1; this.y1 = y1; 5248 this.x2 = x2; this.y2 = y2;
5249 this.radius = radius; 5250 }).prototype.exec = function(ctx) { ctx.arcTo(this.x1, this.y1, this.x2, this.y2, this.radius); }; 5251 5252 /** 5253 * Graphics command object. See {{#crossLink "Graphics/arc"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information. 5254 * @class Arc 5255 * @constructor 5256 * @param {Number} x 5257 * @param {Number} y 5258 * @param {Number} radius 5259 * @param {Number} startAngle 5260 * @param {Number} endAngle 5261 * @param {Number} anticlockwise 5262 **/ 5263 /** 5264 * @property x 5265 * @type Number 5266 */ 5267 /** 5268 * @property y 5269 * @type Number 5270 */ 5271 /** 5272 * @property radius 5273 * @type Number 5274 */ 5275 /** 5276 * @property startAngle 5277 * @type Number 5278 */ 5279 /** 5280 * @property endAngle 5281 * @type Number 5282 */ 5283 /** 5284 * @property anticlockwise 5285 * @type Number 5286 */ 5287 /** 5288 * Execute the Graphics command in the provided Canvas context. 5289 * @method exec 5290 * @param {CanvasRenderingContext2D} ctx The canvas rendering context 5291 */ 5292 (G.Arc = function(x, y, radius, startAngle, endAngle, anticlockwise) { 5293 this.x = x; this.y = y; 5294 this.radius = radius; 5295 this.startAngle = startAngle; this.endAngle = endAngle; 5296 this.anticlockwise = !!anticlockwise; 5297 }).prototype.exec = function(ctx) { ctx.arc(this.x, this.y, this.radius, this.startAngle, this.endAngle, this.anticlockwise); }; 5298 5299 /** 5300 * Graphics command object. See {{#crossLink "Graphics/quadraticCurveTo"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information. 5301 * @class QuadraticCurveTo 5302 * @constructor 5303 * @param {Number} cpx 5304 * @param {Number} cpy 5305 * @param {Number} x 5306 * @param {Number} y 5307 **/ 5308 /** 5309 * @property cpx 5310 * @type Number 5311 */ 5312 /** 5313 * @property cpy 5314 * @type Number 5315 */ 5316 /** 5317 * @property x 5318 * @type Number 5319 */ 5320 /** 5321 * @property y 5322 * @type Number 5323 */ 5324 /** 5325 * Execute the Graphics command in the provided Canvas context. 5326 * @method exec 5327 * @param {CanvasRenderingContext2D} ctx The canvas rendering context 5328 */ 5329 (G.QuadraticCurveTo = function(cpx, cpy, x, y) { 5330 this.cpx = cpx; this.cpy = cpy; 5331 this.x = x; this.y = y; 5332 }).prototype.exec = function(ctx) { ctx.quadraticCurveTo(this.cpx, this.cpy, this.x, this.y); }; 5333 5334 /** 5335 * Graphics command object. See {{#crossLink "Graphics/bezierCurveTo"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information. 5336 * @class BezierCurveTo 5337 * @constructor 5338 * @param {Number} cp1x 5339 * @param {Number} cp1y 5340 * @param {Number} cp2x 5341 * @param {Number} cp2y 5342 * @param {Number} x 5343 * @param {Number} y 5344 **/ 5345 /** 5346 * @property cp1x 5347 * @type Number 5348 */ 5349 /** 5350 * @property cp1y 5351 * @type Number 5352 */ 5353 /** 5354 * @property cp2x 5355 * @type Number 5356 */ 5357 /** 5358 * @property cp2y 5359 * @type Number 5360 */ 5361 /** 5362 * @property x 5363 * @type Number 5364 */ 5365 /** 5366 * @property y 5367 * @type Number 5368 */ 5369 /** 5370 * Execute the Graphics command in the provided Canvas context. 5371 * @method exec 5372 * @param {CanvasRenderingContext2D} ctx The canvas rendering context 5373 */ 5374 (G.BezierCurveTo = function(cp1x, cp1y, cp2x, cp2y, x, y) { 5375 this.cp1x = cp1x; this.cp1y = cp1y; 5376 this.cp2x = cp2x; this.cp2y = cp2y; 5377 this.x = x; this.y = y; 5378 }).prototype.exec = function(ctx) { ctx.bezierCurveTo(this.cp1x, this.cp1y, this.cp2x, this.cp2y, this.x, this.y); }; 5379 5380 /** 5381 * Graphics command object. See {{#crossLink "Graphics/rect"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information. 5382 * @class Rect 5383 * @constructor 5384 * @param {Number} x 5385 * @param {Number} y 5386 * @param {Number} w 5387 * @param {Number} h 5388 **/ 5389 /** 5390 * @property x 5391 * @type Number 5392 */ 5393 /** 5394 * @property y 5395 * @type Number 5396 */ 5397 /** 5398 * @property w 5399 * @type Number 5400 */ 5401 /** 5402 * @property h 5403 * @type Number 5404 */ 5405 /** 5406 * Execute the Graphics command in the provided Canvas context. 5407 * @method exec 5408 * @param {CanvasRenderingContext2D} ctx The canvas rendering context 5409 */ 5410 (G.Rect = function(x, y, w, h) { 5411 this.x = x; this.y = y; 5412 this.w = w; this.h = h; 5413 }).prototype.exec = function(ctx) { ctx.rect(this.x, this.y, this.w, this.h); }; 5414 5415 /** 5416 * Graphics command object. See {{#crossLink "Graphics/closePath"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information. 5417 * @class ClosePath 5418 * @constructor 5419 **/ 5420 /** 5421 * Execute the Graphics command in the provided Canvas context. 5422 * @method exec 5423 * @param {CanvasRenderingContext2D} ctx The canvas rendering context 5424 */ 5425 (G.ClosePath = function() { 5426 }).prototype.exec = function(ctx) { ctx.closePath(); }; 5427 5428 /** 5429 * Graphics command object to begin a new path. See {{#crossLink "Graphics"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information. 5430 * @class BeginPath 5431 * @constructor 5432 **/ 5433 /** 5434 * Execute the Graphics command in the provided Canvas context. 5435 * @method exec 5436 * @param {CanvasRenderingContext2D} ctx The canvas rendering context 5437 */ 5438 (G.BeginPath = function() { 5439 }).prototype.exec = function(ctx) { ctx.beginPath(); }; 5440 5441 /** 5442 * Graphics command object. See {{#crossLink "Graphics/beginFill"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information. 5443 * @class Fill 5444 * @constructor 5445 * @param {Object} style A valid Context2D fillStyle. 5446 * @param {Matrix2D} matrix 5447 **/ 5448 /** 5449 * A valid Context2D fillStyle. 5450 * @property style 5451 * @type Object 5452 */ 5453 /** 5454 * @property matrix 5455 * @type Matrix2D 5456 */ 5457 /** 5458 * Execute the Graphics command in the provided Canvas context. 5459 * @method exec 5460 * @param {CanvasRenderingContext2D} ctx The canvas rendering context 5461 */
5462 p = (G.Fill = function(style, matrix) { 5463 this.style = style; 5464 this.matrix = matrix; 5465 }).prototype; 5466 p.exec = function(ctx) { 5467 if (!this.style) { return; } 5468 ctx.fillStyle = this.style; 5469 var mtx = this.matrix; 5470 if (mtx) { ctx.save(); ctx.transform(mtx.a, mtx.b, mtx.c, mtx.d, mtx.tx, mtx.ty); } 5471 ctx.fill(); 5472 if (mtx) { ctx.restore(); } 5473 }; 5474 /** 5475 * Creates a linear gradient style and assigns it to {{#crossLink "Fill/style:property"}}{{/crossLink}}. 5476 * See {{#crossLink "Graphics/beginLinearGradientFill"}}{{/crossLink}} for more information. 5477 * @method linearGradient 5478 * @param {Array} colors 5479 * 5480 * @param {Array} ratios 5481 * @param {Number} x0 5482 * @param {Number} y0 5483 * @param {Number} x1 5484 * @param {Number} y1 5485 * @return {Fill} Returns this Fill object for chaining or assignment. 5486 */ 5487 p.linearGradient = function(colors, ratios, x0, y0, x1, y1) { 5488 var o = this.style = Graphics._ctx.createLinearGradient(x0, y0, x1, y1); 5489 for (var i=0, l=colors.length; i<l; i++) { o.addColorStop(ratios[i], colors[i]); } 5490 o.props = {colors:colors, ratios:ratios, x0:x0, y0:y0, x1:x1, y1:y1, type:"linear"}; 5491 return this; 5492 }; 5493 /** 5494 * Creates a radial gradient style and assigns it to {{#crossLink "Fill/style:property"}}{{/crossLink}}. 5495 * See {{#crossLink "Graphics/beginRadialGradientFill"}}{{/crossLink}} for more information. 5496 * @method radialGradient 5497 * @param {Array} colors 5498 * @param {Array} ratios 5499 * @param {Number} x0 5500 * @param {Number} y0 5501 * @param {Number} r0 5502 * @param {Number} x1 5503 * @param {Number} y1 5504 * @param {Number} r1 5505 * @return {Fill} Returns this Fill object for chaining or assignment. 5506 */ 5507 p.radialGradient = function(colors, ratios, x0, y0, r0, x1, y1, r1) { 5508 var o = this.style = Graphics._ctx.createRadialGradient(x0, y0, r0, x1, y1, r1); 5509 for (var i=0, l=colors.length; i<l; i++) { o.addColorStop(ratios[i], colors[i]); } 5510 o.props = {colors:colors, ratios:ratios, x0:x0, y0:y0, r0:r0, x1:x1, y1:y1, r1:r1, type:"radial"}; 5511 return this; 5512 }; 5513 /** 5514 * Creates a bitmap fill style and assigns it to the {{#crossLink "Fill/style:property"}}{{/crossLink}}. 5515 * See {{#crossLink "Graphics/beginBitmapFill"}}{{/crossLink}} for more information. 5516 * @method bitmap 5517 * @param {HTMLImageElement | HTMLCanvasElement | HTMLVideoElement} image Must be loaded prior to creating a bitmap fill, or the fill will be empty. 5518 * @param {String} [repetition] One of: repeat, repeat-x, repeat-y, or no-repeat. 5519 * @return {Fill} Returns this Fill object for chaining or assignment. 5520 */ 5521 p.bitmap = function(image, repetition) { 5522 if (image.naturalWidth || image.getContext || image.readyState >= 2) { 5523 var o = this.style = Graphics._ctx.createPattern(image, repetition || ""); 5524 o.props = {image: image, repetition: repetition, type: "bitmap"}; 5525 } 5526 return this; 5527 }; 5528 p.path = false; 5529 5530 /** 5531 * Graphics command object. See {{#crossLink "Graphics/beginStroke"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information. 5532 * @class Stroke 5533 * @constructor 5534 * @param {Object} style A valid Context2D fillStyle. 5535 * @param {Boolean} ignoreScale 5536 **/ 5537 /** 5538 * A valid Context2D strokeStyle. 5539 * @property style 5540 * @type Object 5541 */ 5542 /** 5543 * @property ignoreScale 5544 * @type Boolean 5545 */ 5546 /** 5547 * Execute the Graphics command in the provided Canvas context. 5548 * @method exec 5549 * @param {CanvasRenderingContext2D} ctx The canvas rendering context 5550 */ 5551 p = (G.Stroke = function(style, ignoreScale) { 5552 this.style = style; 5553 this.ignoreScale = ignoreScale; 5554 }).prototype; 5555 p.exec = function(ctx) { 5556 if (!this.style) { return; } 5557 ctx.strokeStyle = this.style; 5558 if (this.ignoreScale) { ctx.save(); ctx.setTransform(1,0,0,1,0,0); } 5559 ctx.stroke(); 5560 if (this.ignoreScale) { ctx.restore(); } 5561 }; 5562 /** 5563 * Creates a linear gradient style and assigns it to {{#crossLink "Stroke/style:property"}}{{/crossLink}}. 5564 * See {{#crossLink "Graphics/beginLinearGradientStroke"}}{{/crossLink}} for more information. 5565 * @method linearGradient 5566 * @param {Array} colors 5567 * @param {Array} ratios 5568 * @param {Number} x0 5569 * @param {Number} y0 5570 * @param {Number} x1 5571 * @param {Number} y1 5572 * @return {Fill} Returns this Stroke object for chaining or assignment. 5573 */ 5574 p.linearGradient = G.Fill.prototype.linearGradient; 5575 /** 5576 * Creates a radial gradient style and assigns it to {{#crossLink "Stroke/style:property"}}{{/crossLink}}. 5577 * See {{#crossLink "Graphics/beginRadialGradientStroke"}}{{/crossLink}} for more information. 5578 * @method radialGradient 5579 * @param {Array} colors 5580 * @param {Array} ratios 5581 * @param {Number} x0 5582 * @param {Number} y0 5583 * @param {Number} r0 5584 * @param {Number} x1 5585 * @param {Number} y1 5586 * @param {Number} r1 5587 * @return {Fill} Returns this Stroke object for chaining or assignment. 5588 */ 5589 p.radialGradient = G.Fill.prototype.radialGradient; 5590 /** 5591 * Creates a bitmap fill style and assigns it to {{#crossLink "Stroke/style:property"}}{{/crossLink}}. 5592 * See {{#crossLink "Graphics/beginBitmapStroke"}}{{/crossLink}} for more information. 5593 * @method bitmap 5594 * @param {HTMLImageElement} image 5595 * @param {String} [repetition] One of: repeat, repeat-x, repeat-y, or no-repeat. 5596 * @return {Fill} Returns this Stroke object for chaining or assignment. 5597 */ 5598 p.bitmap = G.Fill.prototype.bitmap; 5599 p.path = false;
5600 5601 /** 5602 * Graphics command object. See {{#crossLink "Graphics/setStrokeStyle"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information. 5603 * @class StrokeStyle 5604 * @constructor 5605 * @param {Number} width 5606 * @param {String} [caps=butt] 5607 * @param {String} [joints=miter] 5608 * @param {Number} [miterLimit=10] 5609 * @param {Boolean} [ignoreScale=false] 5610 **/ 5611 /** 5612 * @property width 5613 * @type Number 5614 */ 5615 /** 5616 * One of: butt, round, square 5617 * @property caps 5618 * @type String 5619 */ 5620 /** 5621 * One of: round, bevel, miter 5622 * @property joints 5623 * @type String 5624 */ 5625 /** 5626 * @property miterLimit 5627 * @type Number 5628 */ 5629 /** 5630 * Execute the Graphics command in the provided Canvas context. 5631 * @method exec 5632 * @param {CanvasRenderingContext2D} ctx The canvas rendering context 5633 */ 5634 p = (G.StrokeStyle = function(width, caps, joints, miterLimit, ignoreScale) { 5635 this.width = width; 5636 this.caps = caps; 5637 this.joints = joints; 5638 this.miterLimit = miterLimit; 5639 this.ignoreScale = ignoreScale; 5640 }).prototype; 5641 p.exec = function(ctx) { 5642 ctx.lineWidth = (this.width == null ? "1" : this.width); 5643 ctx.lineCap = (this.caps == null ? "butt" : (isNaN(this.caps) ? this.caps : Graphics.STROKE_CAPS_MAP[this.caps])); 5644 ctx.lineJoin = (this.joints == null ? "miter" : (isNaN(this.joints) ? this.joints : Graphics.STROKE_JOINTS_MAP[this.joints])); 5645 ctx.miterLimit = (this.miterLimit == null ? "10" : this.miterLimit); 5646 ctx.ignoreScale = (this.ignoreScale == null ? false : this.ignoreScale); 5647 }; 5648 p.path = false; 5649 5650 /** 5651 * Graphics command object. See {{#crossLink "Graphics/setStrokeDash"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information. 5652 * @class StrokeDash 5653 * @constructor 5654 * @param {Array} [segments] 5655 * @param {Number} [offset=0] 5656 **/ 5657 /** 5658 * @property segments 5659 * @type Array 5660 */ 5661 /** 5662 * @property offset 5663 * @type Number 5664 */ 5665 /** 5666 * Execute the Graphics command in the provided Canvas context. 5667 * @method exec 5668 * @param {CanvasRenderingContext2D} ctx The canvas rendering context 5669 */ 5670 (G.StrokeDash = function(segments, offset) { 5671 this.segments = segments; 5672 this.offset = offset||0; 5673 }).prototype.exec = function(ctx) { 5674 if (ctx.setLineDash) { // feature detection. 5675 ctx.setLineDash(this.segments|| G.StrokeDash.EMPTY_SEGMENTS); // instead of [] to reduce churn. 5676 ctx.lineDashOffset = this.offset||0; 5677 } 5678 }; 5679 /** 5680 * The default value for segments (ie. no dash). 5681 * @property EMPTY_SEGMENTS 5682 * @static 5683 * @final 5684 * @readonly 5685 * @protected 5686 * @type {Array} 5687 **/ 5688 G.StrokeDash.EMPTY_SEGMENTS = []; 5689 5690 /** 5691 * Graphics command object. See {{#crossLink "Graphics/drawRoundRectComplex"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information. 5692 * @class RoundRect 5693 * @constructor 5694 * @param {Number} x 5695 * @param {Number} y 5696 * @param {Number} w 5697 * @param {Number} h 5698 * @param {Number} radiusTL 5699 * @param {Number} radiusTR 5700 * @param {Number} radiusBR 5701 * @param {Number} radiusBL 5702 **/ 5703 /** 5704 * @property x 5705 * @type Number 5706 */ 5707 /** 5708 * @property y 5709 * @type Number 5710 */ 5711 /** 5712 * @property w 5713 * @type Number 5714 */ 5715 /** 5716 * @property h 5717 * @type Number 5718 */ 5719 /** 5720 * @property radiusTL 5721 * @type Number 5722 */ 5723 /** 5724 * @property radiusTR 5725 * @type Number 5726 */ 5727 /** 5728 * @property radiusBR 5729 * @type Number 5730 */ 5731 /** 5732 * @property radiusBL 5733 * @type Number 5734 */ 5735 /** 5736 * Execute the Graphics command in the provided Canvas context. 5737 * @method exec 5738 * @param {CanvasRenderingContext2D} ctx The canvas rendering context 5739 */ 5740 (G.RoundRect = function(x, y, w, h, radiusTL, radiusTR, radiusBR, radiusBL) { 5741 this.x = x; this.y = y; 5742 this.w = w; this.h = h; 5743 this.radiusTL = radiusTL; this.radiusTR = radiusTR; 5744 this.radiusBR = radiusBR;
5744 this.radiusBL = radiusBL; 5745 }).prototype.exec = function(ctx) { 5746 var max = (w<h?w:h)/2; 5747 var mTL=0, mTR=0, mBR=0, mBL=0; 5748 var x = this.x, y = this.y, w = this.w, h = this.h; 5749 var rTL = this.radiusTL, rTR = this.radiusTR, rBR = this.radiusBR, rBL = this.radiusBL; 5750 5751 if (rTL < 0) { rTL *= (mTL=-1); } 5752 if (rTL > max) { rTL = max; } 5753 if (rTR < 0) { rTR *= (mTR=-1); } 5754 if (rTR > max) { rTR = max; } 5755 if (rBR < 0) { rBR *= (mBR=-1); } 5756 if (rBR > max) { rBR = max; } 5757 if (rBL < 0) { rBL *= (mBL=-1); } 5758 if (rBL > max) { rBL = max; } 5759 5760 ctx.moveTo(x+w-rTR, y); 5761 ctx.arcTo(x+w+rTR*mTR, y-rTR*mTR, x+w, y+rTR, rTR); 5762 ctx.lineTo(x+w, y+h-rBR); 5763 ctx.arcTo(x+w+rBR*mBR, y+h+rBR*mBR, x+w-rBR, y+h, rBR); 5764 ctx.lineTo(x+rBL, y+h); 5765 ctx.arcTo(x-rBL*mBL, y+h+rBL*mBL, x, y+h-rBL, rBL); 5766 ctx.lineTo(x, y+rTL); 5767 ctx.arcTo(x-rTL*mTL, y-rTL*mTL, x+rTL, y, rTL); 5768 ctx.closePath(); 5769 }; 5770 5771 /** 5772 * Graphics command object. See {{#crossLink "Graphics/drawCircle"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information. 5773 * @class Circle 5774 * @constructor 5775 * @param {Number} x 5776 * @param {Number} y 5777 * @param {Number} radius 5778 **/ 5779 /** 5780 * @property x 5781 * @type Number 5782 */ 5783 /** 5784 * @property y 5785 * @type Number 5786 */ 5787 /** 5788 * @property radius 5789 * @type Number 5790 */ 5791 /** 5792 * Execute the Graphics command in the provided Canvas context. 5793 * @method exec 5794 * @param {CanvasRenderingContext2D} ctx The canvas rendering context 5795 */ 5796 (G.Circle = function(x, y, radius) { 5797 this.x = x; this.y = y; 5798 this.radius = radius; 5799 }).prototype.exec = function(ctx) { ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2); }; 5800 5801 /** 5802 * Graphics command object. See {{#crossLink "Graphics/drawEllipse"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information. 5803 * @class Ellipse 5804 * @constructor 5805 * @param {Number} x 5806 * @param {Number} y 5807 * @param {Number} w 5808 * @param {Number} h 5809 **/ 5810 /** 5811 * @property x 5812 * @type Number 5813 */ 5814 /** 5815 * @property y 5816 * @type Number 5817 */ 5818 /** 5819 * @property w 5820 * @type Number 5821 */ 5822 /** 5823 * @property h 5824 * @type Number 5825 */ 5826 /** 5827 * Execute the Graphics command in the provided Canvas context. 5828 * @method exec 5829 * @param {CanvasRenderingContext2D} ctx The canvas rendering context 5830 */ 5831 (G.Ellipse = function(x, y, w, h) { 5832 this.x = x; this.y = y; 5833 this.w = w; this.h = h; 5834 }).prototype.exec = function(ctx) { 5835 var x = this.x, y = this.y; 5836 var w = this.w, h = this.h; 5837 5838 var k = 0.5522848; 5839 var ox = (w / 2) * k; 5840 var oy = (h / 2) * k; 5841 var xe = x + w; 5842 var ye = y + h; 5843 var xm = x + w / 2; 5844 var ym = y + h / 2; 5845 5846 ctx.moveTo(x, ym); 5847 ctx.bezierCurveTo(x, ym-oy, xm-ox, y, xm, y); 5848 ctx.bezierCurveTo(xm+ox, y, xe, ym-oy, xe, ym); 5849 ctx.bezierCurveTo(xe, ym+oy, xm+ox, ye, xm, ye); 5850 ctx.bezierCurveTo(xm-ox, ye, x, ym+oy, x, ym); 5851 }; 5852 5853 /** 5854 * Graphics command object. See {{#crossLink "Graphics/drawPolyStar"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information. 5855 * @class PolyStar 5856 * @constructor 5857 * @param {Number} x 5858 * @param {Number} y 5859 * @param {Number} radius 5860 * @param {Number} sides 5861 * @param {Number} pointSize 5862 * @param {Number} angle 5863 **/ 5864 /** 5865 * @property x 5866 * @type Number 5867 */ 5868 /** 5869 * @property y 5870 * @type Number 5871 */ 5872 /** 5873 * @property radius 5874 * @type Number 5875 */ 5876 /** 5877 * @property sides 5878 * @type Number 5879 */ 5880 /** 5881 * @property pointSize 5882 * @type Number 5883 */ 5884 /** 5885 * @property angle 5886 * @type Number 5887 */ 5888 /** 5889 * Execute the Graphics command in the provided Canvas context. 5890 * @method exec 5891 * @param {CanvasRenderingContext2D} ctx The canvas rendering context 5892 */ 5893 (G.PolyStar = function(x, y, radius, sides, pointSize, angle) { 5894 this.x = x; this.y = y; 5895 this.radius = radius; 5896 this.sides = sides; 5897 this.pointSize = pointSize; 5898 this.angle = angle; 5899 }).prototype.exec = function(ctx) { 5900 var x = this.x, y = this.y; 5901 var radius = this.radius; 5902 var angle = (this.angle||0)/180*Math.PI; 5903 var sides = this.sides; 5904 var ps = 1-(this.pointSize||0); 5905 var a = Math.PI/sides; 5906 5907 ctx.moveTo(x+Math.cos(angle)*radius, y+Math.sin(angle)*radius); 5908 for (var i=0; i<sides; i++) { 5909 angle += a; 5910 if (ps != 1) { 5911 ctx.lineTo(x+Math.cos(angle)*radius*ps, y+Math.sin(angle)*radius*ps); 5912 } 5913 angle += a; 5914 ctx.lineTo(x+Math.cos(angle)*radius, y+Math.sin(angle)*radius); 5915 } 5916 ctx.closePath(); 5917 }; 5918 5919 // docced above. 5920 Graphics.beginCmd = new G.BeginPath(); // so we don't have to instantiate multiple instances. 5921 5922 5923 createjs.Graphics = Graphics; 5924}()); 5925 5926//############################################################################## 5927// DisplayObject.js 5928//############################################################################## 5929 5930this.createjs = this.createjs||{}; 5931 5932(function() { 5933 "use strict"; 5934 5935 5936// constructor: 5937 /** 5938 * DisplayObject is an abstract class that should not be constructed directly. Instead construct subclasses such as 5939 * {{#crossLink "Container"}}{{/crossLink}}, {{#crossLink "Bitmap"}}{{/crossLink}}, and {{#crossLink "Shape"}}{{/crossLink}}. 5940 * DisplayObject is the base class for all display classes in the EaselJS library. It defines the core properties and 5941 * methods that are shared between all display objects, such as transformation properties (x, y, scaleX, scaleY, etc), 5942 * caching, and mouse handlers. 5943 * @class DisplayObject
5944 * @extends EventDispatcher 5945 * @constructor 5946 **/ 5947 function DisplayObject() { 5948 this.EventDispatcher_constructor(); 5949 5950 5951 // public properties: 5952 /** 5953 * The alpha (transparency) for this display object. 0 is fully transparent, 1 is fully opaque. 5954 * @property alpha 5955 * @type {Number} 5956 * @default 1 5957 **/ 5958 this.alpha = 1; 5959 5960 /** 5961 * If a cache is active, this returns the canvas that holds the cached version of this display object. See {{#crossLink "cache"}}{{/crossLink}} 5962 * for more information. 5963 * @property cacheCanvas 5964 * @type {HTMLCanvasElement | Object} 5965 * @default null 5966 * @readonly 5967 **/ 5968 this.cacheCanvas = null; 5969 5970 /** 5971 * Returns an ID number that uniquely identifies the current cache for this display object. This can be used to 5972 * determine if the cache has changed since a previous check. 5973 * @property cacheID 5974 * @type {Number} 5975 * @default 0 5976 */ 5977 this.cacheID = 0; 5978 5979 /** 5980 * Unique ID for this display object. Makes display objects easier for some uses. 5981 * @property id 5982 * @type {Number} 5983 * @default -1 5984 **/ 5985 this.id = createjs.UID.get(); 5986 5987 /** 5988 * Indicates whether to include this object when running mouse interactions. Setting this to `false` for children 5989 * of a {{#crossLink "Container"}}{{/crossLink}} will cause events on the Container to not fire when that child is 5990 * clicked. Setting this property to `false` does not prevent the {{#crossLink "Container/getObjectsUnderPoint"}}{{/crossLink}} 5991 * method from returning the child. 5992 * 5993 * <strong>Note:</strong> In EaselJS 0.7.0, the mouseEnabled property will not work properly with nested Containers. Please 5994 * check out the latest NEXT version in <a href="https://github.com/CreateJS/EaselJS/tree/master/lib">GitHub</a> for an updated version with this issue resolved. The fix will be 5995 * provided in the next release of EaselJS. 5996 * @property mouseEnabled 5997 * @type {Boolean} 5998 * @default true 5999 **/ 6000 this.mouseEnabled = true; 6001 6002 /** 6003 * If false, the tick will not run on this display object (or its children). This can provide some performance benefits. 6004 * In addition to preventing the "tick" event from being dispatched, it will also prevent tick related updates 6005 * on some display objects (ex. Sprite & MovieClip frame advancing, DOMElement visibility handling). 6006 * @property tickEnabled 6007 * @type Boolean 6008 * @default true 6009 **/ 6010 this.tickEnabled = true; 6011 6012 /** 6013 * An optional name for this display object. Included in {{#crossLink "DisplayObject/toString"}}{{/crossLink}} . Useful for 6014 * debugging. 6015 * @property name 6016 * @type {String} 6017 * @default null 6018 **/ 6019 this.name = null; 6020 6021 /** 6022 * A reference to the {{#crossLink "Container"}}{{/crossLink}} or {{#crossLink "Stage"}}{{/crossLink}} object that 6023 * contains this display object, or null if it has not been added 6024 * to one. 6025 * @property parent 6026 * @final 6027 * @type {Container} 6028 * @default null 6029 * @readonly 6030 **/ 6031 this.parent = null; 6032 6033 /** 6034 * The left offset for this display object's registration point. For example, to make a 100x100px Bitmap rotate 6035 * around its center, you would set regX and {{#crossLink "DisplayObject/regY:property"}}{{/crossLink}} to 50. 6036 * @property regX 6037 * @type {Number} 6038 * @default 0 6039 **/ 6040 this.regX = 0; 6041 6042 /** 6043 * The y offset for this display object's registration point. For example, to make a 100x100px Bitmap rotate around 6044 * its center, you would set {{#crossLink "DisplayObject/regX:property"}}{{/crossLink}} and regY to 50. 6045 * @property regY 6046 * @type {Number} 6047 * @default 0 6048 **/ 6049 this.regY = 0; 6050 6051 /** 6052 * The rotation in degrees for this display object. 6053 * @property rotation 6054 * @type {Number} 6055 * @default 0 6056 **/ 6057 this.rotation = 0; 6058 6059 /** 6060 * The factor to stretch this display object horizontally. For example, setting scaleX to 2 will stretch the display 6061 * object to twice its nominal width. To horizontally flip an object, set the scale to a negative number. 6062 * @property scaleX 6063 * @type {Number} 6064 * @default 1 6065 **/ 6066 this.scaleX = 1; 6067 6068 /** 6069 * The factor to stretch this display object vertically. For example, setting scaleY to 0.5 will stretch the display 6070 * object to half its nominal height. To vertically flip an object, set the scale to a negative number. 6071 * @property scaleY 6072 * @type {Number} 6073 * @default 1 6074 **/ 6075 this.scaleY = 1; 6076 6077 /** 6078 * The factor to skew this display object horizontally. 6079 * @property skewX 6080 * @type {Number} 6081 * @default 0 6082 **/ 6083 this.skewX = 0; 6084 6085 /** 6086 * The factor to skew this display object vertically. 6087 * @property skewY 6088 * @type {Number} 6089 * @default 0 6090 **/ 6091 this.skewY = 0; 6092 6093 /** 6094 * A shadow object that defines the shadow to render on this display object. Set to `null` to remove a shadow. If 6095 * null, this property is inherited from the parent container. 6096 * @property shadow 6097 * @type {Shadow} 6098 * @default null 6099 **/ 6100 this.shadow = null; 6101 6102 /** 6103 * Indicates whether this display object should be rendered to the canvas and included when running the Stage 6104 * {{#crossLink "Stage/getObjectsUnderPoint"}}{{/crossLink}} method. 6105 * @property visible 6106 * @type {Boolean} 6107 * @default true 6108 **/ 6109 this.visible = true; 6110 6111 /** 6112 * The x (horizontal) position of the display object, relative to its parent. 6113 * @property x 6114 * @type {Number} 6115 * @default 0 6116 **/ 6117 this.x = 0; 6118 6119 /** The y (vertical) position of the display object, relative to its parent. 6120 * @property y 6121 * @type {Number} 6122 * @default 0 6123 **/ 6124 this.y = 0; 6125 6126 /** 6127 * If set, defines the transformation for this display object, overriding all other transformation properties 6128 * (x, y, rotation, scale, skew). 6129 * @property transformMatrix 6130 * @type {Matrix2D} 6131 * @default null 6132 **/ 6133 this.transformMatrix = null; 6134 6135 /** 6136 * The composite operation indicates how the pixels of this display object will be composited
6136with the elements 6137 * behind it. If `null`, this property is inherited from the parent container. For more information, read the 6138 * <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#compositing"> 6139 * whatwg spec on compositing</a>. 6140 * @property compositeOperation 6141 * @type {String} 6142 * @default null 6143 **/ 6144 this.compositeOperation = null; 6145 6146 /** 6147 * Indicates whether the display object should be drawn to a whole pixel when 6148 * {{#crossLink "Stage/snapToPixelEnabled"}}{{/crossLink}} is true. To enable/disable snapping on whole 6149 * categories of display objects, set this value on the prototype (Ex. Text.prototype.snapToPixel = true). 6150 * @property snapToPixel 6151 * @type {Boolean} 6152 * @default true 6153 **/ 6154 this.snapToPixel = true; 6155 6156 /** 6157 * An array of Filter objects to apply to this display object. Filters are only applied / updated when {{#crossLink "cache"}}{{/crossLink}} 6158 * or {{#crossLink "updateCache"}}{{/crossLink}} is called on the display object, and only apply to the area that is 6159 * cached. 6160 * @property filters 6161 * @type {Array} 6162 * @default null 6163 **/ 6164 this.filters = null; 6165 6166 /** 6167 * A Shape instance that defines a vector mask (clipping path) for this display object. The shape's transformation 6168 * will be applied relative to the display object's parent coordinates (as if it were a child of the parent). 6169 * @property mask 6170 * @type {Shape} 6171 * @default null 6172 */ 6173 this.mask = null; 6174 6175 /** 6176 * A display object that will be tested when checking mouse interactions or testing {{#crossLink "Container/getObjectsUnderPoint"}}{{/crossLink}}. 6177 * The hit area will have its transformation applied relative to this display object's coordinate space (as though 6178 * the hit test object were a child of this display object and relative to its regX/Y). The hitArea will be tested 6179 * using only its own `alpha` value regardless of the alpha value on the target display object, or the target's 6180 * ancestors (parents). 6181 * 6182 * If set on a {{#crossLink "Container"}}{{/crossLink}}, children of the Container will not receive mouse events. 6183 * This is similar to setting {{#crossLink "mouseChildren"}}{{/crossLink}} to false. 6184 * 6185 * Note that hitArea is NOT currently used by the `hitTest()` method, nor is it supported for {{#crossLink "Stage"}}{{/crossLink}}. 6186 * @property hitArea 6187 * @type {DisplayObject} 6188 * @default null 6189 */ 6190 this.hitArea = null; 6191 6192 /** 6193 * A CSS cursor (ex. "pointer", "help", "text", etc) that will be displayed when the user hovers over this display 6194 * object. You must enable mouseover events using the {{#crossLink "Stage/enableMouseOver"}}{{/crossLink}} method to 6195 * use this property. Setting a non-null cursor on a Container will override the cursor set on its descendants. 6196 * @property cursor 6197 * @type {String} 6198 * @default null 6199 */ 6200 this.cursor = null; 6201 6202 6203 // private properties: 6204 /** 6205 * @property _cacheOffsetX 6206 * @protected 6207 * @type {Number} 6208 * @default 0 6209 **/ 6210 this._cacheOffsetX = 0; 6211 6212 /** 6213 * @property _cacheOffsetY 6214 * @protected 6215 * @type {Number} 6216 * @default 0 6217 **/ 6218 this._cacheOffsetY = 0; 6219 6220 /** 6221 * @property _filterOffsetX 6222 * @protected 6223 * @type {Number} 6224 * @default 0 6225 **/ 6226 this._filterOffsetX = 0; 6227 6228 /** 6229 * @property _filterOffsetY 6230 * @protected 6231 * @type {Number} 6232 * @default 0 6233 **/ 6234 this._filterOffsetY = 0; 6235 6236 /** 6237 * @property _cacheScale 6238 * @protected 6239 * @type {Number} 6240 * @default 1 6241 **/ 6242 this._cacheScale = 1; 6243 6244 /** 6245 * @property _cacheDataURLID 6246 * @protected 6247 * @type {Number} 6248 * @default 0 6249 */ 6250 this._cacheDataURLID = 0; 6251 6252 /** 6253 * @property _cacheDataURL 6254 * @protected 6255 * @type {String} 6256 * @default null 6257 */ 6258 this._cacheDataURL = null; 6259 6260 /** 6261 * @property _props 6262 * @protected 6263 * @type {DisplayObject} 6264 * @default null 6265 **/ 6266 this._props = new createjs.DisplayProps(); 6267 6268 /** 6269 * @property _rectangle 6270 * @protected 6271 * @type {Rectangle} 6272 * @default null 6273 **/ 6274 this._rectangle = new createjs.Rectangle(); 6275 6276 /** 6277 * @property _bounds 6278 * @protected 6279 * @type {Rectangle} 6280 * @default null 6281 **/ 6282 this._bounds = null; 6283 }
6284 var p = createjs.extend(DisplayObject, createjs.EventDispatcher); 6285 6286 // TODO: deprecated 6287 // p.initialize = function() {}; // searchable for devs wondering where it is. REMOVED. See docs for details. 6288 6289// static properties: 6290 /** 6291 * Listing of mouse event names. Used in _hasMouseEventListener. 6292 * @property _MOUSE_EVENTS 6293 * @protected 6294 * @static 6295 * @type {Array} 6296 **/ 6297 DisplayObject._MOUSE_EVENTS = ["click","dblclick","mousedown","mouseout","mouseover","pressmove","pressup","rollout","rollover"]; 6298 6299 /** 6300 * Suppresses errors generated when using features like hitTest, mouse events, and {{#crossLink "getObjectsUnderPoint"}}{{/crossLink}} 6301 * with cross domain content. 6302 * @property suppressCrossDomainErrors 6303 * @static 6304 * @type {Boolean} 6305 * @default false 6306 **/ 6307 DisplayObject.suppressCrossDomainErrors = false; 6308 6309 /** 6310 * @property _snapToPixelEnabled 6311 * @protected 6312 * @static 6313 * @type {Boolean} 6314 * @default false 6315 **/ 6316 DisplayObject._snapToPixelEnabled = false; // stage.snapToPixelEnabled is temporarily copied here during a draw to provide global access. 6317 6318 /** 6319 * @property _hitTestCanvas 6320 * @type {HTMLCanvasElement | Object} 6321 * @static 6322 * @protected 6323 **/ 6324 /** 6325 * @property _hitTestContext 6326 * @type {CanvasRenderingContext2D} 6327 * @static 6328 * @protected 6329 **/ 6330 var canvas = createjs.createCanvas?createjs.createCanvas():document.createElement("canvas"); // prevent errors on load in browsers without canvas. 6331 if (canvas.getContext) { 6332 DisplayObject._hitTestCanvas = canvas; 6333 DisplayObject._hitTestContext = canvas.getContext("2d"); 6334 canvas.width = canvas.height = 1; 6335 } 6336 6337 /** 6338 * @property _nextCacheID 6339 * @type {Number} 6340 * @static 6341 * @protected 6342 **/ 6343 DisplayObject._nextCacheID = 1; 6344 6345 6346// events: 6347 /** 6348 * Dispatched when the user presses their left mouse button over the display object. See the 6349 * {{#crossLink "MouseEvent"}}{{/crossLink}} class for a listing of event properties. 6350 * @event mousedown 6351 * @since 0.6.0 6352 */ 6353 6354 /** 6355 * Dispatched when the user presses their left mouse button and then releases it while over the display object. 6356 * See the {{#crossLink "MouseEvent"}}{{/crossLink}} class for a listing of event properties. 6357 * @event click 6358 * @since 0.6.0 6359 */ 6360 6361 /** 6362 * Dispatched when the user double clicks their left mouse button over this display object. 6363 * See the {{#crossLink "MouseEvent"}}{{/crossLink}} class for a listing of event properties. 6364 * @event dblclick 6365 * @since 0.6.0 6366 */ 6367 6368 /** 6369 * Dispatched when the user's mouse enters this display object. This event must be enabled using 6370 * {{#crossLink "Stage/enableMouseOver"}}{{/crossLink}}. See also {{#crossLink "DisplayObject/rollover:event"}}{{/crossLink}}. 6371 * See the {{#crossLink "MouseEvent"}}{{/crossLink}} class for a listing of event properties. 6372 * @event mouseover 6373 * @since 0.6.0 6374 */ 6375 6376 /** 6377 * Dispatched when the user's mouse leaves this display object. This event must be enabled using 6378 * {{#crossLink "Stage/enableMouseOver"}}{{/crossLink}}. See also {{#crossLink "DisplayObject/rollout:event"}}{{/crossLink}}. 6379 * See the {{#crossLink "MouseEvent"}}{{/crossLink}} class for a listing of event properties. 6380 * @event mouseout 6381 * @since 0.6.0 6382 */ 6383 6384 /** 6385 * This event is similar to {{#crossLink "DisplayObject/mouseover:event"}}{{/crossLink}}, with the following 6386 * differences: it does not bubble, and it considers {{#crossLink "Container"}}{{/crossLink}} instances as an 6387 * aggregate of their content. 6388 * 6389 * For example, myContainer contains two overlapping children: shapeA and shapeB. The user moves their mouse over 6390 * shapeA and then directly on to shapeB. With a listener for {{#crossLink "mouseover:event"}}{{/crossLink}} on 6391 * myContainer, two events would be received, each targeting a child element:<OL> 6392 * <LI>when the mouse enters shapeA (target=shapeA)</LI> 6393 * <LI>when the mouse enters shapeB (target=shapeB)</LI> 6394 * </OL> 6395 * However, with a listener for "rollover" instead, only a single event is received when the mouse first enters 6396 * the aggregate myContainer content (target=myContainer). 6397 * 6398 * This event must be enabled using {{#crossLink "Stage/enableMouseOver"}}{{/crossLink}}. 6399 * See the {{#crossLink "MouseEvent"}}{{/crossLink}} class for a listing of event properties. 6400 * @event rollover 6401 * @since 0.7.0 6402 */ 6403 6404 /** 6405 * This event is similar to {{#crossLink "DisplayObject/mouseout:event"}}{{/crossLink}}, with the following 6406 * differences: it does not bubble, and it considers {{#crossLink "Container"}}{{/crossLink}} instances as an 6407 * aggregate of their content. 6408 * 6409 * For example, myContainer contains two overlapping children: shapeA and shapeB. The user moves their mouse over 6410 * shapeA, then directly on to shapeB, then off both. With a listener for {{#crossLink "mouseout:event"}}{{/crossLink}} 6411 * on myContainer, two events would be received, each targeting a child element:<OL> 6412 * <LI>when the mouse leaves shapeA (target=shapeA)</LI> 6413 * <LI>when the mouse leaves shapeB (target=shapeB)</LI> 6414 * </OL> 6415 * However, with a listener for "rollout" instead, only a single event is received when the mouse leaves 6416 * the aggregate myContainer content (target=myContainer). 6417 * 6418 * This event must be enabled using {{#crossLink "Stage/enableMouseOver"}}{{/crossLink}}. 6419 * See the {{#crossLink "MouseEvent"}}{{/crossLink}} class for a listing of event properties. 6420 * @event rollout 6421 * @since 0.7.0 6422 */ 6423 6424 /** 6425 * After a {{#crossLink "DisplayObject/mousedown:event"}}{{/crossLink}} occurs on a display object, a pressmove 6426 * event will be generated on that object whenever the mouse moves until the mouse press is released. This can be 6427 * useful for dragging and similar operations. 6428 * @event pressmove 6429 * @since 0.7.0 6430 */ 6431 6432 /** 6433 * After a {{#crossLink "DisplayObject/mousedown:event"}}{{/crossLink}} occurs on a display object, a pressup event 6434 * will be generated on that object when that mouse press is released. This can be useful for dragging and similar 6435 * operations. 6436 * @event pressup 6437 * @since 0.7.0 6438 */ 6439 6440 /** 6441 * Dispatched when the display object is added to a parent container. 6442 * @event added 6443 */ 6444 6445 /** 6446 * Dispatched when the display object is removed from its parent container. 6447 * @event removed 6448 */ 6449 6450 /** 6451 * Dispatched on each display object on a stage whenever the stage updates. This occurs immediately before the 6452 * rendering (draw) pass. When {{#crossLink "Stage/update"}}{{/crossLink}} is called, first all display objects on 6453 * the stage dispatch the tick event, then all of the display objects are drawn to stage. Children will have their 6454 * {{#crossLink "tick:event"}}{{/crossLink}} event dispatched in order of their depth prior to the event being 6455 * dispatched on their parent. 6456 * @event tick 6457 * @param {Object} target The object that dispatched the event. 6458 * @param {String} type The event type. 6459 * @param {Array} params An array containing any arguments that were passed to the Stage.update(
6459) method. For 6460 * example if you called stage.update("hello"), then the params would be ["hello"]. 6461 * @since 0.6.0 6462 */ 6463 6464 6465// getter / setters: 6466 /** 6467 * Use the {{#crossLink "DisplayObject/stage:property"}}{{/crossLink}} property instead. 6468 * @method getStage 6469 * @return {Stage} 6470 * @deprecated 6471 **/ 6472 p.getStage = function() { 6473 // uses dynamic access to avoid circular dependencies; 6474 var o = this, _Stage = createjs["Stage"]; 6475 while (o.parent) { o = o.parent; } 6476 if (o instanceof _Stage) { return o; } 6477 return null; 6478 }; 6479 6480 /** 6481 * Returns the Stage instance that this display object will be rendered on, or null if it has not been added to one. 6482 * @property stage 6483 * @type {Stage} 6484 * @readonly 6485 **/ 6486 try { 6487 Object.defineProperties(p, { 6488 stage: { get: p.getStage } 6489 }); 6490 } catch (e) {} 6491 6492 6493// public methods: 6494 /** 6495 * Returns true or false indicating whether the display object would be visible if drawn to a canvas. 6496 * This does not account for whether it would be visible within the boundaries of the stage. 6497 * 6498 * NOTE: This method is mainly for internal use, though it may be useful for advanced uses. 6499 * @method isVisible 6500 * @return {Boolean} Boolean indicating whether the display object would be visible if drawn to a canvas 6501 **/ 6502 p.isVisible = function() { 6503 return !!(this.visible && this.alpha > 0 && this.scaleX != 0 && this.scaleY != 0); 6504 }; 6505 6506 /** 6507 * Draws the display object into the specified context ignoring its visible, alpha, shadow, and transform. 6508 * Returns <code>true</code> if the draw was handled (useful for overriding functionality). 6509 * 6510 * NOTE: This method is mainly for internal use, though it may be useful for advanced uses. 6511 * @method draw 6512 * @param {CanvasRenderingContext2D} ctx The canvas 2D context object to draw into. 6513 * @param {Boolean} [ignoreCache=false] Indicates whether the draw operation should ignore any current cache. For example, 6514 * used for drawing the cache (to prevent it from simply drawing an existing cache back into itself). 6515 * @return {Boolean} 6516 **/ 6517 p.draw = function(ctx, ignoreCache) { 6518 var cacheCanvas = this.cacheCanvas; 6519 if (ignoreCache || !cacheCanvas) { return false; } 6520 var scale = this._cacheScale; 6521 ctx.drawImage(cacheCanvas, this._cacheOffsetX+this._filterOffsetX, this._cacheOffsetY+this._filterOffsetY, cacheCanvas.width/scale, cacheCanvas.height/scale); 6522 return true; 6523 }; 6524 6525 /** 6526 * Applies this display object's transformation, alpha, globalCompositeOperation, clipping path (mask), and shadow 6527 * to the specified context. This is typically called prior to {{#crossLink "DisplayObject/draw"}}{{/crossLink}}. 6528 * @method updateContext 6529 * @param {CanvasRenderingContext2D} ctx The canvas 2D to update. 6530 **/ 6531 p.updateContext = function(ctx) { 6532 var o=this, mask=o.mask, mtx= o._props.matrix; 6533 6534 if (mask && mask.graphics && !mask.graphics.isEmpty()) { 6535 mask.getMatrix(mtx); 6536 ctx.transform(mtx.a, mtx.b, mtx.c, mtx.d, mtx.tx, mtx.ty); 6537 6538 mask.graphics.drawAsPath(ctx); 6539 ctx.clip(); 6540 6541 mtx.invert(); 6542 ctx.transform(mtx.a, mtx.b, mtx.c, mtx.d, mtx.tx, mtx.ty); 6543 } 6544 6545 this.getMatrix(mtx); 6546 var tx = mtx.tx, ty = mtx.ty; 6547 if (DisplayObject._snapToPixelEnabled && o.snapToPixel) { 6548 tx = tx + (tx < 0 ? -0.5 : 0.5) | 0; 6549 ty = ty + (ty < 0 ? -0.5 : 0.5) | 0; 6550 } 6551 ctx.transform(mtx.a, mtx.b, mtx.c, mtx.d, tx, ty); 6552 ctx.globalAlpha *= o.alpha; 6553 if (o.compositeOperation) { ctx.globalCompositeOperation = o.compositeOperation; } 6554 if (o.shadow) { this._applyShadow(ctx, o.shadow); } 6555 }; 6556 6557 /** 6558 * Draws the display object into a new canvas, which is then used for subsequent draws. For complex content 6559 * that does not change frequently (ex. a Container with many children that do not move, or a complex vector Shape), 6560 * this can provide for much faster rendering because the content does not need to be re-rendered each tick. The 6561 * cached display object can be moved, rotated, faded, etc freely, however if its content changes, you must 6562 * manually update the cache by calling <code>updateCache()</code> or <code>cache()</code> again. You must specify 6563 * the cache area via the x, y, w, and h parameters. This defines the rectangle that will be rendered and cached
6564 * using this display object's coordinates. 6565 * 6566 * <h4>Example</h4> 6567 * For example if you defined a Shape that drew a circle at 0, 0 with a radius of 25: 6568 * 6569 * var shape = new createjs.Shape(); 6570 * shape.graphics.beginFill("#ff0000").drawCircle(0, 0, 25); 6571 * myShape.cache(-25, -25, 50, 50); 6572 * 6573 * Note that filters need to be defined <em>before</em> the cache is applied. Check out the {{#crossLink "Filter"}}{{/crossLink}} 6574 * class for more information. Some filters (ex. BlurFilter) will not work as expected in conjunction with the scale param. 6575 * 6576 * Usually, the resulting cacheCanvas will have the dimensions width*scale by height*scale, however some filters (ex. BlurFilter) 6577 * will add padding to the canvas dimensions. 6578 * 6579 * @method cache 6580 * @param {Number} x The x coordinate origin for the cache region. 6581 * @param {Number} y The y coordinate origin for the cache region. 6582 * @param {Number} width The width of the cache region. 6583 * @param {Number} height The height of the cache region. 6584 * @param {Number} [scale=1] The scale at which the cache will be created. For example, if you cache a vector shape using 6585 * myShape.cache(0,0,100,100,2) then the resulting cacheCanvas will be 200x200 px. This lets you scale and rotate 6586 * cached elements with greater fidelity. Default is 1. 6587 **/ 6588 p.cache = function(x, y, width, height, scale) { 6589 // draw to canvas. 6590 scale = scale||1; 6591 if (!this.cacheCanvas) { this.cacheCanvas = createjs.createCanvas?createjs.createCanvas():document.createElement("canvas"); } 6592 this._cacheWidth = width; 6593 this._cacheHeight = height; 6594 this._cacheOffsetX = x; 6595 this._cacheOffsetY = y; 6596 this._cacheScale = scale; 6597 this.updateCache(); 6598 }; 6599 6600 /** 6601 * Redraws the display object to its cache. Calling updateCache without an active cache will throw an error. 6602 * If compositeOperation is null the current cache will be cleared prior to drawing. Otherwise the display object 6603 * will be drawn over the existing cache using the specified compositeOperation. 6604 * 6605 * <h4>Example</h4> 6606 * Clear the current graphics of a cached shape, draw some new instructions, and then update the cache. The new line 6607 * will be drawn on top of the old one. 6608 * 6609 * // Not shown: Creating the shape, and caching it. 6610 * shapeInstance.clear(); 6611 * shapeInstance.setStrokeStyle(3).beginStroke("#ff0000").moveTo(100, 100).lineTo(200,200); 6612 * shapeInstance.updateCache(); 6613 * 6614 * @method updateCache 6615 * @param {String} compositeOperation The compositeOperation to use, or null to clear the cache and redraw it. 6616 * <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#compositing"> 6617 * whatwg spec on compositing</a>. 6618 **/ 6619 p.updateCache = function(compositeOperation) { 6620 var cacheCanvas = this.cacheCanvas; 6621 if (!cacheCanvas) { throw "cache() must be called before updateCache()"; } 6622 var scale = this._cacheScale, offX = this._cacheOffsetX*scale, offY = this._cacheOffsetY*scale; 6623 var w = this._cacheWidth, h = this._cacheHeight, ctx = cacheCanvas.getContext("2d"); 6624 6625 var fBounds = this._getFilterBounds(); 6626 offX += (this._filterOffsetX = fBounds.x); 6627 offY += (this._filterOffsetY = fBounds.y); 6628 6629 w = Math.ceil(w*scale) + fBounds.width; 6630 h = Math.ceil(h*scale) + fBounds.height; 6631 if (w != cacheCanvas.width || h != cacheCanvas.height) { 6632 // TODO: it would be nice to preserve the content if there is a compositeOperation. 6633 cacheCanvas.width = w; 6634 cacheCanvas.height = h; 6635 } else if (!compositeOperation) { 6636 ctx.clearRect(0, 0, w+1, h+1); 6637 } 6638 6639 ctx.save(); 6640 ctx.globalCompositeOperation = compositeOperation; 6641 ctx.setTransform(scale, 0, 0, scale, -offX, -offY); 6642 this.draw(ctx, true); 6643 // TODO: filters and cache scale don't play well together at present. 6644 this._applyFilters(); 6645 ctx.restore(); 6646 this.cacheID = DisplayObject._nextCacheID++; 6647 }; 6648 6649 /** 6650 * Clears the current cache. See {{#crossLink "DisplayObject/cache"}}{{/crossLink}} for more information. 6651 * @method uncache 6652 **/ 6653 p.uncache = function() { 6654 this._cacheDataURL = this.cacheCanvas = null; 6655 this.cacheID = this._cacheOffsetX = this._cacheOffsetY = this._filterOffsetX = this._filterOffsetY = 0; 6656 this._cacheScale = 1; 6657 }; 6658 6659 /** 6660 * Returns a data URL for the cache, or null if this display object is not cached. 6661 * Uses cacheID to ensure a new data URL is not generated if the cache has not changed. 6662 * @method getCacheDataURL 6663 * @return {String} The image data url for the cache. 6664 **/ 6665 p.getCacheDataURL = function() { 6666 if (!this.cacheCanvas) { return null; } 6667 if (this.cacheID != this._cacheDataURLID) { this._cacheDataURL = this.cacheCanvas.toDataURL(); } 6668 return this._cacheDataURL; 6669 }; 6670 6671 /** 6672 * Transforms the specified x and y position from the coordinate space of the display object 6673 * to the global (stage) coordinate space. For example, this could be used to position an HTML label 6674 * over a specific point on a nested display object. Returns a Point instance with x and y properties 6675 * correlating to the transformed coordinates on the stage. 6676 * 6677 * <h4>Example</h4> 6678 * 6679 * displayObject.x = 300; 6680 * displayObject.y = 200; 6681 * stage.addChild(displayObject); 6682 * var point = displayObject.localToGlobal(100, 100); 6683 * // Results in x=400, y=300 6684 * 6685 * @method localToGlobal 6686 * @param {Number} x The x position in the source display object to transform. 6687 * @param {Number} y The y position in the source display object to transform. 6688 * @param {Point | Object} [pt] An object to copy the result into. If omitted a new Point object with x/y properties will be returned. 6689 * @return {Point} A Point instance with x and y properties correlating to the transformed coordinates 6690 * on the stage. 6691 **/ 6692 p.localToGlobal = function(x, y, pt) {
6693 return this.getConcatenatedMatrix(this._props.matrix).transformPoint(x,y, pt||new createjs.Point()); 6694 }; 6695 6696 /** 6697 * Transforms the specified x and y position from the global (stage) coordinate space to the 6698 * coordinate space of the display object. For example, this could be used to determine 6699 * the current mouse position within the display object. Returns a Point instance with x and y properties 6700 * correlating to the transformed position in the display object's coordinate space. 6701 * 6702 * <h4>Example</h4> 6703 * 6704 * displayObject.x = 300; 6705 * displayObject.y = 200; 6706 * stage.addChild(displayObject); 6707 * var point = displayObject.globalToLocal(100, 100); 6708 * // Results in x=-200, y=-100 6709 * 6710 * @method globalToLocal 6711 * @param {Number} x The x position on the stage to transform. 6712 * @param {Number} y The y position on the stage to transform. 6713 * @param {Point | Object} [pt] An object to copy the result into. If omitted a new Point object with x/y properties will be returned. 6714 * @return {Point} A Point instance with x and y properties correlating to the transformed position in the 6715 * display object's coordinate space. 6716 **/ 6717 p.globalToLocal = function(x, y, pt) { 6718 return this.getConcatenatedMatrix(this._props.matrix).invert().transformPoint(x,y, pt||new createjs.Point()); 6719 }; 6720 6721 /** 6722 * Transforms the specified x and y position from the coordinate space of this display object to the coordinate 6723 * space of the target display object. Returns a Point instance with x and y properties correlating to the 6724 * transformed position in the target's coordinate space. Effectively the same as using the following code with 6725 * {{#crossLink "DisplayObject/localToGlobal"}}{{/crossLink}} and {{#crossLink "DisplayObject/globalToLocal"}}{{/crossLink}}. 6726 * 6727 * var pt = this.localToGlobal(x, y); 6728 * pt = target.globalToLocal(pt.x, pt.y); 6729 * 6730 * @method localToLocal 6731 * @param {Number} x The x position in the source display object to transform. 6732 * @param {Number} y The y position on the source display object to transform. 6733 * @param {DisplayObject} target The target display object to which the coordinates will be transformed. 6734 * @param {Point | Object} [pt] An object to copy the result into. If omitted a new Point object with x/y properties will be returned. 6735 * @return {Point} Returns a Point instance with x and y properties correlating to the transformed position 6736 * in the target's coordinate space. 6737 **/ 6738 p.localToLocal = function(x, y, target, pt) { 6739 pt = this.localToGlobal(x, y, pt); 6740 return target.globalToLocal(pt.x, pt.y, pt); 6741 }; 6742 6743 /** 6744 * Shortcut method to quickly set the transform properties on the display object. All parameters are optional. 6745 * Omitted parameters will have the default value set. 6746 * 6747 * <h4>Example</h4> 6748 * 6749 * displayObject.setTransform(100, 100, 2, 2); 6750 * 6751 * @method setTransform 6752 * @param {Number} [x=0] The horizontal translation (x position) in pixels 6753 * @param {Number} [y=0] The vertical translation (y position) in pixels 6754 * @param {Number} [scaleX=1] The horizontal scale, as a percentage of 1 6755 * @param {Number} [scaleY=1] the vertical scale, as a percentage of 1 6756 * @param {Number} [rotation=0] The rotation, in degrees 6757 * @param {Number} [skewX=0] The horizontal skew factor 6758 * @param {Number} [skewY=0] The vertical skew factor 6759 * @param {Number} [regX=0] The horizontal registration point in pixels 6760 * @param {Number} [regY=0] The vertical registration point in pixels 6761 * @return {DisplayObject} Returns this instance. Useful for chaining commands. 6762 * @chainable 6763 */ 6764 p.setTransform = function(x, y, scaleX, scaleY, rotation, skewX, skewY, regX, regY) { 6765 this.x = x || 0; 6766 this.y = y || 0; 6767 this.scaleX = scaleX == null ? 1 : scaleX; 6768 this.scaleY = scaleY == null ? 1 : scaleY; 6769 this.rotation = rotation || 0; 6770 this.skewX = skewX || 0; 6771 this.skewY = skewY || 0; 6772 this.regX = regX || 0; 6773 this.regY = regY || 0; 6774 return this; 6775 }; 6776 6777 /** 6778 * Returns a matrix based on this object's current transform. 6779 * @method getMatrix 6780 * @param {Matrix2D} matrix Optional. A Matrix2D object to populate with the calculated values. If null, a new 6781 * Matrix object is returned. 6782 * @return {Matrix2D} A matrix representing this display object's transform. 6783 **/ 6784 p.getMatrix = function(matrix) { 6785 var o = this, mtx = matrix&&matrix.identity() || new createjs.Matrix2D(); 6786 return o.transformMatrix ? mtx.copy(o.transformMatrix) : mtx.appendTransform(o.x, o.y, o.scaleX, o.scaleY, o.rotation, o.skewX, o.skewY, o.regX, o.regY); 6787 }; 6788 6789 /**
6790 * Generates a Matrix2D object representing the combined transform of the display object and all of its 6791 * parent Containers up to the highest level ancestor (usually the {{#crossLink "Stage"}}{{/crossLink}}). This can 6792 * be used to transform positions between coordinate spaces, such as with {{#crossLink "DisplayObject/localToGlobal"}}{{/crossLink}} 6793 * and {{#crossLink "DisplayObject/globalToLocal"}}{{/crossLink}}. 6794 * @method getConcatenatedMatrix 6795 * @param {Matrix2D} [matrix] A {{#crossLink "Matrix2D"}}{{/crossLink}} object to populate with the calculated values. 6796 * If null, a new Matrix2D object is returned. 6797 * @return {Matrix2D} The combined matrix. 6798 **/ 6799 p.getConcatenatedMatrix = function(matrix) { 6800 var o = this, mtx = this.getMatrix(matrix); 6801 while (o = o.parent) { 6802 mtx.prependMatrix(o.getMatrix(o._props.matrix)); 6803 } 6804 return mtx; 6805 }; 6806 6807 /** 6808 * Generates a DisplayProps object representing the combined display properties of the object and all of its 6809 * parent Containers up to the highest level ancestor (usually the {{#crossLink "Stage"}}{{/crossLink}}). 6810 * @method getConcatenatedDisplayProps 6811 * @param {DisplayProps} [props] A {{#crossLink "DisplayProps"}}{{/crossLink}} object to populate with the calculated values. 6812 * If null, a new DisplayProps object is returned. 6813 * @return {DisplayProps} The combined display properties. 6814 **/ 6815 p.getConcatenatedDisplayProps = function(props) { 6816 props = props ? props.identity() : new createjs.DisplayProps(); 6817 var o = this, mtx = o.getMatrix(props.matrix); 6818 do { 6819 props.prepend(o.visible, o.alpha, o.shadow, o.compositeOperation); 6820 6821 // we do this to avoid problems with the matrix being used for both operations when o._props.matrix is passed in as the props param. 6822 // this could be simplified (ie. just done as part of the prepend above) if we switched to using a pool. 6823 if (o != this) { mtx.prependMatrix(o.getMatrix(o._props.matrix)); } 6824 } while (o = o.parent); 6825 return props; 6826 }; 6827 6828 /** 6829 * Tests whether the display object intersects the specified point in <em>local</em> coordinates (ie. draws a pixel 6830 * with alpha > 0 at the specified position). This ignores the alpha, shadow, hitArea, mask, and compositeOperation 6831 * of the display object. 6832 * 6833 * <h4>Example</h4> 6834 * 6835 * var myShape = new createjs.Shape(); 6836 * myShape.graphics.beginFill("red").drawRect(100, 100, 20, 50); 6837 * 6838 * console.log(myShape.hitTest(10,10); // false 6839 * console.log(myShape.hitTest(110, 25); // true 6840 * 6841 * Note that to use Stage coordinates (such as {{#crossLink "Stage/mouseX:property"}}{{/crossLink}}), they must 6842 * first be converted to local coordinates: 6843 * 6844 * stage.addEventListener("stagemousedown", handleMouseDown); 6845 * function handleMouseDown(event) { 6846 * var p = myShape.globalToLocal(stage.mouseX, stage.mouseY); 6847 * var hit = myShape.hitTest(p.x, p.y); 6848 * } 6849 * 6850 * Shape-to-shape collision is not currently supported by EaselJS. 6851 * 6852 * @method hitTest 6853 * @param {Number} x The x position to check in the display object's local coordinates. 6854 * @param {Number} y The y position to check in the display object's local coordinates. 6855 * @return {Boolean} A Boolean indicating whether a visible portion of the DisplayObject intersect the specified 6856 * local Point. 6857 */ 6858 p.hitTest = function(x, y) { 6859 var ctx = DisplayObject._hitTestContext; 6860 ctx.setTransform(1, 0, 0, 1, -x, -y); 6861 this.draw(ctx); 6862 6863 var hit = this._testHit(ctx); 6864 ctx.setTransform(1, 0, 0, 1, 0, 0); 6865 ctx.clearRect(0, 0, 2, 2); 6866 return hit; 6867 }; 6868 6869 /** 6870 * Provides a chainable shortcut method for setting a number of properties on the instance. 6871 * 6872 * <h4>Example</h4> 6873 * 6874 * var myGraphics = new createjs.Graphics().beginFill("#ff0000").drawCircle(0, 0, 25); 6875 * var shape = stage.addChild(new createjs.Shape()).set({graphics:myGraphics, x:100, y:100, alpha:0.5}); 6876 * 6877 * @method set 6878 * @param {Object}
6878 props A generic object containing properties to copy to the DisplayObject instance. 6879 * @return {DisplayObject} Returns the instance the method is called on (useful for chaining calls.) 6880 * @chainable 6881 */ 6882 p.set = function(props) { 6883 for (var n in props) { this[n] = props[n]; } 6884 return this; 6885 }; 6886 6887 /** 6888 * Returns a rectangle representing this object's bounds in its local coordinate system (ie. with no transformation). 6889 * Objects that have been cached will return the bounds of the cache. 6890 * 6891 * Not all display objects can calculate their own bounds (ex. Shape). For these objects, you can use 6892 * {{#crossLink "DisplayObject/setBounds"}}{{/crossLink}} so that they are included when calculating Container 6893 * bounds. 6894 * 6895 * <table> 6896 * <tr><td><b>All</b></td><td> 6897 * All display objects support setting bounds manually using setBounds(). Likewise, display objects that 6898 * have been cached using cache() will return the bounds of their cache. Manual and cache bounds will override 6899 * the automatic calculations listed below. 6900 * </td></tr> 6901 * <tr><td><b>Bitmap</b></td><td> 6902 * Returns the width and height of the sourceRect (if specified) or image, extending from (x=0,y=0). 6903 * </td></tr> 6904 * <tr><td><b>Sprite</b></td><td> 6905 * Returns the bounds of the current frame. May have non-zero x/y if a frame registration point was specified 6906 * in the spritesheet data. See also {{#crossLink "SpriteSheet/getFrameBounds"}}{{/crossLink}} 6907 * </td></tr> 6908 * <tr><td><b>Container</b></td><td> 6909 * Returns the aggregate (combined) bounds of all children that return a non-null value from getBounds(). 6910 * </td></tr> 6911 * <tr><td><b>Shape</b></td><td> 6912 * Does not currently support automatic bounds calculations. Use setBounds() to manually define bounds. 6913 * </td></tr> 6914 * <tr><td><b>Text</b></td><td> 6915 * Returns approximate bounds. Horizontal values (x/width) are quite accurate, but vertical values (y/height) are 6916 * not, especially when using textBaseline values other than "top". 6917 * </td></tr> 6918 * <tr><td><b>BitmapText</b></td><td> 6919 * Returns approximate bounds. Values will be more accurate if spritesheet frame registration points are close 6920 * to (x=0,y=0). 6921 * </td></tr> 6922 * </table> 6923 * 6924 * Bounds can be expensive to calculate for some objects (ex. text, or containers with many children), and 6925 * are recalculated each time you call getBounds(). You can prevent recalculation on static objects by setting the 6926 * bounds explicitly: 6927 * 6928 * var bounds = obj.getBounds(); 6929 * obj.setBounds(bounds.x, bounds.y, bounds.width, bounds.height); 6930 * // getBounds will now use the set values, instead of recalculating 6931 * 6932 * To reduce memory impact, the returned Rectangle instance may be reused internally; clone the instance or copy its 6933 * values if you need to retain it. 6934 * 6935 * var myBounds = obj.getBounds().clone(); 6936 * // OR: 6937 * myRect.copy(obj.getBounds()); 6938 * 6939 * @method getBounds 6940 * @return {Rectangle} A Rectangle instance representing the bounds, or null if bounds are not available for this 6941 * object. 6942 **/ 6943 p.getBounds = function() { 6944 if (this._bounds) { return this._rectangle.copy(this._bounds); } 6945 var cacheCanvas = this.cacheCanvas; 6946 if (cacheCanvas) { 6947 var scale = this._cacheScale; 6948 return this._rectangle.setValues(this._cacheOffsetX, this._cacheOffsetY, cacheCanvas.width/scale, cacheCanvas.height/scale); 6949 } 6950 return null; 6951 }; 6952 6953 /** 6954 * Returns a rectangle representing this object's bounds in its parent's coordinate system (ie. with transformations applied). 6955 * Objects that have been cached will return the transformed bounds of the cache. 6956 * 6957 * Not all display objects can calculate their own bounds (ex. Shape). For these objects, you can use 6958 * {{#crossLink "DisplayObject/setBounds"}}{{/crossLink}} so that they are included when calculating Container 6959 * bounds. 6960 * 6961 * To reduce memory impact, the returned Rectangle instance may be reused internally; clone the instance or copy its 6962 * values if you need to retain it. 6963 * 6964 * Container instances calculate aggregate bounds for all children that return bounds via getBounds. 6965 * @method getTransformedBounds 6966 * @return {Rectangle} A Rectangle instance representing the bounds, or null if bounds are not available for this object. 6967 **/ 6968 p.getTransformedBounds = function() { 6969 return this._getBounds(); 6970 }; 6971 6972 /** 6973 * Allows you to manually specify the bounds of an object that either cannot calculate their own bounds (ex. Shape & 6974 * Text) for future reference, or so the object can be included in Container bounds. Manually set bounds will always 6975 * override calculated bounds. 6976 * 6977 * The bounds should be specified in the object's local (untransformed) coordinates. For example, a Shape instance
6978 * with a 25px radius circle centered at 0,0 would have bounds of (-25, -25, 50, 50). 6979 * @method setBounds 6980 * @param {Number} x The x origin of the bounds. Pass null to remove the manual bounds. 6981 * @param {Number} y The y origin of the bounds. 6982 * @param {Number} width The width of the bounds. 6983 * @param {Number} height The height of the bounds. 6984 **/ 6985 p.setBounds = function(x, y, width, height) { 6986 if (x == null) { this._bounds = x; } 6987 this._bounds = (this._bounds || new createjs.Rectangle()).setValues(x, y, width, height); 6988 }; 6989 6990 /** 6991 * Returns a clone of this DisplayObject. Some properties that are specific to this instance's current context are 6992 * reverted to their defaults (for example .parent). Caches are not maintained across clones, and some elements 6993 * are copied by reference (masks, individual filter instances, hit area) 6994 * @method clone 6995 * @return {DisplayObject} A clone of the current DisplayObject instance. 6996 **/ 6997 p.clone = function() { 6998 return this._cloneProps(new DisplayObject()); 6999 }; 7000 7001 /** 7002 * Returns a string representation of this object. 7003 * @method toString 7004 * @return {String} a string representation of the instance. 7005 **/ 7006 p.toString = function() { 7007 return "[DisplayObject (name="+ this.name +")]"; 7008 }; 7009 7010 7011// private methods: 7012 // separated so it can be used more easily in subclasses: 7013 /** 7014 * @method _cloneProps 7015 * @param {DisplayObject} o The DisplayObject instance which will have properties from the current DisplayObject 7016 * instance copied into. 7017 * @return {DisplayObject} o 7018 * @protected 7019 **/ 7020 p._cloneProps = function(o) { 7021 o.alpha = this.alpha; 7022 o.mouseEnabled = this.mouseEnabled; 7023 o.tickEnabled = this.tickEnabled; 7024 o.name = this.name; 7025 o.regX = this.regX; 7026 o.regY = this.regY; 7027 o.rotation = this.rotation; 7028 o.scaleX = this.scaleX; 7029 o.scaleY = this.scaleY; 7030 o.shadow = this.shadow; 7031 o.skewX = this.skewX; 7032 o.skewY = this.skewY; 7033 o.visible = this.visible; 7034 o.x = this.x; 7035 o.y = this.y; 7036 o.compositeOperation = this.compositeOperation; 7037 o.snapToPixel = this.snapToPixel; 7038 o.filters = this.filters==null?null:this.filters.slice(0); 7039 o.mask = this.mask; 7040 o.hitArea = this.hitArea; 7041 o.cursor = this.cursor; 7042 o._bounds = this._bounds; 7043 return o; 7044 }; 7045 7046 /** 7047 * @method _applyShadow 7048 * @protected 7049 * @param {CanvasRenderingContext2D} ctx 7050 * @param {Shadow} shadow 7051 **/ 7052 p._applyShadow = function(ctx, shadow) { 7053 shadow = shadow || Shadow.identity; 7054 ctx.shadowColor = shadow.color; 7055 ctx.shadowOffsetX = shadow.offsetX; 7056 ctx.shadowOffsetY = shadow.offsetY; 7057 ctx.shadowBlur = shadow.blur; 7058 }; 7059 7060 7061 /** 7062 * @method _tick 7063 * @param {Object} evtObj An event object that will be dispatched to all tick listeners. This object is reused between dispatchers to reduce construction & GC costs. 7064 * @protected 7065 **/ 7066 p._tick = function(evtObj) { 7067 // because tick can be really performance sensitive, check for listeners before calling dispatchEvent. 7068 var ls = this._listeners; 7069 if (ls && ls["tick"]) { 7070 // reset & reuse the event object to avoid construction / GC costs: 7071 evtObj.target = null; 7072 evtObj.propagationStopped = evtObj.immediatePropagationStopped = false; 7073 this.dispatchEvent(evtObj); 7074 } 7075 }; 7076 7077 /** 7078 * @method _testHit 7079 * @protected 7080 * @param {CanvasRenderingContext2D} ctx 7081 * @return {Boolean} 7082 **/ 7083 p._testHit = function(ctx) { 7084 try { 7085 var hit = ctx.getImageData(0, 0, 1, 1).data[3] > 1; 7086 } catch (e) { 7087 if (!DisplayObject.suppressCrossDomainErrors) { 7088 throw "An error has occurred. This is most likely due to security restrictions on reading canvas pixel data with local or cross-domain images."; 7089 } 7090 } 7091 return hit; 7092 }; 7093 7094 /** 7095 * @method _applyFilters 7096 * @protected 7097 **/ 7098 p._applyFilters = function() { 7099 if (!this.filters || this.filters.length == 0 || !this.cacheCanvas) { return; } 7100 var l = this.filters.length; 7101 var ctx = this.cacheCanvas.getContext("2d"); 7102 var w = this.cacheCanvas.width; 7103 var h = this.cacheCanvas.height; 7104 for (var i=0; i<l; i++) { 7105 this.filters[i].applyFilter(ctx, 0, 0, w, h); 7106 } 7107 }; 7108 7109 /** 7110 * @method _getFilterBounds 7111 * @return {Rectangle} 7112 * @protected 7113 **/ 7114 p._getFilterBounds = function(rect) { 7115 var l, filters = this.filters, bounds = this._rectangle.setValues(0,0,0,0); 7116 if (!filters || !(l=filters.length)) { return bounds; } 7117 7118 for (var i=0; i<l; i++) { 7119 var f = this.filters[i]; 7120 f.getBounds&&f.getBounds(bounds); 7121 } 7122 return bounds; 7123 }; 7124 7125 /** 7126 * @method _getBounds 7127 * @param {Matrix2D} matrix 7128 * @param {Boolean} ignoreTransform If true, does not apply this object's transform. 7129 * @return {Rectangle} 7130 * @protected 7131 **/ 7132 p._getBounds = function(matrix, ignoreTransform){ 7133 return this._transformBounds(this.getBounds(), matrix, ignoreTransform); 7134 }; 7135 7136 /** 7137 * @method _transformBounds 7138 * @param {Rectangle}
7138 bounds 7139 * @param {Matrix2D} matrix 7140 * @param {Boolean} ignoreTransform 7141 * @return {Rectangle} 7142 * @protected 7143 **/ 7144 p._transformBounds = function(bounds, matrix, ignoreTransform) { 7145 if (!bounds) { return bounds; } 7146 var x = bounds.x, y = bounds.y, width = bounds.width, height = bounds.height, mtx = this._props.matrix; 7147 mtx = ignoreTransform ? mtx.identity() : this.getMatrix(mtx); 7148 7149 if (x || y) { mtx.appendTransform(0,0,1,1,0,0,0,-x,-y); } // TODO: simplify this. 7150 if (matrix) { mtx.prependMatrix(matrix); } 7151 7152 var x_a = width*mtx.a, x_b = width*mtx.b; 7153 var y_c = height*mtx.c, y_d = height*mtx.d; 7154 var tx = mtx.tx, ty = mtx.ty; 7155 7156 var minX = tx, maxX = tx, minY = ty, maxY = ty; 7157 7158 if ((x = x_a + tx) < minX) { minX = x; } else if (x > maxX) { maxX = x; } 7159 if ((x = x_a + y_c + tx) < minX) { minX = x; } else if (x > maxX) { maxX = x; } 7160 if ((x = y_c + tx) < minX) { minX = x; } else if (x > maxX) { maxX = x; } 7161 7162 if ((y = x_b + ty) < minY) { minY = y; } else if (y > maxY) { maxY = y; } 7163 if ((y = x_b + y_d + ty) < minY) { minY = y; } else if (y > maxY) { maxY = y; } 7164 if ((y = y_d + ty) < minY) { minY = y; } else if (y > maxY) { maxY = y; } 7165 7166 return bounds.setValues(minX, minY, maxX-minX, maxY-minY); 7167 }; 7168 7169 /** 7170 * Indicates whether the display object has any mouse event listeners or a cursor. 7171 * @method _isMouseOpaque 7172 * @return {Boolean} 7173 * @protected 7174 **/ 7175 p._hasMouseEventListener = function() { 7176 var evts = DisplayObject._MOUSE_EVENTS; 7177 for (var i= 0, l=evts.length; i<l; i++) { 7178 if (this.hasEventListener(evts[i])) { return true; } 7179 } 7180 return !!this.cursor; 7181 }; 7182 7183 createjs.DisplayObject = createjs.promote(DisplayObject, "EventDispatcher"); 7184}()); 7185 7186//############################################################################## 7187// Container.js 7188//############################################################################## 7189 7190this.createjs = this.createjs||{}; 7191 7192(function() { 7193 "use strict"; 7194 7195 7196// constructor: 7197/** 7198 * A Container is a nestable display list that allows you to work with compound dis
7198play elements. For example you could 7199 * group arm, leg, torso and head {{#crossLink "Bitmap"}}{{/crossLink}} instances together into a Person Container, and 7200 * transform them as a group, while still being able to move the individual parts relative to each other. Children of 7201 * containers have their <code>transform</code> and <code>alpha</code> properties concatenated with their parent 7202 * Container. 7203 * 7204 * For example, a {{#crossLink "Shape"}}{{/crossLink}} with x=100 and alpha=0.5, placed in a Container with <code>x=50</code> 7205 * and <code>alpha=0.7</code> will be rendered to the canvas at <code>x=150</code> and <code>alpha=0.35</code>. 7206 * Containers have some overhead, so you generally shouldn't create a Container to hold a single child. 7207 * 7208 * <h4>Example</h4> 7209 * 7210 * var container = new createjs.Container(); 7211 * container.addChild(bitmapInstance, shapeInstance); 7212 * container.x = 100; 7213 * 7214 * @class Container 7215 * @extends DisplayObject 7216 * @constructor 7217 **/ 7218 function Container() { 7219 this.DisplayObject_constructor(); 7220 7221 // public properties: 7222 /** 7223 * The array of children in the display list. You should usually use the child management methods such as 7224 * {{#crossLink "Container/addChild"}}{{/crossLink}}, {{#crossLink "Container/removeChild"}}{{/crossLink}}, 7225 * {{#crossLink "Container/swapChildren"}}{{/crossLink}}, etc, rather than accessing this directly, but it is 7226 * included for advanced uses. 7227 * @property children 7228 * @type Array 7229 * @default null 7230 **/ 7231 this.children = []; 7232 7233 /** 7234 * Indicates whether the children of this container are independently enabled for mouse/pointer interaction. 7235 * If false, the children will be aggregated under the container - for example, a click on a child shape would 7236 * trigger a click event on the container. 7237 * @property mouseChildren 7238 * @type Boolean 7239 * @default true 7240 **/ 7241 this.mouseChildren = true; 7242 7243 /** 7244 * If false, the tick will not be propagated to children of this Container. This can provide some performance benefits. 7245 * In addition to preventing the "tick" event from being dispatched, it will also prevent tick related updates 7246 * on some display objects (ex. Sprite & MovieClip frame advancing, DOMElement visibility handling). 7247 * @property tickChildren 7248 * @type Boolean 7249 * @default true 7250 **/ 7251 this.tickChildren = true; 7252 } 7253 var p = createjs.extend(Container, createjs.DisplayObject); 7254 7255 7256// getter / setters: 7257 /** 7258 * Use the {{#crossLink "Container/numChildren:property"}}{{/crossLink}} property instead. 7259 * @method getNumChildren 7260 * @return {Number} 7261 * @deprecated 7262 **/ 7263 p.getNumChildren = function() { 7264 return this.children.length; 7265 }; 7266 7267 /** 7268 * Returns the number of children in the container. 7269 * @property numChildren 7270 * @type {Number} 7271 * @readonly 7272 **/ 7273 try { 7274 Object.defineProperties(p, { 7275 numChildren: { get: p.getNumChildren } 7276 }); 7277 } catch (e) {} 7278 7279 7280// public methods: 7281 /** 7282 * Constructor alias for backwards compatibility. This method will be removed in future versions. 7283 * Subclasses should be updated to use {{#crossLink "Utility Methods/extends"}}{{/crossLink}}. 7284 * @method initialize 7285 * @deprecated in favour of `createjs.promote()` 7286 **/ 7287 p.initialize = Container; // TODO: deprecated. 7288 7289 /** 7290 * Returns true or false indicating whether the display object would be visible if drawn to a canvas. 7291 * This does not account for whether it would be visible within the boundaries of the stage. 7292 * 7293 * NOTE: This method is mainly for internal use, though it may be useful for advanced uses. 7294 * @method isVisible 7295 * @return {Boolean} Boolean indicating whether the display object would be visible if drawn to a canvas 7296 **/ 7297 p.isVisible = function() { 7298 var hasContent = this.cacheCanvas || this.children.length; 7299 return !!(this.visible && this.alpha > 0 && this.scaleX != 0 && this.scaleY != 0 && hasContent); 7300 }; 7301 7302 /** 7303 * Draws the display object into the specified context ignoring its visible, alpha, shadow, and transform. 7304 * Returns true if the draw was handled (useful for overriding functionality). 7305 * 7306 * NOTE: This method is mainly for internal use, though it may be useful for advanced uses. 7307 * @method draw 7308 * @param {CanvasRenderingContext2D} ctx The canvas 2D context object to draw into. 7309 * @param {Boolean} [ignoreCache=false] Indicates whether the draw operation should ignore any current cache. 7310 * For example, used for drawing the cache (to prevent it from simply drawing an existing cache back 7311 * into itself). 7312 **/ 7313 p.draw = function(ctx, ignoreCache) { 7314 if (this.DisplayObject_draw(ctx, ignoreCache)) { return true; } 7315 7316 // this ensures we don't have issues with display list changes that occur during a draw: 7317 var list = this.children.slice(); 7318 for (var i=0,l=list.length; i<l; i++) { 7319 var child = list[i]; 7320 if (!child.isVisible()) { continue; } 7321 7322 // draw the child: 7323 ctx.save(); 7324 child.updateContext(ctx); 7325 child.draw(ctx);
7326 ctx.restore(); 7327 } 7328 return true; 7329 }; 7330 7331 /** 7332 * Adds a child to the top of the display list. 7333 * 7334 * <h4>Example</h4> 7335 * 7336 * container.addChild(bitmapInstance); 7337 * 7338 * You can also add multiple children at once: 7339 * 7340 * container.addChild(bitmapInstance, shapeInstance, textInstance); 7341 * 7342 * @method addChild 7343 * @param {DisplayObject} child The display object to add. 7344 * @return {DisplayObject} The child that was added, or the last child if multiple children were added. 7345 **/ 7346 p.addChild = function(child) { 7347 if (child == null) { return child; } 7348 var l = arguments.length; 7349 if (l > 1) { 7350 for (var i=0; i<l; i++) { this.addChild(arguments[i]); } 7351 return arguments[l-1]; 7352 } 7353 if (child.parent) { child.parent.removeChild(child); } 7354 child.parent = this; 7355 this.children.push(child); 7356 child.dispatchEvent("added"); 7357 return child; 7358 }; 7359 7360 /** 7361 * Adds a child to the display list at the specified index, bumping children at equal or greater indexes up one, and 7362 * setting its parent to this Container. 7363 * 7364 * <h4>Example</h4> 7365 * 7366 * addChildAt(child1, index); 7367 * 7368 * You can also add multiple children, such as: 7369 * 7370 * addChildAt(child1, child2, ..., index); 7371 * 7372 * The index must be between 0 and numChildren. For example, to add myShape under otherShape in the display list, 7373 * you could use: 7374 * 7375 * container.addChildAt(myShape, container.getChildIndex(otherShape)); 7376 * 7377 * This would also bump otherShape's index up by one. Fails silently if the index is out of range. 7378 * 7379 * @method addChildAt 7380 * @param {DisplayObject} child The display object to add. 7381 * @param {Number} index The index to add the child at. 7382 * @return {DisplayObject} Returns the last child that was added, or the last child if multiple children were added. 7383 **/ 7384 p.addChildAt = function(child, index) { 7385 var l = arguments.length; 7386 var indx = arguments[l-1]; // can't use the same name as the index param or it replaces arguments[1] 7387 if (indx < 0 || indx > this.children.length) { return arguments[l-2]; } 7388 if (l > 2) { 7389 for (var i=0; i<l-1; i++) { this.addChildAt(arguments[i], indx+i); } 7390 return arguments[l-2]; 7391 } 7392 if (child.parent) { child.parent.removeChild(child); } 7393 child.parent = this; 7394 this.children.splice(index, 0, child); 7395 child.dispatchEvent("added"); 7396 return child; 7397 }; 7398 7399 /** 7400 * Removes the specified child from the display list. Note that it is faster to use removeChildAt() if the index is 7401 * already known. 7402 * 7403 * <h4>Example</h4> 7404 * 7405 * container.removeChild(child); 7406 * 7407 * You can also remove multiple children: 7408 * 7409 * removeChild(child1, child2, ...); 7410 * 7411 * Returns true if the child (or children) was removed, or false if it was not in the display list. 7412 * @method removeChild 7413 * @param {DisplayObject} child The child to remove. 7414 * @return {Boolean} true if the child (or children) was removed, or false if it was not in the display list. 7415 **/ 7416 p.removeChild = function(child) { 7417 var l = arguments.length; 7418 if (l > 1) { 7419 var good = true; 7420 for (var i=0; i<l; i++) { good = good && this.removeChild(arguments[i]); } 7421 return good; 7422 } 7423 return this.removeChildAt(createjs.indexOf(this.children, child)); 7424 }; 7425 7426 /** 7427 * Removes the child at the specified index from the display list, and sets its parent to null. 7428 * 7429 * <h4>Example</h4> 7430 * 7431 * container.removeChildAt(2); 7432 * 7433 * You can also remove multiple children: 7434 * 7435 * container.removeChild(2, 7, ...) 7436 * 7437 * Returns true if the child (or children) was removed, or false if any index was out of range. 7438 * @method removeChildAt 7439 * @param {Number} index The index of the child to remove. 7440 * @return {Boolean} true if the child (or children) was removed, or false if any index was out of range. 7441 **/ 7442 p.removeChildAt = function(index) { 7443 var l = arguments.length; 7444 if (l > 1) { 7445 var a = []; 7446 for (var i=0; i<l; i++) { a[i] = arguments[i]; } 7447 a.sort(function(a, b) { return b-a; }); 7448 var good = true; 7449 for (var i=0; i<l; i++) { good = good && this.removeChildAt(a[i]); } 7450 return good; 7451 } 7452 if (index < 0 || index > this.children.length-1) { return false; } 7453 var child = this.children[index]; 7454 if (child) { child.parent = null; } 7455 this.children.splice(index, 1); 7456 child.dispatchEvent("removed"); 7457 return true; 7458 }; 7459 7460 /** 7461 * Removes all children from the display list. 7462 * 7463 * <h4>Example</h4> 7464 * 7465 * container.removeAllChildren(); 7466 * 7467 * @method removeAllChildren 7468 **/ 7469 p.removeAllChildren = function() { 7470 var kids = this.children; 7471 while (kids.length) { this.removeChildAt(0); } 7472 }; 7473 7474 /** 7475 * Returns the child at the specified index. 7476 * 7477 * <h4>Example</h4> 7478 * 7479 * container.getChildAt(2); 7480 * 7481 * @method getChildAt 7482 * @param {Number} index The index of the child to return. 7483 * @return {DisplayObject} The child at the specified index. Returns null if there is no child at the index. 7484 **/ 7485 p.getChildAt = function(index) { 7486 return this.children[index]; 7487 }; 7488 7489 /** 7490 * Returns the child with the specified name. 7491 * @method getChildByName 7492 * @param {String} name The name of the child to return. 7493 * @return {DisplayObject} The child with the specified name. 7494 **/ 7495 p.getChildByName = function(name) { 7496 var kids = this.children; 7497 for (var i=0,l=kids.length;i<l;i++) { 7498 if(kids[i].name == name) { return kids[i]; } 7499 } 7500 return null; 7501 }; 7502 7503 /** 7504 * Performs an array sort operation on the child list. 7505 * 7506 * <h4>Example: Display children with a higher y in front.</h4> 7507 * 7508 * var sortFunction = function(obj1, obj2, options) { 7509 * if (obj1.y > obj2.y) { return 1; } 7510 * if (obj1.y < obj2.y) { return -1; } 7511 * return 0; 7512 * } 7513 * container.sortChildren(sortFunction); 7514 * 7515 * @method sortChildren 7516 * @param {Function} sortFunction the function to use to sort the child list. See JavaScript's <code>Array.sort</code> 7517 * documentation for details. 7518 **/ 7519 p.sortChildren = function(sortFunction) { 7520 this.children.sort(sortFunction); 7521 }; 7522 7523 /** 7524 * Returns the index of the specified child in the display list, or -1 if it is not in the display list. 7525 * 7526 * <h4>Example</h4> 7527 * 7528 * var index = container.getChildIndex(child); 7529 * 7530 * @method getChildIndex 7531 * @param {DisplayObject} child The child to return the index of. 7532 * @return {Number} The index of the specified child. -1 if the child is not found. 7533 **/ 7534 p.getChildIndex = function(child) { 7535 return createjs.indexOf(this.children, child); 7536 }; 7537 7538 /** 7539 * Swaps the children at the specified indexes. Fails silently if either index is out of range. 7540 * @method swapChildrenAt 7541 * @param {Number} index1 7542 * @param {Number} index2 7543 **/ 7544 p.swapChildrenAt = function(index1, index2) { 7545 var kids = this.children; 7546 var o1 = kids[index1]; 7547 var o2 = kids[index2]; 7548 if (!o1 || !o2) { return; } 7549 kids[index1] = o2; 7550 kids[index2] = o1; 7551 }; 7552 7553 /** 7554 * Swaps the specified children's depth in the display list. Fails silently if either child is not a child of this 7555 * Container. 7556 * @method swapChildren 7557 * @param {DisplayObject} child1 7558 * @param {DisplayObject} child2 7559 **/ 7560 p.swapChildren = function(child1, child2) { 7561 var kids = this.children; 7562 var index1,index2; 7563 for (var i=0,l=kids.length;i<l;i++) { 7564 if (kids[i] == child1) { index1 = i; } 7565 if (kids[i] == child2) { index2 = i; } 7566 if (index1 != null && index2 != null) { break; } 7567 } 7568 if (i==l) { return; } // TODO: throw error? 7569 kids[index1] = child2; 7570 kids[index2] = child1; 7571 }; 7572 7573 /** 7574 * Changes the depth of the specified child. Fails silently if the child is not a child of this container, or the index is out of range. 7575 * @param {DisplayObject} child 7576 * @param {Number} index 7577 * @method setChildIndex 7578 **/ 7579 p.setChildIndex = function(child, index) { 7580 var kids = this.children, l=kids.length; 7581 if (child.parent != this || index < 0 || index >= l) { return; } 7582 for (var i=0;i<l;i++) { 7583 if (kids[i] == child) { break; } 7584 } 7585 if (i==l || i == index) { return; } 7586 kids.splice(i,1); 7587 kids.splice(index,0,child); 7588 }; 7589 7590 /** 7591 * Returns true if the specified display object either is this container or is a descendent (child, grandchild, etc) 7592 * of this container. 7593 * @method contains 7594 * @param {DisplayObject} child The DisplayObject to be checked. 7595 * @return {Boolean} true if the specified display object either is this container or is a descendent. 7596 **/ 7597 p.contains = function(child) { 7598 while (child) { 7599 if (child == this) { return true; } 7600 child = child.parent; 7601 } 7602 return false;
7603 }; 7604 7605 /** 7606 * Tests whether the display object intersects the specified local point (ie. draws a pixel with alpha > 0 at the 7607 * specified position). This ignores the alpha, shadow and compositeOperation of the display object, and all 7608 * transform properties including regX/Y. 7609 * @method hitTest 7610 * @param {Number} x The x position to check in the display object's local coordinates. 7611 * @param {Number} y The y position to check in the display object's local coordinates. 7612 * @return {Boolean} A Boolean indicating whether there is a visible section of a DisplayObject that overlaps the specified 7613 * coordinates. 7614 **/ 7615 p.hitTest = function(x, y) { 7616 // TODO: optimize to use the fast cache check where possible. 7617 return (this.getObjectUnderPoint(x, y) != null); 7618 }; 7619 7620 /** 7621 * Returns an array of all display objects under the specified coordinates that are in this container's display 7622 * list. This routine ignores any display objects with {{#crossLink "DisplayObject/mouseEnabled:property"}}{{/crossLink}} 7623 * set to `false`. The array will be sorted in order of visual depth, with the top-most display object at index 0. 7624 * This uses shape based hit detection, and can be an expensive operation to run, so it is best to use it carefully. 7625 * For example, if testing for objects under the mouse, test on tick (instead of on {{#crossLink "DisplayObject/mousemove:event"}}{{/crossLink}}), 7626 * and only if the mouse's position has changed. 7627 * 7628 * <ul> 7629 * <li>By default (mode=0) this method evaluates all display objects.</li> 7630 * <li>By setting the `mode` parameter to `1`, the {{#crossLink "DisplayObject/mouseEnabled:property"}}{{/crossLink}} 7631 * and {{#crossLink "mouseChildren:property"}}{{/crossLink}} properties will be respected.</li> 7632 * <li>Setting the `mode` to `2` additionally excludes display objects that do not have active mouse event 7633 * listeners or a {{#crossLink "DisplayObject:cursor:property"}}{{/crossLink}} property. That is, only objects 7634 * that would normally intercept mouse interaction will be included. This can significantly improve performance 7635 * in some cases by reducing the number of display objects that need to be tested.</li> 7636 * </li> 7637 * 7638 * This method accounts for both {{#crossLink "DisplayObject/hitArea:property"}}{{/crossLink}} and {{#crossLink "DisplayObject/mask:property"}}{{/crossLink}}. 7639 * @method getObjectsUnderPoint 7640 * @param {Number} x The x position in the container to test. 7641 * @param {Number} y The y position in the container to test. 7642 * @param {Number} [mode=0] The mode to use to determine which display objects to include. 0-all, 1-respect mouseEnabled/mouseChildren, 2-only mouse opaque objects. 7643 * @return {Array} An Array of DisplayObjects under the specified coordinates. 7644 **/ 7645 p.getObjectsUnderPoint = function(x, y, mode) { 7646 var arr = []; 7647 var pt = this.localToGlobal(x, y); 7648 this._getObjectsUnderPoint(pt.x, pt.y, arr, mode>0, mode==1); 7649 return arr; 7650 }; 7651 7652 /** 7653 * Similar to {{#crossLink "Container/getObjectsUnderPoint"}}{{/crossLink}}, but returns only the top-most display 7654 * object. This runs significantly faster than <code>getObjectsUnderPoint()</code>, but is still potentially an expensive 7655 * operation. See {{#crossLink "Container/getObjectsUnderPoint"}}{{/crossLink}} for more information. 7656 * @method getObjectUnderPoint 7657 * @param {Number} x The x position in the container to test. 7658 * @param {Number} y The y position in the container to test. 7659 * @param {Number} mode The mode to use to determine which display objects to include. 0-all, 1-respect mouseEnabled/mouseChildren, 2-only mouse opaque objects. 7660 * @return {DisplayObject} The top-most display object under the specified coordinates. 7661 **/ 7662 p.getObjectUnderPoint = function(x, y, mode) { 7663 var pt = this.localToGlobal(x, y); 7664 return this._getObjectsUnderPoint(pt.x, pt.y, null, mode>0, mode==1); 7665 }; 7666 7667 /** 7668 * Docced in superclass. 7669 */ 7670 p.getBounds = function() { 7671 return this._getBounds(null, true); 7672 }; 7673 7674 7675 /** 7676 * Docced in superclass. 7677 */ 7678 p.getTransformedBounds = function() { 7679 return this._getBounds(); 7680 }; 7681 7682 /** 7683 * Returns a clone of this Container. Some properties that are specific to this instance's current context are 7684 * reverted to their defaults (for example .parent). 7685 * @method clone 7686 * @param {Boolean} [recursive=false] If true, all of the descendants of this container will be cloned recursively. If false, the 7687 * properties of the container will be cloned, but the new instance will not have any children. 7688 * @return {Container} A clone of the current Container instance. 7689 **/ 7690 p.clone = function(recursive) { 7691 var o = this._cloneProps(new Container()); 7692 if (recursive) { this._cloneChildren(o); } 7693 return o; 7694 }; 7695 7696 /** 7697 * Returns a string representation of this object. 7698 * @method toString 7699 * @return {String} a string representation of the instance. 7700 **/ 7701 p.toString = function() { 7702 return "[Container (name="+ this.name +")]"; 7703 }; 7704 7705 7706// private methods: 7707 /** 7708 * @method _tick 7709 * @param {Object} evtObj An event object that will be dispatched to all tick listeners. This object is reused between dispatchers to reduce construction & GC costs. 7710 * @protected 7711 **/ 7712 p._tick = function(evtObj) { 7713 if (this.tickChildren) { 7714 for (var i=this.children.length-1; i>=0; i--) { 7715 var child = this.children[i]; 7716 if (child.tickEnabled && child._tick) { child._tick(evtObj); } 7717 } 7718 } 7719 this.DisplayObject__tick(evtObj); 7720 }; 7721 7722 /** 7723 * Recursively clones all children of this container, and adds them to the target container. 7724 * @method cloneChildren 7725 * @protected 7726 * @param {Container} o The target container. 7727 **/ 7728 p._cloneChildren = function(o) { 7729 if (o.children.length) { o.removeAllChildren(); } 7730 var arr = o.children; 7731 for (var i=0, l=this.children.length; i<l; i++) { 7732 var clone = this.children[i].clone(true); 7733 clone.parent = o; 7734 arr.push(clone); 7735 } 7736 }; 7737 7738 /** 7739 * @method _getObjectsUnderPoint 7740 * @param {Number} x 7741 * @param {Number} y 7742 * @param {Array} arr 7743 * @param {Boolean} mouse If true, it will respect mouse interaction properties like mouseEnabled, mouseChildren, and active listeners. 7744 * @param {Boolean} activeListener If true, there is an active mouse event listener on a parent object. 7745 * @param {Number} currentDepth Indicates the current depth of the search. 7746 * @return {DisplayObject} 7747 * @protected 7748 **/ 7749 p._getObjectsUnderPoint = function(x, y, arr, mouse, activeListener, currentDepth) { 7750 currentDepth = currentDepth || 0; 7751 if (!currentDepth && !this._testMask(this, x, y)) { return null; } 7752 var mtx, ctx = createjs.DisplayObject._hitTestContext; 7753 activeListener = activeListener || (mouse&&this._hasMouseEventListener()); 7754 7755 // draw children one at a time, and check if we get a hit: 7756 var children = this.children, l = children.length; 7757 for (var i=l-1; i>=0; i--) { 7758 var child = children[i]; 7759 var hitArea = child.hitArea; 7760 if (!child.visible || (!hitArea && !child.isVisible()) || (mouse && !child.mouseEnabled)) { continue; } 7761 if (!hitArea && !this._testMask(child, x, y)) { continue; } 7762 7763 // if a child container has a hitArea then we only need to check its hitArea, so we can treat it as a normal DO: 7764 if (!hitArea && child instanceof Container) { 7765 var result = child._getObjectsUnderPoint(x, y, arr, mouse, activeListener, currentDepth+1); 7766 if (!arr && result) { return (mouse && !this.mouseChildren) ? this
7766: result; } 7767 } else { 7768 if (mouse && !activeListener && !child._hasMouseEventListener()) { continue; } 7769 7770 // TODO: can we pass displayProps forward, to avoid having to calculate this backwards every time? It's kind of a mixed bag. When we're only hunting for DOs with event listeners, it may not make sense. 7771 var props = child.getConcatenatedDisplayProps(child._props); 7772 mtx = props.matrix; 7773 7774 if (hitArea) { 7775 mtx.appendMatrix(hitArea.getMatrix(hitArea._props.matrix)); 7776 props.alpha = hitArea.alpha; 7777 } 7778 7779 ctx.globalAlpha = props.alpha; 7780 ctx.setTransform(mtx.a, mtx.b, mtx.c, mtx.d, mtx.tx-x, mtx.ty-y); 7781 (hitArea||child).draw(ctx); 7782 if (!this._testHit(ctx)) { continue; } 7783 ctx.setTransform(1, 0, 0, 1, 0, 0); 7784 ctx.clearRect(0, 0, 2, 2); 7785 if (arr) { arr.push(child); } 7786 else { return (mouse && !this.mouseChildren) ? this : child; } 7787 } 7788 } 7789 return null; 7790 }; 7791 7792 /** 7793 * @method _testMask 7794 * @param {DisplayObject} target 7795 * @param {Number} x 7796 * @param {Number} y 7797 * @return {Boolean} Indicates whether the x/y is within the masked region. 7798 * @protected 7799 **/ 7800 p._testMask = function(target, x, y) { 7801 var mask = target.mask; 7802 if (!mask || !mask.graphics || mask.graphics.isEmpty()) { return true; } 7803 7804 var mtx = this._props.matrix, parent = target.parent; 7805 mtx = parent ? parent.getConcatenatedMatrix(mtx) : mtx.identity();
7806 mtx = mask.getMatrix(mask._props.matrix).prependMatrix(mtx); 7807 7808 var ctx = createjs.DisplayObject._hitTestContext; 7809 ctx.setTransform(mtx.a, mtx.b, mtx.c, mtx.d, mtx.tx-x, mtx.ty-y); 7810 7811 // draw the mask as a solid fill: 7812 mask.graphics.drawAsPath(ctx); 7813 ctx.fillStyle = "#000"; 7814 ctx.fill(); 7815 7816 if (!this._testHit(ctx)) { return false; } 7817 ctx.setTransform(1, 0, 0, 1, 0, 0); 7818 ctx.clearRect(0, 0, 2, 2); 7819 7820 return true; 7821 }; 7822 7823 /** 7824 * @method _getBounds 7825 * @param {Matrix2D} matrix 7826 * @param {Boolean} ignoreTransform If true, does not apply this object's transform. 7827 * @return {Rectangle} 7828 * @protected 7829 **/ 7830 p._getBounds = function(matrix, ignoreTransform) { 7831 var bounds = this.DisplayObject_getBounds(); 7832 if (bounds) { return this._transformBounds(bounds, matrix, ignoreTransform); } 7833 7834 var mtx = this._props.matrix; 7835 mtx = ignoreTransform ? mtx.identity() : this.getMatrix(mtx); 7836 if (matrix) { mtx.prependMatrix(matrix); } 7837 7838 var l = this.children.length, rect=null; 7839 for (var i=0; i<l; i++) { 7840 var child = this.children[i]; 7841 if (!child.visible || !(bounds = child._getBounds(mtx))) { continue; } 7842 if (rect) { rect.extend(bounds.x, bounds.y, bounds.width, bounds.height); } 7843 else { rect = bounds.clone(); } 7844 } 7845 return rect; 7846 }; 7847 7848 7849 createjs.Container = createjs.promote(Container, "DisplayObject"); 7850}()); 7851 7852//############################################################################## 7853// Stage.js 7854//############################################################################## 7855 7856this.createjs = this.createjs||{}; 7857 7858(function() { 7859 "use strict"; 7860 7861 7862// constructor: 7863 /** 7864 * A stage is the root level {{#crossLink "Container"}}{{/crossLink}} for a display list. Each time its {{#crossLink "Stage/tick"}}{{/crossLink}} 7865 * method is called, it will render its display list to its target canvas. 7866 * 7867 * <h4>Example</h4> 7868 * This example creates a stage, adds a child to it, then uses {{#crossLink "Ticker"}}{{/crossLink}} to update the child 7869 * and redraw the stage using {{#crossLink "Stage/update"}}{{/crossLink}}. 7870 * 7871 * var stage = new createjs.Stage("canvasElementId"); 7872 * var image = new createjs.Bitmap("imagePath.png"); 7873 * stage.addChild(image); 7874 * createjs.Ticker.addEventListener("tick", handleTick); 7875 * function handleTick(event) { 7876 * image.x += 10; 7877 * stage.update(); 7878 * } 7879 * 7880 * @class Stage 7881 * @extends Container 7882 * @constructor 7883 * @param {HTMLCanvasElement | String | Object} canvas A canvas object that the Stage will render to, or the string id 7884 * of a canvas object in the current document. 7885 **/ 7886 function Stage(canvas) {
7887 this.Container_constructor(); 7888 7889 7890 // public properties: 7891 /** 7892 * Indicates whether the stage should automatically clear the canvas before each render. You can set this to <code>false</code> 7893 * to manually control clearing (for generative art, or when pointing multiple stages at the same canvas for 7894 * example). 7895 * 7896 * <h4>Example</h4> 7897 * 7898 * var stage = new createjs.Stage("canvasId"); 7899 * stage.autoClear = false; 7900 * 7901 * @property autoClear 7902 * @type Boolean 7903 * @default true 7904 **/ 7905 this.autoClear = true; 7906 7907 /** 7908 * The canvas the stage will render to. Multiple stages can share a single canvas, but you must disable autoClear for all but the 7909 * first stage that will be ticked (or they will clear each other's render). 7910 * 7911 * When changing the canvas property you must disable the events on the old canvas, and enable events on the 7912 * new canvas or mouse events will not work as expected. For example: 7913 * 7914 * myStage.enableDOMEvents(false); 7915 * myStage.canvas = anotherCanvas; 7916 * myStage.enableDOMEvents(true); 7917 * 7918 * @property canvas 7919 * @type HTMLCanvasElement | Object 7920 **/ 7921 this.canvas = (typeof canvas == "string") ? document.getElementById(canvas) : canvas; 7922 7923 /** 7924 * The current mouse X position on the canvas. If the mouse leaves the canvas, this will indicate the most recent 7925 * position over the canvas, and mouseInBounds will be set to false. 7926 * @property mouseX 7927 * @type Number 7928 * @readonly 7929 **/ 7930 this.mouseX = 0; 7931 7932 /** 7933 * The current mouse Y position on the canvas. If the mouse leaves the canvas, this will indicate the most recent 7934 * position over the canvas, and mouseInBounds will be set to false. 7935 * @property mouseY 7936 * @type Number 7937 * @readonly 7938 **/ 7939 this.mouseY = 0; 7940 7941 /** 7942 * Specifies the area of the stage to affect when calling update. This can be use to selectively 7943 * re-draw specific regions of the canvas. If null, the whole canvas area is drawn. 7944 * @property drawRect 7945 * @type {Rectangle} 7946 */ 7947 this.drawRect = null; 7948 7949 /** 7950 * Indicates whether display objects should be rendered on whole pixels. You can set the 7951 * {{#crossLink "DisplayObject/snapToPixel"}}{{/crossLink}} property of 7952 * display objects to false to enable/disable this behaviour on a per instance basis. 7953 * @property snapToPixelEnabled 7954 * @type Boolean 7955 * @default false 7956 **/ 7957 this.snapToPixelEnabled = false; 7958 7959 /** 7960 * Indicates whether the mouse is currently within the bounds of the canvas. 7961 * @property mouseInBounds 7962 * @type Boolean 7963 * @default false 7964 **/ 7965 this.mouseInBounds = false; 7966 7967 /** 7968 * If true, tick callbacks will be called on all display objects on the stage prior to rendering to the canvas. 7969 * @property tickOnUpdate 7970 * @type Boolean 7971 * @default true 7972 **/ 7973 this.tickOnUpdate = true; 7974 7975 /** 7976 * If true, mouse move events will continue to be called when the mouse leaves the target canvas. See 7977 * {{#crossLink "Stage/mouseInBounds:property"}}{{/crossLink}}, and {{#crossLink "MouseEvent"}}{{/crossLink}} 7978 * x/y/rawX/rawY. 7979 * @property mouseMoveOutside 7980 * @type Boolean 7981 * @default false 7982 **/ 7983 this.mouseMoveOutside = false;
7984 7985 7986 /** 7987 * Prevents selection of other elements in the html page if the user clicks and drags, or double clicks on the canvas. 7988 * This works by calling `preventDefault()` on any mousedown events (or touch equivalent) originating on the canvas. 7989 * @property preventSelection 7990 * @type Boolean 7991 * @default true 7992 **/ 7993 this.preventSelection = true; 7994 7995 /** 7996 * The hitArea property is not supported for Stage. 7997 * @property hitArea 7998 * @type {DisplayObject} 7999 * @default null 8000 */ 8001 8002 8003 // private properties: 8004 /** 8005 * Holds objects with data for each active pointer id. Each object has the following properties: 8006 * x, y, event, target, overTarget, overX, overY, inBounds, posEvtObj (native event that last updated position) 8007 * @property _pointerData 8008 * @type {Object} 8009 * @private 8010 */ 8011 this._pointerData = {}; 8012 8013 /** 8014 * Number of active pointers. 8015 * @property _pointerCount 8016 * @type {Object} 8017 * @private 8018 */ 8019 this._pointerCount = 0; 8020 8021 /** 8022 * The ID of the primary pointer. 8023 * @property _primaryPointerID 8024 * @type {Object} 8025 * @private 8026 */ 8027 this._primaryPointerID = null; 8028 8029 /** 8030 * @property _mouseOverIntervalID 8031 * @protected 8032 * @type Number 8033 **/ 8034 this._mouseOverIntervalID = null; 8035 8036 /** 8037 * @property _nextStage 8038 * @protected 8039 * @type Stage 8040 **/ 8041 this._nextStage = null; 8042 8043 /** 8044 * @property _prevStage 8045 * @protected 8046 * @type Stage 8047 **/ 8048 this._prevStage = null; 8049 8050 8051 // initialize: 8052 this.enableDOMEvents(true); 8053 } 8054 var p = createjs.extend(Stage, createjs.Container); 8055 8056 /** 8057 * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`. 8058 * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}} 8059 * for details. 8060 * 8061 * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance. 8062 * 8063 * @method initialize 8064 * @protected 8065 * @deprecated 8066 */ 8067 // p.initialize = function() {}; // searchable for devs wondering where it is. 8068 8069 8070// events: 8071 /** 8072 * Dispatched when the user moves the mouse over the canvas. 8073 * See the {{#crossLink "MouseEvent"}}{{/crossLink}} class for a listing of event properties. 8074 * @event stagemousemove 8075 * @since 0.6.0 8076 */ 8077 8078 /** 8079 * Dispatched when the user presses their left mouse button on the canvas. See the {{#crossLink "MouseEvent"}}{{/crossLink}} 8080 * class for a listing of event properties. 8081 * @event stagemousedown 8082 * @since 0.6.0 8083 */ 8084 8085 /** 8086 * Dispatched when the user the user presses somewhere on the stage, then releases the mouse button anywhere that the page can detect it (this varies slightly between browsers). 8087 * You can use {{#crossLink "Stage/mouseInBounds:property"}}{{/crossLink}} to check whether the mouse is currently within the stage bounds. 8088 * See the {{#crossLink "MouseEvent"}}{{/crossLink}} class for a listing of event properties. 8089 * @event stagemouseup 8090 * @since 0.6.0 8091 */ 8092 8093 /** 8094 * Dispatched when the mouse moves from within the canvas area (mouseInBounds == true) to outside it (mouseInBounds == false). 8095 * This is currently only dispatched for mouse input (not touch). See the {{#crossLink "MouseEvent"}}{{/crossLink}} 8096 * class for a listing of event properties. 8097 * @event mouseleave 8098 * @since 0.7.0 8099 */ 8100 8101 /** 8102 * Dispatched when the mouse moves into the canvas area (mouseInBounds == false) from outside it (mouseInBounds == true). 8103 * This is currently only dispatched for mouse input (not touch). See the {{#crossLink "MouseEvent"}}{{/crossLink}} 8104 * class for a listing of event properties. 8105 * @event mouseenter 8106 * @since 0.7.0 8107 */ 8108 8109 /** 8110 * Dispatched each update immediately before the tick event is propagated through the display list. 8111 * You can call preventDefault on the event object to cancel propagating the tick event. 8112 * @event tickstart 8113 * @since 0.7.0 8114 */ 8115 8116 /** 8117 * Dispatched each update immediately after the tick event is propagated through the display list. Does not fire if 8118 * tickOnUpdate is false. Precedes the "drawstart" event. 8119 * @event tickend 8120 * @since 0.7.0 8121 */ 8122 8123 /** 8124 * Dispatched each update immediately before the canvas is cleared and the display list is drawn to it. 8125 * You can call preventDefault on the event object to cancel the draw. 8126 * @event drawstart 8127 * @since 0.7.0 8128 */ 8129 8130 /** 8131 * Dispatched each update immediately after the display list is drawn to the canvas and the canvas context is restored. 8132 * @event drawend 8133 * @since 0.7.0 8134 */ 8135 8136 8137// getter / setters:
8138 /** 8139 * Specifies a target stage that will have mouse / touch interactions relayed to it after this stage handles them. 8140 * This can be useful in cases where you have multiple layered canvases and want user interactions 8141 * events to pass through. For example, this would relay mouse events from topStage to bottomStage: 8142 * 8143 * topStage.nextStage = bottomStage; 8144 * 8145 * To disable relaying, set nextStage to null. 8146 * 8147 * MouseOver, MouseOut, RollOver, and RollOut interactions are also passed through using the mouse over settings 8148 * of the top-most stage, but are only processed if the target stage has mouse over interactions enabled. 8149 * Considerations when using roll over in relay targets:<OL> 8150 * <LI> The top-most (first) stage must have mouse over interactions enabled (via enableMouseOver)</LI> 8151 * <LI> All stages that wish to participate in mouse over interaction must enable them via enableMouseOver</LI> 8152 * <LI> All relay targets will share the frequency value of the top-most stage</LI> 8153 * </OL> 8154 * To illustrate, in this example the targetStage would process mouse over interactions at 10hz (despite passing 8155 * 30 as it's desired frequency): 8156 * topStage.nextStage = targetStage; 8157 * topStage.enableMouseOver(10); 8158 * targetStage.enableMouseOver(30); 8159 * 8160 * If the target stage's canvas is completely covered by this stage's canvas, you may also want to disable its 8161 * DOM events using: 8162 * 8163 * targetStage.enableDOMEvents(false); 8164 * 8165 * @property nextStage 8166 * @type {Stage} 8167 **/ 8168 p._get_nextStage = function() { 8169 return this._nextStage; 8170 }; 8171 p._set_nextStage = function(value) { 8172 if (this._nextStage) { this._nextStage._prevStage = null; } 8173 if (value) { value._prevStage = this; } 8174 this._nextStage = value; 8175 }; 8176 8177 try { 8178 Object.defineProperties(p, { 8179 nextStage: { get: p._get_nextStage, set: p._set_nextStage } 8180 }); 8181 } catch (e) {} // TODO: use Log 8182 8183 8184// public methods: 8185 /** 8186 * Each time the update method is called, the stage will call {{#crossLink "Stage/tick"}}{{/crossLink}} 8187 * unless {{#crossLink "Stage/tickOnUpdate:property"}}{{/crossLink}} is set to false, 8188 * and then render the display list to the canvas. 8189 * 8190 * @method update 8191 * @param {Object} [props] Props object to pass to `tick()`. Should usually be a {{#crossLink "Ticker"}}{{/crossLink}} event object, or similar object with a delta property. 8192 **/ 8193 p.update = function(props) { 8194 if (!this.canvas) { return; } 8195 if (this.tickOnUpdate) { this.tick(props); } 8196 if (this.dispatchEvent("drawstart", false, true) === false) { return; } 8197 createjs.DisplayObject._snapToPixelEnabled = this.snapToPixelEnabled; 8198 var r = this.drawRect, ctx = this.canvas.getContext("2d"); 8199 ctx.setTransform(1, 0, 0, 1, 0, 0); 8200 if (this.autoClear) { 8201 if (r) { ctx.clearRect(r.x, r.y, r.width, r.height); } 8202 else { ctx.clearRect(0, 0, this.canvas.width+1, this.canvas.height+1); } 8203 } 8204 ctx.save(); 8205 if (this.drawRect) { 8206 ctx.beginPath(); 8207 ctx.rect(r.x, r.y, r.width, r.height); 8208 ctx.clip(); 8209 } 8210 this.updateContext(ctx); 8211 this.draw(ctx, false); 8212 ctx.restore(); 8213 this.dispatchEvent("drawend"); 8214 }; 8215 8216 /** 8217 * Propagates a tick event through the display list. This is automatically called by {{#crossLink "Stage/update"}}{{/crossLink}} 8218 * unless {{#crossLink "Stage/tickOnUpdate:property"}}{{/crossLink}} is set to false. 8219 * 8220 * If a props object is passed to `tick()`, then all of its properties will be copied to the event object that is 8221 * propagated to listeners. 8222 * 8223 * Some time-based features in EaselJS (for example {{#crossLink "Sprite/framerate"}}{{/crossLink}} require that 8224 * a {{#crossLink "Ticker/tick:event"}}{{/crossLink}} event object (or equivalent object with a delta property) be 8225 * passed as the `props` parameter to `tick()`. For example: 8226 * 8227 * Ticker.on("tick", handleTick); 8228 * function handleTick(evtObj) { 8229 * // clone the event object from Ticker, and add some custom data to it: 8230 * var evt = evtObj.clone().set({greeting:"hello", name:"world"}); 8231 * 8232 * // pass it to stage.update(): 8233 * myStage.update(evt); // subsequently calls tick() with the same param 8234 * } 8235 * 8236 * // ... 8237 * myDisplayObject.on("tick", handleDisplayObjectTick); 8238 * function handleDisplayObjectTick(evt) { 8239 * console.log(evt.delta); // the delta property from the Ticker tick event object 8240 * console.log(evt.greeting, evt.name); // custom data: "hello world" 8241 * } 8242 * 8243 * @method tick 8244 * @param {Object} [props] An object with properties that should be copied to the event object. Should usually be a Ticker event object, or similar object with a delta property. 8245 **/ 8246 p.tick = function(props) { 8247 if (!this.tickEnabled || this.dispatchEvent("tickstart", false, true) === false) { return; } 8248 var evtObj = new createjs.Event("tick"); 8249 if (props) { 8250 for (var n in props) { 8251 if (props.hasOwnProperty(n)) { evtObj[n] = props[n]; } 8252 } 8253 } 8254 this._tick(evtObj); 8255 this.dispatchEvent("tickend"); 8256 }; 8257 8258 /** 8259 * Default event handler that calls the Stage {{#crossLink "Stage/update"}}{{/crossLink}} method when a {{#crossLink "DisplayObject/tick:event"}}{{/crossLink}} 8260 * event is received. This allows you to register a Stage instance as a event listener on {{#crossLink "Ticker"}}{{/crossLink}} 8261 * directly, using: 8262 * 8263 * Ticker.addEventListener("tick", myStage"); 8264 * 8265 * Note that if you subscribe to ticks using this pattern, then the tick event object will be passed through to 8266 * display object tick handlers, instead of <code>delta</code> and <code>paused</code> parameters. 8267 * @property handleEvent 8268 * @type Function 8269 **/ 8270 p.handleEvent = function(evt) { 8271 if (evt.type == "tick") { this.update(evt); } 8272 }; 8273 8274 /** 8275 * Clears the target canvas. Useful if {{#crossLink "Stage/autoClear:property"}}{{/crossLink}} is set to `false`. 8276 * @method clear 8277 **/ 8278 p.clear = function() { 8279 if (!this.canvas) { return; } 8280 var ctx = this.canvas.getContext("2d"); 8281 ctx.setTransform(1, 0, 0, 1, 0, 0); 8282 ctx.clearRect(0, 0, this.canvas.width+1, this.canvas.height+1); 8283 }; 8284 8285 /** 8286 * Returns a data url that contains a Base64-encoded image of the contents of the stage. The returned data url can 8287 * be specified as the src value of an image element. 8288 * @method toDataURL 8289 * @param {String} [backgroundColor] The background color to be used for the generated image. Any valid CSS color 8290 * value is allowed. The default value is a transparent background. 8291 * @param {String} [mimeType="image/png"] The MIME type of the image format to be create. The default is "image/png". If an unknown MIME type 8292 * is passed in, or if the browser does not support the specified MIME type, the default value will be used. 8293 * @return {String} a Base64 encoded image. 8294 **/ 8295 p.toDataURL = function(backgroundColor, mimeType) { 8296 var data, ctx = this.canvas.getContext('2d'), w = this.canvas.width, h = this.canvas.height; 8297 8298 if (backgroundColor) { 8299 data = ctx.getImageData(0, 0, w, h); 8300 var compositeOperation = ctx.globalCompositeOperation; 8301 ctx.globalCompositeOperation = "destination-over"; 8302 8303 ctx.fillStyle = backgroundColor; 8304 ctx.fillRect(0, 0, w, h); 8305 } 8306 8307 var dataURL = this.canvas.toDataURL(mimeType||"image/png"); 8308 8309 if(backgroundColor) { 8310 ctx.putImageData(data, 0, 0); 8311 ctx.globalCompositeOperation = compositeOperation; 8312 } 8313 8314 return dataURL; 8315 }; 8316 8317 /** 8318 * Enables or disables (by passing a frequency of 0) mouse over ({{#crossLink "DisplayObject/mouseover:event"}}{{/crossLink}} 8319 * and {{#crossLink "DisplayObject/mouseout:event"}}{{/crossLink}}) and roll over events ({{#crossLink "DisplayObject/rollover:event"}}{{/crossLink}} 8320 * and {{#crossLink "DisplayObject/rollout:event"}}{{/crossLink}}) for this stage's display list. These events can 8321 * be expensive to generate, so they are disabled by default. The frequency of the events can be controlled 8322 * independently of mouse move events via the optional `frequency` parameter. 8323 * 8324 * <h4>Example</h4> 8325 * 8326 * var stage = new createjs.Stage("canvasId"); 8327 * stage.enableMouseOver(10); // 10 updates per second 8328 * 8329 * @method enableMouseOver 8330 * @param {Number} [frequency=20] Optional param specifying the maximum number of times per second to broadcast 8331 * mouse over/out events. Set to 0 to disable mouse over events completely. Maximum is 50. A lower frequency is less 8332 * responsive, but uses less CPU. 8333 **/ 8334 p.enableMouseOver = function(frequency) { 8335 if (this._mouseOverIntervalID) { 8336 clearInterval(this._mouseOverIntervalID); 8337 this._mouseOverIntervalID = null; 8338 if (frequency == 0) { 8339 this._testMouseOver(true); 8340 } 8341 } 8342 if (frequency == null) { frequency = 20; } 8343 else if (frequency <= 0) { return; } 8344 var o = this; 8345 this._mouseOverIntervalID = setInterval(function(){ o._testMouseOver(); }, 1000/Math.min(50,frequency)); 8346 }; 8347 8348 /** 8349 * Enables or disables the event listeners that stage adds to DOM elements (window, document and canvas). It is good 8350 * practice to disable events when disposing of a Stage instance, otherwise the stage will continue to receive 8351 * events from the page. 8352 * 8353 * When changing the canvas property you must disable the events on the old canvas, and enable events on the 8354 * new canvas or mouse events will not work as expected. For example: 8355 * 8356 * myStage.enableDOMEvents(false); 8357 * myStage.canvas = anotherCanvas; 8358 * myStage.enableDOMEvents(true); 8359 * 8360 * @method enableDOMEvents 8361 * @param {Boolean} [enable=true] Indicates whether to enable or disable the events. Default is true. 8362 **/ 8363 p.enableDOMEvents = function(enable) { 8364 if (enable == null) { enable = true; } 8365 var n, o, ls = this._eventListeners; 8366 if (!enable && ls) { 8367 for (n in ls) { 8368 o = ls[n]; 8369 o.t.removeEventListener(n, o.f, false); 8370 } 8371 this._eventListeners = null; 8372 } else if (enable && !ls && this.canvas) { 8373 var t = window.addEventListener ? window : document; 8374 var _this = this; 8375 ls = this._eventListeners = {};
8376 ls["mouseup"] = {t:t, f:function(e) { _this._handleMouseUp(e)} }; 8377 ls["mousemove"] = {t:t, f:function(e) { _this._handleMouseMove(e)} }; 8378 ls["dblclick"] = {t:this.canvas, f:function(e) { _this._handleDoubleClick(e)} }; 8379 ls["mousedown"] = {t:this.canvas, f:function(e) { _this._handleMouseDown(e)} }; 8380 8381 for (n in ls) { 8382 o = ls[n]; 8383 o.t.addEventListener(n, o.f, false); 8384 } 8385 } 8386 }; 8387 8388 /** 8389 * Stage instances cannot be cloned. 8390 * @method clone 8391 **/ 8392 p.clone = function() { 8393 throw("Stage cannot be cloned."); 8394 }; 8395 8396 /** 8397 * Returns a string representation of this object. 8398 * @method toString 8399 * @return {String} a string representation of the instance. 8400 **/ 8401 p.toString = function() { 8402 return "[Stage (name="+ this.name +")]"; 8403 }; 8404 8405 8406// private methods: 8407 /** 8408 * @method _getElementRect 8409 * @protected 8410 * @param {HTMLElement} e 8411 **/ 8412 p._getElementRect = function(e) { 8413 var bounds; 8414 try { bounds = e.getBoundingClientRect(); } // this can fail on disconnected DOM elements in IE9 8415 catch (err) { bounds = {top: e.offsetTop, left: e.offsetLeft, width:e.offsetWidth, height:e.offsetHeight}; } 8416 8417 var offX = (window.pageXOffset || document.scrollLeft || 0) - (document.clientLeft || document.body.clientLeft || 0); 8418 var offY = (window.pageYOffset || document.scrollTop || 0) - (document.clientTop || document.body.clientTop || 0); 8419 8420 var styles = window.getComputedStyle ? getComputedStyle(e,null) : e.currentStyle; // IE <9 compatibility. 8421 var padL = parseInt(styles.paddingLeft)+parseInt(styles.borderLeftWidth); 8422 var padT = parseInt(styles.paddingTop)+parseInt(styles.borderTopWidth); 8423 var padR = parseInt(styles.paddingRight)+parseInt(styles.borderRightWidth); 8424 var padB = parseInt(styles.paddingBottom)+parseInt(styles.borderBottomWidth); 8425 8426 // note: in some browsers bounds properties are read only. 8427 return { 8428 left: bounds.left+offX+padL, 8429 right: bounds.right+offX-padR, 8430 top: bounds.top+offY+padT, 8431 bottom: bounds.bottom+offY-padB 8432 } 8433 }; 8434 8435 /** 8436 * @method _getPointerData 8437 * @protected 8438 * @param {Number} id 8439 **/ 8440 p._getPointerData = function(id) { 8441 var data = this._pointerData[id]; 8442 if (!data) { data = this._pointerData[id] = {x:0,y:0}; } 8443 return data; 8444 }; 8445 8446 /** 8447 * @method _handleMouseMove 8448 * @protected 8449 * @param {MouseEvent} e 8450 **/ 8451 p._handleMouseMove = function(e) { 8452 if(!e){ e = window.event; } 8453 this._handlePointerMove(-1, e, e.pageX, e.pageY); 8454 }; 8455 8456 /** 8457 * @method _handlePointerMove 8458 * @protected 8459 * @param {Number} id 8460 * @param {Event} e 8461 * @param {Number} pageX 8462 * @param {Number} pageY 8463 * @param {Stage} owner Indicates that the event has already been captured & handled by the indicated stage. 8464 **/ 8465 p._handlePointerMove = function(id, e, pageX, pageY, owner) { 8466 if (this._prevStage && owner === undefined) { return; } // redundant listener. 8467 if (!this.canvas) { return; } 8468 var nextStage=this._nextStage, o=this._getPointerData(id); 8469 8470 var inBounds = o.inBounds; 8471 this._updatePointerPosition(id, e, pageX, pageY); 8472 if (inBounds || o.inBounds || this.mouseMoveOutside) { 8473 if (id === -1 && o.inBounds == !inBounds) { 8474 this._dispatchMouseEvent(this, (inBounds ? "mouseleave" : "mouseenter"), false, id, o, e); 8475 } 8476 8477 this._dispatchMouseEvent(this, "stagemousemove", false, id, o, e); 8478 this._dispatchMouseEvent(o.target, "pressmove", true, id, o, e); 8479 } 8480 8481 nextStage&&nextStage._handlePointerMove(id, e, pageX, pageY, null); 8482 }; 8483 8484 /** 8485 * @method _updatePointerPosition 8486 * @protected 8487 * @param {Number} id 8488 * @param {Event} e 8489 * @param {Number} pageX 8490 * @param {Number} pageY 8491 **/ 8492 p._updatePointerPosition = function(id, e, pageX, pageY) { 8493 var rect = this._getElementRect(this.canvas); 8494 pageX -= rect.left; 8495 pageY -= rect.top; 8496 8497 var w = this.canvas.width; 8498 var h = this.canvas.height; 8499 pageX /= (rect.right-rect.left)/w; 8500 pageY /= (rect.bottom-rect.top)/h; 8501 var o = this._getPointerData(id); 8502 if (o.inBounds = (pageX >= 0 && pageY >= 0 && pageX <= w-1 && pageY <= h-1)) { 8503 o.x = pageX; 8504 o.y = pageY; 8505 } else if (this.mouseMoveOutside) { 8506 o.x = pageX < 0 ? 0 : (pageX > w-1 ? w-1 : pageX); 8507 o.y = pageY < 0 ? 0 : (pageY > h-1 ? h-1 : pageY); 8508 } 8509 8510 o.posEvtObj = e; 8511 o.rawX = pageX; 8512 o.rawY = pageY; 8513 8514 if (id === this._primaryPointerID || id === -1) { 8515 this.mouseX = o.x; 8516 this.mouseY = o.y; 8517 this.mouseInBounds = o.inBounds; 8518 } 8519 }; 8520 8521 /** 8522 * @method _handleMouseUp 8523 * @protected 8524 * @param {MouseEvent} e 8525 **/ 8526 p._handleMouseUp = function(e) { 8527 this._handlePointerUp(-1, e, false); 8528 }; 8529 8530 /** 8531 * @method _handlePointerUp 8532 * @protected 8533 * @param {Number} id 8534 * @param {Event} e 8535 * @param {Boolean} clear 8536 * @param {Stage} owner Indicates that the event has already been captured & handled by the indicated stage. 8537 **/ 8538 p._handlePointerUp = function(id, e, clear, owner) { 8539 var nextStage = this._nextStage, o = this._getPointerData(id); 8540 if (this._prevStage && owner === undefined) { return; } // redundant listener. 8541 8542 var target=null, oTarget = o.target; 8543 if (!owner && (oTarget || nextStage)) { target = this._getObjectsUnderPoint(o.x, o.y, null, true); } 8544 8545 if (o.down) { this._dispatchMouseEvent(this, "stagemouseup", false, id, o, e, target); o.down = false; } 8546 8547 if (target == oTarget) { this._dispatchMouseEvent(oTarget, "click", true, id, o, e); } 8548 this._dispatchMouseEvent(oTarget, "pressup", true, id, o, e); 8549 8550 if (clear) { 8551 if (id==this._primaryPointerID) { this._primaryPointerID = null; } 8552 delete(this._pointerData[id]); 8553 } else { o.target = null; } 8554 8555 nextStage&&nextStage._handlePointerUp(id, e, clear, owner || target && this); 8556 }; 8557 8558 /** 8559 * @method _handleMouseDown 8560 * @protected 8561 * @param {MouseEvent} e 8562 **/ 8563 p._handleMouseDown = function(e) { 8564 this._handlePointerDown(-1, e, e.pageX, e.pageY); 8565 }; 8566 8567 /** 8568 * @method _handlePointerDown 8569 * @protected 8570 * @param {Number} id 8571 * @param {Event} e 8572 * @param {Number} pageX 8573 * @param {Number} pageY 8574 * @param {Stage} owner Indicates that the event has already been captured & handled by the indicated stage. 8575 **/ 8576 p._handlePointerDown = function(id, e, pageX, pageY, owner) { 8577 if (this.preventSelection) { e.preventDefault(); } 8578 if (this._primaryPointerID == null || id === -1) { this._primaryPointerID = id; } // mouse always takes over. 8579 8580 if (pageY != null) { this._updatePointerPosition(id, e, pageX, pageY); } 8581 var target = null, nextStage = this._nextStage, o = this._getPointerData(id); 8582 if (!owner) { target = o.target = this._getObjectsUnderPoint(o.x, o.y, null, true); } 8583 8584 if (o.inBounds) { this._dispatchMouseEvent(this, "stagemousedown", false, id, o, e, target); o.down = true; } 8585 this._dispatchMouseEvent(target, "mousedown", true, id, o, e); 8586 8587 nextStage&&nextStage._handlePointerDown(id, e, pageX, pageY, owner || target && this); 8588 }; 8589 8590 /** 8591 * @method _testMouseOver 8592 * @param {Boolean} clear If true, clears the mouseover / rollover (ie. no target) 8593 * @param {Stage} owner Indicates that the event has already been captured & handled by the indicated stage. 8594 * @param {Stage} eventTarget The stage that the cursor is actively over. 8595 * @protected 8596 **/ 8597 p._testMouseOver = function(clear, owner, eventTarget) { 8598 if (this._prevStage && owner === undefined) { return; } // redundant listener. 8599 8600 var nextStage = this._nextStage; 8601 if (!this._mouseOverIntervalID) { 8602 // not enabled for mouseover, but should still relay the event. 8603 nextStage&&nextStage._testMouseOver(clear, owner, eventTarget); 8604 return; 8605 } 8606 var o = this._getPointerData(-1); 8607 // only update if the mouse position has changed. This provides a lot of optimization, but has some trade-offs. 8608 if (!o || (!clear && this.mouseX == this._mouseOverX && this.mouseY == this._mouseOverY && this.mouseInBounds)) { return; } 8609 8610 var e = o.posEvtObj; 8611 var isEventTarget = eventTarget || e&&(e.target == this.canvas); 8612 var target=null, common = -1, cursor="", t, i, l; 8613 8614 if (!owner && (clear || this.mouseInBounds && isEventTarget)) { 8615 target = this._getObjectsUnderPoint(this.mouseX, this.mouseY, null, true); 8616 this._mouseOverX = this.mouseX; 8617 this._mouseOverY = this.mouseY; 8618 } 8619 8620 var oldList = this._mouseOverTarget||[]; 8621 var oldTarget = oldList[oldList.length-1]; 8622 var list = this._mouseOverTarget = []; 8623 8624 // generate ancestor list and check for cursor: 8625 t = target; 8626 while (t) { 8627 list.unshift(t);
8628 if (!cursor) { cursor = t.cursor; } 8629 t = t.parent; 8630 } 8631 this.canvas.style.cursor = cursor; 8632 if (!owner && eventTarget) { eventTarget.canvas.style.cursor = cursor; } 8633 8634 // find common ancestor: 8635 for (i=0,l=list.length; i<l; i++) { 8636 if (list[i] != oldList[i]) { break; } 8637 common = i; 8638 } 8639 8640 if (oldTarget != target) { 8641 this._dispatchMouseEvent(oldTarget, "mouseout", true, -1, o, e, target); 8642 } 8643 8644 for (i=oldList.length-1; i>common; i--) { 8645 this._dispatchMouseEvent(oldList[i], "rollout", false, -1, o, e, target); 8646 } 8647 8648 for (i=list.length-1; i>common; i--) { 8649 this._dispatchMouseEvent(list[i], "rollover", false, -1, o, e, oldTarget); 8650 } 8651 8652 if (oldTarget != target) { 8653 this._dispatchMouseEvent(target, "mouseover", true, -1, o, e, oldTarget); 8654 } 8655 8656 nextStage&&nextStage._testMouseOver(clear, owner || target && this, eventTarget || isEventTarget && this); 8657 }; 8658 8659 /** 8660 * @method _handleDoubleClick 8661 * @protected 8662 * @param {MouseEvent} e 8663 * @param {Stage} owner Indicates that the event has already been captured & handled by the indicated stage. 8664 **/ 8665 p._handleDoubleClick = function(e, owner) { 8666 var target=null, nextStage=this._nextStage, o=this._getPointerData(-1); 8667 if (!owner) { 8668 target = this._getObjectsUnderPoint(o.x, o.y, null, true); 8669 this._dispatchMouseEvent(target, "dblclick", true, -1, o, e); 8670 } 8671 nextStage&&nextStage._handleDoubleClick(e, owner || target && this); 8672 }; 8673 8674 /** 8675 * @method _dispatchMouseEvent 8676 * @protected 8677 * @param {DisplayObject} target 8678 * @param {String} type 8679 * @param {Boolean} bubbles 8680 * @param {Number} pointerId 8681 * @param {Object} o 8682 * @param {MouseEvent} [nativeEvent] 8683 * @param {DisplayObject} [relatedTarget] 8684 **/ 8685 p._dispatchMouseEvent = function(target, type, bubbles, pointerId, o, nativeEvent, relatedTarget) { 8686 // TODO: might be worth either reusing MouseEvent instances, or adding a willTrigger method to avoid GC. 8687 if (!target || (!bubbles && !target.hasEventListener(type))) { return; } 8688 /* 8689 // TODO: account for stage transformations? 8690 this._mtx = this.getConcatenatedMatrix(this._mtx).invert(); 8691 var pt = this._mtx.transformPoint(o.x, o.y); 8692 var evt = new createjs.MouseEvent(type, bubbles, false, pt.x, pt.y, nativeEvent, pointerId, pointerId==this._primaryPointerID || pointerId==-1, o.rawX, o.rawY); 8693 */ 8694 var evt = new createjs.MouseEvent(type, bubbles, false, o.x, o.y, nativeEvent, pointerId, pointerId === this._primaryPointerID || pointerId === -1, o.rawX, o.rawY, relatedTarget); 8695 target.dispatchEvent(evt); 8696 }; 8697 8698 8699 createjs.Stage = createjs.promote(Stage, "Container"); 8700}()); 8701 8702//############################################################################## 8703// Bitmap.js 8704//############################################################################## 8705 8706this.createjs = this.createjs||{}; 8707 8708(function() { 8709 8710 /** 8711 * A Bitmap represents an Image, Canvas, or Video in the display list. A Bitmap can be instantiated using an existing 8712 * HTML element, or a string. 8713 * 8714 * <h4>Example</h4> 8715 * 8716 * var bitmap = new createjs.Bitmap("imagePath.jpg"); 8717 * 8718 * <strong>Notes:</strong> 8719 * <ol> 8720 * <li>When a string path or image tag that is not yet loaded is used, the stage may need to be redrawn before it 8721 * will be displayed.</li> 8722 * <li>Bitmaps with an SVG source currently will not respect an alpha value other than 0 or 1. To get around this, 8723 * the Bitmap can be cached.</li> 8724 * <li>Bitmaps with an SVG source will taint the canvas with cross-origin data, which prevents interactivity. This 8725 * happens in all browsers except recent Firefox builds.</li> 8726 * <li>Images loaded cross-origin will throw cross-origin security errors when interacted with using a mouse, using 8727 * methods such as `getObjectUnderPoint`, or using filters, or caching. You can get around this by setting 8728 * `crossOrigin` flags on your images before passing them to EaselJS, eg: `img.crossOrigin="Anonymous";`</li> 8729 * </ol> 8730 * 8731 * @class Bitmap 8732 * @extends DisplayObject 8733 * @constructor 8734 * @param {HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | String} imageOrUri The source object or URI to an image to 8735 * display. This can be either an Image, Canvas, or Video object, or a string URI to an image file to load and use. 8736 * If it is a URI, a new Image object will be constructed and assigned to the .image property. 8737 **/ 8738 function Bitmap(imageOrUri) { 8739 this.DisplayObject_constructor(); 8740 8741 8742 // public properties: 8743 /** 8744 * The image to render. This can be an Image, a Canvas, or a Video. Not all browsers (especially 8745 * mobile browsers) support drawing video to a canvas. 8746 * @property image 8747 * @type HTMLImageElement | HTMLCanvasElement | HTMLVideoElement 8748 **/ 8749 if (typeof imageOrUri == "string") { 8750 this.image = document.createElement("img"); 8751 this.image.src = imageOrUri; 8752 } else { 8753 this.image = imageOrUri; 8754 } 8755 8756 /** 8757 * Specifies an area of the source image to draw. If omitted, the whole image will be drawn. 8758 * Note that video sources must have a width / height set to work correctly with `sourceRect`. 8759 * @property sourceRect 8760 * @type Rectangle 8761 * @default null 8762 */ 8763 this.sourceRect = null; 8764 }
8765 var p = createjs.extend(Bitmap, createjs.DisplayObject); 8766 8767 8768// public methods: 8769 /** 8770 * Constructor alias for backwards compatibility. This method will be removed in future versions. 8771 * Subclasses should be updated to use {{#crossLink "Utility Methods/extends"}}{{/crossLink}}. 8772 * @method initialize 8773 * @deprecated in favour of `createjs.promote()` 8774 **/ 8775 p.initialize = Bitmap; // TODO: deprecated. 8776 8777 /** 8778 * Returns true or false indicating whether the display object would be visible if drawn to a canvas. 8779 * This does not account for whether it would be visible within the boundaries of the stage. 8780 * 8781 * NOTE: This method is mainly for internal use, though it may be useful for advanced uses. 8782 * @method isVisible 8783 * @return {Boolean} Boolean indicating whether the display object would be visible if drawn to a canvas 8784 **/ 8785 p.isVisible = function() { 8786 var image = this.image; 8787 var hasContent = this.cacheCanvas || (image && (image.naturalWidth || image.getContext || image.readyState >= 2)); 8788 return !!(this.visible && this.alpha > 0 && this.scaleX != 0 && this.scaleY != 0 && hasContent); 8789 }; 8790 8791 /** 8792 * Draws the display object into the specified context ignoring its visible, alpha, shadow, and transform. 8793 * Returns true if the draw was handled (useful for overriding functionality). 8794 * 8795 * NOTE: This method is mainly for internal use, though it may be useful for advanced uses. 8796 * @method draw 8797 * @param {CanvasRenderingContext2D} ctx The canvas 2D context object to draw into. 8798 * @param {Boolean} [ignoreCache=false] Indicates whether the draw operation should ignore any current cache. 8799 * For example, used for drawing the cache (to prevent it from simply drawing an existing cache back 8800 * into itself). 8801 * @return {Boolean} 8802 **/ 8803 p.draw = function(ctx, ignoreCache) { 8804 if (this.DisplayObject_draw(ctx, ignoreCache) || !this.image) { return true; } 8805 var img = this.image, rect = this.sourceRect; 8806 if (rect) { 8807 // some browsers choke on out of bound values, so we'll fix them:
8808 var x1 = rect.x, y1 = rect.y, x2 = x1 + rect.width, y2 = y1 + rect.height, x = 0, y = 0, w = img.width, h = img.height; 8809 if (x1 < 0) { x -= x1; x1 = 0; } 8810 if (x2 > w) { x2 = w; } 8811 if (y1 < 0) { y -= y1; y1 = 0; } 8812 if (y2 > h) { y2 = h; } 8813 ctx.drawImage(img, x1, y1, x2-x1, y2-y1, x, y, x2-x1, y2-y1); 8814 } else { 8815 ctx.drawImage(img, 0, 0); 8816 } 8817 return true; 8818 }; 8819 8820 //Note, the doc sections below document using the specified APIs (from DisplayObject) from 8821 //Bitmap. This is why they have no method implementations. 8822 8823 /** 8824 * Because the content of a Bitmap is already in a simple format, cache is unnecessary for Bitmap instances. 8825 * You should <b>not</b> cache Bitmap instances as it can degrade performance. 8826 * 8827 * <strong>However: If you want to use a filter on a Bitmap, you <em>MUST</em> cache it, or it will not work.</strong> 8828 * To see the API for caching, please visit the DisplayObject {{#crossLink "DisplayObject/cache"}}{{/crossLink}} 8829 * method. 8830 * @method cache 8831 **/ 8832 8833 /** 8834 * Because the content of a Bitmap is already in a simple format, cache is unnecessary for Bitmap instances. 8835 * You should <b>not</b> cache Bitmap instances as it can degrade performance. 8836 * 8837 * <strong>However: If you want to use a filter on a Bitmap, you <em>MUST</em> cache it, or it will not work.</strong> 8838 * To see the API for caching, please visit the DisplayObject {{#crossLink "DisplayObject/cache"}}{{/crossLink}} 8839 * method. 8840 * @method updateCache 8841 **/ 8842 8843 /** 8844 * Because the content of a Bitmap is already in a simple format, cache is unnecessary for Bitmap instances. 8845 * You should <b>not</b> cache Bitmap instances as it can degrade performance. 8846 * 8847 * <strong>However: If you want to use a filter on a Bitmap, you <em>MUST</em> cache it, or it will not work.</strong> 8848 * To see the API for caching, please visit the DisplayObject {{#crossLink "DisplayObject/cache"}}{{/crossLink}} 8849 * method. 8850 * @method uncache 8851 **/ 8852 8853 /** 8854 * Docced in superclass. 8855 */ 8856 p.getBounds = function() { 8857 var rect = this.DisplayObject_getBounds(); 8858 if (rect) { return rect; } 8859 var image = this.image, o = this.sourceRect || image; 8860 var hasContent = (image && (image.naturalWidth || image.getContext || image.readyState >= 2)); 8861 return hasContent ? this._rectangle.setValues(0, 0, o.width, o.height) : null; 8862 }; 8863 8864 /** 8865 * Returns a clone of the Bitmap instance. 8866 * @method clone 8867 * @return {Bitmap} a clone of the Bitmap instance. 8868 **/ 8869 p.clone = function() { 8870 var o = new Bitmap(this.image); 8871 if (this.sourceRect) { o.sourceRect = this.sourceRect.clone(); } 8872 this._cloneProps(o); 8873 return o; 8874 }; 8875 8876 /** 8877 * Returns a string representation of this object. 8878 * @method toString 8879 * @return {String} a string representation of the instance. 8880 **/ 8881 p.toString = function() { 8882 return "[Bitmap (name="+ this.name +")]"; 8883 }; 8884 8885 8886 createjs.Bitmap = createjs.promote(Bitmap, "DisplayObject"); 8887}()); 8888 8889//############################################################################## 8890// Sprite.js 8891//############################################################################## 8892 8893this.createjs = this.createjs||{}; 8894 8895(function() { 8896 "use strict"; 8897 8898 8899// constructor: 8900 /** 8901 * Displays a frame or sequence of frames (ie. an animation) from a SpriteSheet instance. A sprite sheet is a series of 8902 * images (usually animation frames) combined into a single image. For example, an animation consisting of 8 100x100 8903 * images could be combined into a 400x200 sprite sheet (4 frames across by 2 high). You can display individual frames, 8904 * play frames as an animation, and even sequence animations together. 8905 * 8906 * See the {{#crossLink "SpriteSheet"}}{{/crossLink}} class for more information on setting up frames and animations. 8907 * 8908 * <h4>Example</h4> 8909 * 8910 * var instance = new createjs.Sprite(spriteSheet); 8911 * instance.gotoAndStop("frameName"); 8912 * 8913 * Until {{#crossLink "Sprite/gotoAndStop"}}{{/crossLink}} or {{#crossLink "Sprite/gotoAndPlay"}}{{/crossLink}} is called, 8914 * only the first defined frame defined in the sprite sheet will be displayed. 8915 * 8916 * @class Sprite
8917 * @extends DisplayObject 8918 * @constructor 8919 * @param {SpriteSheet} spriteSheet The SpriteSheet instance to play back. This includes the source image(s), frame 8920 * dimensions, and frame data. See {{#crossLink "SpriteSheet"}}{{/crossLink}} for more information. 8921 * @param {String|Number} [frameOrAnimation] The frame number or animation to play initially. 8922 **/ 8923 function Sprite(spriteSheet, frameOrAnimation) { 8924 this.DisplayObject_constructor(); 8925 8926 8927 // public properties: 8928 /** 8929 * The frame index that will be drawn when draw is called. Note that with some {{#crossLink "SpriteSheet"}}{{/crossLink}} 8930 * definitions, this will advance non-sequentially. This will always be an integer value. 8931 * @property currentFrame 8932 * @type {Number} 8933 * @default 0 8934 * @readonly 8935 **/ 8936 this.currentFrame = 0; 8937 8938 /** 8939 * Returns the name of the currently playing animation. 8940 * @property currentAnimation 8941 * @type {String} 8942 * @final 8943 * @readonly 8944 **/ 8945 this.currentAnimation = null; 8946 8947 /** 8948 * Prevents the animation from advancing each tick automatically. For example, you could create a sprite 8949 * sheet of icons, set paused to true, and display the appropriate icon by setting <code>currentFrame</code>. 8950 * @property paused 8951 * @type {Boolean} 8952 * @default false 8953 **/ 8954 this.paused = true; 8955 8956 /** 8957 * The SpriteSheet instance to play back. This includes the source image, frame dimensions, and frame 8958 * data. See {{#crossLink "SpriteSheet"}}{{/crossLink}} for more information. 8959 * @property spriteSheet 8960 * @type {SpriteSheet} 8961 * @readonly 8962 **/ 8963 this.spriteSheet = spriteSheet; 8964 8965 /** 8966 * Specifies the current frame index within the currently playing animation. When playing normally, this will increase 8967 * from 0 to n-1, where n is the number of frames in the current animation. 8968 * 8969 * This could be a non-integer value if 8970 * using time-based playback (see {{#crossLink "Sprite/framerate"}}{{/crossLink}}, or if the animation's speed is 8971 * not an integer. 8972 * @property currentAnimationFrame 8973 * @type {Number} 8974 * @default 0 8975 **/ 8976 this.currentAnimationFrame = 0; 8977 8978 /** 8979 * By default Sprite instances advance one frame per tick. Specifying a framerate for the Sprite (or its related 8980 * SpriteSheet) will cause it to advance based on elapsed time between ticks as appropriate to maintain the target 8981 * framerate. 8982 * 8983 * For example, if a Sprite with a framerate of 10 is placed on a Stage being updated at 40fps, then the Sprite will 8984 * advance roughly one frame every 4 ticks. This will not be exact, because the time between each tick will 8985 * vary slightly between frames. 8986 * 8987 * This feature is dependent on the tick event object (or an object with an appropriate "delta" property) being 8988 * passed into {{#crossLink "Stage/update"}}{{/crossLink}}. 8989 * @property framerate 8990 * @type {Number} 8991 * @default 0 8992 **/ 8993 this.framerate = 0; 8994 8995 8996 // private properties: 8997 /** 8998 * Current animation object. 8999 * @property _animation 9000 * @protected 9001 * @type {Object} 9002 * @default null 9003 **/ 9004 this._animation = null; 9005 9006 /** 9007 * Current frame index. 9008 * @property _currentFrame 9009 * @protected 9010 * @type {Number} 9011 * @default null 9012 **/ 9013 this._currentFrame = null; 9014 9015 /** 9016 * Skips the next auto advance. Used by gotoAndPlay to avoid immediately jumping to the next frame 9017 * @property _skipAdvance 9018 * @protected 9019 * @type {Boolean} 9020 * @default false 9021 **/ 9022 this._skipAdvance = false; 9023 9024 9025 if (frameOrAnimation != null) { this.gotoAndPlay(frameOrAnimation); } 9026 } 9027 var p = createjs.extend(Sprite, createjs.DisplayObject); 9028 9029 /** 9030 * Constructor alias for backwards compatibility. This method will be removed in future versions. 9031 * Subclasses should be updated to use {{#crossLink "Utility Methods/extends"}}{{/crossLink}}. 9032 * @method initialize 9033 * @deprecated in favour of `createjs.promote()` 9034 **/ 9035 p.initialize = Sprite; // TODO: Deprecated. This is for backwards support of FlashCC spritesheet export. 9036 9037 9038// events: 9039 /** 9040 * Dispatched when an animation reaches its ends. 9041 * @event animationend 9042 * @param {Object} target The object that dispatched the event. 9043 * @param {String} type The event type. 9044 * @param {String} name The name of the animation that just ended. 9045 * @param {String} next The name of the next animation that will be played, or null. This will be the same as name if the animation is looping. 9046 * @since 0.6.0 9047 */ 9048 9049 /** 9050 * Dispatched any time the current frame changes. For example, this could be due to automatic advancement on a tick, 9051 * or calling gotoAndPlay() or gotoAndStop(). 9052 * @event change 9053 * @param {Object} target The object that dispatched the event. 9054 * @param {String} type The event type. 9055 */ 9056 9057 9058// public methods: 9059 /** 9060 * Returns true or false indicating whether the display object would be visible if drawn to a canvas. 9061 * This does not account for whether it would be visible within the boundaries of the stage. 9062 * NOTE: This method is mainly for internal use, though it may be useful for advanced uses. 9063 * @method isVisible 9064 * @return {Boolean} Boolean indicating whether the display object would be visible if drawn to a canvas 9065 **/ 9066 p.isVisible = function() { 9067 var hasContent = this.cacheCanvas || this.spriteSheet.complete; 9068 return !!(this.visible && this.alpha > 0 && this.scaleX != 0 && this.scaleY != 0 && hasContent); 9069 }; 9070 9071 /** 9072 * Draws the display object into the specified context ignoring its visible, alpha, shadow, and transform. 9073 * Returns true if the draw was handled (useful for overriding functionality). 9074 * NOTE: This method is mainly for internal use, though it may be useful for advanced uses. 9075 * @method draw 9076 * @param {CanvasRenderingContext2D} ctx The canvas 2D context object to draw into. 9077 * @param {Boolean} ignoreCache Indicates whether the draw operation should ignore any current cache. 9078 * For example, used for drawing the cache (to prevent it from simply drawing an existing cache back 9079 * into itself). 9080 **/ 9081 p.draw = function(ctx, ignoreCache) { 9082 if (this.DisplayObject_draw(ctx, ignoreCache)) { return true; } 9083 this._normalizeFrame(); 9084 var o = this.spriteSheet.getFrame(this._currentFrame|0); 9085 if (!o) { return false; } 9086 var rect = o.rect; 9087 if (rect.width && rect.height) { ctx.drawImage(o.image, rect.x, rect.y, rect.width, rect.height, -o.regX, -o.regY, rect.width, rect.height); } 9088 return true; 9089 }; 9090 9091 //Note, the doc sections below document using the specified APIs (from DisplayObject) from 9092 //Bitmap. This is why they have no method implementations. 9093 9094 /** 9095 * Because the content of a Sprite is already in a raster format, cache is unnecessary for Sprite instances. 9096 * You should not cache Sprite instances as it can degrade performance. 9097 * @method cache 9098 **/ 9099 9100 /** 9101 * Because the content of a Sprite is already in a raster format, cache is unnecessary for Sprite instances. 9102 * You should not cache Sprite instances as it can degrade performance. 9103 * @method updateCache 9104 **/ 9105 9106 /** 9107 * Because the content of a Sprite is already in a raster format, cache is unnecessary for Sprite instances. 9108 * You should not cache Sprite instances as it can degrade performance. 9109 * @method uncache 9110 **/ 9111 9112 /** 9113 * Play (unpause) the current animation. The Sprite will be paused if either {{#crossLink "Sprite/stop"}}{{/crossLink}} 9114 * or {{#crossLink "Sprite/gotoAndStop"}}{{/crossLink}} is called. Single frame animations will remain 9115 * unchanged. 9116 * @method play 9117 **/ 9118 p.play = function() { 9119 this.paused = false;
9120 }; 9121 9122 /** 9123 * Stop playing a running animation. The Sprite will be playing if {{#crossLink "Sprite/gotoAndPlay"}}{{/crossLink}} 9124 * is called. Note that calling {{#crossLink "Sprite/gotoAndPlay"}}{{/crossLink}} or {{#crossLink "Sprite/play"}}{{/crossLink}} 9125 * will resume playback. 9126 * @method stop 9127 **/ 9128 p.stop = function() { 9129 this.paused = true; 9130 }; 9131 9132 /** 9133 * Sets paused to false and plays the specified animation name, named frame, or frame number. 9134 * @method gotoAndPlay 9135 * @param {String|Number} frameOrAnimation The frame number or animation name that the playhead should move to 9136 * and begin playing. 9137 **/ 9138 p.gotoAndPlay = function(frameOrAnimation) { 9139 this.paused = false; 9140 this._skipAdvance = true; 9141 this._goto(frameOrAnimation); 9142 }; 9143 9144 /** 9145 * Sets paused to true and seeks to the specified animation name, named frame, or frame number. 9146 * @method gotoAndStop 9147 * @param {String|Number} frameOrAnimation The frame number or animation name that the playhead should move to 9148 * and stop. 9149 **/ 9150 p.gotoAndStop = function(frameOrAnimation) { 9151 this.paused = true; 9152 this._goto(frameOrAnimation); 9153 }; 9154 9155 /** 9156 * Advances the playhead. This occurs automatically each tick by default. 9157 * @param [time] {Number} The amount of time in ms to advance by. Only applicable if framerate is set on the Sprite 9158 * or its SpriteSheet. 9159 * @method advance 9160 */ 9161 p.advance = function(time) { 9162 var fps = this.framerate || this.spriteSheet.framerate; 9163 var t = (fps && time != null) ? time/(1000/fps) : 1; 9164 this._normalizeFrame(t); 9165 }; 9166 9167 /** 9168 * Returns a {{#crossLink "Rectangle"}}{{/crossLink}} instance defining the bounds of the current frame relative to 9169 * the origin. For example, a 90 x 70 frame with <code>regX=50</code> and <code>regY=40</code> would return a 9170 * rectangle with [x=-50, y=-40, width=90, height=70]. This ignores transformations on the display object. 9171 * 9172 * Also see the SpriteSheet {{#crossLink "SpriteSheet/getFrameBounds"}}{{/crossLink}} method. 9173 * @method getBounds 9174 * @return {Rectangle} A Rectangle instance. Returns null if the frame does not exist, or the image is not fully 9175 * loaded. 9176 **/ 9177 p.getBounds = function() { 9178 // TODO: should this normalizeFrame? 9179 return this.DisplayObject_getBounds() || this.spriteSheet.getFrameBounds(this.currentFrame, this._rectangle); 9180 }; 9181 9182 /** 9183 * Returns a clone of the Sprite instance. Note that the same SpriteSheet is shared between cloned 9184 * instances. 9185 * @method clone 9186 * @return {Sprite} a clone of the Sprite instance. 9187 **/ 9188 p.clone = function() { 9189 return this._cloneProps(new Sprite(this.spriteSheet)); 9190 }; 9191 9192 /** 9193 * Returns a string representation of this object. 9194 * @method toString 9195 * @return {String} a string representation of the instance. 9196 **/ 9197 p.toString = function() { 9198 return "[Sprite (name="+ this.name +")]"; 9199 }; 9200 9201// private methods: 9202 /** 9203 * @method _cloneProps 9204 * @param {Sprite} o 9205 * @return {Sprite} o 9206 * @protected 9207 **/ 9208 p._cloneProps = function(o) { 9209 this.DisplayObject__cloneProps(o); 9210 o.currentFrame = this.currentFrame; 9211 o.currentAnimation = this.currentAnimation; 9212 o.paused = this.paused; 9213 o.currentAnimationFrame = this.currentAnimationFrame; 9214 o.framerate = this.framerate; 9215 9216 o._animation = this._animation; 9217 o._currentFrame = this._currentFrame; 9218 o._skipAdvance = this._skipAdvance; 9219 return o; 9220 }; 9221 9222 /** 9223 * Advances the <code>currentFrame</code> if paused is not true. This is called automatically when the {{#crossLink "Stage"}}{{/crossLink}} 9224 * ticks. 9225 * @param {Object} evtObj An event object that will be dispatched to all tick listeners. This object is reused between dispatchers to reduce construction & GC costs. 9226 * @protected 9227 * @method _tick 9228 **/ 9229 p._tick = function(evtObj) { 9230 if (!this.paused) { 9231 if (!this._skipAdvance) { this.advance(evtObj&&evtObj.delta); } 9232 this._skipAdvance = false; 9233 } 9234 this.DisplayObject__tick(evtObj); 9235 }; 9236 9237 9238 /** 9239 * Normalizes the current frame, advancing animations and dispatching callbacks as appropriate. 9240 * @protected 9241 * @method _normalizeFrame 9242 **/ 9243 p._normalizeFrame = function(frameDelta) { 9244 frameDelta = frameDelta || 0; 9245 var animation = this._animation; 9246 var paused = this.paused; 9247 var frame = this._currentFrame; 9248 var l; 9249 9250 if (animation) { 9251 var speed = animation.speed || 1; 9252 var animFrame = this.currentAnimationFrame; 9253 l = animation.frames.length; 9254 if (animFrame + frameDelta * speed >= l) { 9255 var next = animation.next; 9256 if (this._dispatchAnimationEnd(animation, frame, paused, next, l - 1)) { 9257 // something changed in the event stack, so we shouldn't make any more changes here. 9258 return; 9259 } else if (next) { 9260 // sequence. Automatically calls _normalizeFrame again with the remaining frames. 9261 return this._goto(next, frameDelta - (l - animFrame) / speed); 9262 } else { 9263 // end. 9264 this.paused = true; 9265 animFrame = animation.frames.length - 1; 9266 } 9267 } else { 9268 animFrame += frameDelta * speed; 9269 } 9270 this.currentAnimationFrame = animFrame; 9271 this._currentFrame = animation.frames[animFrame | 0] 9272 } else { 9273 frame = (this._currentFrame += frameDelta); 9274 l = this.spriteSheet.getNumFrames(); 9275 if (frame >= l && l > 0) { 9276 if (!this._dispatchAnimationEnd(animation, frame, paused, l - 1)) { 9277 // looped. 9278 if ((this._currentFrame -= l) >= l) { return this._normalizeFrame(); } 9279 } 9280 } 9281 } 9282 frame = this._currentFrame | 0; 9283 if (this.currentFrame != frame) { 9284 this.currentFrame = frame; 9285 this.dispatchEvent("change"); 9286 } 9287 }; 9288 9289 /** 9290 * Dispatches the "animationend" event. Returns true if a handler changed the animation (ex. calling {{#crossLink "Sprite/stop"}}{{/crossLink}}, 9291 * {{#crossLink "Sprite/gotoAndPlay"}}{{/crossLink}}, etc.) 9292 * @property _dispatchAnimationEnd 9293 * @private 9294 * @type {Function} 9295 **/ 9296 p._dispatchAnimationEnd = function(animation, frame, paused, next, end) { 9297 var name = animation ? animation.name : null; 9298 if (this.hasEventListener("animationend")) { 9299 var evt = new createjs.Event("animationend"); 9300 evt.name = name; 9301 evt.next = next; 9302 this.dispatchEvent(evt); 9303 } 9304 // did the animation get changed in the event stack?: 9305 var changed = (this._animation != animation || this._currentFrame != frame); 9306 // if the animation hasn't changed, but the sprite was paused, then we want to stick to the last frame: 9307 if (!changed && !paused && this.paused) { this.currentAnimationFrame = end; changed = true; } 9308 return changed; 9309 }; 9310 9311 /** 9312 * Moves the playhead to the specified frame number or animation. 9313 * @method _goto 9314 * @param {String|Number} frameOrAnimation The frame number or animation that the playhead should move to. 9315 * @param {Boolean} [frame] The frame of the animation to go to. Defaults to 0. 9316 * @protected 9317 **/ 9318 p._goto = function(frameOrAnimation, frame) { 9319 this.currentAnimationFrame = 0; 9320 if (isNaN(frameOrAnimation)) { 9321 var data = this.spriteSheet.getAnimation(frameOrAnimation); 9322 if (data) { 9323 this._animation = data; 9324 this.currentAnimation = frameOrAnimation; 9325 this._normalizeFrame(frame); 9326 } 9327 } else { 9328 this.currentAnimation = this._animation = null; 9329 this._currentFrame = frameOrAnimation; 9330 this._normalizeFrame(); 9331 } 9332 }; 9333 9334 9335 createjs.Sprite = createjs.promote(Sprite, "DisplayObject"); 9336}()); 9337 9338//############################################################################## 9339// Shape.js 9340//############################################################################## 9341 9342this.createjs = this.createjs||{}; 9343 9344(function() { 9345 "use strict"; 9346 9347 9348// constructor: 9349 /** 9350 * A Shape allows you to display vector art in the display list. It composites a {{#crossLink "Graphics"}}{{/crossLink}} 9351 * instance which exposes all of the vector drawing methods. The Graphics instance can be shared between multiple Shape 9352 * instances to display the same vector graphics with different positions or transforms. 9353 * 9354 * If the vector art will not 9355 * change between draws, you may want to use the {{#crossLink "DisplayObject/cache"}}{{/crossLink}} method to reduce the 9356 * rendering cost. 9357 * 9358 * <h4>Example</h4> 9359 * 9360 * var graphics = new createjs.Graphics().beginFill("#ff0000").drawRect(0, 0, 100, 100);
9361 * var shape = new createjs.Shape(graphics); 9362 * 9363 * //Alternatively use can also use the graphics property of the Shape class to renderer the same as above. 9364 * var shape = new createjs.Shape(); 9365 * shape.graphics.beginFill("#ff0000").drawRect(0, 0, 100, 100); 9366 * 9367 * @class Shape 9368 * @extends DisplayObject 9369 * @constructor 9370 * @param {Graphics} graphics Optional. The graphics instance to display. If null, a new Graphics instance will be created. 9371 **/ 9372 function Shape(graphics) { 9373 this.DisplayObject_constructor(); 9374 9375 9376 // public properties: 9377 /** 9378 * The graphics instance to display. 9379 * @property graphics 9380 * @type Graphics 9381 **/ 9382 this.graphics = graphics ? graphics : new createjs.Graphics(); 9383 } 9384 var p = createjs.extend(Shape, createjs.DisplayObject); 9385 9386 // TODO: deprecated 9387 // p.initialize = function() {}; // searchable for devs wondering where it is. REMOVED. See docs for details. 9388 9389 9390// public methods: 9391 /** 9392 * Returns true or false indicating whether the Shape would be visible if drawn to a canvas. 9393 * This does not account for whether it would be visible within the boundaries of the stage. 9394 * NOTE: This method is mainly for internal use, though it may be useful for advanced uses. 9395 * @method isVisible 9396 * @return {Boolean} Boolean indicating whether the Shape would be visible if drawn to a canvas 9397 **/ 9398 p.isVisible = function() { 9399 var hasContent = this.cacheCanvas || (this.graphics && !this.graphics.isEmpty()); 9400 return !!(this.visible && this.alpha > 0 && this.scaleX != 0 && this.scaleY != 0 && hasContent); 9401 }; 9402 9403 /** 9404 * Draws the Shape into the specified context ignoring its visible, alpha, shadow, and transform. Returns true if 9405 * the draw was handled (useful for overriding functionality). 9406 * 9407 * <i>NOTE: This method is mainly for internal use, though it may be useful for advanced uses.</i> 9408 * @method draw 9409 * @param {CanvasRenderingContext2D} ctx The canvas 2D context object to draw into. 9410 * @param {Boolean} [ignoreCache=false] Indicates whether the draw operation should ignore any current cache. For example, 9411 * used for drawing the cache (to prevent it from simply drawing an existing cache back into itself). 9412 * @return {Boolean} 9413 **/ 9414 p.draw = function(ctx, ignoreCache) { 9415 if (this.DisplayObject_draw(ctx, ignoreCache)) { return true; } 9416 this.graphics.draw(ctx, this); 9417 return true; 9418 }; 9419 9420 /** 9421 * Returns a clone of this Shape. Some properties that are specific to this instance's current context are reverted to 9422 * their defaults (for example .parent). 9423 * @method clone 9424 * @param {Boolean} recursive If true, this Shape's {{#crossLink "Graphics"}}{{/crossLink}} instance will also be 9425 * cloned. If false, the Graphics instance will be shared with the new Shape. 9426 **/ 9427 p.clone = function(recursive) { 9428 var g = (recursive && this.graphics) ? this.graphics.clone() : this.graphics; 9429 return this._cloneProps(new Shape(g)); 9430 }; 9431 9432 /** 9433 * Returns a string representation of this object. 9434 * @method toString 9435 * @return {String} a string representation of the instance. 9436 **/ 9437 p.toString = function() { 9438 return "[Shape (name="+ this.name +")]"; 9439 }; 9440 9441 9442 createjs.Shape = createjs.promote(Shape, "DisplayObject"); 9443}()); 9444 9445//############################################################################## 9446// Text.js 9447//############################################################################## 9448 9449this.createjs = this.createjs||{}; 9450 9451(function() { 9452 "use strict"; 9453 9454 9455// constructor: 9456 /** 9457 * Display one or more lines of dynamic text (not user editable) in the display list. Line wrapping support (using the 9458 * lineWidth) is very basic, wrapping on spaces and tabs only. Note that as an alternative to Text, you can position HTML 9459 * text above or below the canvas relative to items in the display list using the {{#crossLink "DisplayObject/localToGlobal"}}{{/crossLink}} 9460 * method, or using {{#crossLink "DOMElement"}}{{/crossLink}}. 9461 * 9462 * <b>Please note that Text does not support HTML text, and can only display one font style at a time.</b> To use 9463 * multiple font styles, you will need to create multiple text instances, and position them manually. 9464 * 9465 * <h4>Example</h4> 9466 * 9467 * var text = new createjs.Text("Hello World", "20px Arial", "#ff7700"); 9468 * text.x = 100; 9469 * text.textBaseline = "alphabetic"; 9470 * 9471 * CreateJS Text supports web fonts (the same rules as Canvas). The font must be loaded and supported by the browser 9472 * before it can be displayed. 9473 * 9474 * <strong>Note:</strong> Text can be expensive to generate, so cache instances where possible. Be aware that not all 9475 * browsers will render Text exactly the same. 9476 * @class Text
9477 * @extends DisplayObject 9478 * @constructor 9479 * @param {String} [text] The text to display. 9480 * @param {String} [font] The font style to use. Any valid value for the CSS font attribute is acceptable (ex. "bold 9481 * 36px Arial"). 9482 * @param {String} [color] The color to draw the text in. Any valid value for the CSS color attribute is acceptable (ex. 9483 * "#F00", "red", or "#FF0000"). 9484 **/ 9485 function Text(text, font, color) { 9486 this.DisplayObject_constructor(); 9487 9488 9489 // public properties: 9490 /** 9491 * The text to display. 9492 * @property text 9493 * @type String 9494 **/ 9495 this.text = text; 9496 9497 /** 9498 * The font style to use. Any valid value for the CSS font attribute is acceptable (ex. "bold 36px Arial"). 9499 * @property font 9500 * @type String 9501 **/ 9502 this.font = font; 9503 9504 /** 9505 * The color to draw the text in. Any valid value for the CSS color attribute is acceptable (ex. "#F00"). Default is "#000". 9506 * It will also accept valid canvas fillStyle values. 9507 * @property color 9508 * @type String 9509 **/ 9510 this.color = color; 9511 9512 /** 9513 * The horizontal text alignment. Any of "start", "end", "left", "right", and "center". For detailed 9514 * information view the 9515 * <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#text-styles"> 9516 * whatwg spec</a>. Default is "left". 9517 * @property textAlign
9518 * @type String 9519 **/ 9520 this.textAlign = "left"; 9521 9522 /** 9523 * The vertical alignment point on the font. Any of "top", "hanging", "middle", "alphabetic", "ideographic", or 9524 * "bottom". For detailed information view the <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#text-styles"> 9525 * whatwg spec</a>. Default is "top". 9526 * @property textBaseline 9527 * @type String 9528 */ 9529 this.textBaseline = "top"; 9530 9531 /** 9532 * The maximum width to draw the text. If maxWidth is specified (not null), the text will be condensed or 9533 * shrunk to make it fit in this width. For detailed information view the 9534 * <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#text-styles"> 9535 * whatwg spec</a>. 9536 * @property maxWidth 9537 * @type Number 9538 */ 9539 this.maxWidth = null; 9540 9541 /** 9542 * If greater than 0, the text will be drawn as a stroke (outline) of the specified width. 9543 * @property outline 9544 * @type Number 9545 **/ 9546 this.outline = 0; 9547 9548 /** 9549 * Indicates the line height (vertical distance between baselines) for multi-line text. If null or 0, 9550 * the value of getMeasuredLineHeight is used. 9551 * @property lineHeight 9552 * @type Number 9553 **/ 9554 this.lineHeight = 0; 9555 9556 /** 9557 * Indicates the maximum width for a line of text before it is wrapped to multiple lines. If null, 9558 * the text will not be wrapped. 9559 * @property lineWidth 9560 * @type Number 9561 **/ 9562 this.lineWidth = null; 9563 } 9564 var p = createjs.extend(Text, createjs.DisplayObject); 9565 9566 // TODO: deprecated 9567 // p.initialize = function() {}; // searchable for devs wondering where it is. REMOVED. See docs for details. 9568 9569 9570// static properties: 9571 /** 9572 * @property _workingContext 9573 * @type CanvasRenderingContext2D 9574 * @private 9575 **/ 9576 var canvas = (createjs.createCanvas?createjs.createCanvas():document.createElement("canvas")); 9577 if (canvas.getContext) { Text._workingContext = canvas.getContext("2d"); canvas.width = canvas.height = 1; } 9578 9579 9580// constants: 9581 /** 9582 * Lookup table for the ratio to offset bounds x calculations based on the textAlign property. 9583 * @property H_OFFSETS 9584 * @type Object 9585 * @protected 9586 * @static 9587 **/ 9588 Text.H_OFFSETS = {start: 0, left: 0, center: -0.5, end: -1, right: -1}; 9589 9590 /** 9591 * Lookup table for the ratio to offset bounds y calculations based on the textBaseline property. 9592 * @property H_OFFSETS 9593 * @type Object 9594 * @protected 9595 * @static 9596 **/ 9597 Text.V_OFFSETS = {top: 0, hanging: -0.01, middle: -0.4, alphabetic: -0.8, ideographic: -0.85, bottom: -1}; 9598 9599 9600// public methods: 9601 /** 9602 * Returns true or false indicating whether the display object would be visible if drawn to a canvas. 9603 * This does not account for whether it would be visible within the boundaries of the stage. 9604 * NOTE: This method is mainly for internal use, though it may be useful for advanced uses. 9605 * @method isVisible 9606 * @return {Boolean} Whether the display object would be visible if drawn to a canvas 9607 **/ 9608 p.isVisible = function() { 9609 var hasContent = this.cacheCanvas || (this.text != null && this.text !== ""); 9610 return !!(this.visible && this.alpha > 0 && this.scaleX != 0 && this.scaleY != 0 && hasContent); 9611 }; 9612 9613 /** 9614 * Draws the Text into the specified context ignoring its visible, alpha, shadow, and transform. 9615 * Returns true if the draw was handled (useful for overriding functionality). 9616 * NOTE: This method is mainly for internal use, though it may be useful for advanced uses. 9617 * @method draw 9618 * @param {CanvasRenderingContext2D} ctx The canvas 2D context object to draw into. 9619 * @param {Boolean} ignoreCache Indicates whether the draw operation should ignore any current cache. 9620 * For example, used for drawing the cache (to prevent it from simply drawing an existing cache back 9621 * into itself). 9622 **/ 9623 p.draw = function(ctx, ignoreCache) { 9624 if (this.DisplayObject_draw(ctx, ignoreCache)) { return true; } 9625 9626 var col = this.color || "#000"; 9627 if (this.outline) { ctx.strokeStyle = col; ctx.lineWidth = this.outline*1; } 9628 else { ctx.fillStyle = col; } 9629 9630 this._drawText(this._prepContext(ctx)); 9631 return true; 9632 }; 9633 9634 /** 9635 * Returns the measured, untransformed width of the text without wrapping. Use getBounds for a more robust value. 9636 * @method getMeasuredWidth 9637 * @return {Number} The measured, untransformed width of the text. 9638 **/ 9639 p.getMeasuredWidth = function() { 9640 return this._getMeasuredWidth(this.text); 9641 }; 9642 9643 /** 9644 * Returns an approximate line height of the text, ignoring the lineHeight property. This is based on the measured 9645 * width of a "M" character multiplied by 1.2, which provides an approximate line height for most fonts. 9646 * @method getMeasuredLineHeight 9647 * @return {Number} an approximate line height of the text, ignoring the lineHeight property. This is 9648 * based on the measured width of a "M" character multiplied by 1.2, which approximates em for most fonts. 9649 **/ 9650 p.getMeasuredLineHeight = function() { 9651 return this._getMeasuredWidth("M")*1.2; 9652 }; 9653 9654 /** 9655 * Returns the approximate height of multi-line text by multiplying the number of lines against either the 9656 * <code>lineHeight</code> (if specified) or {{#crossLink "Text/getMeasuredLineHeight"}}{{/crossLink}}. Note that 9657 * this operation requires the text flowing logic to run, which has an associated CPU cost. 9658 * @method getMeasuredHeight 9659 * @return {Number} The approximate height of the untransformed multi-line text. 9660 **/ 9661 p.getMeasuredHeight = function() { 9662 return this._drawText(null,{}).height; 9663 }; 9664 9665 /** 9666 * Docced in superclass. 9667 */ 9668 p.getBounds = function() { 9669 var rect = this.DisplayObject_getBounds(); 9670 if (rect) { return rect; } 9671 if (this.text == null || this.text === "") { return null; } 9672 var o = this._drawText(null, {}); 9673 var w = (this.maxWidth && this.maxWidth < o.width) ? this.maxWidth : o.width; 9674 var x = w * Text.H_OFFSETS[this.textAlign||"left"]; 9675 var lineHeight = this.lineHeight||this.getMeasuredLineHeight(); 9676 var y = lineHeight * Text.V_OFFSETS[this.textBaseline||"top"]; 9677 return this._rectangle.setValues(x, y, w, o.height); 9678 }; 9679 9680 /** 9681 * Returns an object with width, height, and lines properties. The width and height are the visual width and height 9682 * of the drawn text. The lines property contains an array of str
9682ings, one for 9683 * each line of text that will be drawn, accounting for line breaks and wrapping. These strings have trailing 9684 * whitespace removed. 9685 * @method getMetrics 9686 * @return {Object} An object with width, height, and lines properties. 9687 **/ 9688 p.getMetrics = function() { 9689 var o = {lines:[]}; 9690 o.lineHeight = this.lineHeight || this.getMeasuredLineHeight(); 9691 o.vOffset = o.lineHeight * Text.V_OFFSETS[this.textBaseline||"top"]; 9692 return this._drawText(null, o, o.lines); 9693 }; 9694 9695 /** 9696 * Returns a clone of the Text instance. 9697 * @method clone 9698 * @return {Text} a clone of the Text instance. 9699 **/ 9700 p.clone = function() { 9701 return this._cloneProps(new Text(this.text, this.font, this.color)); 9702 }; 9703 9704 /** 9705 * Returns a string representation of this object. 9706 * @method toString 9707 * @return {String} a string representation of the instance. 9708 **/ 9709 p.toString = function() { 9710 return "[Text (text="+ (this.text.length > 20 ? this.text.substr(0, 17)+"..." : this.text) +")]"; 9711 }; 9712 9713 9714// private methods: 9715 /** 9716 * @method _cloneProps 9717 * @param {Text} o 9718 * @protected 9719 * @return {Text} o 9720 **/ 9721 p._cloneProps = function(o) { 9722 this.DisplayObject__cloneProps(o); 9723 o.textAlign = this.textAlign; 9724 o.textBaseline = this.textBaseline; 9725 o.maxWidth = this.maxWidth; 9726 o.outline = this.outline; 9727 o.lineHeight = this.lineHeight; 9728 o.lineWidth = this.lineWidth; 9729 return o; 9730 }; 9731 9732 /** 9733 * @method _getWorkingContext 9734 * @param {CanvasRenderingContext2D} ctx 9735 * @return {CanvasRenderingContext2D} 9736 * @protected 9737 **/ 9738 p._prepContext = function(ctx) { 9739 ctx.font = this.font||"10px sans-serif"; 9740 ctx.textAlign = this.textAlign||"left"; 9741 ctx.textBaseline = this.textBaseline||"top"; 9742 return ctx; 9743 }; 9744 9745 /** 9746 * Draws multiline text. 9747 * @method _drawText 9748 * @param {CanvasRenderingContext2D} ctx 9749 * @param {Object} o 9750 * @param {Array} lines 9751 * @return {Object} 9752 * @protected 9753 **/ 9754 p._drawText = function(ctx, o, lines) { 9755 var paint = !!ctx; 9756 if (!paint) { 9757 ctx = Text._workingContext; 9758 ctx.save(); 9759 this._prepContext(ctx); 9760 } 9761 var lineHeight = this.lineHeight||this.getMeasuredLineHeight(); 9762 9763 var maxW = 0, count = 0; 9764 var hardLines = String(this.text).split(/(?:\r\n|\r|\n)/); 9765 for (var i=0, l=hardLines.length; i<l; i++) { 9766 var str = hardLines[i]; 9767 var w = null; 9768 9769 if (this.lineWidth != null && (w = ctx.measureText(str).width) > this.lineWidth) { 9770 // text wrapping: 9771 var words = str.split(/(\s)/); 9772 str = words[0]; 9773 w = ctx.measureText(str).width; 9774 9775 for (var j=1, jl=words.length; j<jl; j+=2) { 9776 // Line needs to wrap: 9777 var wordW = ctx.measureText(words[j] + words[j+1]).width; 9778 if (w + wordW > this.lineWidth) { 9779 if (paint) { this._drawTextLine(ctx, str, count*lineHeight); } 9780 if (lines) { lines.push(str); } 9781 if (w > maxW) { maxW = w; } 9782 str = words[j+1]; 9783 w = ctx.measureText(str).width; 9784 count++; 9785 } else { 9786 str += words[j] + words[j+1]; 9787 w += wordW; 9788 } 9789 } 9790 } 9791 9792 if (paint) { this._drawTextLine(ctx, str, count*lineHeight); } 9793 if (lines) { lines.push(str); } 9794 if (o && w == null) { w = ctx.measureText(str).width; } 9795 if (w > maxW) { maxW = w; } 9796 count++; 9797 } 9798 9799 if (o) { 9800 o.width = maxW; 9801 o.height = count*lineHeight; 9802 } 9803 if (!paint) { ctx.restore(); } 9804 return o; 9805 }; 9806 9807 /** 9808 * @method _drawTextLine 9809 * @param {CanvasRenderingContext2D} ctx 9810 * @param {String} text 9811 * @param {Number} y 9812 * @protected 9813 **/ 9814 p._drawTextLine = function(ctx, text, y) { 9815 // Chrome 17 will fail to draw the text if the last param is included but null, so we feed it a large value instead: 9816 if (this.outline) { ctx.strokeText(text, 0, y, this.maxWidth||0xFFFF); } 9817 else { ctx.fillText(text, 0, y, this.maxWidth||0xFFFF); } 9818 }; 9819 9820 9821 /** 9822 * @method _getMeasuredWidth 9823 * @param {String} text 9824 * @protected 9825 **/ 9826 p._getMeasuredWidth = function(text) { 9827 var ctx = Text._workingContext; 9828 ctx.save(); 9829 var w = this._prepContext(ctx).measureText(text).width; 9830 ctx.restore(); 9831 return w; 9832 }; 9833 9834 9835 createjs.Text = createjs.promote(Text, "DisplayObject"); 9836}()); 9837 9838//############################################################################## 9839// BitmapText.js 9840//############################################################################## 9841 9842this.createjs = this.createjs || {}; 9843 9844(function () { 9845 "use strict"; 9846 9847 9848// constructor: 9849 /** 9850 * Displays text using bitmap glyphs defined in a sprite sheet. Multi-line text is supported 9851 * using new line characters, but automatic wrapping is not supported. See the 9852 * {{#crossLink "BitmapText/spriteSheet:property"}}{{/crossLink}} 9853 * property for more information on defining glyphs. 9854 * 9855 * <strong>Important:</strong> BitmapText extends Container, but is not designed to be used as one. 9856 * As such, methods like addChild and removeChild are disabled. 9857 * @class BitmapText
9858 * @extends DisplayObject 9859 * @param {String} [text=""] The text to display. 9860 * @param {SpriteSheet} [spriteSheet=null] The spritesheet that defines the character glyphs. 9861 * @constructor 9862 **/ 9863 function BitmapText(text, spriteSheet) { 9864 this.Container_constructor(); 9865 9866 9867 // public properties: 9868 /** 9869 * The text to display. 9870 * @property text 9871 * @type String 9872 * @default "" 9873 **/ 9874 this.text = text||""; 9875 9876 /** 9877 * A SpriteSheet instance that defines the glyphs for this bitmap text. Each glyph/character 9878 * should have a single frame animation defined in the sprite sheet named the same as 9879 * corresponding character. For example, the following animation definition: 9880 * 9881 * "A": {frames: [0]} 9882 * 9883 * would indicate that the frame at index 0 of the spritesheet should be drawn for the "A" character. The short form 9884 * is also acceptable: 9885 * 9886 * "A": 0 9887 * 9888 * Note that if a character in the text is not found in the sprite sheet, it will also 9889 * try to use the alternate case (upper or lower). 9890 * 9891 * See SpriteSheet for more information on defining sprite sheet data. 9892 * @property spriteSheet 9893 * @type SpriteSheet 9894 * @default null 9895 **/ 9896 this.spriteSheet = spriteSheet; 9897 9898 /** 9899 * The height of each line of text. If 0, then it will use a line height calculated 9900 * by checking for the height of the "1", "T", or "L" character (in that order). If 9901 * those characters are not defined, it will use the height of the first frame of the 9902 * sprite sheet. 9903 * @property lineHeight 9904 * @type Number 9905 * @default 0 9906 **/ 9907 this.lineHeight = 0; 9908 9909 /** 9910 * This spacing (in pixels) will be added after each character in the output. 9911 * @property letterSpacing 9912 * @type Number 9913 * @default 0 9914 **/ 9915 this.letterSpacing = 0; 9916 9917 /** 9918 * If a space character is not defined in the sprite sheet, then empty pixels equal to 9919 * spaceWidth will be inserted instead. If 0, then it will use a value calculated 9920 * by checking for the width of the "1", "l", "E", or "A" character (in that order). If 9921 * those characters are not defined, it will use the width of the first frame of the 9922 * sprite sheet.
9923 * @property spaceWidth 9924 * @type Number 9925 * @default 0 9926 **/ 9927 this.spaceWidth = 0; 9928 9929 9930 // private properties: 9931 /** 9932 * @property _oldProps 9933 * @type Object 9934 * @protected 9935 **/ 9936 this._oldProps = {text:0,spriteSheet:0,lineHeight:0,letterSpacing:0,spaceWidth:0}; 9937 } 9938 var p = createjs.extend(BitmapText, createjs.Container); 9939 9940 /** 9941 * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`. 9942 * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}} 9943 * for details. 9944 * 9945 * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance. 9946 * 9947 * @method initialize 9948 * @protected 9949 * @deprecated 9950 */ 9951 // p.initialize = function() {}; // searchable for devs wondering where it is. 9952 9953// static properties: 9954 /** 9955 * BitmapText uses Sprite instances to draw text. To reduce the creation and destruction of instances (and thus garbage collection), it maintains 9956 * an internal object pool of sprite instances to reuse. Increasing this value can cause more sprites to be 9957 * retained, slightly increasing memory use, but reducing instantiation. 9958 * @property maxPoolSize 9959 * @type Number 9960 * @static 9961 * @default 100 9962 **/ 9963 BitmapText.maxPoolSize = 100; 9964 9965 /** 9966 * Sprite object pool. 9967 * @type {Array} 9968 * @static 9969 * @private 9970 */ 9971 BitmapText._spritePool = []; 9972 9973 9974// public methods: 9975 /** 9976 * Docced in superclass. 9977 **/ 9978 p.draw = function(ctx, ignoreCache) { 9979 if (this.DisplayObject_draw(ctx, ignoreCache)) { return; } 9980 this._updateText(); 9981 this.Container_draw(ctx, ignoreCache); 9982 }; 9983 9984 /** 9985 * Docced in superclass. 9986 **/ 9987 p.getBounds = function() { 9988 this._updateText(); 9989 return this.Container_getBounds(); 9990 }; 9991 9992 /** 9993 * Returns true or false indicating whether the display object would be visible if drawn to a canvas. 9994 * This does not account for whether it would be visible within the boundaries of the stage. 9995 * NOTE: This method is mainly for internal use, though it may be useful for advanced uses. 9996 * @method isVisible 9997 * @return {Boolean} Boolean indicating whether the display object would be visible if drawn to a canvas 9998 **/ 9999 p.isVisible = function() { 10000 var hasContent = this.cacheCanvas || (this.spriteSheet && this.spriteSheet.complete && this.text); 10001 return !!(this.visible && this.alpha > 0 && this.scaleX !== 0 && this.scaleY !== 0 && hasContent); 10002 }; 10003 10004 p.clone = function() { 10005 return this._cloneProps(new BitmapText(this.text, this.spriteSheet)); 10006 }; 10007 10008 /** 10009 * <strong>Disabled in BitmapText.</strong> 10010 * @method addChild 10011 **/ 10012 /** 10013 * <strong>Disabled in BitmapText.</strong> 10014 * @method addChildAt 10015 **/ 10016 /** 10017 * <strong>Disabled in BitmapText.</strong> 10018 * @method removeChild 10019 **/ 10020 /** 10021 * <strong>Disabled in BitmapText.</strong> 10022 * @method removeChildAt 10023 **/ 10024 /** 10025 * <strong>Disabled in BitmapText.</strong> 10026 * @method removeAllChildren 10027 **/ 10028 p.addChild = p.addChildAt = p.removeChild = p.removeChildAt = p.removeAllChildren = function() {}; 10029 10030 10031// private methods: 10032 /** 10033 * @method _cloneProps 10034 * @param {BitmapText} o 10035 * @return {BitmapText} o 10036 * @protected 10037 **/ 10038 p._cloneProps = function(o) { 10039 this.Container__cloneProps(o); 10040 o.lineHeight = this.lineHeight; 10041 o.letterSpacing = this.letterSpacing; 10042 o.spaceWidth = this.spaceWidth; 10043 return o; 10044 }; 10045 10046 /** 10047 * @method _getFrameIndex 10048 * @param {String} character 10049 * @param {SpriteSheet} spriteSheet 10050 * @return {Number} 10051 * @protected 10052 **/ 10053 p._getFrameIndex = function(character, spriteSheet) { 10054 var c, o = spriteSheet.getAnimation(character); 10055 if (!o) { 10056 (character != (c = character.toUpperCase())) || (character != (c = character.toLowerCase())) || (c=null); 10057 if (c) { o = spriteSheet.getAnimation(c); } 10058 } 10059 return o && o.frames[0]; 10060 }; 10061 10062 /** 10063 * @method _getFrame 10064 * @param {String} character 10065 * @param {SpriteSheet} spriteSheet 10066 * @return {Object} 10067 * @protected 10068 **/ 10069 p._getFrame = function(character, spriteSheet) { 10070 var index = this._getFrameIndex(character, spriteSheet); 10071 return index == null ? index : spriteSheet.getFrame(index); 10072 }; 10073 10074 /** 10075 * @method _getLineHeight 10076 * @param {SpriteSheet} ss 10077 * @return {Number} 10078 * @protected 10079 **/ 10080 p._getLineHeight = function(ss) { 10081 var frame = this._getFrame("1",ss) || this._getFrame("T",ss) || this._getFrame("L",ss) || ss.getFrame(0); 10082 return frame ? frame.rect.height : 1; 10083 }; 10084 /**
10085 * @method _getSpaceWidth 10086 * @param {SpriteSheet} ss 10087 * @return {Number} 10088 * @protected 10089 **/ 10090 p._getSpaceWidth = function(ss) { 10091 var frame = this._getFrame("1",ss) || this._getFrame("l",ss) || this._getFrame("e",ss) || this._getFrame("a",ss) || ss.getFrame(0); 10092 return frame ? frame.rect.width : 1; 10093 }; 10094 10095 /** 10096 * @method _drawText 10097 * @protected 10098 **/ 10099 p._updateText = function() { 10100 var x=0, y=0, o=this._oldProps, change=false, spaceW=this.spaceWidth, lineH=this.lineHeight, ss=this.spriteSheet; 10101 var pool=BitmapText._spritePool, kids=this.children, childIndex=0, numKids=kids.length, sprite; 10102 10103 for (var n in o) { 10104 if (o[n] != this[n]) { 10105 o[n] = this[n]; 10106 change = true; 10107 } 10108 } 10109 if (!change) { return; } 10110 10111 var hasSpace = !!this._getFrame(" ", ss); 10112 if (!hasSpace && !spaceW) { spaceW = this._getSpaceWidth(ss); } 10113 if (!lineH) { lineH = this._getLineHeight(ss); } 10114 10115 for(var i=0, l=this.text.length; i<l; i++) { 10116 var character = this.text.charAt(i); 10117 if (character == " " && !hasSpace) { 10118 x += spaceW; 10119 continue; 10120 } else if (character=="\n" || character=="\r") { 10121 if (character=="\r" && this.text.charAt(i+1) == "\n") { i++; } // crlf 10122 x = 0; 10123 y += lineH; 10124 continue; 10125 } 10126 10127 var index = this._getFrameIndex(character, ss); 10128 if (index == null) { continue; } 10129 10130 if (childIndex < numKids) { 10131 sprite = kids[childIndex]; 10132 } else { 10133 kids.push(sprite = pool.length ? pool.pop() : new createjs.Sprite()); 10134 sprite.parent = this; 10135 numKids++; 10136 } 10137 sprite.spriteSheet = ss; 10138 sprite.gotoAndStop(index); 10139 sprite.x = x; 10140 sprite.y = y; 10141 childIndex++; 10142 10143 x += sprite.getBounds().width + this.letterSpacing; 10144 } 10145 while (numKids > childIndex) { 10146 // faster than removeChild. 10147 pool.push(sprite = kids.pop()); 10148 sprite.parent = null; 10149 numKids--; 10150 } 10151 if (pool.length > BitmapText.maxPoolSize) { pool.length = BitmapText.maxPoolSize; } 10152 }; 10153 10154 10155 createjs.BitmapText = createjs.promote(BitmapText, "Container"); 10156}()); 10157 10158//############################################################################## 10159// MovieClip.js 10160//############################################################################## 10161 10162this.createjs = this.createjs||{}; 10163 10164(function() { 10165 "use strict"; 10166 10167 10168// constructor: 10169 /** 10170 * The MovieClip class associates a TweenJS Timeline with an EaselJS {{#crossLink "Container"}}{{/crossLink}}. It allows 10171 * you to create objects which encapsulate timeline animations, state changes, and synched actions. Due to the 10172 * complexities inherent in correctly setting up a MovieClip, it is largely intended for tool output and is not included 10173 * in the main EaselJS library. 10174 * 10175 * Currently MovieClip only works properly if it is tick based (as opposed to time based) though some concessions have 10176 * been made to support time-based timelines in the future. 10177 * 10178 * <h4>Example</h4> 10179 * This example animates two shapes back and forth. The grey shape starts on the left, but we jump to a mid-point in 10180 * the animation using {{#crossLink "MovieClip/gotoAndPlay"}}{{/crossLink}}. 10181 * 10182 * var stage = new createjs.Stage("canvas"); 10183 * createjs.Ticker.addEventListener("tick", stage); 10184 * 10185 * var mc = new createjs.MovieClip(null, 0, true, {start:20}); 10186 * stage.addChild(mc); 10187 * 10188 * var child1 = new createjs.Shape( 10189 * new createjs.Graphics().beginFill("#999999") 10190 * .drawCircle(30,30,30)); 10191 * var child2 = new createjs.Shape( 10192 * new createjs.Graphics().beginFill("#5a9cfb") 10193 * .drawCircle(30,30,30)); 10194 * 10195 * mc.timeline.addTween( 10196 * createjs.Tween.get(child1) 10197 * .to({x:0}).to({x:60}, 50).to({x:0}, 50)); 10198 * mc.timeline.addTween( 10199 * createjs.Tween.get(child2) 10200 * .to({x:60}).to({x:0}, 50).to({x:60}, 50)); 10201 * 10202 * mc.gotoAndPlay("start"); 10203 * 10204 * It is recommended to use <code>tween.to()</code> to animate and set properties (use no duration to have it set 10205 * immediately), and the <code>tween.wait()</code> method to create delays between animations. Note that using the 10206 * <code>tween.set()</code> method to affect properties will likely not provide the desired result. 10207 * 10208 * @class MovieClip 10209 * @main MovieClip 10210 * @extends Container 10211 * @constructor 10212 * @param {String} [mode=independent] Initial value for the mode property. One of {{#crossLink "MovieClip/INDEPENDENT:property"}}{{/crossLink}}, 10213 * {{#crossLink "MovieClip/SINGLE_FRAME:property"}}{{/crossLink}}, or {{#crossLink "MovieClip/SYNCHED:property"}}{{/crossLink}}. 10214 * The default is {{#crossLink "MovieClip/INDEPENDENT:property"}}{{/crossLink}}. 10215 * @param {Number} [startPosition=0] Initial value for the {{#crossLink "MovieClip/startPosition:property"}}{{/crossLink}} 10216 * property. 10217 * @param {Boolean} [loop=true] Initial value for the {{#crossLink "MovieClip/loop:property"}}{{/crossLink}} 10218 * property. The default is `true`. 10219 * @param {Object} [labels=null] A hash of labels to pass to the {{#crossLink "MovieClip/timeline:property"}}{{/crossLink}} 10220 * instance associated with this MovieClip. Labels only need to be passed if they need to be used. 10221 **/ 10222 function MovieClip(mode, startPosition, loop, labels) {
10223 this.Container_constructor(); 10224 !MovieClip.inited&&MovieClip.init(); // static init 10225 10226 10227 // public properties: 10228 /** 10229 * Controls how this MovieClip advances its time. Must be one of 0 (INDEPENDENT), 1 (SINGLE_FRAME), or 2 (SYNCHED). 10230 * See each constant for a description of the behaviour. 10231 * @property mode 10232 * @type String 10233 * @default null 10234 **/ 10235 this.mode = mode||MovieClip.INDEPENDENT; 10236 10237 /** 10238 * Specifies what the first frame to play in this movieclip, or the only frame to display if mode is SINGLE_FRAME. 10239 * @property startPosition 10240 * @type Number 10241 * @default 0 10242 */ 10243 this.startPosition = startPosition || 0; 10244 10245 /** 10246 * Indicates whether this MovieClip should loop when it reaches the end of its timeline. 10247 * @property loop 10248 * @type Boolean 10249 * @default true 10250 */ 10251 this.loop = loop; 10252 10253 /** 10254 * The current frame of the movieclip. 10255 * @property currentFrame 10256 * @type Number 10257 * @default 0 10258 * @readonly 10259 */ 10260 this.currentFrame = 0; 10261 10262 /** 10263 * The TweenJS Timeline that is associated with this MovieClip. This is created automatically when the MovieClip 10264 * instance is initialized. Animations are created by adding <a href="http://tweenjs.com">TweenJS</a> Tween 10265 * instances to the timeline. 10266 * 10267 * <h4>Example</h4> 10268 * 10269 * var tween = createjs.Tween.get(target).to({x:0}).to({x:100}, 30); 10270 * var mc = new createjs.MovieClip(); 10271 * mc.timeline.addTween(tween); 10272 * 10273 * Elements can be added and removed from the timeline by toggling an "_off" property 10274 * using the <code>tweenInstance.to()</code> method. Note that using <code>Tween.set</code> is not recommended to 10275 * create MovieClip animations. The following example will toggle the target off on frame 0, and then back on for 10276 * frame 1. You can use the "visible" property to achieve the same effect. 10277 * 10278 * var tween = createjs.Tween.get(target).to({_off:false}) 10279 * .wait(1).to({_off:true}) 10280 * .wait(1).to({_off:false}); 10281 * 10282 * @property timeline 10283 * @type Timeline 10284 * @default null 10285 */ 10286 this.timeline = new createjs.Timeline(null, labels, {paused:true, position:startPosition, useTicks:true}); 10287 10288 /** 10289 * If true, the MovieClip's position will not advance when ticked. 10290 * @property paused 10291 * @type Boolean 10292 * @default false 10293 */ 10294 this.paused = false; 10295 10296 /** 10297 * If true, actions in this MovieClip's tweens will be run when the playhead advances. 10298 * @property actionsEnabled 10299 * @type Boolean 10300 * @default true 10301 */ 10302 this.actionsEnabled = true; 10303 10304 /** 10305 * If true, the MovieClip will automatically be reset to its first frame whenever the timeline adds 10306 * it back onto the display list. This only applies to MovieClip instances with mode=INDEPENDENT. 10307 * <br><br> 10308 * For example, if you had a character animation with a "body" child MovieClip instance 10309 * with different costumes on each frame, you could set body.autoReset = false, so that 10310 * you can manually change the frame it is on, without worrying that it will be reset 10311 * automatically. 10312 * @property autoReset 10313 * @type Boolean 10314 * @default true 10315 */ 10316 this.autoReset = true; 10317 10318 /** 10319 * An array of bounds for each frame in the MovieClip. This is mainly intended for tool output. 10320 * @property frameBounds 10321 * @type Array 10322 * @default null 10323 */ 10324 this.frameBounds = this.frameBounds||null; // TODO: Deprecated. This is for backwards support of FlashCC 10325 10326 /** 10327 * By default MovieClip instances advance one frame per tick. Specifying a framerate for the MovieClip 10328 * will cause it to advance based on elapsed time between ticks as appropriate to maintain the target 10329 * framerate. 10330 * 10331 * For example, if a MovieClip with a framerate of 10 is placed on a Stage being updated at 40fps, then the MovieClip will 10332 * advance roughly one frame every 4 ticks. This will not be exact, because the time between each tick will 10333 * vary slightly between frames. 10334 * 10335 * This feature is dependent on the tick event object (or an object with an appropriate "delta" property) being 10336 * passed into {{#crossLink "Stage/update"}}{{/crossLink}}. 10337 * @property framerate 10338 * @type {Number} 10339 * @default null 10340 **/ 10341 this.framerate = null; 10342 10343 10344 // private properties: 10345 /** 10346 * @property _synchOffset 10347 * @type Number 10348 * @default 0 10349 * @private 10350 */ 10351 this._synchOffset = 0; 10352 10353 /** 10354 * @property _prevPos 10355 * @type Number 10356 * @default -1 10357 * @private 10358 */ 10359 this._prevPos = -1; // TODO: evaluate using a ._reset Boolean prop instead of -1. 10360 10361 /** 10362 * @property _prevPosition 10363 * @type Number 10364 * @default 0 10365 * @private 10366 */ 10367 this._prevPosition = 0; 10368 10369 /** 10370 * The time remaining from the previous tick, only applicable when .framerate is set. 10371 * @property _t 10372 * @type Number 10373 * @private 10374 */ 10375 this._t = 0; 10376 10377 /** 10378 * List of display objects that are actively being managed by the MovieClip. 10379 * @property _managed 10380 * @type Object 10381 * @private 10382 */ 10383 this._managed = {}; 10384 }
10385 var p = createjs.extend(MovieClip, createjs.Container); 10386 10387 10388// constants: 10389 /** 10390 * The MovieClip will advance independently of its parent, even if its parent is paused. 10391 * This is the default mode. 10392 * @property INDEPENDENT 10393 * @static 10394 * @type String 10395 * @default "independent" 10396 * @readonly 10397 **/ 10398 MovieClip.INDEPENDENT = "independent"; 10399 10400 /** 10401 * The MovieClip will only display a single frame (as determined by the startPosition property). 10402 * @property SINGLE_FRAME 10403 * @static 10404 * @type String 10405 * @default "single" 10406 * @readonly 10407 **/ 10408 MovieClip.SINGLE_FRAME = "single"; 10409 10410 /** 10411 * The MovieClip will be advanced only when its parent advances and will be synched to the position of 10412 * the parent MovieClip. 10413 * @property SYNCHED 10414 * @static 10415 * @type String 10416 * @default "synched" 10417 * @readonly 10418 **/ 10419 MovieClip.SYNCHED = "synched"; 10420 10421 10422// static properties: 10423 MovieClip.inited = false; 10424 10425 10426// static methods: 10427 MovieClip.init = function() { 10428 if (MovieClip.inited) { return; } 10429 // plugins introduce some overhead to Tween, so we only install this if an MC is instantiated. 10430 MovieClipPlugin.install(); 10431 MovieClip.inited = true; 10432 }; 10433 10434 10435// getter / setters: 10436 /** 10437 * Use the {{#crossLink "MovieClip/labels:property"}}{{/crossLink}} property instead. 10438 * @method getLabels 10439 * @return {Array} 10440 * @deprecated 10441 **/ 10442 p.getLabels = function() { 10443 return this.timeline.getLabels(); 10444 }; 10445 10446 /** 10447 * Use the {{#crossLink "MovieClip/currentLabel:property"}}{{/crossLink}} property instead. 10448 * @method getCurrentLabel 10449 * @return {String} 10450 * @deprecated 10451 **/ 10452 p.getCurrentLabel = function() { 10453 this._updateTimeline(); 10454 return this.timeline.getCurrentLabel(); 10455 }; 10456 10457 /** 10458 * Use the {{#crossLink "MovieClip/duration:property"}}{{/crossLink}} property instead. 10459 * @method getDuration 10460 * @return {Number} 10461 * @protected 10462 **/ 10463 p.getDuration = function() { 10464 return this.timeline.duration; 10465 }; 10466 10467 /** 10468 * Returns an array of objects with label and position (aka frame) properties, sorted by position. 10469 * Shortcut to TweenJS: Timeline.getLabels(); 10470 * @property labels 10471 * @type {Array} 10472 * @readonly 10473 **/ 10474 10475 /** 10476 * Returns the name of the label on or immediately before the current frame. See TweenJS: Timeline.getCurrentLabel() 10477 * for more information. 10478 * @property currentLabel 10479 * @type {String} 10480 * @readonly 10481 **/ 10482 10483 /** 10484 * Returns the duration of this MovieClip in seconds or ticks. Identical to {{#crossLink "MovieClip/duration:property"}}{{/crossLink}} 10485 * and provided for Flash API compatibility. 10486 * @property totalFrames 10487 * @type {Number} 10488 * @readonly 10489 **/ 10490 10491 /** 10492 * Returns the duration of this MovieClip in seconds or ticks. 10493 * @property duration 10494 * @type {Number} 10495 * @readonly 10496 **/ 10497 try { 10498 Object.defineProperties(p, { 10499 labels: { get: p.getLabels }, 10500 currentLabel: { get: p.getCurrentLabel }, 10501 totalFrames: { get: p.getDuration }, 10502 duration: { get: p.getDuration } 10503 }); 10504 } catch (e) {} 10505 10506 10507// public methods: 10508 /** 10509 * Constructor alias for backwards compatibility. This method will be removed in future versions. 10510 * Subclasses should be updated to use {{#crossLink "Utility Methods/extends"}}{{/crossLink}}. 10511 * @method initialize 10512 * @deprecated in favour of `createjs.promote()` 10513 **/ 10514 p.initialize = MovieClip; // TODO: Deprecated. This is for backwards support of FlashCC 10515 10516 /** 10517 * Returns true or false indicating whether the display object would be visible if drawn to a canvas. 10518 * This does not account for whether it would be visible within the boundaries of the stage. 10519 * NOTE: This method is mainly for internal use, though it may be useful for advanced uses. 10520 * @method isVisible 10521 * @return {Boolean} Boolean indicating whether the display object would be visible if drawn to a canvas 10522 **/ 10523 p.isVisible = function() { 10524 // children are placed in draw, so we can't determine if we have content. 10525 return !!(this.visible && this.alpha > 0 && this.scaleX != 0 && this.scaleY != 0); 10526 }; 10527 10528 /** 10529 * Draws the display object into the specified context ignoring its visible, alpha, shadow, and transform. 10530 * Returns true if the draw was handled (useful for overriding functionality). 10531 * NOTE: This method is mainly for internal use, though it may be useful for advanced uses. 10532 * @method draw 10533 * @param {CanvasRenderingContext2D} ctx The canvas 2D context object to draw into. 10534 * @param {Boolean} ignoreCache Indicates whether the draw operation should ignore any current cache. 10535 * For example, used for drawing the cache (to prevent it from simply drawing an existing cache back 10536 * into itself). 10537 **/ 10538 p.draw = function(ctx, ignoreCache) { 10539 // draw to cache first: 10540 if (this.DisplayObject_draw(ctx, ignoreCache)) { return true; } 10541 this._updateTimeline(); 10542 this.Container_draw(ctx, ignoreCache); 10543 return true; 10544 }; 10545 10546 /**
10547 * Sets paused to false. 10548 * @method play 10549 **/ 10550 p.play = function() { 10551 this.paused = false; 10552 }; 10553 10554 /** 10555 * Sets paused to true. 10556 * @method stop 10557 **/ 10558 p.stop = function() { 10559 this.paused = true; 10560 }; 10561 10562 /** 10563 * Advances this movie clip to the specified position or label and sets paused to false. 10564 * @method gotoAndPlay 10565 * @param {String|Number} positionOrLabel The animation name or frame number to go to. 10566 **/ 10567 p.gotoAndPlay = function(positionOrLabel) { 10568 this.paused = false; 10569 this._goto(positionOrLabel); 10570 }; 10571 10572 /** 10573 * Advances this movie clip to the specified position or label and sets paused to true. 10574 * @method gotoAndStop 10575 * @param {String|Number} positionOrLabel The animation or frame name to go to. 10576 **/ 10577 p.gotoAndStop = function(positionOrLabel) { 10578 this.paused = true; 10579 this._goto(positionOrLabel); 10580 }; 10581 10582 /** 10583 * Advances the playhead. This occurs automatically each tick by default. 10584 * @param [time] {Number} The amount of time in ms to advance by. Only applicable if framerate is set. 10585 * @method advance 10586 */ 10587 p.advance = function(time) { 10588 // TODO: should we worry at all about clips who change their own modes via frame scripts? 10589 var independent = MovieClip.INDEPENDENT; 10590 if (this.mode != independent) { return; } 10591 10592 var o=this, fps = o.framerate; 10593 while ((o = o.parent) && fps == null) { 10594 if (o.mode == independent) { fps = o._framerate; } 10595 } 10596 this._framerate = fps; 10597 10598 var t = (fps != null && fps != -1 && time != null) ? time/(1000/fps) + this._t : 1; 10599 var frames = t|0; 10600 this._t = t-frames; // leftover time 10601 10602 while (!this.paused && frames--) { 10603 this._prevPosition = (this._prevPos < 0) ? 0 : this._prevPosition+1; 10604 this._updateTimeline(); 10605 } 10606 }; 10607 10608 /** 10609 * MovieClip instances cannot be cloned. 10610 * @method clone 10611 **/ 10612 p.clone = function() { 10613 // TODO: add support for this? Need to clone the Timeline & retarget tweens - pretty complex. 10614 throw("MovieClip cannot be cloned.") 10615 }; 10616 10617 /** 10618 * Returns a string representation of this object. 10619 * @method toString 10620 * @return {String} a string representation of the instance. 10621 **/ 10622 p.toString = function() { 10623 return "[MovieClip (name="+ this.name +")]"; 10624 }; 10625 10626 10627// private methods: 10628 /** 10629 * @method _tick 10630 * @param {Object} evtObj An event object that will be dispatched to all tick listeners. This object is reused between dispatchers to reduce construction & GC costs. 10631 * function. 10632 * @protected 10633 **/ 10634 p._tick = function(evtObj) { 10635 this.advance(evtObj&&evtObj.delta); 10636 this.Container__tick(evtObj); 10637 }; 10638 10639 /** 10640 * @method _goto 10641 * @param {String|Number} positionOrLabel The animation name or frame number to go to. 10642 * @protected 10643 **/ 10644 p._goto = function(positionOrLabel) { 10645 var pos = this.timeline.resolve(positionOrLabel); 10646 if (pos == null) { return; } 10647 // prevent _updateTimeline from overwriting the new position because of a reset: 10648 if (this._prevPos == -1) { this._prevPos = NaN; } 10649 this._prevPosition = pos; 10650 this._t = 0; 10651 this._updateTimeline(); 10652 }; 10653 10654 /** 10655 * @method _reset 10656 * @private 10657 **/ 10658 p._reset = function() { 10659 this._prevPos = -1; 10660 this._t = this.currentFrame = 0; 10661 this.paused = false; 10662 }; 10663 10664 /** 10665 * @method _updateTimeline 10666 * @protected 10667 **/ 10668 p._updateTimeline = function() { 10669 var tl = this.timeline; 10670 var synched = this.mode != MovieClip.INDEPENDENT; 10671 tl.loop = (this.loop==null) ? true : this.loop; 10672 10673 var pos = synched ? this.startPosition + (this.mode==MovieClip.SINGLE_FRAME?0:this._synchOffset) : (this._prevPos < 0 ? 0 : this._prevPosition); 10674 var mode = synched || !this.actionsEnabled ? createjs.Tween.NONE : null; 10675 10676 // pre-assign currentFrame so it is available to frame scripts: 10677 this.currentFrame = tl._calcPosition(pos); 10678 10679 // update timeline position, ignoring actions if this is a graphic. 10680 tl.setPosition(pos, mode); 10681 10682 this._prevPosition = tl._prevPosition; 10683 if (this._prevPos == tl._prevPos) { return; } 10684 this.currentFrame = this._prevPos = tl._prevPos; 10685 10686 for (var n in this._managed) { this._managed[n] = 1; } 10687 10688 var tweens = tl._tweens; 10689 for (var i=0, l=tweens.length; i<l; i++) { 10690 var tween = tweens[i]; 10691 var target = tween._target; 10692 if (target == this || tween.passive) { continue; } // TODO: this assumes actions tween has this as the target. Valid? 10693 var offset = tween._stepPosition; 10694 10695 if (target instanceof createjs.DisplayObject) { 10696 // motion tween. 10697 this._addManagedChild(target, offset); 10698 } else { 10699 // state tween. 10700 this._setState(target.state, offset); 10701 } 10702 } 10703 10704 var kids = this.children; 10705 for (i=kids.length-1; i>=0; i--) { 10706 var id = kids[i].id; 10707 if (this._managed[id] == 1) { 10708 this.removeChildAt(i); 10709 delete(this._managed[id]); 10710 } 10711 } 10712 }; 10713 10714 /** 10715 * @method _setState 10716 * @param {Array} state 10717 * @param {Number} offset 10718 * @protected 10719 **/ 10720 p._setState = function(state, offset) { 10721 if (!state) { return; } 10722 for (var i=state.length-1;i>=0;i--) { 10723 var o = state[i]; 10724 var target = o.t; 10725 var props = o.p; 10726 for (var n in props) { target[n] = props[n]; } 10727 this._addManagedChild(target, offset); 10728 } 10729 }; 10730 10731 /** 10732 * Adds a child to the timeline, and sets it up as a managed child. 10733 * @method _addManagedChild 10734 * @param {MovieClip} child The child MovieClip to manage 10735 * @param {Number} offset 10736 * @private 10737 **/ 10738 p._addManagedChild = function(child, offset) { 10739 if (child._off) { return; } 10740 this.addChildAt(child,0); 10741 10742 if (child instanceof MovieClip) { 10743 child._synchOffset = offset; 10744 // TODO: this does not precisely match Flash. Flash loses track of the clip if it is renamed or removed from the timeline, which causes it to reset. 10745 if (child.mode == MovieClip.INDEPENDENT && child.autoReset && !this._managed[child.id]) { child._reset(); } 10746 } 10747 this._managed[child.id] = 2; 10748 }; 10749 10750 /** 10751 * @method _getBounds 10752 * @param {Matrix2D} matrix 10753 * @param {Boolean} ignoreTransform 10754 * @return {Rectangle} 10755 * @protected 10756 **/ 10757 p._getBounds = function(matrix, ignoreTransform) { 10758 var bounds = this.DisplayObject_getBounds(); 10759 if (!bounds) { 10760 this._updateTimeline(); 10761 if (this.frameBounds) { bounds = this._rectangle.copy(this.frameBounds[this.currentFrame]); } 10762 } 10763 if (bounds) { return this._transformBounds(bounds, matrix, ignoreTransform); } 10764 return this.Container__getBounds(matrix, ignoreTransform); 10765 }; 10766 10767 10768 createjs.MovieClip = createjs.promote(MovieClip, "Container"); 10769 10770 10771 10772// MovieClipPlugin for TweenJS:
10773 /** 10774 * This plugin works with <a href="http://tweenjs.com" target="_blank">TweenJS</a> to prevent the startPosition 10775 * property from tweening. 10776 * @private 10777 * @class MovieClipPlugin 10778 * @constructor 10779 **/ 10780 function MovieClipPlugin() { 10781 throw("MovieClipPlugin cannot be instantiated.") 10782 } 10783 10784 /** 10785 * @method priority 10786 * @private 10787 **/ 10788 MovieClipPlugin.priority = 100; // very high priority, should run first 10789 10790 /** 10791 * @method install 10792 * @private 10793 **/ 10794 MovieClipPlugin.install = function() { 10795 createjs.Tween.installPlugin(MovieClipPlugin, ["startPosition"]); 10796 }; 10797 10798 /** 10799 * @method init 10800 * @param {Tween} tween 10801 * @param {String} prop 10802 * @param {String|Number|Boolean} value 10803 * @private 10804 **/ 10805 MovieClipPlugin.init = function(tween, prop, value) { 10806 return value; 10807 }; 10808 10809 /** 10810 * @method step 10811 * @private 10812 **/ 10813 MovieClipPlugin.step = function() { 10814 // unused. 10815 }; 10816 10817 /** 10818 * @method tween 10819 * @param {Tween} tween 10820 * @param {String} prop 10821 * @param {String | Number | Boolean} value 10822 * @param {Array} startValues 10823 * @param {Array} endValues 10824 * @param {Number} ratio 10825 * @param {Object} wait 10826 * @param {Object} end 10827 * @return {*} 10828 */ 10829 MovieClipPlugin.tween = function(tween, prop, value, startValues, endValues, ratio, wait, end) { 10830 if (!(tween.target instanceof MovieClip)) { return value; } 10831 return (ratio == 1 ? endValues[prop] : startValues[prop]); 10832 }; 10833 10834}()); 10835 10836//############################################################################## 10837// SpriteSheetUtils.js 10838//############################################################################## 10839 10840this.createjs = this.createjs||{}; 10841 10842(function() { 10843 "use strict"; 10844 10845 10846// constructor: 10847 /** 10848 * The SpriteSheetUtils class is a collection of static methods for working with {{#crossLink "SpriteSheet"}}{{/crossLink}}s. 10849 * A sprite sheet is a series of images (usually animation frames) combined into a single image on a regular grid. For 10850 * example, an animation consisting of 8 100x100 images could be combined into a 400x200 sprite sheet (4 frames across 10851 * by 2 high). The SpriteSheetUtils class uses a static interface and should not be instantiated. 10852 * @class SpriteSheetUtils 10853 * @static 10854 **/ 10855 function SpriteSheetUtils() { 10856 throw "SpriteSheetUtils cannot be instantiated"; 10857 } 10858 10859 10860// private static properties: 10861 /** 10862 * @property _workingCanvas 10863 * @static 10864 * @type HTMLCanvasElement | Object 10865 * @protected 10866 */ 10867 /** 10868 * @property _workingContext 10869 * @static 10870 * @type CanvasRenderingContext2D 10871 * @protected 10872 */ 10873 var canvas = (createjs.createCanvas?createjs.createCanvas():document.createElement("canvas")); 10874 if (canvas.getContext) { 10875 SpriteSheetUtils._workingCanvas = canvas; 10876 SpriteSheetUtils._workingContext = canvas.getContext("2d"); 10877 canvas.width = canvas.height = 1; 10878 } 10879 10880 10881// public static methods: 10882 /** 10883 * <b>This is an experimental method, and may be buggy. Please report issues.</b><br/><br/> 10884 * Extends the existing sprite sheet by flipping the original frames horizontally, vertically, or both, 10885 * and adding appropriate animation & frame data. The flipped animations will have a suffix added to their names 10886 * (_h, _v, _hv as appropriate). Make sure the sprite sheet images are fully loaded before using this method. 10887 * <br/><br/> 10888 * For example:<br/> 10889 * SpriteSheetUtils.addFlippedFrames(mySpriteSheet, true, true); 10890 * The above would add frames that are flipped horizontally AND frames that are flipped vertically. 10891 * <br/><br/> 10892 * Note that you can also flip any display object by setting its scaleX or scaleY to a negative value. On some 10893 * browsers (especially those without hardware accelerated canvas) this can result in slightly degraded performance, 10894 * which is why addFlippedFrames is available. 10895 * @method addFlippedFrames 10896 * @static 10897 * @param {SpriteSheet} spriteSheet 10898 * @param {Boolean} horizontal If true, horizontally flipped frames will be added. 10899 * @param {Boolean} vertical If true, vertically flipped frames will be added. 10900 * @param {Boolean} both If true, frames that are flipped both horizontally and vertically will be added. 10901 * @deprecated Modern browsers perform better when flipping via a transform (ex. scaleX=-1) rendering this obsolete. 10902 **/ 10903 SpriteSheetUtils.addFlippedFrames = function(spriteSheet, horizontal, vertical, both) { 10904 if (!horizontal && !vertical && !both) { return; } 10905 10906 var count = 0; 10907 if (horizontal) { SpriteSheetUtils._flip(spriteSheet,++count,true,false); } 10908 if (vertical) { SpriteSheetUtils._flip(spriteSheet,++count,false,true); } 10909 if (both) { SpriteSheetUtils._flip(spriteSheet,++count,true,true); } 10910 }; 10911 10912 /** 10913 * Returns a single frame of the specified sprite sheet as a new PNG image. An example of when this may be useful is 10914 * to use a spritesheet frame as the source for a bitmap fill. 10915 * 10916 * <strong>WARNING:</strong> In almost all cases it is better to display a single frame using a {{#crossLink "Sprite"}}{{/crossLink}} 10917 * with a {{#crossLink "Sprite/gotoAndStop"}}{{/crossLink}} call than it is to slice out a frame using this 10918 * method and display it with a Bitmap instance. You can also crop an image using the {{#crossLink "Bitmap/sourceRect"}}{{/crossLink}} 10919 * property of {{#crossLink "Bitmap"}}{{/crossLink}}. 10920 * 10921 * The extractFrame method may cause cross-domain warnings since it accesses pixels directly on the canvas. 10922 * @method extractFrame 10923 * @static 10924 * @param {SpriteSheet} spriteSheet The SpriteSheet instance to extract a frame from. 10925 * @param {Number|String} frameOrAnimation The frame number or animation name to extract. If an animation 10926 * name is specified, only the first frame of the animation will be extracted. 10927 * @return {HTMLImageElement} a single frame of the specified sprite sheet as a new PNG image. 10928 */ 10929 SpriteSheetUtils.extractFrame = function(spriteSheet, frameOrAnimation) { 10930 if (isNaN(frameOrAnimation)) { 10931 frameOrAnimation = spriteSheet.getAnimation(frameOrAnimation).frames[0]; 10932 } 10933 var data = spriteSheet.getFrame(frameOrAnimation); 10934 if (!data) { return null; } 10935 var r = data.rect; 10936 var canvas = SpriteSheetUtils._workingCanvas; 10937 canvas.width = r.width;
10938 canvas.height = r.height; 10939 SpriteSheetUtils._workingContext.drawImage(data.image, r.x, r.y, r.width, r.height, 0, 0, r.width, r.height); 10940 var img = document.createElement("img"); 10941 img.src = canvas.toDataURL("image/png"); 10942 return img; 10943 }; 10944 10945 /** 10946 * Merges the rgb channels of one image with the alpha channel of another. This can be used to combine a compressed 10947 * JPEG image containing color data with a PNG32 monochromatic image containing alpha data. With certain types of 10948 * images (those with detail that lend itself to JPEG compression) this can provide significant file size savings 10949 * versus a single RGBA PNG32. This method is very fast (generally on the order of 1-2 ms to run). 10950 * @method mergeAlpha 10951 * @static 10952 * @param {HTMLImageElement} rbgImage The image (or canvas) containing the RGB channels to use. 10953 * @param {HTMLImageElement} alphaImage The image (or canvas) containing the alpha channel to use. 10954 * @param {HTMLCanvasElement} canvas Optional. If specified, this canvas will be used and returned. If not, a new canvas will be created. 10955 * @return {HTMLCanvasElement} A canvas with the combined image data. This can be used as a source for Bitmap or SpriteSheet. 10956 * @deprecated Tools such as ImageAlpha generally provide better results. This will be moved to sandbox in the future. 10957 */ 10958 SpriteSheetUtils.mergeAlpha = function(rgbImage, alphaImage, canvas) { 10959 if (!canvas) { canvas = createjs.createCanvas?createjs.createCanvas():document.createElement("canvas"); } 10960 canvas.width = Math.max(alphaImage.width, rgbImage.width); 10961 canvas.height = Math.max(alphaImage.height, rgbImage.height); 10962 var ctx = canvas.getContext("2d"); 10963 ctx.save(); 10964 ctx.drawImage(rgbImage,0,0); 10965 ctx.globalCompositeOperation = "destination-in"; 10966 ctx.drawImage(alphaImage,0,0); 10967 ctx.restore(); 10968 return canvas; 10969 }; 10970 10971 10972// private static methods: 10973 SpriteSheetUtils._flip = function(spriteSheet, count, h, v) { 10974 var imgs = spriteSheet._images; 10975 var canvas = SpriteSheetUtils._workingCanvas; 10976 var ctx = SpriteSheetUtils._workingContext; 10977 var il = imgs.length/count; 10978 for (var i=0;i<il;i++) { 10979 var src = imgs[i]; 10980 src.__tmp = i; // a bit hacky, but faster than doing indexOf below. 10981 ctx.setTransform(1,0,0,1,0,0); 10982 ctx.clearRect(0,0,canvas.width+1,canvas.height+1); 10983 canvas.width = src.width; 10984 canvas.height = src.height; 10985 ctx.setTransform(h?-1:1, 0, 0, v?-1:1, h?src.width:0, v?src.height:0); 10986 ctx.drawImage(src,0,0); 10987 var img = document.createElement("img"); 10988 img.src = canvas.toDataURL("image/png"); 10989 // work around a strange bug in Safari: 10990 img.width = src.width; 10991 img.height = src.height; 10992 imgs.push(img); 10993 } 10994 10995 var frames = spriteSheet._frames; 10996 var fl = frames.length/count; 10997 for (i=0;i<fl;i++) { 10998 src = frames[i]; 10999 var rect = src.rect.clone(); 11000 img = imgs[src.image.__tmp+il*count]; 11001
11002 var frame = {image:img,rect:rect,regX:src.regX,regY:src.regY}; 11003 if (h) { 11004 rect.x = img.width-rect.x-rect.width; // update rect 11005 frame.regX = rect.width-src.regX; // update registration point 11006 } 11007 if (v) { 11008 rect.y = img.height-rect.y-rect.height; // update rect 11009 frame.regY = rect.height-src.regY; // update registration point 11010 } 11011 frames.push(frame); 11012 } 11013 11014 var sfx = "_"+(h?"h":"")+(v?"v":""); 11015 var names = spriteSheet._animations; 11016 var data = spriteSheet._data; 11017 var al = names.length/count; 11018 for (i=0;i<al;i++) { 11019 var name = names[i]; 11020 src = data[name]; 11021 var anim = {name:name+sfx,speed:src.speed,next:src.next,frames:[]}; 11022 if (src.next) { anim.next += sfx; } 11023 frames = src.frames; 11024 for (var j=0,l=frames.length;j<l;j++) { 11025 anim.frames.push(frames[j]+fl*count); 11026 } 11027 data[anim.name] = anim; 11028 names.push(anim.name); 11029 } 11030 }; 11031 11032 11033 createjs.SpriteSheetUtils = SpriteSheetUtils; 11034}()); 11035 11036//############################################################################## 11037// SpriteSheetBuilder.js 11038//############################################################################## 11039 11040this.createjs = this.createjs||{}; 11041 11042(function() { 11043 "use strict"; 11044 11045 11046// constructor: 11047 /** 11048 * The SpriteSheetBuilder allows you to generate {{#crossLink "SpriteSheet"}}{{/crossLink}} instances at run time 11049 * from any display object. This can allow you to maintain your assets as vector graphics (for low file size), and 11050 * render them at run time as SpriteSheets for better performance. 11051 * 11052 * SpriteSheets can be built either synchronously, or asynchronously, so that large SpriteSheets can be generated 11053 * without locking the UI. 11054 * 11055 * Note that the "images" used in the generated SpriteSheet are actually canvas elements, and that they will be 11056 * sized to the nearest power of 2 up to the value of {{#crossLink "SpriteSheetBuilder/maxWidth:property"}}{{/crossLink}} 11057 * or {{#crossLink "SpriteSheetBuilder/maxHeight:property"}}{{/crossLink}}. 11058 * @class SpriteSheetBuilder 11059 * @param {Number} [framerate=0] The {{#crossLink "SpriteSheet/framerate:property"}}{{/crossLink}} of 11060 * {{#crossLink "SpriteSheet"}}{{/crossLink}} instances that are created. 11061 * @extends EventDispatcher 11062 * @constructor 11063 **/ 11064 function SpriteSheetBuilder(framerate) { 11065 this.EventDispatcher_constructor(); 11066 11067 // public properties: 11068 /** 11069 * The maximum width for the images (not individual frames) in the generated SpriteSheet. It is recommended to 11070 * use a power of 2 for this value (ex. 1024, 2048, 4096). If the frames cannot all fit within the max 11071 * dimensions, then additional images will be created as needed. 11072 * @property maxWidth 11073 * @type Number 11074 * @default 2048 11075 */ 11076 this.maxWidth = 2048; 11077 11078 /** 11079 * The maximum height for the images (not individual frames) in the generated SpriteSheet. It is recommended to 11080 * use a power of 2 for this value (ex. 1024, 2048, 4096). If the frames cannot all fit within the max 11081 * dimensions, then additional images will be created as needed. 11082 * @property maxHeight 11083 * @type Number 11084 * @default 2048 11085 **/ 11086 this.maxHeight = 2048; 11087 11088 /** 11089 * The SpriteSheet that was generated. This will be null before a build is completed successfully. 11090 * @property spriteSheet 11091 * @type SpriteSheet 11092 **/ 11093 this.spriteSheet = null; 11094 11095 /** 11096 * The scale to apply when drawing all frames to the SpriteSheet. This is multiplied against any scale specified 11097 * in the addFrame call. This can be used, for example, to generate a SpriteSheet at run time that is tailored 11098 * to the a specific device resolution (ex. tablet vs mobile). 11099 * @property scale 11100 * @type Number 11101 * @default 1 11102 **/ 11103 this.scale = 1; 11104 11105 /** 11106 * The padding to use between frames. This is helpful to preserve antialiasing on drawn vector content. 11107 * @property padding 11108 * @type Number 11109 * @default 1 11110 **/ 11111 this.padding = 1; 11112 11113 /** 11114 * A number from 0.01 to 0.99 that indicates what percentage of time the builder can use. This can be 11115 * thought of as the number of seconds per second the builder will use. For example, with a timeSlice value of 0.3, 11116 * the builder will run 20 times per second, using approximately 15ms per build (30% of available time, or 0.3s per second). 11117 * Defaults to 0.3. 11118 * @property timeSlice 11119 * @type Number 11120 * @default 0.3 11121 **/ 11122 this.timeSlice = 0.3; 11123 11124 /** 11125 * A value between 0 and 1 that indicates the progress of a build, or -1 if a build has not 11126 * been initiated. 11127 * @property progress 11128 * @type Number 11129 * @default -1 11130 * @readonly 11131 */ 11132 this.progress = -1; 11133 11134 /** 11135 * A {{#crossLink "SpriteSheet/framerate:property"}}{{/crossLink}}
11135 value that will be passed to new {{#crossLink "SpriteSheet"}}{{/crossLink}} instances that are 11136 * created. If no framerate is specified (or it is 0), then SpriteSheets will use the {{#crossLink "Ticker"}}{{/crossLink}} 11137 * framerate. 11138 * @property framerate 11139 * @type Number 11140 * @default 0 11141 */ 11142 this.framerate = framerate || 0; 11143 11144 11145 // private properties: 11146 /** 11147 * @property _frames 11148 * @protected 11149 * @type Array 11150 **/ 11151 this._frames = []; 11152 11153 /** 11154 * @property _animations 11155 * @protected 11156 * @type Array 11157 **/ 11158 this._animations = {}; 11159 11160 /** 11161 * @property _data 11162 * @protected 11163 * @type Array 11164 **/ 11165 this._data = null; 11166 11167 /** 11168 * @property _nextFrameIndex 11169 * @protected 11170 * @type Number 11171 **/ 11172 this._nextFrameIndex = 0; 11173 11174 /** 11175 * @property _index 11176 * @protected 11177 * @type Number 11178 **/ 11179 this._index = 0; 11180 11181 /** 11182 * @property _timerID 11183 * @protected 11184 * @type Number 11185 **/ 11186 this._timerID = null; 11187 11188 /** 11189 * @property _scale 11190 * @protected 11191 * @type Number 11192 **/ 11193 this._scale = 1; 11194 } 11195 var p = createjs.extend(SpriteSheetBuilder, createjs.EventDispatcher); 11196 11197 /** 11198 * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`. 11199 * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}} 11200 * for details. 11201 * 11202 * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance. 11203 * 11204 * @method initialize 11205 * @protected 11206 * @deprecated 11207 */ 11208 // p.initialize = function() {}; // searchable for devs wondering where it is. 11209 11210 11211// constants: 11212 SpriteSheetBuilder.ERR_DIMENSIONS = "frame dimensions exceed max spritesheet dimensions"; 11213 SpriteSheetBuilder.ERR_RUNNING = "a build is already running"; 11214 11215// events: 11216 /** 11217 * Dispatched when a build completes. 11218 * @event complete 11219 * @param {Object} target The object that dispatched the event. 11220 * @param {String} type The event type. 11221 * @since 0.6.0 11222 */ 11223 11224 /** 11225 * Dispatched when an asynchronous build has progress. 11226 * @event progress 11227 * @param {Object} target The object that dispatched the event. 11228 * @param {String} type The event type. 11229 * @param {Number} progress The current progress value (0-1). 11230 * @since 0.6.0 11231 */ 11232 11233 11234// public methods: 11235 /** 11236 * Adds a frame to the {{#crossLink "SpriteSheet"}}{{/crossLink}}. Note that the frame will not be drawn until you 11237 * call {{#crossLink "SpriteSheetBuilder/build"}}{{/crossLink}} method. The optional setup params allow you to have 11238 * a function run immediately before the draw occurs. For example, this allows you to add a single source multiple 11239 * times, but manipulate it or its children to change it to generate different frames. 11240 * 11241 * Note that the source's transformations (x, y, scale, rotate, alpha) will be ignored, except for regX/Y. To apply 11242 * transforms to a source object and have them captured in the SpriteSheet, simply place it into a {{#crossLink "Container"}}{{/crossLink}} 11243 * and pass in the Container as the source. 11244 * @method addFrame 11245 * @param {DisplayObject} source The source {{#crossLink "DisplayObject"}}{{/crossLink}} to draw as the frame. 11246 * @param {Rectangle} [sourceRect] A {{#crossLink "Rectangle"}}{{/crossLink}} defining the portion of the 11247 * source to draw to the frame. If not specified, it will look for a `getBounds` method, bounds property, or 11248 * `nominalBounds` property on the source to use. If one is not found, the frame will be skipped. 11249 * @param {Number} [scale=1] Optional. The scale to draw this frame at. Default is 1. 11250 * @param {Function} [setupFunction] A function to call immediately before drawing this frame. It will be called with two parameters: the source, and setupData. 11251 * @param {Object} [setupData] Arbitrary setup data to pass to setupFunction as the second parameter. 11252 * @return {Number} The index of the frame that was just added, or null if a sourceRect could not be determined. 11253 **/ 11254 p.addFrame = function(source, sourceRect, scale, setupFunction, setupData) { 11255 if (this._data) { throw SpriteSheetBuilder.ERR_RUNNING; } 11256 var rect = sourceRect||source.bounds||source.nominalBounds; 11257 if (!rect&&source.getBounds) { rect = source.getBounds(); } 11258 if (!rect) { return null; } 11259 scale = scale||1; 11260 return this._frames.push({source:source, sourceRect:rect, scale:scale, funct:setupFunction, data:setupData, index:this._frames.length, height:rect.height*scale})-1; 11261 }; 11262 11263 /** 11264 * Adds an animation that will be included in the created {{#crossLink "SpriteSheet"}}{{/crossLink}}. 11265 * @method addAnimation 11266 * @param {String} name The name for the animation. 11267 * @param {Array} frames An array of frame indexes that comprise the animation. Ex. [3,6,5] would describe an animation 11268 * that played frame indexes 3, 6, and 5 in that order. 11269 * @param {String} [next] Specifies the name of the animation to continue to after this animation ends. You can 11270 * also pass false to have the animation stop when it ends. By default it will loop to the start of the same animation. 11271 * @param {Number} [speed] Specifies a frame advance speed for this animation. For example, a value of 0.5 would 11272 * cause the animation to advance every second tick. Note that earlier versions used `frequency` instead, which had 11273 * the opposite effect. 11274 **/ 11275 p.addAnimation = function(name, frames, next, speed) { 11276 if (this._data) { throw SpriteSheetBuilder.ERR_RUNNING; } 11277 this._animations[name] = {frames:frames, next:next, speed:speed}; 11278 }; 11279 11280 /** 11281 * This will take a {{#crossLink "MovieClip"}}{{/crossLink}} instance, and add its frames and labels to this 11282 * builder. Labels will be added as an animation running from the label index to the next label. For example, if 11283 * there is a label named "foo" at frame 0 and a label named "bar" at frame 10, in a MovieClip with 15 frames, it 11284 * will add an animation named "foo" that runs from frame index 0 to 9, and an animation named "bar" that runs from 11285 * frame index 10 to 14. 11286 * 11287 * Note that this will iterate through the full MovieClip with {{#crossLink "MovieClip/actionsEnabled:property"}}{{/crossLink}} 11288 * set to `false`, ending on the last frame. 11289 * @method addMovieClip 11290 * @param {MovieClip} source The source MovieClip instance to add to the SpriteSheet. 11291 * @param {Rectangle} [sourceRect] A {{#crossLink "Rectangle"}}{{/crossLink}} defining the portion of the source to 11292 * draw to the frame. If not specified, it will look for a {{#crossLink "DisplayObject/getBounds"}}{{/crossLink}} 11293 * method, `frameBounds` Array, `bounds` property, or `nominalBounds` property on the source to use. If one is not 11294 * found, the MovieClip will be skipped. 11295 * @param {Number}
11295 [scale=1] The scale to draw the movie clip at. 11296 * @param {Function} [setupFunction] A function to call immediately before drawing each frame. It will be called 11297 * with three parameters: the source, setupData, and the frame index. 11298 * @param {Object} [setupData] Arbitrary setup data to pass to setupFunction as the second parameter. 11299 * @param {Function} [labelFunction] This method will be called for each MovieClip label that is added with four 11300 * parameters: the label name, the source MovieClip instance, the starting frame index (in the movieclip timeline) 11301 * and the end index. It must return a new name for the label/animation, or `false` to exclude the label. 11302 **/ 11303 p.addMovieClip = function(source, sourceRect, scale, setupFunction, setupData, labelFunction) { 11304 if (this._data) { throw SpriteSheetBuilder.ERR_RUNNING; } 11305 var rects = source.frameBounds; 11306 var rect = sourceRect||source.bounds||source.nominalBounds; 11307 if (!rect&&source.getBounds) { rect = source.getBounds(); } 11308 if (!rect && !rects) { return; } 11309 11310 var i, l, baseFrameIndex = this._frames.length; 11311 var duration = source.timeline.duration; 11312 for (i=0; i<duration; i++) { 11313 var r = (rects&&rects[i]) ? rects[i] : rect; 11314 this.addFrame(source, r, scale, this._setupMovieClipFrame, {i:i, f:setupFunction, d:setupData}); 11315 } 11316 var labels = source.timeline._labels; 11317 var lbls = []; 11318 for (var n in labels) { 11319 lbls.push({index:labels[n], label:n}); 11320 } 11321 if (lbls.length) { 11322 lbls.sort(function(a,b){ return a.index-b.index; }); 11323 for (i=0,l=lbls.length; i<l; i++) { 11324 var label = lbls[i].label; 11325 var start = baseFrameIndex+lbls[i].index; 11326 var end = baseFrameIndex+((i == l-1) ? duration : lbls[i+1].index); 11327 var frames = []; 11328 for (var j=start; j<end; j++) { frames.push(j); } 11329 if (labelFunction) { 11330 label = labelFunction(label, source, start, end); 11331 if (!label) { continue; } 11332 } 11333 this.addAnimation(label, frames, true); // for now, this loops all animations. 11334 } 11335 } 11336 }; 11337 11338 /** 11339 * Builds a {{#crossLink "SpriteSheet"}}{{/crossLink}} instance based on the current frames. 11340 * @method build 11341 * @return {SpriteSheet} The created SpriteSheet instance, or null if a build is already running or an error 11342 * occurred. 11343 **/ 11344 p.build = function() { 11345 if (this._data) { throw SpriteSheetBuilder.ERR_RUNNING; } 11346 this._startBuild(); 11347 while (this._drawNext()) {} 11348 this._endBuild(); 11349 return this.spriteSheet; 11350 }; 11351 11352 /** 11353 * Asynchronously builds a {{#crossLink "SpriteSheet"}}{{/crossLink}} instance based on the current frames. It will 11354 * run 20 times per second, using an amount of time defined by `timeSlice`. When it is complete it will call the 11355 * specified callback. 11356 * @method buildAsync 11357 * @param {Number} [timeSlice] Sets the timeSlice property on this instance. 11358 **/ 11359 p.buildAsync = function(timeSlice) { 11360 if (this._data) { throw SpriteSheetBuilder.ERR_RUNNING; } 11361 this.timeSlice = timeSlice; 11362 this._startBuild(); 11363 var _this = this; 11364 this._timerID = setTimeout(function() { _this._run(); }, 50-Math.max(0.01, Math.min(0.99, this.timeSlice||0.3))*50); 11365 }; 11366 11367 /** 11368 * Stops the current asynchronous build. 11369 * @method stopAsync 11370 **/ 11371 p.stopAsync = function() { 11372 clearTimeout(this._timerID); 11373 this._data = null; 11374 }; 11375 11376 /** 11377 * SpriteSheetBuilder instances cannot be cloned. 11378 * @method clone 11379 **/ 11380 p.clone = function() { 11381 throw("SpriteSheetBuilder cannot be cloned."); 11382 }; 11383 11384 /** 11385 * Returns a string representation of this object. 11386 * @method toString 11387 * @return {String} a string representation of the instance. 11388 **/ 11389 p.toString = function() { 11390 return "[SpriteSheetBuilder]"; 11391 }; 11392 11393 11394// private methods: 11395 /** 11396 * @method _startBuild 11397 * @protected 11398 **/ 11399 p._startBuild = function() { 11400 var pad = this.padding||0; 11401 this.progress = 0; 11402 this.spriteSheet = null; 11403 this._index = 0; 11404 this._scale = this.scale; 11405 var dataFrames = []; 11406 this._data = { 11407 images: [], 11408 frames: dataFrames, 11409 framerate: this.framerate, 11410 animations: this._animations // TODO: should we "clone" _animations in case someone adds more animations after a build? 11411 }; 11412 11413 var frames = this._frames.slice(); 11414 frames.sort(function(a,b) { return (a.height<=b.height) ? -1 : 1; }); 11415 11416 if (frames[frames.length-1].height+pad*2 > this.maxHeight) { throw SpriteSheetBuilder.ERR_DIMENSIONS; } 11417 var y=0, x=0; 11418 var img = 0; 11419 while (frames.length) { 11420 var o = this._fillRow(frames, y, img, dataFrames, pad); 11421 if (o.w > x) { x = o.w; } 11422 y += o.h; 11423 if (!o.h || !frames.length) { 11424 var canvas = createjs.createCanvas?createjs.createCanvas():document.createElement("canvas"); 11425 canvas.width = this._getSize(x,this.maxWidth); 11426 canvas.height = this._getSize(y,this.maxHeight); 11427 this._data.images[img] = canvas; 11428 if (!o.h) { 11429 x=y=0; 11430 img++; 11431 } 11432 } 11433 } 11434 }; 11435 11436 /** 11437 * @method _setupMovieClipFrame 11438 * @protected 11439 * @return {Number} The width & height of the row. 11440 **/ 11441 p._setupMovieClipFrame = function(source, data) { 11442 var ae = source.actionsEnabled; 11443 source.actionsEnabled = false;
11444 source.gotoAndStop(data.i); 11445 source.actionsEnabled = ae; 11446 data.f&&data.f(source, data.d, data.i); 11447 }; 11448 11449 /** 11450 * @method _getSize 11451 * @protected 11452 * @return {Number} The width & height of the row. 11453 **/ 11454 p._getSize = function(size,max) { 11455 var pow = 4; 11456 while (Math.pow(2,++pow) < size){} 11457 return Math.min(max,Math.pow(2,pow)); 11458 }; 11459 11460 /** 11461 * @method _fillRow 11462 * @param {Array} frames 11463 * @param {Number} y 11464 * @param {HTMLImageElement} img 11465 * @param {Object} dataFrames 11466 * @param {Number} pad 11467 * @protected 11468 * @return {Number} The width & height of the row. 11469 **/ 11470 p._fillRow = function(frames, y, img, dataFrames, pad) { 11471 var w = this.maxWidth; 11472 var maxH = this.maxHeight; 11473 y += pad; 11474 var h = maxH-y; 11475 var x = pad; 11476 var height = 0; 11477 for (var i=frames.length-1; i>=0; i--) { 11478 var frame = frames[i]; 11479 var sc = this._scale*frame.scale; 11480 var rect = frame.sourceRect; 11481 var source = frame.source; 11482 var rx = Math.floor(sc*rect.x-pad); 11483 var ry = Math.floor(sc*rect.y-pad); 11484 var rh = Math.ceil(sc*rect.height+pad*2); 11485 var rw = Math.ceil(sc*rect.width+pad*2); 11486 if (rw > w) { throw SpriteSheetBuilder.ERR_DIMENSIONS; } 11487 if (rh > h || x+rw > w) { continue; } 11488 frame.img = img; 11489 frame.rect = new createjs.Rectangle(x,y,rw,rh); 11490 height = height || rh; 11491 frames.splice(i,1); 11492 dataFrames[frame.index] = [x,y,rw,rh,img,Math.round(-rx+sc*source.regX-pad),Math.round(-ry+sc*source.regY-pad)]; 11493 x += rw; 11494 } 11495 return {w:x, h:height}; 11496 }; 11497 11498 /** 11499 * @method _endBuild 11500 * @protected 11501 **/ 11502 p._endBuild = function() { 11503 this.spriteSheet = new createjs.SpriteSheet(this._data); 11504 this._data = null; 11505 this.progress = 1; 11506 this.dispatchEvent("complete"); 11507 }; 11508 11509 /** 11510 * @method _run 11511 * @protected 11512 **/ 11513 p._run = function() { 11514 var ts = Math.max(0.01, Math.min(0.99, this.timeSlice||0.3))*50; 11515 var t = (new Date()).getTime()+ts; 11516 var complete = false; 11517 while (t > (new Date()).getTime()) { 11518 if (!this._drawNext()) { complete = true; break; } 11519 } 11520 if (complete) { 11521 this._endBuild(); 11522 } else { 11523 var _this = this; 11524 this._timerID = setTimeout(function() { _this._run(); }, 50-ts); 11525 } 11526 var p = this.progress = this._index/this._frames.length; 11527 if (this.hasEventListener("progress")) { 11528 var evt = new createjs.Event("progress"); 11529 evt.progress = p; 11530 this.dispatchEvent(evt); 11531 } 11532 }; 11533 11534 /** 11535 * @method _drawNext 11536 * @protected 11537 * @return Boolean Returns false if this is the last draw. 11538 **/ 11539 p._drawNext = function() { 11540 var frame = this._frames[this._index]; 11541 var sc = frame.scale*this._scale; 11542 var rect = frame.rect; 11543 var sourceRect = frame.sourceRect; 11544 var canvas = this._data.images[frame.img]; 11545 var ctx = canvas.getContext("2d"); 11546 frame.funct&&frame.funct(frame.source, frame.data); 11547 ctx.save(); 11548 ctx.beginPath(); 11549 ctx.rect(rect.x, rect.y, rect.width, rect.height); 11550 ctx.clip(); 11551 ctx.translate(Math.ceil(rect.x-sourceRect.x*sc), Math.ceil(rect.y-sourceRect.y*sc)); 11552 ctx.scale(sc,sc); 11553 frame.source.draw(ctx); // display object will draw itself. 11554 ctx.restore(); 11555 return (++this._index) < this._frames.length; 11556 }; 11557 11558 11559 createjs.SpriteSheetBuilder = createjs.promote(SpriteSheetBuilder, "EventDispatcher"); 11560}()); 11561 11562//############################################################################## 11563// DOMElement.js 11564//############################################################################## 11565 11566this.createjs = this.createjs||{}; 11567 11568(function() { 11569 "use strict"; 11570 11571 11572// constructor: 11573 /** 11574 * <b>This class is still experimental, and more advanced use is likely to be buggy. Please report bugs.</b> 11575 * 11576 * A DOMElement allows you to associate a HTMLElement with the display list. It will be transformed 11577 * within the DOM as though it is child of the {{#crossLink "Container"}}{{/crossLink}} it is added to. However, it is 11578 * not rendered to canvas, and as such will retain whatever z-index it has relative to the canvas (ie. it will be 11579 * drawn in front of or behind the canvas). 11580 * 11581 * The position of a DOMElement is relative to their parent node in the DOM. It is recommended that 11582 * the DOM Object be added to a div that also contains the canvas so that they share the same position 11583 * on the page. 11584 * 11585 * DOMElement is useful for positioning HTML elements over top of c
11585anvas content, and for elements 11586 * that you want to display outside the bounds of the canvas. For example, a tooltip with rich HTML 11587 * content. 11588 * 11589 * <h4>Mouse Interaction</h4> 11590 * 11591 * DOMElement instances are not full EaselJS display objects, and do not participate in EaselJS mouse 11592 * events or support methods like hitTest. To get mouse events from a DOMElement, you must instead add handlers to 11593 * the htmlElement (note, this does not support EventDispatcher) 11594 * 11595 * var domElement = new createjs.DOMElement(htmlElement); 11596 * domElement.htmlElement.onclick = function() { 11597 * console.log("clicked"); 11598 * } 11599 * 11600 * @class DOMElement 11601 * @extends DisplayObject 11602 * @constructor 11603 * @param {HTMLElement} htmlElement A reference or id for the DOM element to manage. 11604 */ 11605 function DOMElement(htmlElement) { 11606 this.DisplayObject_constructor(); 11607 11608 if (typeof(htmlElement)=="string") { htmlElement = document.getElementById(htmlElement); } 11609 this.mouseEnabled = false; 11610 11611 var style = htmlElement.style; 11612 style.position = "absolute"; 11613 style.transformOrigin = style.WebkitTransformOrigin = style.msTransformOrigin = style.MozTransformOrigin = style.OTransformOrigin = "0% 0%"; 11614 11615 11616 // public properties: 11617 /** 11618 * The DOM object to manage. 11619 * @property htmlElement 11620 * @type HTMLElement 11621 */ 11622 this.htmlElement = htmlElement; 11623 11624 11625 // private properties: 11626 /** 11627 * @property _oldMtx 11628 * @type Matrix2D 11629 * @protected 11630 */ 11631 this._oldProps = null; 11632 } 11633 var p = createjs.extend(DOMElement, createjs.DisplayObject); 11634 11635 // TODO: deprecated 11636 // p.initialize = function() {}; // searchable for devs wondering where it is. REMOVED. See docs for details. 11637 11638 11639// public methods: 11640 /** 11641 * Returns true or false indicating whether the display object would be visible if drawn to a canvas. 11642 * This does not account for whether it would be visible within the boundaries of the stage. 11643 * NOTE: This method is mainly for internal use, though it may be useful for advanced uses. 11644 * @method isVisible 11645 * @return {Boolean} Boolean indicating whether the display object would be visible if drawn to a canvas 11646 */ 11647 p.isVisible = function() { 11648 return this.htmlElement != null; 11649 }; 11650 11651 /** 11652 * Draws the display object into the specified context ignoring its visible, alpha, shadow, and transform. 11653 * Returns true if the draw was handled (useful for overriding functionality). 11654 * NOTE: This method is mainly for internal use, though it may be useful for advanced uses. 11655 * @method draw 11656 * @param {CanvasRenderingContext2D} ctx The canvas 2D context object to draw into. 11657 * @param {Boolean} ignoreCache Indicates whether the draw operation should ignore any current cache. 11658 * For example, used for drawing the cache (to prevent it from simply drawing an existing cache back 11659 * into itself). 11660 * @return {Boolean} 11661 */ 11662 p.draw = function(ctx, ignoreCache) { 11663 // this relies on the _tick method because draw isn't called if the parent is not visible. 11664 // the actual update happens in _handleDrawEnd 11665 return true; 11666 }; 11667 11668 /** 11669 * Not applicable to DOMElement. 11670 * @method cache 11671 */ 11672 p.cache = function() {}; 11673 11674 /** 11675 * Not applicable to DOMElement. 11676 * @method uncache 11677 */ 11678 p.uncache = function() {}; 11679 11680 /** 11681 * Not applicable to DOMElement. 11682 * @method updateCache 11683 */ 11684 p.updateCache = function() {}; 11685 11686 /** 11687 * Not applicable to DOMElement. 11688 * @method hitTest 11689 */ 11690 p.hitTest = function() {}; 11691 11692 /** 11693 * Not applicable to DOMElement. 11694 * @method localToGlobal 11695 */ 11696 p.localToGlobal = function() {}; 11697 11698 /** 11699 * Not applicable to DOMElement. 11700 * @method globalToLocal 11701 */ 11702 p.globalToLocal = function() {}; 11703 11704 /** 11705 * Not applicable to DOMElement. 11706 * @method localToLocal 11707 */ 11708 p.localToLocal = function() {}; 11709 11710 /** 11711 * DOMElement cannot be cloned. Throws an error. 11712 * @method clone 11713 */ 11714 p.clone = function() { 11715 throw("DOMElement cannot be cloned.") 11716 }; 11717 11718 /** 11719 * Returns a string representation of this object. 11720 * @method toString 11721 * @return {String} a string representation of the instance. 11722 */ 11723 p.toString = function() { 11724 return "[DOMElement (name="+ this.name +")]"; 11725 }; 11726 11727 /** 11728 * Interaction events should be added to `htmlElement`, and not the DOMElement instance, since DOMElement instances 11729 * are not full EaselJS display objects and do not participate in EaselJS mouse events. 11730 * @event click 11731 */ 11732 11733 /** 11734 * Interaction events should be added to `htmlElement`, and not the DOMElement instance, since DOMElement instances 11735 * are not full EaselJS display objects and do not participate in EaselJS mouse events. 11736 * @event dblClick 11737 */ 11738 11739 /** 11740 * Interaction events should be added to `htmlElement`, and not the DOMElement instance, since DOMElement instances 11741 * are not full EaselJS display objects and do not participate in EaselJS mouse events. 11742 * @event mousedown 11743 */ 11744 11745 /** 11746 * The HTMLElement can listen for the mouseover event, not the DOMElement instance. 11747 * Since DOMElement instances are not full EaselJS display objects and do not participate in EaselJS mouse events. 11748 * @event mouseover 11749 */ 11750 11751 /** 11752 * Not applicable to DOMElement. 11753 * @event tick 11754 */ 11755 11756 11757// private methods: 11758 /** 11759 * @method _tick 11760 * @param {Object} evtObj An event object that will be dispatched to all tick listeners. This object is reused between dispatchers to reduce construction & GC costs. 11761 * function. 11762 * @protected 11763 */ 11764 p._tick = function(evtObj) {
11765 var stage = this.getStage(); 11766 stage&&stage.on("drawend", this._handleDrawEnd, this, true); 11767 this.DisplayObject__tick(evtObj); 11768 }; 11769 11770 /** 11771 * @method _handleDrawEnd 11772 * @param {Event} evt 11773 * @protected 11774 */ 11775 p._handleDrawEnd = function(evt) { 11776 var o = this.htmlElement; 11777 if (!o) { return; } 11778 var style = o.style; 11779 11780 var props = this.getConcatenatedDisplayProps(this._props), mtx = props.matrix; 11781 11782 var visibility = props.visible ? "visible" : "hidden"; 11783 if (visibility != style.visibility) { style.visibility = visibility; } 11784 if (!props.visible) { return; } 11785 11786 var oldProps = this._oldProps, oldMtx = oldProps&&oldProps.matrix; 11787 var n = 10000; // precision 11788 11789 if (!oldMtx || !oldMtx.equals(mtx)) { 11790 var str = "matrix(" + (mtx.a*n|0)/n +","+ (mtx.b*n|0)/n +","+ (mtx.c*n|0)/n +","+ (mtx.d*n|0)/n +","+ (mtx.tx+0.5|0); 11791 style.transform = style.WebkitTransform = style.OTransform = style.msTransform = str +","+ (mtx.ty+0.5|0) +")"; 11792 style.MozTransform = str +"px,"+ (mtx.ty+0.5|0) +"px)"; 11793 if (!oldProps) { oldProps = this._oldProps = new createjs.DisplayProps(true, NaN); } 11794 oldProps.matrix.copy(mtx); 11795 } 11796 11797 if (oldProps.alpha != props.alpha) { 11798 style.opacity = ""+(props.alpha*n|0)/n; 11799 oldProps.alpha = props.alpha; 11800 } 11801 }; 11802 11803 11804 createjs.DOMElement = createjs.promote(DOMElement, "DisplayObject"); 11805}()); 11806 11807//############################################################################## 11808// Filter.js 11809//############################################################################## 11810 11811this.createjs = this.createjs||{}; 11812 11813(function() { 11814 "use strict"; 11815 11816 11817// constructor: 11818 /** 11819 * Base class that all filters should inherit from. Filters need to be applied to objects that have been cached using 11820 * the {{#crossLink "DisplayObject/cache"}}{{/crossLink}} method. If an object changes, please cache it again, or use 11821 * {{#crossLink "DisplayObject/updateCache"}}{{/crossLink}}. Note that the filters must be applied before caching. 11822 * 11823 * <h4>Example</h4> 11824 * 11825 * myInstance.filters = [ 11826 * new createjs.ColorFilter(0, 0, 0, 1, 255, 0, 0), 11827 * new createjs.BlurFilter(5, 5, 10) 11828 * ]; 11829 * myInstance.cache(0,0, 100, 100); 11830 * 11831 * Note that each filter can implement a {{#crossLink "Filter/getBounds"}}{{/crossLink}} method, which returns the 11832 * margins that need to be applied in order to fully display the filter. For example, the {{#crossLink "BlurFilter"}}{{/crossLink}} 11833 * will cause an object to feather outwards, resulting in a margin around the shape. 11834 * 11835 * <h4>EaselJS Filters</h4> 11836 * EaselJS comes with a number of pre-built filters: 11837 * <ul><li>{{#crossLink "AlphaMapFilter"}}{{/crossLink}} : Map a greyscale image to the alpha channel of a display object</li> 11838 * <li>{{#crossLink "AlphaMaskFilter"}}{{/crossLink}}: Map an image's alpha channel to the alpha channel of a display object</li> 11839 * <li>{{#crossLink "BlurFilter"}}{{/crossLink}}: Apply vertical and horizontal blur to a display object</li> 11840 * <li>{{#crossLink "ColorFilter"}}{{/crossLink}}: Color transform a display object</li> 11841 * <li>{{#crossLink "ColorMatrixFilter"}}{{/crossLink}}: Transform an image using a {{#crossLink "ColorMatrix"}}{{/crossLink}}</li> 11842 * </ul> 11843 * 11844 * @class Filter 11845 * @constructor 11846 **/ 11847 function Filter() {} 11848 var p = Filter.prototype; 11849 11850 /** 11851 * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`. 11852 * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}} 11853 * for details. 11854 * 11855 * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance. 11856 * 11857 * @method initialize 11858 * @protected 11859 * @deprecated 11860 */ 11861 // p.initialize = function() {}; // searchable for devs wondering where it is. 11862 11863 11864// public methods: 11865 /** 11866 * Provides padding values for this filter. That is, how much the filter will extend the visual bounds of an object it is applied to. 11867 * @method getBounds 11868 * @param {Rectangle} [rect] If specified, the provided Rectangle instance will be expanded by the padding amounts and returned. 11869 * @return {Rectangle} If a `rect` param was provided, it is returned. If not, either a new rectangle with the padding values, or null if no padding is required for this filter. 11870 **/ 11871 p.getBounds = function(rect) { 11872 return rect; 11873 }; 11874 11875 /** 11876 * Applies the filter to the specified context. 11877 * @method applyFilter 11878 * @param {CanvasRenderingContext2D} ctx The 2D context to use as the source. 11879 * @param {Number} x The x position to use for the source rect. 11880 * @param {Number} y The y position to use for the source rect. 11881 * @param {Number} width The width to use for the source rect. 11882 * @param {Number} height The height to use for the source rect. 11883 * @param {CanvasRenderingContext2D} [targetCtx] The 2D context to draw the result to. Defaults to the context passed to ctx. 11884 * @param {Number} [targetX] The x position to draw the result to. Defaults to the value passed to x. 11885 * @param {Number} [targetY] The y position to draw the result to. Defaults to the value passed to y. 11886 * @return {Boolean} If the filter was applied successfully. 11887 **/ 11888 p.applyFilter = function(ctx, x, y, width, height, targetCtx, targetX, targetY) { 11889 // this is the default behaviour because most filters access pixel data. It is overridden when not needed. 11890 targetCtx = targetCtx || ctx; 11891 if (targetX == null) { targetX = x; } 11892 if (targetY == null) { targetY = y; } 11893 try { 11894 var imageData = ctx.getImageData(x, y, width, height); 11895 } catch (e) { 11896 return false;
11897 } 11898 if (this._applyFilter(imageData)) { 11899 targetCtx.putImageData(imageData, targetX, targetY); 11900 return true; 11901 } 11902 return false; 11903 }; 11904 11905 /** 11906 * Returns a string representation of this object. 11907 * @method toString 11908 * @return {String} a string representation of the instance. 11909 **/ 11910 p.toString = function() { 11911 return "[Filter]"; 11912 }; 11913 11914 /** 11915 * Returns a clone of this Filter instance. 11916 * @method clone 11917 * @return {Filter} A clone of the current Filter instance. 11918 **/ 11919 p.clone = function() { 11920 return new Filter(); 11921 }; 11922 11923// private methods: 11924 /** 11925 * @method _applyFilter 11926 * @param {ImageData} imageData Target ImageData instance. 11927 * @return {Boolean} 11928 **/ 11929 p._applyFilter = function(imageData) { return true; }; 11930 11931 11932 createjs.Filter = Filter; 11933}()); 11934 11935//############################################################################## 11936// BlurFilter.js 11937//############################################################################## 11938 11939this.createjs = this.createjs||{}; 11940 11941(function() { 11942 "use strict"; 11943 11944 11945// constructor: 11946 /** 11947 * Applies a box blur to DisplayObjects. Note that this filter is fairly CPU intensive, particularly if the quality is 11948 * set higher than 1. 11949 * 11950 * <h4>Example</h4> 11951 * This example creates a red circle, and then applies a 5 pixel blur to it. It uses the {{#crossLink "Filter/getBounds"}}{{/crossLink}} 11952 * method to account for the spread that the blur causes. 11953 * 11954 * var shape = new createjs.Shape().set({x:100,y:100}); 11955 * shape.graphics.beginFill("#ff0000").drawCircle(0,0,50); 11956 * 11957 * var blurFilter = new createjs.BlurFilter(5, 5, 1); 11958 * shape.filters = [blurFilter]; 11959 * var bounds = blurFilter.getBounds(); 11960 * 11961 * shape.cache(-50+bounds.x, -50+bounds.y, 100+bounds.width, 100+bounds.height); 11962 * 11963 * See {{#crossLink "Filter"}}{{/crossLink}} for an more information on applying filters. 11964 * @class BlurFilter 11965 * @extends Filter 11966 * @constructor 11967 * @param {Number} [blurX=0] The horizontal blur radius in pixels. 11968 * @param {Number} [blurY=0] The vertical blur radius in pixels. 11969 * @param {Number} [quality=1] The number of blur iterations. 11970 **/ 11971 function BlurFilter( blurX, blurY, quality) { 11972 if ( isNaN(blurX) || blurX < 0 ) blurX = 0; 11973 if ( isNaN(blurY) || blurY < 0 ) blurY = 0; 11974 if ( isNaN(quality) || quality < 1 ) quality = 1; 11975 11976 11977 // public properties: 11978 /** 11979 * Horizontal blur radius in pixels 11980 * @property blurX 11981 * @default 0 11982 * @type Number 11983 **/ 11984 this.blurX = blurX | 0; 11985 11986 /** 11987 * Vertical blur radius in pixels 11988 * @property blurY 11989 * @default 0 11990 * @type Number 11991 **/ 11992 this.blurY = blurY | 0; 11993 11994 /** 11995 * Number of blur iterations. For example, a value of 1 will produce a rough blur. A value of 2 will produce a 11996 * smoother blur, but take twice as long to run. 11997 * @property quality 11998 * @default 1 11999 * @type Number 12000 **/ 12001 this.quality = quality | 0; 12002 } 12003 var p = createjs.extend(BlurFilter, createjs.Filter); 12004 12005 // TODO: deprecated 12006 // p.initialize = function() {}; // searchable for devs wondering where it is. REMOVED. See docs for details. 12007 12008 12009// constants: 12010 /** 12011 * Array of multiply values for blur calculations. 12012 * @property MUL_TABLE 12013 * @type Array 12014 * @protected 12015 * @static 12016 **/ 12017 BlurFilter.MUL_TABLE = [1, 171, 205, 293, 57, 373, 79, 137, 241, 27, 391, 357, 41, 19, 283, 265, 497, 469, 443, 421, 25, 191, 365, 349, 335, 161, 155, 149, 9, 278, 269, 261, 505, 245, 475, 231, 449, 437, 213, 415, 405, 395, 193, 377, 369, 361, 353, 345, 169, 331, 325, 319, 313, 307, 301, 37, 145, 285, 281, 69, 271, 267, 263, 259, 509, 501, 493, 243, 479, 118, 465, 459, 113, 446, 55, 435, 429, 423, 209, 413, 51, 403, 199, 393, 97, 3, 379, 375, 371, 367, 363, 359, 355, 351, 347, 43, 85, 337, 333, 165, 327, 323, 5, 317, 157, 311, 77, 305, 303, 75, 297, 294, 73, 289, 287, 71, 141, 279, 277, 275, 68, 135, 67, 133, 33, 262, 260, 129, 511, 507, 503, 499, 495, 491, 61, 121, 481, 477, 237, 235, 467, 232, 115, 457, 227, 451, 7, 445, 221, 439, 218, 433, 215, 427, 425, 211, 419, 417, 207, 411, 409, 203, 202, 401, 399, 396, 197, 49, 389, 387, 385, 383, 95, 189, 47, 187, 93, 185, 23, 183, 91, 181, 45, 179, 89, 177, 11, 175, 87, 173, 345, 343, 341, 339, 337, 21, 167, 83, 331, 329, 327, 163, 81, 323, 321, 319, 159, 79, 315, 313, 39, 155, 309, 307, 153, 305, 303, 151, 75, 299, 149, 37, 295, 147, 73, 291, 145, 289, 287, 143, 285, 71, 141, 281, 35, 279, 139, 69, 275, 137, 273, 17, 271, 135, 269, 267, 133, 265, 33, 263, 131, 261, 130, 259, 129, 257, 1]; 12018 12019 /** 12020 * Array of shift values for blur calculations. 12021 * @property SHG_TABLE 12022 * @type Array 12023 * @protected 12024 * @static 12025 **/ 12026 BlurFilter.SHG_TABLE = [0, 9, 10, 11, 9, 12, 10, 11, 12, 9, 13, 13, 10, 9, 13, 13, 14, 14, 14, 14, 10, 13, 14, 14, 14, 13, 13, 13, 9, 14, 14, 14, 15, 14, 15, 14, 15, 15, 14, 15, 15, 15, 14, 15, 15, 15, 15, 15, 14, 15, 15, 15, 15, 15, 15, 12, 14, 15, 15, 13, 15, 15, 15, 15, 16, 16, 16, 15, 16, 14, 16, 16, 14, 16, 13, 16, 16, 16, 15, 16, 13, 16, 15, 16, 14, 9, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, 14, 16, 16, 15, 16, 16, 10, 16, 15, 16, 14, 16, 16, 14, 16, 16, 14, 16, 16, 14, 15, 16, 16, 16, 14, 15, 14, 15, 13, 16, 16, 15, 17, 17, 17, 17, 17, 17, 14, 15, 17, 17, 16, 16, 17, 16, 15, 17, 16, 17, 11, 17, 16, 17, 16, 17, 16, 17, 17, 16, 17, 17, 16, 17, 17, 16, 16, 17, 17, 17, 16, 14, 17, 17, 17, 17, 15, 16, 14, 16, 15, 16, 13, 16, 15, 16, 14, 16, 15, 16, 12, 16, 15, 16, 17, 17, 17, 17, 17, 13, 16, 15, 17, 17, 17, 16, 15, 17, 17, 17, 16, 15, 17, 17, 14, 16, 17, 17, 16, 17, 17, 16, 15, 17, 16, 14, 17, 16, 15, 17, 16, 17, 17, 16, 17, 15, 16, 17, 14, 17, 16, 15, 17, 16, 17, 13, 17, 16, 17, 17, 16, 17, 14, 17, 16, 17, 16, 17, 16, 17, 9]; 12027 12028// public methods: 12029 /** docced in super class **/ 12030 p.getBounds = function (rect) { 12031 var x = this.blurX|0, y = this.blurY| 0; 12032 if (x <= 0 && y <= 0) { return rect; }
12033 var q = Math.pow(this.quality, 0.2); 12034 return (rect || new createjs.Rectangle()).pad(x*q+1,y*q+1,x*q+1,y*q+1); 12035 }; 12036 12037 /** docced in super class **/ 12038 p.clone = function() { 12039 return new BlurFilter(this.blurX, this.blurY, this.quality); 12040 }; 12041 12042 /** docced in super class **/ 12043 p.toString = function() { 12044 return "[BlurFilter]"; 12045 }; 12046 12047 12048// private methods: 12049 12050 /** docced in super class **/ 12051 p._applyFilter = function (imageData) { 12052 12053 var radiusX = this.blurX >> 1; 12054 if (isNaN(radiusX) || radiusX < 0) return false; 12055 var radiusY = this.blurY >> 1; 12056 if (isNaN(radiusY) || radiusY < 0) return false; 12057 if (radiusX == 0 && radiusY == 0) return false; 12058 12059 var iterations = this.quality; 12060 if (isNaN(iterations) || iterations < 1) iterations = 1; 12061 iterations |= 0; 12062 if (iterations > 3) iterations = 3; 12063 if (iterations < 1) iterations = 1; 12064 12065 var px = imageData.data; 12066 var x=0, y=0, i=0, p=0, yp=0, yi=0, yw=0, r=0, g=0, b=0, a=0, pr=0, pg=0, pb=0, pa=0; 12067 12068 var divx = (radiusX + radiusX + 1) | 0; 12069 var divy = (radiusY + radiusY + 1) | 0; 12070 var w = imageData.width | 0;
12071 var h = imageData.height | 0; 12072 12073 var w1 = (w - 1) | 0; 12074 var h1 = (h - 1) | 0; 12075 var rxp1 = (radiusX + 1) | 0; 12076 var ryp1 = (radiusY + 1) | 0; 12077 12078 var ssx = {r:0,b:0,g:0,a:0}; 12079 var sx = ssx; 12080 for ( i = 1; i < divx; i++ ) 12081 { 12082 sx = sx.n = {r:0,b:0,g:0,a:0}; 12083 } 12084 sx.n = ssx; 12085 12086 var ssy = {r:0,b:0,g:0,a:0}; 12087 var sy = ssy; 12088 for ( i = 1; i < divy; i++ ) 12089 { 12090 sy = sy.n = {r:0,b:0,g:0,a:0}; 12091 } 12092 sy.n = ssy; 12093 12094 var si = null; 12095 12096 12097 var mtx = BlurFilter.MUL_TABLE[radiusX] | 0; 12098 var stx = BlurFilter.SHG_TABLE[radiusX] | 0; 12099 var mty = BlurFilter.MUL_TABLE[radiusY] | 0; 12100 var sty = BlurFilter.SHG_TABLE[radiusY] | 0; 12101 12102 while (iterations-- > 0) { 12103 12104 yw = yi = 0; 12105 var ms = mtx; 12106 var ss = stx; 12107 for (y = h; --y > -1;) { 12108 r = rxp1 * (pr = px[(yi) | 0]); 12109 g = rxp1 * (pg = px[(yi + 1) | 0]); 12110 b = rxp1 * (pb = px[(yi + 2) | 0]); 12111 a = rxp1 * (pa = px[(yi + 3) | 0]); 12112 12113 sx = ssx; 12114 12115 for( i = rxp1; --i > -1; ) 12116 { 12117 sx.r = pr; 12118 sx.g = pg; 12119 sx.b = pb; 12120 sx.a = pa; 12121 sx = sx.n; 12122 } 12123 12124 for( i = 1; i < rxp1; i++ ) 12125 { 12126 p = (yi + ((w1 < i ? w1 : i) << 2)) | 0; 12127 r += ( sx.r = px[p]); 12128 g += ( sx.g = px[p+1]); 12129 b += ( sx.b = px[p+2]); 12130 a += ( sx.a = px[p+3]); 12131 12132 sx = sx.n; 12133 } 12134 12135 si = ssx; 12136 for ( x = 0; x < w; x++ ) 12137 { 12138 px[yi++] = (r * ms) >>> ss; 12139 px[yi++] = (g * ms) >>> ss; 12140 px[yi++] = (b * ms) >>> ss; 12141 px[yi++] = (a * ms) >>> ss; 12142 12143 p = ((yw + ((p = x + radiusX + 1) < w1 ? p : w1)) << 2); 12144 12145 r -= si.r - ( si.r = px[p]); 12146 g -= si.g - ( si.g = px[p+1]); 12147 b -= si.b - ( si.b = px[p+2]); 12148 a -= si.a - ( si.a = px[p+3]); 12149 12150 si = si.n; 12151 12152 } 12153 yw += w; 12154 } 12155 12156 ms = mty; 12157 ss = sty; 12158 for (x = 0; x < w; x++) { 12159 yi = (x << 2) | 0; 12160 12161 r = (ryp1 * (pr = px[yi])) | 0; 12162 g = (ryp1 * (pg = px[(yi + 1) | 0])) | 0; 12163 b = (ryp1 * (pb = px[(yi + 2) | 0])) | 0; 12164 a = (ryp1 * (pa = px[(yi + 3) | 0])) | 0; 12165 12166 sy = ssy; 12167 for( i = 0; i < ryp1; i++ ) 12168 { 12169 sy.r = pr; 12170 sy.g = pg; 12171 sy.b = pb; 12172 sy.a = pa; 12173 sy = sy.n; 12174 } 12175 12176 yp = w; 12177 12178 for( i = 1; i <= radiusY; i++ ) 12179 { 12180 yi = ( yp + x ) << 2; 12181 12182 r += ( sy.r = px[yi]); 12183 g += ( sy.g = px[yi+1]); 12184 b += ( sy.b = px[yi+2]); 12185 a += ( sy.a = px[yi+3]); 12186 12187 sy = sy.n; 12188 12189 if( i < h1 ) 12190 { 12191 yp += w; 12192 } 12193 } 12194 12195 yi = x; 12196 si = ssy; 12197 if ( iterations > 0 ) 12198 { 12199 for ( y = 0; y < h; y++ ) 12200 { 12201 p = yi << 2; 12202 px[p+3] = pa =(a * ms) >>> ss; 12203 if ( pa > 0 ) 12204 { 12205 px[p] = ((r * ms) >>> ss ); 12206 px[p+1] = ((g * ms) >>> ss ); 12207 px[p+2] = ((b * ms) >>> ss ); 12208 } else { 12209 px[p] = px[p+1] = px[p+2] = 0 12210 } 12211 12212 p = ( x + (( ( p = y + ryp1) < h1 ? p : h1 ) * w )) << 2; 12213 12214 r -= si.r - ( si.r = px[p]); 12215 g -= si.g - ( si.g = px[p+1]); 12216 b -= si.b - ( si.b = px[p+2]); 12217 a -= si.a - ( si.a = px[p+3]); 12218 12219 si = si.n; 12220 12221 yi += w; 12222 } 12223 } else { 12224 for ( y = 0; y < h; y++ ) 12225 { 12226 p = yi << 2; 12227 px[p+3] = pa =(a * ms) >>> ss; 12228 if ( pa > 0 ) 12229 { 12230 pa = 255 / pa; 12231 px[p] = ((r * ms) >>> ss ) * pa; 12232 px[p+1] = ((g * ms) >>> ss ) * pa; 12233 px[p+2] = ((b * ms) >>> ss ) * pa; 12234 } else { 12235 px[p] = px[p+1] = px[p+2] = 0 12236 } 12237 12238 p = ( x + (( ( p = y + ryp1) < h1 ? p : h1 ) * w )) << 2; 12239 12240 r -= si.r - ( si.r = px[p]); 12241 g -= si.g - ( si.g = px[p+1]); 12242 b -= si.b - ( si.b = px[p+2]); 12243 a -= si.a - ( si.a = px[p+3]); 12244 12245 si = si.n; 12246 12247 yi += w; 12248 } 12249 } 12250 } 12251 12252 } 12253 return true; 12254 }; 12255 12256 createjs.BlurFilter = createjs.promote(BlurFilter, "Filter"); 12257}()); 12258 12259//############################################################################## 12260// AlphaMapFilter.js 12261//############################################################################## 12262 12263this.createjs = this.createjs || {}; 12264 12265(function () { 12266 "use strict"; 12267 12268 12269// constructor: 12270 /** 12271 * Applies a greyscale alpha map image (or canvas) to the target, such that the alpha channel of the result will 12272 * be copied from the red channel of the map, and the RGB channels will be copied from the target. 12273 * 12274 * Generally, it is recommended that you use {{#crossLink "AlphaMaskFilter"}}{{/crossLink}}, because it has much 12275 * better performance. 12276 * 12277 * <h4>Example</h4> 12278 * This example draws a red->blue box, caches it, and then uses the cache canvas as an alpha map on a 100x100 image. 12279 * 12280 * var box = new createjs.Shape(); 12281 * box.graphics.beginLinearGradientFill(["#ff0000", "#0000ff"], [0, 1], 0, 0, 0, 100) 12282 * box.graphics.drawRect(0, 0, 100, 100); 12283 * box.cache(0, 0, 100, 100); 12284 * 12285 * var bmp = new createjs.Bitmap("path/to/image.jpg"); 12286 * bmp.filters = [ 12287 * new createjs.AlphaMapFilter(box.cacheCanvas) 12288 * ]; 12289 * bmp.cache(0, 0, 100, 100); 12290 * stage.addChild(bmp); 12291 * 12292 * See {{#crossLink "Filter"}}{{/crossLink}} for more information on applying filters. 12293 * @class AlphaMapFilter 12294 * @extends Filter 12295 * @constructor 12296 * @param {HTMLImageElement|HTMLCanvasElement} alphaMap The greyscale image (or canvas) to use as the alpha value for the 12297 * result. This should be exactly the same dimensions as the target. 12298 **/ 12299 function AlphaMapFilter(alphaMap) { 12300 12301 12302 // public properties: 12303 /** 12304 * The greyscale image (or canvas) to use as the alpha value for the result. This should be exactly the same 12305 * dimensions as the target. 12306 * @property alphaMap 12307 * @type HTMLImageElement|HTMLCanvasElement 12308 **/ 12309 this.alphaMap = alphaMap; 12310 12311 12312 // private properties: 12313 /** 12314 * @property _alphaMap 12315 * @protected 12316 * @type HTMLImageElement|HTMLCanvasElement 12317 **/ 12318 this._alphaMap = null; 12319 12320 /** 12321 * @property _mapData 12322 * @protected 12323 * @type Uint8ClampedArray 12324 **/ 12325 this._mapData = null; 12326 }
12327 var p = createjs.extend(AlphaMapFilter, createjs.Filter); 12328 12329 // TODO: deprecated 12330 // p.initialize = function() {}; // searchable for devs wondering where it is. REMOVED. See docs for details. 12331 12332 12333// public methods: 12334 /** docced in super class **/ 12335 p.clone = function () { 12336 var o = new AlphaMapFilter(this.alphaMap); 12337 o._alphaMap = this._alphaMap; 12338 o._mapData = this._mapData; 12339 return o; 12340 }; 12341 12342 /** docced in super class **/ 12343 p.toString = function () { 12344 return "[AlphaMapFilter]"; 12345 }; 12346 12347 12348// private methods: 12349 /** docced in super class **/ 12350 p._applyFilter = function (imageData) { 12351 if (!this.alphaMap) { return true; } 12352 if (!this._prepAlphaMap()) { return false; } 12353 12354 // TODO: update to support scenarios where the target has different dimensions. 12355 var data = imageData.data; 12356 var map = this._mapData; 12357 for(var i=0, l=data.length; i<l; i += 4) { data[i + 3] = map[i] || 0; } 12358 12359 return true; 12360 }; 12361 12362 /** 12363 * @method _prepAlphaMap 12364 * @protected 12365 **/ 12366 p._prepAlphaMap = function () { 12367 if (!this.alphaMap) { return false; } 12368 if (this.alphaMap == this._alphaMap && this._mapData) { return true; } 12369 12370 this._mapData = null; 12371 var map = this._alphaMap = this.alphaMap; 12372 var canvas = map; 12373 var ctx; 12374 if (map instanceof HTMLCanvasElement) { 12375 ctx = canvas.getContext("2d"); 12376 } else { 12377 canvas = createjs.createCanvas ? createjs.createCanvas() : document.createElement("canvas"); 12378 canvas.width = map.width; 12379 canvas.height = map.height; 12380 ctx = canvas.getContext("2d"); 12381 ctx.drawImage(map, 0, 0); 12382 } 12383 12384 try { 12385 var imgData = ctx.getImageData(0, 0, map.width, map.height); 12386 } catch (e) { 12387 //if (!this.suppressCrossDomainErrors) throw new Error("unable to access local image data: " + e); 12388 return false; 12389 } 12390 12391 this._mapData = imgData.data; 12392 return true; 12393 }; 12394 12395 12396 createjs.AlphaMapFilter = createjs.promote(AlphaMapFilter, "Filter"); 12397}()); 12398 12399//############################################################################## 12400// AlphaMaskFilter.js 12401//############################################################################## 12402 12403this.createjs = this.createjs || {}; 12404 12405(function () { 12406 "use strict"; 12407 12408 12409// constructor: 12410 /** 12411 * Applies the alpha from the mask image (or canvas) to the target, such that the alpha channel of the result will 12412 * be derived from the mask, and the RGB channels will be copied from the target. This can be used, for example, to 12413 * apply an alpha mask to a display object. This can also be used to combine a JPG compressed RGB image with a PNG32 12414 * alpha mask, which can result in a much smaller file size than a single PNG32 containing ARGB. 12415 * 12416 * <b>IMPORTANT NOTE: This filter currently does not support the targetCtx, or targetX/Y parameters correctly.</b> 12417 * 12418 * <h4>Example</h4> 12419 * This example draws a gradient box, then caches it and uses the "cacheCanvas" as the alpha mask on a 100x100 image. 12420 * 12421 * var box = new createjs.Shape(); 12422 * box.graphics.beginLinearGradientFill(["#000000", "rgba(0, 0, 0, 0)"], [0, 1], 0, 0, 100, 100) 12423 * box.graphics.drawRect(0, 0, 100, 100); 12424 * box.cache(0, 0, 100, 100); 12425 * 12426 * var bmp = new createjs.Bitmap("path/to/image.jpg"); 12427 * bmp.filters = [ 12428 * new createjs.AlphaMaskFilter(box.cacheCanvas) 12429 * ]; 12430 * bmp.cache(0, 0, 100, 100); 12431 * 12432 * See {{#crossLink "Filter"}}{{/crossLink}} for more information on applying filters. 12433 * @class AlphaMaskFilter 12434 * @extends Filter 12435 * @constructor 12436 * @param {HTMLImageElement|HTMLCanvasElement} mask 12437 **/ 12438 function AlphaMaskFilter(mask) { 12439 12440 12441 // public properties: 12442 /** 12443 * The image (or canvas) to use as the mask. 12444 * @property mask 12445 * @type HTMLImageElement|HTMLCanvasElement 12446 **/ 12447 this.mask = mask; 12448 } 12449 var p = createjs.extend(AlphaMaskFilter, createjs.Filter); 12450 12451 // TODO: deprecated 12452 // p.initialize = function() {}; // searchable for devs wondering where it is. REMOVED. See docs for details. 12453 12454 12455// public methods: 12456 /** 12457 * Applies the filter to the specified context. 12458 * 12459 * <strong>IMPORTANT NOTE: This filter currently does not support the targetCtx, or targetX/Y parameters 12460 * correctly.</strong> 12461 * @method applyFilter 12462 * @param {CanvasRenderingContext2D} ctx The 2D context to use as the source. 12463 * @param {Number} x The x position to use for the source rect. 12464 * @param {Number} y The y position to use for the source rect. 12465 * @param {Number} width The width to use for the source rect. 12466 * @param {Number} height The height to use for the source rect. 12467 * @param {CanvasRenderingContext2D} [targetCtx] NOT SUPPORTED IN THIS FILTER. The 2D context to draw the result to. Defaults to the context passed to ctx. 12468 * @param {Number} [targetX] NOT SUPPORTED IN THIS FILTER. The x position to draw the result to. Defaults to the value passed to x. 12469 * @param {Number} [targetY] NOT SUPPORTED IN THIS FILTER. The y position to draw the result to. Defaults to the value passed to y. 12470 * @return {Boolean} If the filter was applied successfully. 12471 **/ 12472 p.applyFilter = function (ctx, x, y, width, height, targetCtx, targetX, targetY) { 12473 if (!this.mask) { return true; } 12474 targetCtx = targetCtx || ctx; 12475 if (targetX == null) { targetX = x; } 12476 if (targetY == null) { targetY = y; } 12477 12478 targetCtx.save(); 12479 if (ctx != targetCtx) { 12480 // TODO: support targetCtx and targetX/Y 12481 // clearRect, then draw the ctx in? 12482 return false;
12483 } 12484 12485 targetCtx.globalCompositeOperation = "destination-in"; 12486 targetCtx.drawImage(this.mask, targetX, targetY); 12487 targetCtx.restore(); 12488 return true; 12489 }; 12490 12491 /** docced in super class **/ 12492 p.clone = function () { 12493 return new AlphaMaskFilter(this.mask); 12494 }; 12495 12496 /** docced in super class **/ 12497 p.toString = function () { 12498 return "[AlphaMaskFilter]"; 12499 }; 12500 12501 12502 createjs.AlphaMaskFilter = createjs.promote(AlphaMaskFilter, "Filter"); 12503}()); 12504 12505//############################################################################## 12506// ColorFilter.js 12507//############################################################################## 12508 12509this.createjs = this.createjs||{}; 12510 12511(function() { 12512 "use strict"; 12513 12514 12515// constructor: 12516 /** 12517 * Applies a color transform to DisplayObjects. 12518 * 12519 * <h4>Example</h4> 12520 * This example draws a red circle, and then transforms it to Blue. This is accomplished by multiplying all the channels 12521 * to 0 (except alpha, which is set to 1), and then adding 255 to the blue channel. 12522 * 12523 * var shape = new createjs.Shape().set({x:100,y:100}); 12524 * shape.graphics.beginFill("#ff0000").drawCircle(0,0,50); 12525 * 12526 * shape.filters = [ 12527 * new createjs.ColorFilter(0,0,0,1, 0,0,255,0) 12528 * ]; 12529 * shape.cache(-50, -50, 100, 100); 12530 * 12531 * See {{#crossLink "Filter"}}{{/crossLink}} for an more information on applying filters. 12532 * @class ColorFilter 12533 * @param {Number} [redMultiplier=1] The amount to multiply against the red channel. This is a range between 0 and 1. 12534 * @param {Number} [greenMultiplier=1] The amount to multiply against the green channel. This is a range between 0 and 1. 12535 * @param {Number} [blueMultiplier=1] The amount to multiply against the blue channel. This is a range between 0 and 1. 12536 * @param {Number} [alphaMultiplier=1] The amount to multiply against the alpha channel. This is a range between 0 and 1. 12537 * @param {Number} [redOffset=0] The amount to add to the red channel after it has been multiplied. This is a range 12538 * between -255 and 255. 12539 * @param {Number} [greenOffset=0] The amount to add to the green channel after it has been multiplied. This is a range 12540 * between -255 and 255. 12541 * @param {Number} [blueOffset=0] The amount to add to the blue channel after it has been multiplied. This is a range 12542 * between -255 and 255. 12543 * @param {Number} [alphaOffset=0] The amount to add to the alpha channel after it has been multiplied. This is a range 12544 * between -255 and 255. 12545 * @constructor 12546 * @extends Filter 12547 **/ 12548 function ColorFilter(redMultiplier, greenMultiplier, blueMultiplier, alphaMultiplier, redOffset, greenOffset, blueOffset, alphaOffset) { 12549 12550 12551 // public properties: 12552 /** 12553 * Red channel multiplier. 12554 * @property redMultiplier 12555 * @type Number 12556 **/ 12557 this.redMultiplier = redMultiplier != null ? redMultiplier : 1; 12558 12559 /** 12560 * Green channel multiplier. 12561 * @property greenMultiplier 12562 * @type Number 12563 **/ 12564 this.greenMultiplier = greenMultiplier != null ? greenMultiplier : 1; 12565 12566 /** 12567 * Blue channel multiplier. 12568 * @property blueMultiplier 12569 * @type Number 12570 **/ 12571 this.blueMultiplier = blueMultiplier != null ? blueMultiplier : 1; 12572 12573 /** 12574 * Alpha channel multiplier. 12575 * @property alphaMultiplier 12576 * @type Number 12577 **/ 12578 this.alphaMultiplier = alphaMultiplier != null ? alphaMultiplier : 1; 12579 12580 /** 12581 * Red channel offset (added to value). 12582 * @property redOffset 12583 * @type Number 12584 **/ 12585 this.redOffset = redOffset || 0; 12586 12587 /** 12588 * Green channel offset (added to value). 12589 * @property greenOffset 12590 * @type Number 12591 **/ 12592 this.greenOffset = greenOffset || 0; 12593 12594 /** 12595 * Blue channel offset (added to value). 12596 * @property blueOffset 12597 * @type Number 12598 **/ 12599 this.blueOffset = blueOffset || 0; 12600 12601 /** 12602 * Alpha channel offset (added to value). 12603 * @property alphaOffset 12604 * @type Number 12605 **/ 12606 this.alphaOffset = alphaOffset || 0; 12607 } 12608 var p = createjs.extend(ColorFilter, createjs.Filter); 12609 12610 // TODO: deprecated 12611 // p.initialize = function() {}; // searchable for devs wondering where it is. REMOVED. See docs for details. 12612 12613 12614// public methods: 12615 /** docced in super class **/ 12616 p.toString = function() { 12617 return "[ColorFilter]"; 12618 }; 12619 12620 /** docced in super class **/ 12621 p.clone = function() { 12622 return new ColorFilter(this.redMultiplier, this.greenMultiplier, this.blueMultiplier, this.alphaMultiplier, this.redOffset, this.greenOffset, this.blueOffset, this.alphaOffset); 12623 }; 12624 12625 12626// private methods: 12627 /** docced in super class **/ 12628 p._applyFilter = function(imageData) { 12629 var data = imageData.data; 12630 var l = data.length; 12631 for (var i=0; i<l; i+=4) { 12632 data[i] = data[i]*this.redMultiplier+this.redOffset; 12633 data[i+1] = data[i+1]*this.greenMultiplier+this.greenOffset; 12634 data[i+2] = data[i+2]*this.blueMultiplier+this.blueOffset; 12635 data[i+3] = data[i+3]*this.alphaMultiplier+this.alphaOffset; 12636 } 12637 return true; 12638 }; 12639 12640 12641 createjs.ColorFilter = createjs.promote(ColorFilter, "Filter"); 12642}()); 12643 12644//############################################################################## 12645// ColorMatrix.js 12646//############################################################################## 12647 12648this.createjs = this.createjs||{}; 12649 12650(function() { 12651 "use strict"; 12652 12653 12654// constructor: 12655 /** 12656 * Provides helper functions for assembling a matrix for use with the {{#crossLink "ColorMatrixFilter"}}{{/crossLink}}. 12657 * Most methods return the instance to facilitate chained calls. 12658 * 12659 * <h4>Example</h4> 12660 * 12661 * myColorMatrix.adjustHue(20).adjustBrightness(50); 12662 * 12663 * See {{#crossLink "Filter"}}{{/crossLink}} for an example of how to apply filters, or {{#crossLink "ColorMatrixFilter"}}{{/crossLink}} 12664 * for an example of how to use ColorMatrix to change a DisplayObject's color. 12665 * @class ColorMatrix 12666 * @param {Number} brightness 12667 * @param {Number} contrast 12668 * @param {Number} saturation 12669 * @param {Number} hue 12670 * @constructor 12671 **/ 12672 function ColorMatrix(brightness, contrast, saturation, hue) { 12673 this.setColor(brightness, contrast, saturation, hue); 12674 }
12675 var p = ColorMatrix.prototype; 12676 12677 /** 12678 * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`. 12679 * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}} 12680 * for details. 12681 * 12682 * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance. 12683 * 12684 * @method initialize 12685 * @protected 12686 * @deprecated 12687 */ 12688 // p.initialize = function() {}; // searchable for devs wondering where it is. 12689 12690 12691// constants: 12692 /** 12693 * Array of delta values for contrast calculations. 12694 * @property DELTA_INDEX 12695 * @type Array 12696 * @protected 12697 * @static 12698 **/ 12699 ColorMatrix.DELTA_INDEX = [ 12700 0, 0.01, 0.02, 0.04, 0.05, 0.06, 0.07, 0.08, 0.1, 0.11, 12701 0.12, 0.14, 0.15, 0.16, 0.17, 0.18, 0.20, 0.21, 0.22, 0.24, 12702 0.25, 0.27, 0.28, 0.30, 0.32, 0.34, 0.36, 0.38, 0.40, 0.42, 12703 0.44, 0.46, 0.48, 0.5, 0.53, 0.56, 0.59, 0.62, 0.65, 0.68, 12704 0.71, 0.74, 0.77, 0.80, 0.83, 0.86, 0.89, 0.92, 0.95, 0.98, 12705 1.0, 1.06, 1.12, 1.18, 1.24, 1.30, 1.36, 1.42, 1.48, 1.54, 12706 1.60, 1.66, 1.72, 1.78, 1.84, 1.90, 1.96, 2.0, 2.12, 2.25, 12707 2.37, 2.50, 2.62, 2.75, 2.87, 3.0, 3.2, 3.4, 3.6, 3.8, 12708 4.0, 4.3, 4.7, 4.9, 5.0, 5.5, 6.0, 6.5, 6.8, 7.0, 12709 7.3, 7.5, 7.8, 8.0, 8.4, 8.7, 9.0, 9.4, 9.6, 9.8, 12710 10.0 12711 ]; 12712 12713 /** 12714 * Identity matrix values. 12715 * @property IDENTITY_MATRIX 12716 * @type Array 12717 * @protected 12718 * @static 12719 **/ 12720 ColorMatrix.IDENTITY_MATRIX = [ 12721 1,0,0,0,0, 12722 0,1,0,0,0, 12723 0,0,1,0,0, 12724 0,0,0,1,0, 12725 0,0,0,0,1 12726 ]; 12727 12728 /** 12729 * The constant length of a color matrix. 12730 * @property LENGTH 12731 * @type Number 12732 * @protected 12733 * @static 12734 **/ 12735 ColorMatrix.LENGTH = ColorMatrix.IDENTITY_MATRIX.length; 12736 12737 12738// public methods: 12739 /** 12740 * Resets the instance with the specified values. 12741 * @method setColor 12742 * @param {Number} brightness 12743 * @param {Number} contrast 12744 * @param {Number} saturation 12745 * @param {Number} hue 12746 * @return {ColorMatrix} The ColorMatrix instance the method is called on (useful for chaining calls.) 12747 * @chainable 12748 */ 12749 p.setColor = function(brightness,contrast,saturation,hue) { 12750 return this.reset().adjustColor(brightness,contrast,saturation,hue); 12751 }; 12752 12753 /** 12754 * Resets the matrix to identity values. 12755 * @method reset 12756 * @return {ColorMatrix} The ColorMatrix instance the method is called on (useful for chaining calls.) 12757 * @chainable 12758 */ 12759 p.reset = function() { 12760 return this.copy(ColorMatrix.IDENTITY_MATRIX); 12761 }; 12762 12763 /** 12764 * Shortcut method to adjust brightness, contrast, saturation and hue. 12765 * Equivalent to calling adjustHue(hue), adjustContrast(contrast), 12766 * adjustBrightness(brightness), adjustSaturation(saturation), in that order. 12767 * @method adjustColor 12768 * @param {Number} brightness 12769 * @param {Number} contrast 12770 * @param {Number} saturation 12771 * @param {Number} hue 12772 * @return {ColorMatrix} The ColorMatrix instance the method is called on (useful for chaining calls.) 12773 * @chainable 12774 **/ 12775 p.adjustColor = function(brightness,contrast,saturation,hue) { 12776 this.adjustHue(hue); 12777 this.adjustContrast(contrast); 12778 this.adjustBrightness(brightness); 12779 return this.adjustSaturation(saturation); 12780 }; 12781 12782 /** 12783 * Adjusts the brightness of pixel color by adding the specified value to the red, green and blue channels. 12784 * Positive values will make the image brighter, negative values will make it darker. 12785 * @method adjustBrightness 12786 * @param {Number} value A value between -255 & 255 that will be added to the RGB channels. 12787 * @return {ColorMatrix} The ColorMatrix instance the method is called on (useful for chaining calls.) 12788 * @chainable 12789 **/ 12790 p.adjustBrightness = function(value) { 12791 if (value == 0 || isNaN(value)) { return this; } 12792 value = this._cleanValue(value,255); 12793 this._multiplyMatrix([ 12794 1,0,0,0,value, 12795 0,1,0,0,value, 12796 0,0,1,0,value, 12797 0,0,0,1,0, 12798 0,0,0,0,1 12799 ]); 12800 return this; 12801 }; 12802 12803 /** 12804 * Adjusts the contrast of pixel color. 12805 * Positive values will increase contrast, negative values will decrease contrast. 12806 * @method adjustContrast 12807 * @param {Number} value A value between -100 & 100. 12808 * @return {ColorMatrix} The ColorMatrix instance the method is called on (useful for chaining calls.) 12809 * @chainable 12810 **/ 12811 p.adjustContrast = function(value) { 12812 if (value == 0 || isNaN(value)) { return this; } 12813 value = this._cleanValue(value,100); 12814 var x; 12815 if (value<0) { 12816 x = 127+value/100*127; 12817 } else { 12818 x = value%1; 12819 if (x == 0) { 12820 x = ColorMatrix.DELTA_INDEX[value]; 12821 } else { 12822 x = ColorMatrix.DELTA_INDEX[(value<<0)]*(1-x)+ColorMatrix.DELTA_INDEX[(value<<0)+1]*x; // use linear interpolation for more granularity. 12823 } 12824 x = x*127+127; 12825 } 12826 this._multiplyMatrix([ 12827 x/127,0,0,0,0.5*(127-x), 12828 0,x/127,0,0,0.5*(127-x), 12829 0,0,x/127,0,0.5*(127-x), 12830 0,0,0,1,0, 12831 0,0,0,0,1 12832 ]); 12833 return this; 12834 }; 12835 12836 /** 12837 * Adjusts the color saturation of the pixel. 12838 * Positive values will increase saturation, negative values will decrease saturation (trend towards greyscale). 12839 * @method adjustSaturation 12840 * @param {Number} value A value between -100 & 100. 12841 * @return {ColorMatrix} The ColorMatrix instance the method is called on (useful for chaining calls.) 12842 * @chainable 12843 **/ 12844 p.adjustSaturation = function(value) { 12845 if (value == 0 || isNaN(value)) { return this; } 12846 value = this._cleanValue(value,100); 12847 var x = 1+((value > 0) ? 3*value/100 : value/100); 12848 var lumR = 0.3086; 12849 var lumG = 0.6094; 12850 var lumB = 0.0820; 12851 this._multiplyMatrix([ 12852 lumR*(1-x)+x,lumG*(1-x),lumB*(1-x),0,0, 12853 lumR*(1-x),lumG*(1-x)+x,lumB*(1-x),0,0, 12854 lumR*(1-x),lumG*(1-x),lumB*(1-x)+x,0,0, 12855 0,0,0,1,0, 12856 0,0,0,0,1 12857 ]); 12858 return this; 12859 }; 12860 12861 12862 /** 12863 * Adjusts the hue of the pixel color. 12864 * @method adjustHue 12865 * @param {Number} value A value between -180 & 180. 12866 * @return {ColorMatrix} The ColorMatrix instance the method is called on (useful for chaining calls.) 12867 * @chainable 12868 **/ 12869 p.adjustHue = function(value) { 12870 if (value == 0 || isNaN(value)) { return this; } 12871 value = this._cleanValue(value,180)/180*Math.PI;
12872 var cosVal = Math.cos(value); 12873 var sinVal = Math.sin(value); 12874 var lumR = 0.213; 12875 var lumG = 0.715; 12876 var lumB = 0.072; 12877 this._multiplyMatrix([ 12878 lumR+cosVal*(1-lumR)+sinVal*(-lumR),lumG+cosVal*(-lumG)+sinVal*(-lumG),lumB+cosVal*(-lumB)+sinVal*(1-lumB),0,0, 12879 lumR+cosVal*(-lumR)+sinVal*(0.143),lumG+cosVal*(1-lumG)+sinVal*(0.140),lumB+cosVal*(-lumB)+sinVal*(-0.283),0,0, 12880 lumR+cosVal*(-lumR)+sinVal*(-(1-lumR)),lumG+cosVal*(-lumG)+sinVal*(lumG),lumB+cosVal*(1-lumB)+sinVal*(lumB),0,0, 12881 0,0,0,1,0, 12882 0,0,0,0,1 12883 ]); 12884 return this; 12885 }; 12886 12887 /** 12888 * Concatenates (multiplies) the specified matrix with this one. 12889 * @method concat 12890 * @param {Array} matrix An array or ColorMatrix instance. 12891 * @return {ColorMatrix} The ColorMatrix instance the method is called on (useful for chaining calls.) 12892 * @chainable 12893 **/ 12894 p.concat = function(matrix) { 12895 matrix = this._fixMatrix(matrix); 12896 if (matrix.length != ColorMatrix.LENGTH) { return this; } 12897 this._multiplyMatrix(matrix); 12898 return this; 12899 }; 12900 12901 /** 12902 * Returns a clone of this ColorMatrix. 12903 * @method clone 12904 * @return {ColorMatrix} A clone of this ColorMatrix. 12905 **/ 12906 p.clone = function() { 12907 return (new ColorMatrix()).copy(this); 12908 }; 12909 12910 /** 12911 * Return a length 25 (5x5) array instance containing this matrix's values. 12912 * @method toArray 12913 * @return {Array} An array holding this matrix's values. 12914 **/ 12915 p.toArray = function() { 12916 var arr = []; 12917 for (var i= 0, l=ColorMatrix.LENGTH; i<l; i++) { 12918 arr[i] = this[i]; 12919 } 12920 return arr; 12921 }; 12922 12923 /** 12924 * Copy the specified matrix's values to this matrix. 12925 * @method copy 12926 * @param {Array} matrix An array or ColorMatrix instance. 12927 * @return {ColorMatrix} The ColorMatrix instance the method is called on (useful for chaining calls.) 12928 * @chainable 12929 **/ 12930 p.copy = function(matrix) { 12931 var l = ColorMatrix.LENGTH; 12932 for (var i=0;i<l;i++) { 12933 this[i] = matrix[i]; 12934 } 12935 return this; 12936 }; 12937 12938 /** 12939 * Returns a string representation of this object. 12940 * @method toString 12941 * @return {String} a string representation of the instance. 12942 **/ 12943 p.toString = function() { 12944 return "[ColorMatrix]"; 12945 }; 12946 12947 12948// private methods: 12949 /** 12950 * @method _multiplyMatrix 12951 * @param {Array} matrix 12952 * @protected 12953 **/ 12954 p._multiplyMatrix = function(matrix) { 12955 var i, j, k, col = []; 12956 12957 for (i=0;i<5;i++) { 12958 for (j=0;j<5;j++) { 12959 col[j] = this[j+i*5]; 12960 } 12961 for (j=0;j<5;j++) { 12962 var val=0; 12963 for (k=0;k<5;k++) { 12964 val += matrix[j+k*5]*col[k]; 12965 } 12966 this[j+i*5] = val; 12967 } 12968 } 12969 }; 12970 12971 /** 12972 * Make sure values are within the specified range, hue has a limit of 180, brightness is 255, others are 100. 12973 * @method _cleanValue 12974 * @param {Number} value The raw number 12975 * @param {Number} limit The maximum that the number can be. The minimum is the limit * -1. 12976 * @protected 12977 **/ 12978 p._cleanValue = function(value, limit) { 12979 return Math.min(limit,Math.max(-limit,value)); 12980 }; 12981 12982 /** 12983 * Makes sure matrixes are 5x5 (25 long). 12984 * @method _fixMatrix 12985 * @param {Array} matrix 12986 * @protected 12987 **/ 12988 p._fixMatrix = function(matrix) { 12989 if (matrix instanceof ColorMatrix) { matrix = matrix.toArray(); } 12990 if (matrix.length < ColorMatrix.LENGTH) { 12991 matrix = matrix.slice(0,matrix.length).concat(ColorMatrix.IDENTITY_MATRIX.slice(matrix.length,ColorMatrix.LENGTH)); 12992 } else if (matrix.length > ColorMatrix.LENGTH) { 12993 matrix = matrix.slice(0,ColorMatrix.LENGTH); 12994 } 12995 return matrix; 12996 }; 12997 12998 12999 createjs.ColorMatrix = ColorMatrix; 13000}()); 13001 13002//############################################################################## 13003// ColorMatrixFilter.js 13004//############################################################################## 13005 13006this.createjs = this.createjs||{}; 13007 13008(function() { 13009 "use strict"; 13010 13011 13012// constructor: 13013 /** 13014 * Allows you to carry out complex color operations such as modifying saturation, brightness, or inverting. See the 13015 * {{#crossLink "ColorMatrix"}}{{/crossLink}} for more information on changing colors. For an easier color transform, 13016 * consider the {{#crossLink "ColorFilter"}}{{/crossLink}}. 13017 * 13018 * <h4>Example</h4> 13019 * This example creates a red circle, inverts its hue, and then saturates it to brighten it up. 13020 * 13021 * var shape = new createjs.Shape().set({x:100,y:100}); 13022 * shape.graphics.beginFill("#ff0000").drawCircle(0,0,50); 13023 * 13024 * var matrix = new createjs.ColorMatrix().adjustHue(180).adjustSaturation(100); 13025 * shape.filters = [ 13026 * new createjs.ColorMatrixFilter(matrix) 13027 * ]; 13028 * 13029 * shape.cache(-50, -50, 100, 100); 13030 * 13031 * See {{#crossLink "Filter"}}{{/crossLink}} for an more information on applying filters. 13032 * @class ColorMatrixFilter 13033 * @constructor 13034 * @extends Filter 13035 * @param {Array | ColorMatrix} matrix A 4x5 matrix describing the color operation to perform. See also the {{#crossLink "ColorMatrix"}}{{/crossLink}} 13036 * class. 13037 **/ 13038 function ColorMatrixFilter(matrix) { 13039 13040 13041 // public properties: 13042 /** 13043 * A 4x5 matrix describing the color operation to perform. See also the {{#crossLink "ColorMatrix"}}{{/crossLink}} 13044 * @property matrix 13045 * @type Array | ColorMatrix 13046 **/ 13047 this.matrix = matrix; 13048 }
13049 var p = createjs.extend(ColorMatrixFilter, createjs.Filter); 13050 13051 // TODO: deprecated 13052 // p.initialize = function() {}; // searchable for devs wondering where it is. REMOVED. See docs for details. 13053 13054 13055// public methods: 13056 /** docced in super class **/ 13057 p.toString = function() { 13058 return "[ColorMatrixFilter]"; 13059 }; 13060 13061 /** docced in super class **/ 13062 p.clone = function() { 13063 return new ColorMatrixFilter(this.matrix); 13064 }; 13065 13066// private methods: 13067 /** docced in super class **/ 13068 p._applyFilter = function(imageData) { 13069 var data = imageData.data; 13070 var l = data.length; 13071 var r,g,b,a; 13072 var mtx = this.matrix; 13073 var m0 = mtx[0], m1 = mtx[1], m2 = mtx[2], m3 = mtx[3], m4 = mtx[4]; 13074 var m5 = mtx[5], m6 = mtx[6], m7 = mtx[7], m8 = mtx[8], m9 = mtx[9]; 13075 var m10 = mtx[10], m11 = mtx[11], m12 = mtx[12], m13 = mtx[13], m14 = mtx[14]; 13076 var m15 = mtx[15], m16 = mtx[16], m17 = mtx[17], m18 = mtx[18], m19 = mtx[19]; 13077 13078 for (var i=0; i<l; i+=4) { 13079 r = data[i]; 13080 g = data[i+1]; 13081 b = data[i+2]; 13082 a = data[i+3]; 13083 data[i] = r*m0+g*m1+b*m2+a*m3+m4; // red 13084 data[i+1] = r*m5+g*m6+b*m7+a*m8+m9; // green 13085 data[i+2] = r*m10+g*m11+b*m12+a*m13+m14; // blue 13086 data[i+3] = r*m15+g*m16+b*m17+a*m18+m19; // alpha 13087 } 13088 return true; 13089 }; 13090 13091 13092 createjs.ColorMatrixFilter = createjs.promote(ColorMatrixFilter, "Filter"); 13093}()); 13094 13095//############################################################################## 13096// Touch.js 13097//############################################################################## 13098 13099this.createjs = this.createjs||{}; 13100 13101(function() { 13102 "use strict"; 13103 13104 13105// constructor: 13106 /** 13107 * Global utility for working with multi-touch enabled devices in EaselJS. Currently supports W3C Touch API (iOS and 13108 * modern Android browser) and the Pointer API (IE), including ms-prefixed events in IE10, and unprefixed in IE11. 13109 * 13110 * Ensure that you {{#crossLink "Touch/disable"}}{{/crossLink}} touch when cleaning up your application. You do not have 13111 * to check if touch is supported to enable it, as it will fail gracefully if it is not supported. 13112 * 13113 * <h4>Example</h4> 13114 * 13115 * var stage = new createjs.Stage("canvasId"); 13116 * createjs.Touch.enable(stage); 13117 * 13118 * <strong>Note:</strong> It is important to disable Touch on a stage that you are no longer using: 13119 * 13120 * createjs.Touch.disable(stage); 13121 * 13122 * @class Touch 13123 * @static 13124 **/ 13125 function Touch() { 13126 throw "Touch cannot be instantiated"; 13127 } 13128 13129 13130// public static methods: 13131 /** 13132 * Returns `true` if touch is supported in the current browser. 13133 * @method isSupported 13134 * @return {Boolean} Indicates whether touch is supported in the current browser. 13135 * @static 13136 **/ 13137 Touch.isSupported = function() { 13138 return !!(('ontouchstart' in window) // iOS & Android 13139 || (window.navigator['msPointerEnabled'] && window.navigator['msMaxTouchPoints'] > 0) // IE10 13140 || (window.navigator['pointerEnabled'] && window.navigator['maxTouchPoints'] > 0)); // IE11+ 13141 }; 13142 13143 /** 13144 * Enables touch interaction for the specified EaselJS {{#crossLink "Stage"}}{{/crossLink}}. Currently supports iOS 13145 * (and compatible browsers, such as modern Android browsers), and IE10/11. Supports both single touch and 13146 * multi-touch modes. Extends the EaselJS {{#crossLink "MouseEvent"}}{{/crossLink}} model, but without support for 13147 * double click or over/out events. See the MouseEvent {{#crossLink "MouseEvent/pointerId:property"}}{{/crossLink}} 13148 * for more information. 13149 * @method enable 13150 * @param {Stage} stage The {{#crossLink "Stage"}}{{/crossLink}} to enable touch on. 13151 * @param {Boolean} [singleTouch=false] If `true`, only a single touch will be active at a time. 13152 * @param {Boolean} [allowDefault=false] If `true`, then default gesture actions (ex. scrolling, zooming) will be 13153 * allowed when the user is interacting with the target canvas. 13154 * @return {Boolean} Returns `true` if touch was successfully enabled on the target stage. 13155 * @static 13156 **/ 13157 Touch.enable = function(stage, singleTouch, allowDefault) { 13158 if (!stage || !stage.canvas || !Touch.isSupported()) { return false; } 13159 if (stage.__touch) { return true; } 13160 13161 // inject required properties on stage: 13162 stage.__touch = {pointers:{}, multitouch:!singleTouch, preventDefault:!allowDefault, count:0}; 13163
13164 // note that in the future we may need to disable the standard mouse event model before adding 13165 // these to prevent duplicate calls. It doesn't seem to be an issue with iOS devices though. 13166 if ('ontouchstart' in window) { Touch._IOS_enable(stage); } 13167 else if (window.navigator['msPointerEnabled'] || window.navigator["pointerEnabled"]) { Touch._IE_enable(stage); } 13168 return true; 13169 }; 13170 13171 /** 13172 * Removes all listeners that were set up when calling `Touch.enable()` on a stage. 13173 * @method disable 13174 * @param {Stage} stage The {{#crossLink "Stage"}}{{/crossLink}} to disable touch on. 13175 * @static 13176 **/ 13177 Touch.disable = function(stage) { 13178 if (!stage) { return; } 13179 if ('ontouchstart' in window) { Touch._IOS_disable(stage); } 13180 else if (window.navigator['msPointerEnabled'] || window.navigator["pointerEnabled"]) { Touch._IE_disable(stage); } 13181 13182 delete stage.__touch; 13183 }; 13184 13185 13186// Private static methods: 13187 /** 13188 * @method _IOS_enable 13189 * @protected 13190 * @param {Stage} stage 13191 * @static 13192 **/ 13193 Touch._IOS_enable = function(stage) { 13194 var canvas = stage.canvas; 13195 var f = stage.__touch.f = function(e) { Touch._IOS_handleEvent(stage,e); }; 13196 canvas.addEventListener("touchstart", f, false); 13197 canvas.addEventListener("touchmove", f, false); 13198 canvas.addEventListener("touchend", f, false); 13199 canvas.addEventListener("touchcancel", f, false); 13200 }; 13201 13202 /** 13203 * @method _IOS_disable 13204 * @protected 13205 * @param {Stage} stage 13206 * @static 13207 **/ 13208 Touch._IOS_disable = function(stage) { 13209 var canvas = stage.canvas; 13210 if (!canvas) { return; } 13211 var f = stage.__touch.f; 13212 canvas.removeEventListener("touchstart", f, false); 13213 canvas.removeEventListener("touchmove", f, false); 13214 canvas.removeEventListener("touchend", f, false); 13215 canvas.removeEventListener("touchcancel", f, false); 13216 }; 13217 13218 /** 13219 * @method _IOS_handleEvent 13220 * @param {Stage} stage 13221 * @param {Object} e The event to handle 13222 * @protected 13223 * @static 13224 **/ 13225 Touch._IOS_handleEvent = function(stage, e) { 13226 if (!stage) { return; } 13227 if (stage.__touch.preventDefault) { e.preventDefault&&e.preventDefault(); } 13228 var touches = e.changedTouches; 13229 var type = e.type; 13230 for (var i= 0,l=touches.length; i<l; i++) { 13231 var touch = touches[i]; 13232 var id = touch.identifier; 13233 if (touch.target != stage.canvas) { continue; } 13234 13235 if (type == "touchstart") { 13236 this._handleStart(stage, id, e, touch.pageX, touch.pageY); 13237 } else if (type == "touchmove") { 13238 this._handleMove(stage, id, e, touch.pageX, touch.pageY); 13239 } else if (type == "touchend" || type == "touchcancel") { 13240 this._handleEnd(stage, id, e); 13241 } 13242 } 13243 }; 13244 13245 /** 13246 * @method _IE_enable 13247 * @protected 13248 * @param {Stage} stage 13249 * @static 13250 **/ 13251 Touch._IE_enable = function(stage) { 13252 var canvas = stage.canvas; 13253 var f = stage.__touch.f = function(e) { Touch._IE_handleEvent(stage,e); }; 13254 13255 if (window.navigator["pointerEnabled"] === undefined) { 13256 canvas.addEventListener("MSPointerDown", f, false); 13257 window.addEventListener("MSPointerMove", f, false); 13258 window.addEventListener("MSPointerUp", f, false); 13259 window.addEventListener("MSPointerCancel", f, false); 13260 if (stage.__touch.preventDefault) { canvas.style.msTouchAction = "none"; } 13261 } else { 13262 canvas.addEventListener("pointerdown", f, false); 13263 window.addEventListener("pointermove", f, false); 13264 window.addEventListener("pointerup", f, false); 13265 window.addEventListener("pointercancel", f, false); 13266 if (stage.__touch.preventDefault) { canvas.style.touchAction = "none"; } 13267 13268 } 13269 stage.__touch.activeIDs = {}; 13270 }; 13271 13272 /** 13273 * @method _IE_disable 13274 * @protected 13275 * @param {Stage} stage 13276 * @static 13277 **/ 13278 Touch._IE_disable = function(stage) { 13279 var f = stage.__touch.f; 13280 13281 if (window.navigator["pointerEnabled"] === undefined) { 13282 window.removeEventListener("MSPointerMove", f, false); 13283 window.removeEventListener("MSPointerUp", f, false); 13284 window.removeEventListener("MSPointerCancel", f, false); 13285 if (stage.canvas) { 13286 stage.canvas.removeEventListener("MSPointerDown", f, false); 13287 } 13288 } else { 13289 window.removeEventListener("pointermove", f, false); 13290 window.removeEventListener("pointerup", f, false); 13291 window.removeEventListener("pointercancel", f, false); 13292 if (stage.canvas) { 13293 stage.canvas.removeEventListener("pointerdown", f, false); 13294 } 13295 } 13296 }; 13297 13298 /** 13299 * @method _IE_handleEvent 13300 * @param {Stage} stage 13301 * @param {Object} e The event to handle. 13302 * @protected 13303 * @static 13304 **/ 13305 Touch._IE_handleEvent = function(stage, e) { 13306 if (!stage) { return; } 13307 if (stage.__touch.preventDefault) { e.preventDefault && e.preventDefault(); } 13308 var type = e.type; 13309 var id = e.pointerId; 13310 var ids = stage.__touch.activeIDs; 13311 13312 if (type == "MSPointerDown" || type == "pointerdown") { 13313 if (e.srcElement != stage.canvas) { return; } 13314 ids[id] = true; 13315 this._handleStart(stage, id, e, e.pageX, e.pageY); 13316 } else if (ids[id]) { // it's an id we're watching 13317 if (type == "MSPointerMove" || type == "pointermove") { 13318 this._handleMove(stage, id, e, e.pageX, e.pageY); 13319 } else if (type == "MSPointerUp" || type == "MSPointerCancel" 13320 || type == "pointerup" || type == "pointercancel") { 13321 delete(ids[id]); 13322 this._handleEnd(stage, id, e); 13323 } 13324 } 13325 }; 13326 13327 /** 13328 * @method _handleStart 13329 * @param {Stage} stage 13330 * @param {String|Number} id 13331 * @param {Object} e 13332 * @param {Number} x 13333 * @param {Number} y 13334 * @protected 13335 **/ 13336 Touch._handleStart = function(stage, id, e, x, y) { 13337 var props = stage.__touch; 13338 if (!props.multitouch && props.count) { return; } 13339 var ids = props.pointers; 13340 if (ids[id]) { return; } 13341 ids[id] = true; 13342 props.count++; 13343 stage._handlePointerDown(id, e, x, y); 13344 }; 13345 13346 /** 13347 * @method _handleMove 13348 * @param {Stage} stage 13349 * @param {String|Number} id 13350 * @param {Object} e 13351 * @param {Number} x 13352 * @param {Number} y 13353 * @protected 13354 **/ 13355 Touch._handleMove = function(stage, id, e, x, y) { 13356 if (!stage.__touch.pointers[id]) { return; } 13357 stage._handlePointerMove(id, e, x, y); 13358 }; 13359 13360 /** 13361 * @method _handleEnd 13362 * @param {Stage} stage 13363 * @param {String|Number} id 13364 * @param {Object} e 13365 * @protected 13366 **/ 13367 Touch._handleEnd = function(stage, id, e) { 13368 // TODO: cancel should be handled differently for proper UI (ex. an up would trigger a click, a cancel would more closely resemble an out). 13369 var props = stage.__touch; 13370 var ids = props.pointers; 13371 if (!ids[id]) { return; } 13372 props.count--; 13373 stage._handlePointerUp(id, e, true); 13374 delete(ids[id]); 13375 }; 13376 13377 13378 createjs.Touch = Touch; 13379}()); 13380 13381//############################################################################## 13382// version.js 13383//############################################################################## 13384 13385this.createjs = this.createjs || {}; 13386 13387(function() { 13388 "use strict"; 13389 13390 /** 13391 * Static class holding library specific information such as the version and buildDate of 13392 * the library. 13393 * @class EaselJS 13394 **/ 13395 var s = createjs.EaselJS = createjs.EaselJS || {}; 13396 13397 /** 13398 * The version string for this release. 13399 * @property version
13400 * @type String 13401 * @static 13402 **/ 13403 s.version = /*=version*/"0.8.2"; // injected by build process 13404 13405 /** 13406 * The build date for this release in UTC format. 13407 * @property buildDate 13408 * @type String 13409 * @static 13410 **/ 13411 s.buildDate = /*=date*/"Thu, 26 Nov 2015 20:44:34 GMT"; // injected by build process 13412 13413})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.