not really known
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

13412 lines
447 KiB

  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. // extend.js
  30. //##############################################################################
  31. this.createjs = this.createjs||{};
  32. /**
  33. * @class Utility Methods
  34. */
  35. /**
  36. * Sets up the prototype chain and constructor property for a new class.
  37. *
  38. * This should be called right after creating the class constructor.
  39. *
  40. * function MySubClass() {}
  41. * createjs.extend(MySubClass, MySuperClass);
  42. * MySubClass.prototype.doSomething = function() { }
  43. *
  44. * var foo = new MySubClass();
  45. * console.log(foo instanceof MySuperClass); // true
  46. * console.log(foo.prototype.constructor === MySubClass); // true
  47. *
  48. * @method extend
  49. * @param {Function} subclass The subclass.
  50. * @param {Function} superclass The superclass to extend.
  51. * @return {Function} Returns the subclass's new prototype.
  52. */
  53. createjs.extend = function(subclass, superclass) {
  54. "use strict";
  55. function o() { this.constructor = subclass; }
  56. o.prototype = superclass.prototype;
  57. return (subclass.prototype = new o());
  58. };
  59. //##############################################################################
  60. // promote.js
  61. //##############################################################################
  62. this.createjs = this.createjs||{};
  63. /**
  64. * @class Utility Methods
  65. */
  66. /**
  67. * Promotes any methods on the super class that were overridden, by creating an alias in the format `prefix_methodName`.
  68. * It is recommended to use the super class's name as the prefix.
  69. * An alias to the super class's constructor is always added in the format `prefix_constructor`.
  70. * This allows the subclass to call super class methods without using `function.call`, providing better performance.
  71. *
  72. * For example, if `MySubClass` extends `MySuperClass`, and both define a `draw` method, then calling `promote(MySubClass, "MySuperClass")`
  73. * would add a `MySuperClass_constructor` method to MySubClass and promote the `draw` method on `MySuperClass` to the
  74. * prototype of `MySubClass` as `MySuperClass_draw`.
  75. *
  76. * This should be called after the class's prototype is fully defined.
  77. *
  78. * function ClassA(name) {
  79. * this.name = name;
  80. * }
  81. * ClassA.prototype.greet = function() {
  82. * return "Hello "+this.name;
  83. * }
  84. *
  85. * function ClassB(name, punctuation) {
  86. * this.ClassA_constructor(name);
  87. * this.punctuation = punctuation;
  88. * }
  89. * createjs.extend(ClassB, ClassA);
  90. * ClassB.prototype.greet = function() {
  91. * return this.ClassA_greet()+this.punctuation;
  92. * }
  93. * createjs.promote(ClassB, "ClassA");
  94. *
  95. * var foo = new ClassB("World", "!?!");
  96. * console.log(foo.greet()); // Hello World!?!
  97. *
  98. * @method promote
  99. * @param {Function} subclass The class to promote super class methods on.
  100. * @param {String} prefix The prefix to add to the promoted method names. Usually the name of the superclass.
  101. * @return {Function} Returns the subclass.
  102. */
  103. createjs.promote = function(subclass, prefix) {
  104. "use strict";
  105. var subP = subclass.prototype, supP = (Object.getPrototypeOf&&Object.getPrototypeOf(subP))||subP.__proto__;
  106. if (supP) {
  107. subP[(prefix+="_") + "constructor"] = supP.constructor; // constructor is not always innumerable
  108. for (var n in supP) {
  109. if (subP.hasOwnProperty(n) && (typeof supP[n] == "function")) { subP[prefix + n] = supP[n]; }
  110. }
  111. }
  112. return subclass;
  113. };
  114. //##############################################################################
  115. // indexOf.js
  116. //##############################################################################
  117. this.createjs = this.createjs||{};
  118. /**
  119. * @class Utility Methods
  120. */
  121. /**
  122. * Finds the first occurrence of a specified value searchElement in the passed in array, and returns the index of
  123. * that value. Returns -1 if value is not found.
  124. *
  125. * var i = createjs.indexOf(myArray, myElementToFind);
  126. *
  127. * @method indexOf
  128. * @param {Array} array Array to search for searchElement
  129. * @param searchElement Element to find in array.
  130. * @return {Number} The first index of searchElement in array.
  131. */
  132. createjs.indexOf = function (array, searchElement){
  133. "use strict";
  134. for (var i = 0,l=array.length; i < l; i++) {
  135. if (searchElement === array[i]) {
  136. return i;
  137. }
  138. }
  139. return -1;
  140. };
  141. //##############################################################################
  142. // Event.js
  143. //##############################################################################
  144. this.createjs = this.createjs||{};
  145. (function() {
  146. "use strict";
  147. // constructor:
  148. /**
  149. * Contains properties and methods shared by all events for use with
  150. * {{#crossLink "EventDispatcher"}}{{/crossLink}}.
  151. *
  152. * Note that Event objects are often reused, so you should never
  153. * rely on an event object's state outside of the call stack it was received in.
  154. * @class Event
  155. * @param {String} type The event type.
  156. * @param {Boolean} bubbles Indicates whether the event will bubble through the display list.
  157. * @param {Boolean} cancelable Indicates whether the default behaviour of this event can be cancelled.
  158. * @constructor
  159. **/
  160. function Event(type, bubbles, cancelable) {
  161. // public properties:
  162. /**
  163. * The type of event.
  164. * @property type
  165. * @type String
  166. **/
  167. this.type = type;
  168. /**
  169. * The object that generated an event.
  170. * @property target
  171. * @type Object
  172. * @default null
  173. * @readonly
  174. */
  175. this.target = null;
  176. /**
  177. * The current target that a bubbling event is being dispatched from. For non-bubbling events, this will
  178. * always be the same as target. For example, if childObj.parent = parentObj, and a bubbling event
  179. * is generated from childObj, then a listener on parentObj would receive the event with
  180. * target=childObj (the original target) and currentTarget=parentObj (where the listener was added).
  181. * @property currentTarget
  182. * @type Object
  183. * @default null
  184. * @readonly
  185. */
  186. this.currentTarget = null;
  187. /**
  188. * For bubbling events, this indicates the current event phase:<OL>
  189. * <LI> capture phase: starting from the top parent to the target</LI>
  190. * <LI> at target phase: currently being dispatched from the target</LI>
  191. * <LI> bubbling phase: from the target to the top parent</LI>
  192. * </OL>
  193. * @property eventPhase
  194. * @type Number
  195. * @default 0
  196. * @readonly
  197. */
  198. this.eventPhase = 0;
  199. /**
  200. * Indicates whether the event will bubble through the display list.
  201. * @property bubbles
  202. * @type Boolean
  203. * @default false
  204. * @readonly
  205. */
  206. this.bubbles = !!bubbles;
  207. /**
  208. * Indicates whether the default behaviour of this event can be cancelled via
  209. * {{#crossLink "Event/preventDefault"}}{{/crossLink}}. This is set via the Event constructor.
  210. * @property cancelable
  211. * @type Boolean
  212. * @default false
  213. * @readonly
  214. */
  215. this.cancelable = !!cancelable;
  216. /**
  217. * The epoch time at which this event was created.
  218. * @property timeStamp
  219. * @type Number
  220. * @default 0
  221. * @readonly
  222. */
  223. this.timeStamp = (new Date()).getTime();
  224. /**
  225. * Indicates if {{#crossLink "Event/preventDefault"}}{{/crossLink}} has been called
  226. * on this event.
  227. * @property defaultPrevented
  228. * @type Boolean
  229. * @default false
  230. * @readonly
  231. */
  232. this.defaultPrevented = false;
  233. /**
  234. * Indicates if {{#crossLink "Event/stopPropagation"}}{{/crossLink}} or
  235. * {{#crossLink "Event/stopImmediatePropagation"}}{{/crossLink}} has been called on this event.
  236. * @property propagationStopped
  237. * @type Boolean
  238. * @default false
  239. * @readonly
  240. */
  241. this.propagationStopped = false;
  242. /**
  243. * Indicates if {{#crossLink "Event/stopImmediatePropagation"}}{{/crossLink}} has been called
  244. * on this event.
  245. * @property immediatePropagationStopped
  246. * @type Boolean
  247. * @default false
  248. * @readonly
  249. */
  250. this.immediatePropagationStopped = false;
  251. /**
  252. * Indicates if {{#crossLink "Event/remove"}}{{/crossLink}} has been called on this event.
  253. * @property removed
  254. * @type Boolean
  255. * @default false
  256. * @readonly
  257. */
  258. this.removed = false;
  259. }
  260. var p = Event.prototype;
  261. /**
  262. * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`.
  263. * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}}
  264. * for details.
  265. *
  266. * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance.
  267. *
  268. * @method initialize
  269. * @protected
  270. * @deprecated
  271. */
  272. // p.initialize = function() {}; // searchable for devs wondering where it is.
  273. // public methods:
  274. /**
  275. * Sets {{#crossLink "Event/defaultPrevented"}}{{/crossLink}} to true if the event is cancelable.
  276. * Mirrors the DOM level 2 event standard. In general, cancelable events that have `preventDefault()` called will
  277. * cancel the default behaviour associated with the event.
  278. * @method preventDefault
  279. **/
  280. p.preventDefault = function() {
  281. this.defaultPrevented = this.cancelable&&true;
  282. };
  283. /**
  284. * Sets {{#crossLink "Event/propagationStopped"}}{{/crossLink}} to true.
  285. * Mirrors the DOM event standard.
  286. * @method stopPropagation
  287. **/
  288. p.stopPropagation = function() {
  289. this.propagationStopped = true;
  290. };
  291. /**
  292. * Sets {{#crossLink "Event/propagationStopped"}}{{/crossLink}} and
  293. * {{#crossLink "Event/immediatePropagationStopped"}}{{/crossLink}} to true.
  294. * Mirrors the DOM event standard.
  295. * @method stopImmediatePropagation
  296. **/
  297. p.stopImmediatePropagation = function() {
  298. this.immediatePropagationStopped = this.propagationStopped = true;
  299. };
  300. /**
  301. * Causes the active listener to be removed via removeEventListener();
  302. *
  303. * myBtn.addEventListener("click", function(evt) {
  304. * // do stuff...
  305. * evt.remove(); // removes this listener.
  306. * });
  307. *
  308. * @method remove
  309. **/
  310. p.remove = function() {
  311. this.removed = true;
  312. };
  313. /**
  314. * Returns a clone of the Event instance.
  315. * @method clone
  316. * @return {Event} a clone of the Event instance.
  317. **/
  318. p.clone = function() {
  319. return new Event(this.type, this.bubbles, this.cancelable);
  320. };
  321. /**
  322. * Provides a chainable shortcut method for setting a number of properties on the instance.
  323. *
  324. * @method set
  325. * @param {Object} props A generic object containing properties to copy to the instance.
  326. * @return {Event} Returns the instance the method is called on (useful for chaining calls.)
  327. * @chainable
  328. */
  329. p.set = function(props) {
  330. for (var n in props) { this[n] = props[n]; }
  331. return this;
  332. };
  333. /**
  334. * Returns a string representation of this object.
  335. * @method toString
  336. * @return {String} a string representation of the instance.
  337. **/
  338. p.toString = function() {
  339. return "[Event (type="+this.type+")]";
  340. };
  341. createjs.Event = Event;
  342. }());
  343. //##############################################################################
  344. // EventDispatcher.js
  345. //##############################################################################
  346. this.createjs = this.createjs||{};
  347. (function() {
  348. "use strict";
  349. // constructor:
  350. /**
  351. * EventDispatcher provides methods for managing queues of event listeners and dispatching events.
  352. *
  353. * You can either extend EventDispatcher or mix its methods into an existing prototype or instance by using the
  354. * EventDispatcher {{#crossLink "EventDispatcher/initialize"}}{{/crossLink}} method.
  355. *
  356. * Together with the CreateJS Event class, EventDispatcher provides an extended event model that is based on the
  357. * DOM Level 2 event model, including addEventListener, removeEventListener, and dispatchEvent. It supports
  358. * bubbling / capture, preventDefault, stopPropagation, stopImmediatePropagation, and handleEvent.
  359. *
  360. * EventDispatcher also exposes a {{#crossLink "EventDispatcher/on"}}{{/crossLink}} method, which makes it easier
  361. * to create scoped listeners, listeners that only run once, and listeners with associated arbitrary data. The
  362. * {{#crossLink "EventDispatcher/off"}}{{/crossLink}} method is merely an alias to
  363. * {{#crossLink "EventDispatcher/removeEventListener"}}{{/crossLink}}.
  364. *
  365. * Another addition to the DOM Level 2 model is the {{#crossLink "EventDispatcher/removeAllEventListeners"}}{{/crossLink}}
  366. * method, which can be used to listeners for all events, or listeners for a specific event. The Event object also
  367. * includes a {{#crossLink "Event/remove"}}{{/crossLink}} method which removes the active listener.
  368. *
  369. * <h4>Example</h4>
  370. * Add EventDispatcher capabilities to the "MyClass" class.
  371. *
  372. * EventDispatcher.initialize(MyClass.prototype);
  373. *
  374. * Add an event (see {{#crossLink "EventDispatcher/addEventListener"}}{{/crossLink}}).
  375. *
  376. * instance.addEventListener("eventName", handlerMethod);
  377. * function handlerMethod(event) {
  378. * console.log(event.target + " Was Clicked");
  379. * }
  380. *
  381. * <b>Maintaining proper scope</b><br />
  382. * Scope (ie. "this") can be be a challenge with events. Using the {{#crossLink "EventDispatcher/on"}}{{/crossLink}}
  383. * method to subscribe to events simplifies this.
  384. *
  385. * instance.addEventListener("click", function(event) {
  386. * console.log(instance == this); // false, scope is ambiguous.
  387. * });
  388. *
  389. * instance.on("click", function(event) {
  390. * console.log(instance == this); // true, "on" uses dispatcher scope by default.
  391. * });
  392. *
  393. * If you want to use addEventListener instead, you may want to use function.bind() or a similar proxy to manage
  394. * scope.
  395. *
  396. * <b>Browser support</b>
  397. * The event model in CreateJS can be used separately from the suite in any project, however the inheritance model
  398. * requires modern browsers (IE9+).
  399. *
  400. *
  401. * @class EventDispatcher
  402. * @constructor
  403. **/
  404. function EventDispatcher() {
  405. // private properties:
  406. /**
  407. * @protected
  408. * @property _listeners
  409. * @type Object
  410. **/
  411. this._listeners = null;
  412. /**
  413. * @protected
  414. * @property _captureListeners
  415. * @type Object
  416. **/
  417. this._captureListeners = null;
  418. }
  419. var p = EventDispatcher.prototype;
  420. /**
  421. * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`.
  422. * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}}
  423. * for details.
  424. *
  425. * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance.
  426. *
  427. * @method initialize
  428. * @protected
  429. * @deprecated
  430. */
  431. // p.initialize = function() {}; // searchable for devs wondering where it is.
  432. // static public methods:
  433. /**
  434. * Static initializer to mix EventDispatcher methods into a target object or prototype.
  435. *
  436. * EventDispatcher.initialize(MyClass.prototype); // add to the prototype of the class
  437. * EventDispatcher.initialize(myObject); // add to a specific instance
  438. *
  439. * @method initialize
  440. * @static
  441. * @param {Object} target The target object to inject EventDispatcher methods into. This can be an instance or a
  442. * prototype.
  443. **/
  444. EventDispatcher.initialize = function(target) {
  445. target.addEventListener = p.addEventListener;
  446. target.on = p.on;
  447. target.removeEventListener = target.off = p.removeEventListener;
  448. target.removeAllEventListeners = p.removeAllEventListeners;
  449. target.hasEventListener = p.hasEventListener;
  450. target.dispatchEvent = p.dispatchEvent;
  451. target._dispatchEvent = p._dispatchEvent;
  452. target.willTrigger = p.willTrigger;
  453. };
  454. // public methods:
  455. /**
  456. * Adds the specified event listener. Note that adding multiple listeners to the same function will result in
  457. * multiple callbacks getting fired.
  458. *
  459. * <h4>Example</h4>
  460. *
  461. * displayObject.addEventListener("click", handleClick);
  462. * function handleClick(event) {
  463. * // Click happened.
  464. * }
  465. *
  466. * @method addEventListener
  467. * @param {String} type The string type of the event.
  468. * @param {Function | Object} listener An object with a handleEvent method, or a function that will be called when
  469. * the event is dispatched.
  470. * @param {Boolean} [useCapture] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase.
  471. * @return {Function | Object} Returns the listener for chaining or assignment.
  472. **/
  473. p.addEventListener = function(type, listener, useCapture) {
  474. var listeners;
  475. if (useCapture) {
  476. listeners = this._captureListeners = this._captureListeners||{};
  477. } else {
  478. listeners = this._listeners = this._listeners||{};
  479. }
  480. var arr = listeners[type];
  481. if (arr) { this.removeEventListener(type, listener, useCapture); }
  482. arr = listeners[type]; // remove may have deleted the array
  483. if (!arr) { listeners[type] = [listener]; }
  484. else { arr.push(listener); }
  485. return listener;
  486. };
  487. /**
  488. * A shortcut method for using addEventListener that makes it easier to specify an execution scope, have a listener
  489. * only run once, associate arbitrary data with the listener, and remove the listener.
  490. *
  491. * This method works by creating an anonymous wrapper function and subscribing it with addEventListener.
  492. * The wrapper function is returned for use with `removeEventListener` (or `off`).
  493. *
  494. * <b>IMPORTANT:</b> To remove a listener added with `on`, you must pass in the returned wrapper function as the listener, or use
  495. * {{#crossLink "Event/remove"}}{{/crossLink}}. Likewise, each time you call `on` a NEW wrapper function is subscribed, so multiple calls
  496. * to `on` with the same params will create multiple listeners.
  497. *
  498. * <h4>Example</h4>
  499. *
  500. * var listener = myBtn.on("click", handleClick, null, false, {count:3});
  501. * function handleClick(evt, data) {
  502. * data.count -= 1;
  503. * console.log(this == myBtn); // true - scope defaults to the dispatcher
  504. * if (data.count == 0) {
  505. * alert("clicked 3 times!");
  506. * myBtn.off("click", listener);
  507. * // alternately: evt.remove();
  508. * }
  509. * }
  510. *
  511. * @method on
  512. * @param {String} type The string type of the event.
  513. * @param {Function | Object} listener An object with a handleEvent method, or a function that will be called when
  514. * the event is dispatched.
  515. * @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).
  516. * @param {Boolean} [once=false] If true, the listener will remove itself after the first time it is triggered.
  517. * @param {*} [data] Arbitrary data that will be included as the second parameter when the listener is called.
  518. * @param {Boolean} [useCapture=false] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase.
  519. * @return {Function} Returns the anonymous function that was created and assigned as the listener. This is needed to remove the listener later using .removeEventListener.
  520. **/
  521. p.on = function(type, listener, scope, once, data, useCapture) {
  522. if (listener.handleEvent) {
  523. scope = scope||listener;
  524. listener = listener.handleEvent;
  525. }
  526. scope = scope||this;
  527. return this.addEventListener(type, function(evt) {
  528. listener.call(scope, evt, data);
  529. once&&evt.remove();
  530. }, useCapture);
  531. };
  532. /**
  533. * Removes the specified event listener.
  534. *
  535. * <b>Important Note:</b> that you must pass the exact function reference used when the event was added. If a proxy
  536. * function, or function closure is used as the callback, the proxy/closure reference must be used - a new proxy or
  537. * closure will not work.
  538. *
  539. * <h4>Example</h4>
  540. *
  541. * displayObject.removeEventListener("click", handleClick);
  542. *
  543. * @method removeEventListener
  544. * @param {String} type The string type of the event.
  545. * @param {Function | Object} listener The listener function or object.
  546. * @param {Boolean} [useCapture] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase.
  547. **/
  548. p.removeEventListener = function(type, listener, useCapture) {
  549. var listeners = useCapture ? this._captureListeners : this._listeners;
  550. if (!listeners) { return; }
  551. var arr = listeners[type];
  552. if (!arr) { return; }
  553. for (var i=0,l=arr.length; i<l; i++) {
  554. if (arr[i] == listener) {
  555. if (l==1) { delete(listeners[type]); } // allows for faster checks.
  556. else { arr.splice(i,1); }
  557. break;
  558. }
  559. }
  560. };
  561. /**
  562. * A shortcut to the removeEventListener method, with the same parameters and return value. This is a companion to the
  563. * .on method.
  564. *
  565. * <b>IMPORTANT:</b> To remove a listener added with `on`, you must pass in the returned wrapper function as the listener. See
  566. * {{#crossLink "EventDispatcher/on"}}{{/crossLink}} for an example.
  567. *
  568. * @method off
  569. * @param {String} type The string type of the event.
  570. * @param {Function | Object} listener The listener function or object.
  571. * @param {Boolean} [useCapture] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase.
  572. **/
  573. p.off = p.removeEventListener;
  574. /**
  575. * Removes all listeners for the specified type, or all listeners of all types.
  576. *
  577. * <h4>Example</h4>
  578. *
  579. * // Remove all listeners
  580. * displayObject.removeAllEventListeners();
  581. *
  582. * // Remove all click listeners
  583. * displayObject.removeAllEventListeners("click");
  584. *
  585. * @method removeAllEventListeners
  586. * @param {String} [type] The string type of the event. If omitted, all listeners for all types will be removed.
  587. **/
  588. p.removeAllEventListeners = function(type) {
  589. if (!type) { this._listeners = this._captureListeners = null; }
  590. else {
  591. if (this._listeners) { delete(this._listeners[type]); }
  592. if (this._captureListeners) { delete(this._captureListeners[type]); }
  593. }
  594. };
  595. /**
  596. * Dispatches the specified event to all listeners.
  597. *
  598. * <h4>Example</h4>
  599. *
  600. * // Use a string event
  601. * this.dispatchEvent("complete");
  602. *
  603. * // Use an Event instance
  604. * var event = new createjs.Event("progress");
  605. * this.dispatchEvent(event);
  606. *
  607. * @method dispatchEvent
  608. * @param {Object | String | Event} eventObj An object with a "type" property, or a string type.
  609. * While a generic object will work, it is recommended to use a CreateJS Event instance. If a string is used,
  610. * dispatchEvent will construct an Event instance if necessary with the specified type. This latter approach can
  611. * be used to avoid event object instantiation for non-bubbling events that may not have any listeners.
  612. * @param {Boolean} [bubbles] Specifies the `bubbles` value when a string was passed to eventObj.
  613. * @param {Boolean} [cancelable] Specifies the `cancelable` value when a string was passed to eventObj.
  614. * @return {Boolean} Returns false if `preventDefault()` was called on a cancelable event, true otherwise.
  615. **/
  616. p.dispatchEvent = function(eventObj, bubbles, cancelable) {
  617. if (typeof eventObj == "string") {
  618. // skip everything if there's no listeners and it doesn't bubble:
  619. var listeners = this._listeners;
  620. if (!bubbles && (!listeners || !listeners[eventObj])) { return true; }
  621. eventObj = new createjs.Event(eventObj, bubbles, cancelable);
  622. } else if (eventObj.target && eventObj.clone) {
  623. // redispatching an active event object, so clone it:
  624. eventObj = eventObj.clone();
  625. }
  626. // TODO: it would be nice to eliminate this. Maybe in favour of evtObj instanceof Event? Or !!evtObj.createEvent
  627. try { eventObj.target = this; } catch (e) {} // try/catch allows redispatching of native events
  628. if (!eventObj.bubbles || !this.parent) {
  629. this._dispatchEvent(eventObj, 2);
  630. } else {
  631. var top=this, list=[top];
  632. while (top.parent) { list.push(top = top.parent); }
  633. var i, l=list.length;
  634. // capture & atTarget
  635. for (i=l-1; i>=0 && !eventObj.propagationStopped; i--) {
  636. list[i]._dispatchEvent(eventObj, 1+(i==0));
  637. }
  638. // bubbling
  639. for (i=1; i<l && !eventObj.propagationStopped; i++) {
  640. list[i]._dispatchEvent(eventObj, 3);
  641. }
  642. }
  643. return !eventObj.defaultPrevented;
  644. };
  645. /**
  646. * Indicates whether there is at least one listener for the specified event type.
  647. * @method hasEventListener
  648. * @param {String} type The string type of the event.
  649. * @return {Boolean} Returns true if there is at least one listener for the specified event.
  650. **/
  651. p.hasEventListener = function(type) {
  652. var listeners = this._listeners, captureListeners = this._captureListeners;
  653. return !!((listeners && listeners[type]) || (captureListeners && captureListeners[type]));
  654. };
  655. /**
  656. * Indicates whether there is at least one listener for the specified event type on this object or any of its
  657. * ancestors (parent, parent's parent, etc). A return value of true indicates that if a bubbling event of the
  658. * specified type is dispatched from this object, it will trigger at least one listener.
  659. *
  660. * This is similar to {{#crossLink "EventDispatcher/hasEventListener"}}{{/crossLink}}, but it searches the entire
  661. * event flow for a listener, not just this object.
  662. * @method willTrigger
  663. * @param {String} type The string type of the event.
  664. * @return {Boolean} Returns `true` if there is at least one listener for the specified event.
  665. **/
  666. p.willTrigger = function(type) {
  667. var o = this;
  668. while (o) {
  669. if (o.hasEventListener(type)) { return true; }
  670. o = o.parent;
  671. }
  672. return false;
  673. };
  674. /**
  675. * @method toString
  676. * @return {String} a string representation of the instance.
  677. **/
  678. p.toString = function() {
  679. return "[EventDispatcher]";
  680. };
  681. // private methods:
  682. /**
  683. * @method _dispatchEvent
  684. * @param {Object | String | Event} eventObj
  685. * @param {Object} eventPhase
  686. * @protected
  687. **/
  688. p._dispatchEvent = function(eventObj, eventPhase) {
  689. var l, listeners = (eventPhase==1) ? this._captureListeners : this._listeners;
  690. if (eventObj && listeners) {
  691. var arr = listeners[eventObj.type];
  692. if (!arr||!(l=arr.length)) { return; }
  693. try { eventObj.currentTarget = this; } catch (e) {}
  694. try { eventObj.eventPhase = eventPhase; } catch (e) {}
  695. eventObj.removed = false;
  696. arr = arr.slice(); // to avoid issues with items being removed or added during the dispatch
  697. for (var i=0; i<l && !eventObj.immediatePropagationStopped; i++) {
  698. var o = arr[i];
  699. if (o.handleEvent) { o.handleEvent(eventObj); }
  700. else { o(eventObj); }
  701. if (eventObj.removed) {
  702. this.off(eventObj.type, o, eventPhase==1);
  703. eventObj.removed = false;
  704. }
  705. }
  706. }
  707. };
  708. createjs.EventDispatcher = EventDispatcher;
  709. }());
  710. //##############################################################################
  711. // Ticker.js
  712. //##############################################################################
  713. this.createjs = this.createjs||{};
  714. (function() {
  715. "use strict";
  716. // constructor:
  717. /**
  718. * The Ticker provides a centralized tick or heartbeat broadcast at a set interval. Listeners can subscribe to the tick
  719. * event to be notified when a set time interval has elapsed.
  720. *
  721. * Note that the interval that the tick event is called is a target interval, and may be broadcast at a slower interval
  722. * when under high CPU load. The Ticker class uses a static interface (ex. `Ticker.framerate = 30;`) and
  723. * can not be instantiated.
  724. *
  725. * <h4>Example</h4>
  726. *
  727. * createjs.Ticker.addEventListener("tick", handleTick);
  728. * function handleTick(event) {
  729. * // Actions carried out each tick (aka frame)
  730. * if (!event.paused) {
  731. * // Actions carried out when the Ticker is not paused.
  732. * }
  733. * }
  734. *
  735. * @class Ticker
  736. * @uses EventDispatcher
  737. * @static
  738. **/
  739. function Ticker() {
  740. throw "Ticker cannot be instantiated.";
  741. }
  742. // constants:
  743. /**
  744. * In this mode, Ticker uses the requestAnimationFrame API, but attempts to synch the ticks to target framerate. It
  745. * uses a simple heuristic that compares the time of the RAF return to the target time for the current frame and
  746. * dispatches the tick when the time is within a certain threshold.
  747. *
  748. * This mode has a higher variance for time between frames than {{#crossLink "Ticker/TIMEOUT:property"}}{{/crossLink}},
  749. * but does not require that content be time based as with {{#crossLink "Ticker/RAF:property"}}{{/crossLink}} while
  750. * gaining the benefits of that API (screen synch, background throttling).
  751. *
  752. * Variance is usually lowest for framerates that are a divisor of the RAF frequency. This is usually 60, so
  753. * framerates of 10, 12, 15, 20, and 30 work well.
  754. *
  755. * Falls back to {{#crossLink "Ticker/TIMEOUT:property"}}{{/crossLink}} if the requestAnimationFrame API is not
  756. * supported.
  757. * @property RAF_SYNCHED
  758. * @static
  759. * @type {String}
  760. * @default "synched"
  761. * @readonly
  762. **/
  763. Ticker.RAF_SYNCHED = "synched";
  764. /**
  765. * In this mode, Ticker passes through the requestAnimationFrame heartbeat, ignoring the target framerate completely.
  766. * Because requestAnimationFrame frequency is not deterministic, any content using this mode should be time based.
  767. * You can leverage {{#crossLink "Ticker/getTime"}}{{/crossLink}} and the {{#crossLink "Ticker/tick:event"}}{{/crossLink}}
  768. * event object's "delta" properties to make this easier.
  769. *
  770. * Falls back on {{#crossLink "Ticker/TIMEOUT:property"}}{{/crossLink}} if the requestAnimationFrame API is not
  771. * supported.
  772. * @property RAF
  773. * @static
  774. * @type {String}
  775. * @default "raf"
  776. * @readonly
  777. **/
  778. Ticker.RAF = "raf";
  779. /**
  780. * In this mode, Ticker uses the setTimeout API. This provides predictable, adaptive frame timing, but does not
  781. * provide the benefits of requestAnimationFrame (screen synch, background throttling).
  782. * @property TIMEOUT
  783. * @static
  784. * @type {String}
  785. * @default "timeout"
  786. * @readonly
  787. **/
  788. Ticker.TIMEOUT = "timeout";
  789. // static events:
  790. /**
  791. * Dispatched each tick. The event will be dispatched to each listener even when the Ticker has been paused using
  792. * {{#crossLink "Ticker/setPaused"}}{{/crossLink}}.
  793. *
  794. * <h4>Example</h4>
  795. *
  796. * createjs.Ticker.addEventListener("tick", handleTick);
  797. * function handleTick(event) {
  798. * console.log("Paused:", event.paused, event.delta);
  799. * }
  800. *
  801. * @event tick
  802. * @param {Object} target The object that dispatched the event.
  803. * @param {String} type The event type.
  804. * @param {Boolean} paused Indicates whether the ticker is currently paused.
  805. * @param {Number} delta The time elapsed in ms since the last tick.
  806. * @param {Number} time The total time in ms since Ticker was initialized.
  807. * @param {Number} runTime The total time in ms that Ticker was not paused since it was initialized. For example,
  808. * you could determine the amount of time that the Ticker has been paused since initialization with `time-runTime`.
  809. * @since 0.6.0
  810. */
  811. // public static properties:
  812. /**
  813. * Deprecated in favour of {{#crossLink "Ticker/timingMode"}}{{/crossLink}}, and will be removed in a future version. If true, timingMode will
  814. * use {{#crossLink "Ticker/RAF_SYNCHED"}}{{/crossLink}} by default.
  815. * @deprecated Deprecated in favour of {{#crossLink "Ticker/timingMode"}}{{/crossLink}}.
  816. * @property useRAF
  817. * @static
  818. * @type {Boolean}
  819. * @default false
  820. **/
  821. Ticker.useRAF = false;
  822. /**
  823. * Specifies the timing api (setTimeout or requestAnimationFrame) and mode to use. See
  824. * {{#crossLink "Ticker/TIMEOUT"}}{{/crossLink}}, {{#crossLink "Ticker/RAF"}}{{/crossLink}}, and
  825. * {{#crossLink "Ticker/RAF_SYNCHED"}}{{/crossLink}} for mode details.
  826. * @property timingMode
  827. * @static
  828. * @type {String}
  829. * @default Ticker.TIMEOUT
  830. **/
  831. Ticker.timingMode = null;
  832. /**
  833. * Specifies a maximum value for the delta property in the tick event object. This is useful when building time
  834. * based animations and systems to prevent issues caused by large time gaps caused by background tabs, system sleep,
  835. * alert dialogs, or other blocking routines. Double the expected frame duration is often an effective value
  836. * (ex. maxDelta=50 when running at 40fps).
  837. *
  838. * This does not impact any other values (ex. time, runTime, etc), so you may experience issues if you enable maxDelta
  839. * when using both delta and other values.
  840. *
  841. * If 0, there is no maximum.
  842. * @property maxDelta
  843. * @static
  844. * @type {number}
  845. * @default 0
  846. */
  847. Ticker.maxDelta = 0;
  848. /**
  849. * When the ticker is paused, all listeners will still receive a tick event, but the <code>paused</code> property
  850. * of the event will be `true`. Also, while paused the `runTime` will not increase. See {{#crossLink "Ticker/tick:event"}}{{/crossLink}},
  851. * {{#crossLink "Ticker/getTime"}}{{/crossLink}}, and {{#crossLink "Ticker/getEventTime"}}{{/crossLink}} for more
  852. * info.
  853. *
  854. * <h4>Example</h4>
  855. *
  856. * createjs.Ticker.addEventListener("tick", handleTick);
  857. * createjs.Ticker.paused = true;
  858. * function handleTick(event) {
  859. * console.log(event.paused,
  860. * createjs.Ticker.getTime(false),
  861. * createjs.Ticker.getTime(true));
  862. * }
  863. *
  864. * @property paused
  865. * @static
  866. * @type {Boolean}
  867. * @default false
  868. **/
  869. Ticker.paused = false;
  870. // mix-ins:
  871. // EventDispatcher methods:
  872. Ticker.removeEventListener = null;
  873. Ticker.removeAllEventListeners = null;
  874. Ticker.dispatchEvent = null;
  875. Ticker.hasEventListener = null;
  876. Ticker._listeners = null;
  877. createjs.EventDispatcher.initialize(Ticker); // inject EventDispatcher methods.
  878. Ticker._addEventListener = Ticker.addEventListener;
  879. Ticker.addEventListener = function() {
  880. !Ticker._inited&&Ticker.init();
  881. return Ticker._addEventListener.apply(Ticker, arguments);
  882. };
  883. // private static properties:
  884. /**
  885. * @property _inited
  886. * @static
  887. * @type {Boolean}
  888. * @protected
  889. **/
  890. Ticker._inited = false;
  891. /**
  892. * @property _startTime
  893. * @static
  894. * @type {Number}
  895. * @protected
  896. **/
  897. Ticker._startTime = 0;
  898. /**
  899. * @property _pausedTime
  900. * @static
  901. * @type {Number}
  902. * @protected
  903. **/
  904. Ticker._pausedTime=0;
  905. /**
  906. * The number of ticks that have passed
  907. * @property _ticks
  908. * @static
  909. * @type {Number}
  910. * @protected
  911. **/
  912. Ticker._ticks = 0;
  913. /**
  914. * The number of ticks that have passed while Ticker has been paused
  915. * @property _pausedTicks
  916. * @static
  917. * @type {Number}
  918. * @protected
  919. **/
  920. Ticker._pausedTicks = 0;
  921. /**
  922. * @property _interval
  923. * @static
  924. * @type {Number}
  925. * @protected
  926. **/
  927. Ticker._interval = 50;
  928. /**
  929. * @property _lastTime
  930. * @static
  931. * @type {Number}
  932. * @protected
  933. **/
  934. Ticker._lastTime = 0;
  935. /**
  936. * @property _times
  937. * @static
  938. * @type {Array}
  939. * @protected
  940. **/
  941. Ticker._times = null;
  942. /**
  943. * @property _tickTimes
  944. * @static
  945. * @type {Array}
  946. * @protected
  947. **/
  948. Ticker._tickTimes = null;
  949. /**
  950. * Stores the timeout or requestAnimationFrame id.
  951. * @property _timerId
  952. * @static
  953. * @type {Number}
  954. * @protected
  955. **/
  956. Ticker._timerId = null;
  957. /**
  958. * True if currently using requestAnimationFrame, false if using setTimeout. This may be different than timingMode
  959. * if that property changed and a tick hasn't fired.
  960. * @property _raf
  961. * @static
  962. * @type {Boolean}
  963. * @protected
  964. **/
  965. Ticker._raf = true;
  966. // static getter / setters:
  967. /**
  968. * Use the {{#crossLink "Ticker/interval:property"}}{{/crossLink}} property instead.
  969. * @method setInterval
  970. * @static
  971. * @param {Number} interval
  972. * @deprecated
  973. **/
  974. Ticker.setInterval = function(interval) {
  975. Ticker._interval = interval;
  976. if (!Ticker._inited) { return; }
  977. Ticker._setupTick();
  978. };
  979. /**
  980. * Use the {{#crossLink "Ticker/interval:property"}}{{/crossLink}} property instead.
  981. * @method getInterval
  982. * @static
  983. * @return {Number}
  984. * @deprecated
  985. **/
  986. Ticker.getInterval = function() {
  987. return Ticker._interval;
  988. };
  989. /**
  990. * Use the {{#crossLink "Ticker/framerate:property"}}{{/crossLink}} property instead.
  991. * @method setFPS
  992. * @static
  993. * @param {Number} value
  994. * @deprecated
  995. **/
  996. Ticker.setFPS = function(value) {
  997. Ticker.setInterval(1000/value);
  998. };
  999. /**
  1000. * Use the {{#crossLink "Ticker/framerate:property"}}{{/crossLink}} property instead.
  1001. * @method getFPS
  1002. * @static
  1003. * @return {Number}
  1004. * @deprecated
  1005. **/
  1006. Ticker.getFPS = function() {
  1007. return 1000/Ticker._interval;
  1008. };
  1009. /**
  1010. * Indicates the target time (in milliseconds) between ticks. Default is 50 (20 FPS).
  1011. * Note that actual time between ticks may be more than specified depending on CPU load.
  1012. * This property is ignored if the ticker is using the `RAF` timing mode.
  1013. * @property interval
  1014. * @static
  1015. * @type {Number}
  1016. **/
  1017. /**
  1018. * Indicates the target frame rate in frames per second (FPS). Effectively just a shortcut to `interval`, where
  1019. * `framerate == 1000/interval`.
  1020. * @property framerate
  1021. * @static
  1022. * @type {Number}
  1023. **/
  1024. try {
  1025. Object.defineProperties(Ticker, {
  1026. interval: { get: Ticker.getInterval, set: Ticker.setInterval },
  1027. framerate: { get: Ticker.getFPS, set: Ticker.setFPS }
  1028. });
  1029. } catch (e) { console.log(e); }
  1030. // public static methods:
  1031. /**
  1032. * Starts the tick. This is called automatically when the first listener is added.
  1033. * @method init
  1034. * @static
  1035. **/
  1036. Ticker.init = function() {
  1037. if (Ticker._inited) { return; }
  1038. Ticker._inited = true;
  1039. Ticker._times = [];
  1040. Ticker._tickTimes = [];
  1041. Ticker._startTime = Ticker._getTime();
  1042. Ticker._times.push(Ticker._lastTime = 0);
  1043. Ticker.interval = Ticker._interval;
  1044. };
  1045. /**
  1046. * Stops the Ticker and removes all listeners. Use init() to restart the Ticker.
  1047. * @method reset
  1048. * @static
  1049. **/
  1050. Ticker.reset = function() {
  1051. if (Ticker._raf) {
  1052. var f = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.oCancelAnimationFrame || window.msCancelAnimationFrame;
  1053. f&&f(Ticker._timerId);
  1054. } else {
  1055. clearTimeout(Ticker._timerId);
  1056. }
  1057. Ticker.removeAllEventListeners("tick");
  1058. Ticker._timerId = Ticker._times = Ticker._tickTimes = null;
  1059. Ticker._startTime = Ticker._lastTime = Ticker._ticks = 0;
  1060. Ticker._inited = false;
  1061. };
  1062. /**
  1063. * Returns the average time spent within a tick. This can vary significantly from the value provided by getMeasuredFPS
  1064. * because it only measures the time spent within the tick execution stack.
  1065. *
  1066. * Example 1: With a target FPS of 20, getMeasuredFPS() returns 20fps, which indicates an average of 50ms between
  1067. * the end of one tick and the end of the next. However, getMeasuredTickTime() returns 15ms. This indicates that
  1068. * there may be up to 35ms of "idle" time between the end of one tick and the start of the next.
  1069. *
  1070. * Example 2: With a target FPS of 30, getFPS() returns 10fps, which indicates an average of 100ms between the end of
  1071. * one tick and the end of the next. However, getMeasuredTickTime() returns 20ms. This would indicate that something
  1072. * other than the tick is using ~80ms (another script, DOM rendering, etc).
  1073. * @method getMeasuredTickTime
  1074. * @static
  1075. * @param {Number} [ticks] The number of previous ticks over which to measure the average time spent in a tick.
  1076. * Defaults to the number of ticks per second. To get only the last tick's time, pass in 1.
  1077. * @return {Number} The average time spent in a tick in milliseconds.
  1078. **/
  1079. Ticker.getMeasuredTickTime = function(ticks) {
  1080. var ttl=0, times=Ticker._tickTimes;
  1081. if (!times || times.length < 1) { return -1; }
  1082. // by default, calculate average for the past ~1 second:
  1083. ticks = Math.min(times.length, ticks||(Ticker.getFPS()|0));
  1084. for (var i=0; i<ticks; i++) { ttl += times[i]; }
  1085. return ttl/ticks;
  1086. };
  1087. /**
  1088. * Returns the actual frames / ticks per second.
  1089. * @method getMeasuredFPS
  1090. * @static
  1091. * @param {Number} [ticks] The number of previous ticks over which to measure the actual frames / ticks per second.
  1092. * Defaults to the number of ticks per second.
  1093. * @return {Number} The actual frames / ticks per second. Depending on performance, this may differ
  1094. * from the target frames per second.
  1095. **/
  1096. Ticker.getMeasuredFPS = function(ticks) {
  1097. var times = Ticker._times;
  1098. if (!times || times.length < 2) { return -1; }
  1099. // by default, calculate fps for the past ~1 second:
  1100. ticks = Math.min(times.length-1, ticks||(Ticker.getFPS()|0));
  1101. return 1000/((times[0]-times[ticks])/ticks);
  1102. };
  1103. /**
  1104. * Use the {{#crossLink "Ticker/paused:property"}}{{/crossLink}} property instead.
  1105. * @method setPaused
  1106. * @static
  1107. * @param {Boolean} value
  1108. * @deprecated
  1109. **/
  1110. Ticker.setPaused = function(value) {
  1111. // TODO: deprecated.
  1112. Ticker.paused = value;
  1113. };
  1114. /**
  1115. * Use the {{#crossLink "Ticker/paused:property"}}{{/crossLink}} property instead.
  1116. * @method getPaused
  1117. * @static
  1118. * @return {Boolean}
  1119. * @deprecated
  1120. **/
  1121. Ticker.getPaused = function() {
  1122. // TODO: deprecated.
  1123. return Ticker.paused;
  1124. };
  1125. /**
  1126. * Returns the number of milliseconds that have elapsed since Ticker was initialized via {{#crossLink "Ticker/init"}}.
  1127. * Returns -1 if Ticker has not been initialized. For example, you could use
  1128. * this in a time synchronized animation to determine the exact amount of time that has elapsed.
  1129. * @method getTime
  1130. * @static
  1131. * @param {Boolean} [runTime=false] If true only time elapsed while Ticker was not paused will be returned.
  1132. * If false, the value returned will be total time elapsed since the first tick event listener was added.
  1133. * @return {Number} Number of milliseconds that have elapsed since Ticker was initialized or -1.
  1134. **/
  1135. Ticker.getTime = function(runTime) {
  1136. return Ticker._startTime ? Ticker._getTime() - (runTime ? Ticker._pausedTime : 0) : -1;
  1137. };
  1138. /**
  1139. * Similar to the {{#crossLink "Ticker/getTime"}}{{/crossLink}} method, but returns the time on the most recent {{#crossLink "Ticker/tick:event"}}{{/crossLink}}
  1140. * event object.
  1141. * @method getEventTime
  1142. * @static
  1143. * @param runTime {Boolean} [runTime=false] If true, the runTime property will be returned instead of time.
  1144. * @returns {number} The time or runTime property from the most recent tick event or -1.
  1145. */
  1146. Ticker.getEventTime = function(runTime) {
  1147. return Ticker._startTime ? (Ticker._lastTime || Ticker._startTime) - (runTime ? Ticker._pausedTime : 0) : -1;
  1148. };
  1149. /**
  1150. * Returns the number of ticks that have been broadcast by Ticker.
  1151. * @method getTicks
  1152. * @static
  1153. * @param {Boolean} pauseable Indicates whether to include ticks that would have been broadcast
  1154. * while Ticker was paused. If true only tick events broadcast while Ticker is not paused will be returned.
  1155. * If false, tick events that would have been broadcast while Ticker was paused will be included in the return
  1156. * value. The default value is false.
  1157. * @return {Number} of ticks that have been broadcast.
  1158. **/
  1159. Ticker.getTicks = function(pauseable) {
  1160. return Ticker._ticks - (pauseable ? Ticker._pausedTicks : 0);
  1161. };
  1162. // private static methods:
  1163. /**
  1164. * @method _handleSynch
  1165. * @static
  1166. * @protected
  1167. **/
  1168. Ticker._handleSynch = function() {
  1169. Ticker._timerId = null;
  1170. Ticker._setupTick();
  1171. // run if enough time has elapsed, with a little bit of flexibility to be early:
  1172. if (Ticker._getTime() - Ticker._lastTime >= (Ticker._interval-1)*0.97) {
  1173. Ticker._tick();
  1174. }
  1175. };
  1176. /**
  1177. * @method _handleRAF
  1178. * @static
  1179. * @protected
  1180. **/
  1181. Ticker._handleRAF = function() {
  1182. Ticker._timerId = null;
  1183. Ticker._setupTick();
  1184. Ticker._tick();
  1185. };
  1186. /**
  1187. * @method _handleTimeout
  1188. * @static
  1189. * @protected
  1190. **/
  1191. Ticker._handleTimeout = function() {
  1192. Ticker._timerId = null;
  1193. Ticker._setupTick();
  1194. Ticker._tick();
  1195. };
  1196. /**
  1197. * @method _setupTick
  1198. * @static
  1199. * @protected
  1200. **/
  1201. Ticker._setupTick = function() {
  1202. if (Ticker._timerId != null) { return; } // avoid duplicates
  1203. var mode = Ticker.timingMode||(Ticker.useRAF&&Ticker.RAF_SYNCHED);
  1204. if (mode == Ticker.RAF_SYNCHED || mode == Ticker.RAF) {
  1205. var f = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame;
  1206. if (f) {
  1207. Ticker._timerId = f(mode == Ticker.RAF ? Ticker._handleRAF : Ticker._handleSynch);
  1208. Ticker._raf = true;
  1209. return;
  1210. }
  1211. }
  1212. Ticker._raf = false;
  1213. Ticker._timerId = setTimeout(Ticker._handleTimeout, Ticker._interval);
  1214. };
  1215. /**
  1216. * @method _tick
  1217. * @static
  1218. * @protected
  1219. **/
  1220. Ticker._tick = function() {
  1221. var paused = Ticker.paused;
  1222. var time = Ticker._getTime();
  1223. var elapsedTime = time-Ticker._lastTime;
  1224. Ticker._lastTime = time;
  1225. Ticker._ticks++;
  1226. if (paused) {
  1227. Ticker._pausedTicks++;
  1228. Ticker._pausedTime += elapsedTime;
  1229. }
  1230. if (Ticker.hasEventListener("tick")) {
  1231. var event = new createjs.Event("tick");
  1232. var maxDelta = Ticker.maxDelta;
  1233. event.delta = (maxDelta && elapsedTime > maxDelta) ? maxDelta : elapsedTime;
  1234. event.paused = paused;
  1235. event.time = time;
  1236. event.runTime = time-Ticker._pausedTime;
  1237. Ticker.dispatchEvent(event);
  1238. }
  1239. Ticker._tickTimes.unshift(Ticker._getTime()-time);
  1240. while (Ticker._tickTimes.length > 100) { Ticker._tickTimes.pop(); }
  1241. Ticker._times.unshift(time);
  1242. while (Ticker._times.length > 100) { Ticker._times.pop(); }
  1243. };
  1244. /**
  1245. * @method _getTime
  1246. * @static
  1247. * @protected
  1248. **/
  1249. var now = window.performance && (performance.now || performance.mozNow || performance.msNow || performance.oNow || performance.webkitNow);
  1250. Ticker._getTime = function() {
  1251. return ((now&&now.call(performance))||(new Date().getTime())) - Ticker._startTime;
  1252. };
  1253. createjs.Ticker = Ticker;
  1254. }());
  1255. //##############################################################################
  1256. // UID.js
  1257. //##############################################################################
  1258. this.createjs = this.createjs||{};
  1259. (function() {
  1260. "use strict";
  1261. // constructor:
  1262. /**
  1263. * Global utility for generating sequential unique ID numbers. The UID class uses a static interface (ex. <code>UID.get()</code>)
  1264. * and should not be instantiated.
  1265. * @class UID
  1266. * @static
  1267. **/
  1268. function UID() {
  1269. throw "UID cannot be instantiated";
  1270. }
  1271. // private static properties:
  1272. /**
  1273. * @property _nextID
  1274. * @type Number
  1275. * @protected
  1276. **/
  1277. UID._nextID = 0;
  1278. // public static methods:
  1279. /**
  1280. * Returns the next unique id.
  1281. * @method get
  1282. * @return {Number} The next unique id
  1283. * @static
  1284. **/
  1285. UID.get = function() {
  1286. return UID._nextID++;
  1287. };
  1288. createjs.UID = UID;
  1289. }());
  1290. //##############################################################################
  1291. // MouseEvent.js
  1292. //##############################################################################
  1293. this.createjs = this.createjs||{};
  1294. (function() {
  1295. "use strict";
  1296. // constructor:
  1297. /**
  1298. * Passed as the parameter to all mouse/pointer/touch related events. For a listing of mouse events and their properties,
  1299. * see the {{#crossLink "DisplayObject"}}{{/crossLink}} and {{#crossLink "Stage"}}{{/crossLink}} event listings.
  1300. * @class MouseEvent
  1301. * @param {String} type The event type.
  1302. * @param {Boolean} bubbles Indicates whether the event will bubble through the display list.
  1303. * @param {Boolean} cancelable Indicates whether the default behaviour of this event can be cancelled.
  1304. * @param {Number} stageX The normalized x position relative to the stage.
  1305. * @param {Number} stageY The normalized y position relative to the stage.
  1306. * @param {MouseEvent} nativeEvent The native DOM event related to this mouse event.
  1307. * @param {Number} pointerID The unique id for the pointer.
  1308. * @param {Boolean} primary Indicates whether this is the primary pointer in a multitouch environment.
  1309. * @param {Number} rawX The raw x position relative to the stage.
  1310. * @param {Number} rawY The raw y position relative to the stage.
  1311. * @param {DisplayObject} relatedTarget The secondary target for the event.
  1312. * @extends Event
  1313. * @constructor
  1314. **/
  1315. function MouseEvent(type, bubbles, cancelable, stageX, stageY, nativeEvent, pointerID, primary, rawX, rawY, relatedTarget) {
  1316. this.Event_constructor(type, bubbles, cancelable);
  1317. // public properties:
  1318. /**
  1319. * The normalized x position on the stage. This will always be within the range 0 to stage width.
  1320. * @property stageX
  1321. * @type Number
  1322. */
  1323. this.stageX = stageX;
  1324. /**
  1325. * The normalized y position on the stage. This will always be within the range 0 to stage height.
  1326. * @property stageY
  1327. * @type Number
  1328. **/
  1329. this.stageY = stageY;
  1330. /**
  1331. * The raw x position relative to the stage. Normally this will be the same as the stageX value, unless
  1332. * stage.mouseMoveOutside is true and the pointer is outside of the stage bounds.
  1333. * @property rawX
  1334. * @type Number
  1335. */
  1336. this.rawX = (rawX==null)?stageX:rawX;
  1337. /**
  1338. * The raw y position relative to the stage. Normally this will be the same as the stageY value, unless
  1339. * stage.mouseMoveOutside is true and the pointer is outside of the stage bounds.
  1340. * @property rawY
  1341. * @type Number
  1342. */
  1343. this.rawY = (rawY==null)?stageY:rawY;
  1344. /**
  1345. * The native MouseEvent generated by the browser. The properties and API for this
  1346. * event may differ between browsers. This property will be null if the
  1347. * EaselJS property was not directly generated from a native MouseEvent.
  1348. * @property nativeEvent
  1349. * @type HtmlMouseEvent
  1350. * @default null
  1351. **/
  1352. this.nativeEvent = nativeEvent;
  1353. /**
  1354. * The unique id for the pointer (touch point or cursor). This will be either -1 for the mouse, or the system
  1355. * supplied id value.
  1356. * @property pointerID
  1357. * @type {Number}
  1358. */
  1359. this.pointerID = pointerID;
  1360. /**
  1361. * Indicates whether this is the primary pointer in a multitouch environment. This will always be true for the mouse.
  1362. * For touch pointers, the first pointer in the current stack will be considered the primary pointer.
  1363. * @property primary
  1364. * @type {Boolean}
  1365. */
  1366. this.primary = !!primary;
  1367. /**
  1368. * The secondary target for the event, if applicable. This is used for mouseout/rollout
  1369. * events to indicate the object that the mouse entered from, mouseover/rollover for the object the mouse exited,
  1370. * and stagemousedown/stagemouseup events for the object that was the under the cursor, if any.
  1371. *
  1372. * Only valid interaction targets will be returned (ie. objects with mouse listeners or a cursor set).
  1373. * @property relatedTarget
  1374. * @type {DisplayObject}
  1375. */
  1376. this.relatedTarget = relatedTarget;
  1377. }
  1378. var p = createjs.extend(MouseEvent, createjs.Event);
  1379. // TODO: deprecated
  1380. // p.initialize = function() {}; // searchable for devs wondering where it is. REMOVED. See docs for details.
  1381. // getter / setters:
  1382. /**
  1383. * Returns the x position of the mouse in the local coordinate system of the current target (ie. the dispatcher).
  1384. * @property localX
  1385. * @type {Number}
  1386. * @readonly
  1387. */
  1388. p._get_localX = function() {
  1389. return this.currentTarget.globalToLocal(this.rawX, this.rawY).x;
  1390. };
  1391. /**
  1392. * Returns the y position of the mouse in the local coordinate system of the current target (ie. the dispatcher).
  1393. * @property localY
  1394. * @type {Number}
  1395. * @readonly
  1396. */
  1397. p._get_localY = function() {
  1398. return this.currentTarget.globalToLocal(this.rawX, this.rawY).y;
  1399. };
  1400. /**
  1401. * Indicates whether the event was generated by a touch input (versus a mouse input).
  1402. * @property isTouch
  1403. * @type {Boolean}
  1404. * @readonly
  1405. */
  1406. p._get_isTouch = function() {
  1407. return this.pointerID !== -1;
  1408. };
  1409. try {
  1410. Object.defineProperties(p, {
  1411. localX: { get: p._get_localX },
  1412. localY: { get: p._get_localY },
  1413. isTouch: { get: p._get_isTouch }
  1414. });
  1415. } catch (e) {} // TODO: use Log
  1416. // public methods:
  1417. /**
  1418. * Returns a clone of the MouseEvent instance.
  1419. * @method clone
  1420. * @return {MouseEvent} a clone of the MouseEvent instance.
  1421. **/
  1422. p.clone = function() {
  1423. return new MouseEvent(this.type, this.bubbles, this.cancelable, this.stageX, this.stageY, this.nativeEvent, this.pointerID, this.primary, this.rawX, this.rawY);
  1424. };
  1425. /**
  1426. * Returns a string representation of this object.
  1427. * @method toString
  1428. * @return {String} a string representation of the instance.
  1429. **/
  1430. p.toString = function() {
  1431. return "[MouseEvent (type="+this.type+" stageX="+this.stageX+" stageY="+this.stageY+")]";
  1432. };
  1433. createjs.MouseEvent = createjs.promote(MouseEvent, "Event");
  1434. }());
  1435. //##############################################################################
  1436. // Matrix2D.js
  1437. //##############################################################################
  1438. this.createjs = this.createjs||{};
  1439. (function() {
  1440. "use strict";
  1441. // constructor:
  1442. /**
  1443. * Represents an affine transformation matrix, and provides tools for constructing and concatenating matrices.
  1444. *
  1445. * This matrix can be visualized as:
  1446. *
  1447. * [ a c tx
  1448. * b d ty
  1449. * 0 0 1 ]
  1450. *
  1451. * Note the locations of b and c.
  1452. *
  1453. * @class Matrix2D
  1454. * @param {Number} [a=1] Specifies the a property for the new matrix.
  1455. * @param {Number} [b=0] Specifies the b property for the new matrix.
  1456. * @param {Number} [c=0] Specifies the c property for the new matrix.
  1457. * @param {Number} [d=1] Specifies the d property for the new matrix.
  1458. * @param {Number} [tx=0] Specifies the tx property for the new matrix.
  1459. * @param {Number} [ty=0] Specifies the ty property for the new matrix.
  1460. * @constructor
  1461. **/
  1462. function Matrix2D(a, b, c, d, tx, ty) {
  1463. this.setValues(a,b,c,d,tx,ty);
  1464. // public properties:
  1465. // assigned in the setValues method.
  1466. /**
  1467. * Position (0, 0) in a 3x3 affine transformation matrix.
  1468. * @property a
  1469. * @type Number
  1470. **/
  1471. /**
  1472. * Position (0, 1) in a 3x3 affine transformation matrix.
  1473. * @property b
  1474. * @type Number
  1475. **/
  1476. /**
  1477. * Position (1, 0) in a 3x3 affine transformation matrix.
  1478. * @property c
  1479. * @type Number
  1480. **/
  1481. /**
  1482. * Position (1, 1) in a 3x3 affine transformation matrix.
  1483. * @property d
  1484. * @type Number
  1485. **/
  1486. /**
  1487. * Position (2, 0) in a 3x3 affine transformation matrix.
  1488. * @property tx
  1489. * @type Number
  1490. **/
  1491. /**
  1492. * Position (2, 1) in a 3x3 affine transformation matrix.
  1493. * @property ty
  1494. * @type Number
  1495. **/
  1496. }
  1497. var p = Matrix2D.prototype;
  1498. /**
  1499. * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`.
  1500. * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}}
  1501. * for details.
  1502. *
  1503. * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance.
  1504. *
  1505. * @method initialize
  1506. * @protected
  1507. * @deprecated
  1508. */
  1509. // p.initialize = function() {}; // searchable for devs wondering where it is.
  1510. // constants:
  1511. /**
  1512. * Multiplier for converting degrees to radians. Used internally by Matrix2D.
  1513. * @property DEG_TO_RAD
  1514. * @static
  1515. * @final
  1516. * @type Number
  1517. * @readonly
  1518. **/
  1519. Matrix2D.DEG_TO_RAD = Math.PI/180;
  1520. // static public properties:
  1521. /**
  1522. * An identity matrix, representing a null transformation.
  1523. * @property identity
  1524. * @static
  1525. * @type Matrix2D
  1526. * @readonly
  1527. **/
  1528. Matrix2D.identity = null; // set at bottom of class definition.
  1529. // public methods:
  1530. /**
  1531. * Sets the specified values on this instance.
  1532. * @method setValues
  1533. * @param {Number} [a=1] Specifies the a property for the new matrix.
  1534. * @param {Number} [b=0] Specifies the b property for the new matrix.
  1535. * @param {Number} [c=0] Specifies the c property for the new matrix.
  1536. * @param {Number} [d=1] Specifies the d property for the new matrix.
  1537. * @param {Number} [tx=0] Specifies the tx property for the new matrix.
  1538. * @param {Number} [ty=0] Specifies the ty property for the new matrix.
  1539. * @return {Matrix2D} This instance. Useful for chaining method calls.
  1540. */
  1541. p.setValues = function(a, b, c, d, tx, ty) {
  1542. // don't forget to update docs in the constructor if these change:
  1543. this.a = (a == null) ? 1 : a;
  1544. this.b = b || 0;
  1545. this.c = c || 0;
  1546. this.d = (d == null) ? 1 : d;
  1547. this.tx = tx || 0;
  1548. this.ty = ty || 0;
  1549. return this;
  1550. };
  1551. /**
  1552. * Appends the specified matrix properties to this matrix. All parameters are required.
  1553. * This is the equivalent of multiplying `(this matrix) * (specified matrix)`.
  1554. * @method append
  1555. * @param {Number} a
  1556. * @param {Number} b
  1557. * @param {Number} c
  1558. * @param {Number} d
  1559. * @param {Number} tx
  1560. * @param {Number} ty
  1561. * @return {Matrix2D} This matrix. Useful for chaining method calls.
  1562. **/
  1563. p.append = function(a, b, c, d, tx, ty) {
  1564. var a1 = this.a;
  1565. var b1 = this.b;
  1566. var c1 = this.c;
  1567. var d1 = this.d;
  1568. if (a != 1 || b != 0 || c != 0 || d != 1) {
  1569. this.a = a1*a+c1*b;
  1570. this.b = b1*a+d1*b;
  1571. this.c = a1*c+c1*d;
  1572. this.d = b1*c+d1*d;
  1573. }
  1574. this.tx = a1*tx+c1*ty+this.tx;
  1575. this.ty = b1*tx+d1*ty+this.ty;
  1576. return this;
  1577. };
  1578. /**
  1579. * Prepends the specified matrix properties to this matrix.
  1580. * This is the equivalent of multiplying `(specified matrix) * (this matrix)`.
  1581. * All parameters are required.
  1582. * @method prepend
  1583. * @param {Number} a
  1584. * @param {Number} b
  1585. * @param {Number} c
  1586. * @param {Number} d
  1587. * @param {Number} tx
  1588. * @param {Number} ty
  1589. * @return {Matrix2D} This matrix. Useful for chaining method calls.
  1590. **/
  1591. p.prepend = function(a, b, c, d, tx, ty) {
  1592. var a1 = this.a;
  1593. var c1 = this.c;
  1594. var tx1 = this.tx;
  1595. this.a = a*a1+c*this.b;
  1596. this.b = b*a1+d*this.b;
  1597. this.c = a*c1+c*this.d;
  1598. this.d = b*c1+d*this.d;
  1599. this.tx = a*tx1+c*this.ty+tx;
  1600. this.ty = b*tx1+d*this.ty+ty;
  1601. return this;
  1602. };
  1603. /**
  1604. * Appends the specified matrix to this matrix.
  1605. * This is the equivalent of multiplying `(this matrix) * (specified matrix)`.
  1606. * @method appendMatrix
  1607. * @param {Matrix2D} matrix
  1608. * @return {Matrix2D} This matrix. Useful for chaining method calls.
  1609. **/
  1610. p.appendMatrix = function(matrix) {
  1611. return this.append(matrix.a, matrix.b, matrix.c, matrix.d, matrix.tx, matrix.ty);
  1612. };
  1613. /**
  1614. * Prepends the specified matrix to this matrix.
  1615. * This is the equivalent of multiplying `(specified matrix) * (this matrix)`.
  1616. * For example, you could calculate the combined transformation for a child object using:
  1617. *
  1618. * var o = myDisplayObject;
  1619. * var mtx = o.getMatrix();
  1620. * while (o = o.parent) {
  1621. * // prepend each parent's transformation in turn:
  1622. * o.prependMatrix(o.getMatrix());
  1623. * }
  1624. * @method prependMatrix
  1625. * @param {Matrix2D} matrix
  1626. * @return {Matrix2D} This matrix. Useful for chaining method calls.
  1627. **/
  1628. p.prependMatrix = function(matrix) {
  1629. return this.prepend(matrix.a, matrix.b, matrix.c, matrix.d, matrix.tx, matrix.ty);
  1630. };
  1631. /**
  1632. * Generates matrix properties from the specified display object transform properties, and appends them to this matrix.
  1633. * For example, you can use this to generate a matrix representing the transformations of a display object:
  1634. *
  1635. * var mtx = new createjs.Matrix2D();
  1636. * mtx.appendTransform(o.x, o.y, o.scaleX, o.scaleY, o.rotation);
  1637. * @method appendTransform
  1638. * @param {Number} x
  1639. * @param {Number} y
  1640. * @param {Number} scaleX
  1641. * @param {Number} scaleY
  1642. * @param {Number} rotation
  1643. * @param {Number} skewX
  1644. * @param {Number} skewY
  1645. * @param {Number} regX Optional.
  1646. * @param {Number} regY Optional.
  1647. * @return {Matrix2D} This matrix. Useful for chaining method calls.
  1648. **/
  1649. p.appendTransform = function(x, y, scaleX, scaleY, rotation, skewX, skewY, regX, regY) {
  1650. if (rotation%360) {
  1651. var r = rotation*Matrix2D.DEG_TO_RAD;
  1652. var cos = Math.cos(r);
  1653. var sin = Math.sin(r);
  1654. } else {
  1655. cos = 1;
  1656. sin = 0;
  1657. }
  1658. if (skewX || skewY) {
  1659. // TODO: can this be combined into a single append operation?
  1660. skewX *= Matrix2D.DEG_TO_RAD;
  1661. skewY *= Matrix2D.DEG_TO_RAD;
  1662. this.append(Math.cos(skewY), Math.sin(skewY), -Math.sin(skewX), Math.cos(skewX), x, y);
  1663. this.append(cos*scaleX, sin*scaleX, -sin*scaleY, cos*scaleY, 0, 0);
  1664. } else {
  1665. this.append(cos*scaleX, sin*scaleX, -sin*scaleY, cos*scaleY, x, y);
  1666. }
  1667. if (regX || regY) {
  1668. // append the registration offset:
  1669. this.tx -= regX*this.a+regY*this.c;
  1670. this.ty -= regX*this.b+regY*this.d;
  1671. }
  1672. return this;
  1673. };
  1674. /**
  1675. * Generates matrix properties from the specified display object transform properties, and prepends them to this matrix.
  1676. * For example, you could calculate the combined transformation for a child object using:
  1677. *
  1678. * var o = myDisplayObject;
  1679. * var mtx = new createjs.Matrix2D();
  1680. * do {
  1681. * // prepend each parent's transformation in turn:
  1682. * mtx.prependTransform(o.x, o.y, o.scaleX, o.scaleY, o.rotation, o.skewX, o.skewY, o.regX, o.regY);
  1683. * } while (o = o.parent);
  1684. *
  1685. * Note that the above example would not account for {{#crossLink "DisplayObject/transformMatrix:property"}}{{/crossLink}}
  1686. * values. See {{#crossLink "Matrix2D/prependMatrix"}}{{/crossLink}} for an example that does.
  1687. * @method prependTransform
  1688. * @param {Number} x
  1689. * @param {Number} y
  1690. * @param {Number} scaleX
  1691. * @param {Number} scaleY
  1692. * @param {Number} rotation
  1693. * @param {Number} skewX
  1694. * @param {Number} skewY
  1695. * @param {Number} regX Optional.
  1696. * @param {Number} regY Optional.
  1697. * @return {Matrix2D} This matrix. Useful for chaining method calls.
  1698. **/
  1699. p.prependTransform = function(x, y, scaleX, scaleY, rotation, skewX, skewY, regX, regY) {
  1700. if (rotation%360) {
  1701. var r = rotation*Matrix2D.DEG_TO_RAD;
  1702. var cos = Math.cos(r);
  1703. var sin = Math.sin(r);
  1704. } else {
  1705. cos = 1;
  1706. sin = 0;
  1707. }
  1708. if (regX || regY) {
  1709. // prepend the registration offset:
  1710. this.tx -= regX; this.ty -= regY;
  1711. }
  1712. if (skewX || skewY) {
  1713. // TODO: can this be combined into a single prepend operation?
  1714. skewX *= Matrix2D.DEG_TO_RAD;
  1715. skewY *= Matrix2D.DEG_TO_RAD;
  1716. this.prepend(cos*scaleX, sin*scaleX, -sin*scaleY, cos*scaleY, 0, 0);
  1717. this.prepend(Math.cos(skewY), Math.sin(skewY), -Math.sin(skewX), Math.cos(skewX), x, y);
  1718. } else {
  1719. this.prepend(cos*scaleX, sin*scaleX, -sin*scaleY, cos*scaleY, x, y);
  1720. }
  1721. return this;
  1722. };
  1723. /**
  1724. * Applies a clockwise rotation transformation to the matrix.
  1725. * @method rotate
  1726. * @param {Number} angle The angle to rotate by, in degrees. To use a value in radians, multiply it by `180/Math.PI`.
  1727. * @return {Matrix2D} This matrix. Useful for chaining method calls.
  1728. **/
  1729. p.rotate = function(angle) {
  1730. angle = angle*Matrix2D.DEG_TO_RAD;
  1731. var cos = Math.cos(angle);
  1732. var sin = Math.sin(angle);
  1733. var a1 = this.a;
  1734. var b1 = this.b;
  1735. this.a = a1*cos+this.c*sin;
  1736. this.b = b1*cos+this.d*sin;
  1737. this.c = -a1*sin+this.c*cos;
  1738. this.d = -b1*sin+this.d*cos;
  1739. return this;
  1740. };
  1741. /**
  1742. * Applies a skew transformation to the matrix.
  1743. * @method skew
  1744. * @param {Number} skewX The amount to skew horizontally in degrees. To use a value in radians, multiply it by `180/Math.PI`.
  1745. * @param {Number} skewY The amount to skew vertically in degrees.
  1746. * @return {Matrix2D} This matrix. Useful for chaining method calls.
  1747. */
  1748. p.skew = function(skewX, skewY) {
  1749. skewX = skewX*Matrix2D.DEG_TO_RAD;
  1750. skewY = skewY*Matrix2D.DEG_TO_RAD;
  1751. this.append(Math.cos(skewY), Math.sin(skewY), -Math.sin(skewX), Math.cos(skewX), 0, 0);
  1752. return this;
  1753. };
  1754. /**
  1755. * Applies a scale transformation to the matrix.
  1756. * @method scale
  1757. * @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.
  1758. * @param {Number} y The amount to scale vertically.
  1759. * @return {Matrix2D} This matrix. Useful for chaining method calls.
  1760. **/
  1761. p.scale = function(x, y) {
  1762. this.a *= x;
  1763. this.b *= x;
  1764. this.c *= y;
  1765. this.d *= y;
  1766. //this.tx *= x;
  1767. //this.ty *= y;
  1768. return this;
  1769. };
  1770. /**
  1771. * Translates the matrix on the x and y axes.
  1772. * @method translate
  1773. * @param {Number} x
  1774. * @param {Number} y
  1775. * @return {Matrix2D} This matrix. Useful for chaining method calls.
  1776. **/
  1777. p.translate = function(x, y) {
  1778. this.tx += this.a*x + this.c*y;
  1779. this.ty += this.b*x + this.d*y;
  1780. return this;
  1781. };
  1782. /**
  1783. * Sets the properties of the matrix to those of an identity matrix (one that applies a null transformation).
  1784. * @method identity
  1785. * @return {Matrix2D} This matrix. Useful for chaining method calls.
  1786. **/
  1787. p.identity = function() {
  1788. this.a = this.d = 1;
  1789. this.b = this.c = this.tx = this.ty = 0;
  1790. return this;
  1791. };
  1792. /**
  1793. * Inverts the matrix, causing it to perform the opposite transformation.
  1794. * @method invert
  1795. * @return {Matrix2D} This matrix. Useful for chaining method calls.
  1796. **/
  1797. p.invert = function() {
  1798. var a1 = this.a;
  1799. var b1 = this.b;
  1800. var c1 = this.c;
  1801. var d1 = this.d;
  1802. var tx1 = this.tx;
  1803. var n = a1*d1-b1*c1;
  1804. this.a = d1/n;
  1805. this.b = -b1/n;
  1806. this.c = -c1/n;
  1807. this.d = a1/n;
  1808. this.tx = (c1*this.ty-d1*tx1)/n;
  1809. this.ty = -(a1*this.ty-b1*tx1)/n;
  1810. return this;
  1811. };
  1812. /**
  1813. * Returns true if the matrix is an identity matrix.
  1814. * @method isIdentity
  1815. * @return {Boolean}
  1816. **/
  1817. p.isIdentity = function() {
  1818. return this.tx === 0 && this.ty === 0 && this.a === 1 && this.b === 0 && this.c === 0 && this.d === 1;
  1819. };
  1820. /**
  1821. * Returns true if this matrix is equal to the specified matrix (all property values are equal).
  1822. * @method equals
  1823. * @param {Matrix2D} matrix The matrix to compare.
  1824. * @return {Boolean}
  1825. **/
  1826. p.equals = function(matrix) {
  1827. 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;
  1828. };
  1829. /**
  1830. * Transforms a point according to this matrix.
  1831. * @method transformPoint
  1832. * @param {Number} x The x component of the point to transform.
  1833. * @param {Number} y The y component of the point to transform.
  1834. * @param {Point | Object} [pt] An object to copy the result into. If omitted a generic object with x/y properties will be returned.
  1835. * @return {Point} This matrix. Useful for chaining method calls.
  1836. **/
  1837. p.transformPoint = function(x, y, pt) {
  1838. pt = pt||{};
  1839. pt.x = x*this.a+y*this.c+this.tx;
  1840. pt.y = x*this.b+y*this.d+this.ty;
  1841. return pt;
  1842. };
  1843. /**
  1844. * Decomposes the matrix into transform properties (x, y, scaleX, scaleY, and rotation). Note that these values
  1845. * may not match the transform properties you used to generate the matrix, though they will produce the same visual
  1846. * results.
  1847. * @method decompose
  1848. * @param {Object} target The object to apply the transform properties to. If null, then a new object will be returned.
  1849. * @return {Object} The target, or a new generic object with the transform properties applied.
  1850. */
  1851. p.decompose = function(target) {
  1852. // 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
  1853. if (target == null) { target = {}; }
  1854. target.x = this.tx;
  1855. target.y = this.ty;
  1856. target.scaleX = Math.sqrt(this.a * this.a + this.b * this.b);
  1857. target.scaleY = Math.sqrt(this.c * this.c + this.d * this.d);
  1858. var skewX = Math.atan2(-this.c, this.d);
  1859. var skewY = Math.atan2(this.b, this.a);
  1860. var delta = Math.abs(1-skewX/skewY);
  1861. if (delta < 0.00001) { // effectively identical, can use rotation:
  1862. target.rotation = skewY/Matrix2D.DEG_TO_RAD;
  1863. if (this.a < 0 && this.d >= 0) {
  1864. target.rotation += (target.rotation <= 0) ? 180 : -180;
  1865. }
  1866. target.skewX = target.skewY = 0;
  1867. } else {
  1868. target.skewX = skewX/Matrix2D.DEG_TO_RAD;
  1869. target.skewY = skewY/Matrix2D.DEG_TO_RAD;
  1870. }
  1871. return target;
  1872. };
  1873. /**
  1874. * Copies all properties from the specified matrix to this matrix.
  1875. * @method copy
  1876. * @param {Matrix2D} matrix The matrix to copy properties from.
  1877. * @return {Matrix2D} This matrix. Useful for chaining method calls.
  1878. */
  1879. p.copy = function(matrix) {
  1880. return this.setValues(matrix.a, matrix.b, matrix.c, matrix.d, matrix.tx, matrix.ty);
  1881. };
  1882. /**
  1883. * Returns a clone of the Matrix2D instance.
  1884. * @method clone
  1885. * @return {Matrix2D} a clone of the Matrix2D instance.
  1886. **/
  1887. p.clone = function() {
  1888. return new Matrix2D(this.a, this.b, this.c, this.d, this.tx, this.ty);
  1889. };
  1890. /**
  1891. * Returns a string representation of this object.
  1892. * @method toString
  1893. * @return {String} a string representation of the instance.
  1894. **/
  1895. p.toString = function() {
  1896. return "[Matrix2D (a="+this.a+" b="+this.b+" c="+this.c+" d="+this.d+" tx="+this.tx+" ty="+this.ty+")]";
  1897. };
  1898. // this has to be populated after the class is defined:
  1899. Matrix2D.identity = new Matrix2D();
  1900. createjs.Matrix2D = Matrix2D;
  1901. }());
  1902. //##############################################################################
  1903. // DisplayProps.js
  1904. //##############################################################################
  1905. this.createjs = this.createjs||{};
  1906. (function() {
  1907. "use strict";
  1908. /**
  1909. * Used for calculating and encapsulating display related properties.
  1910. * @class DisplayProps
  1911. * @param {Number} [visible=true] Visible value.
  1912. * @param {Number} [alpha=1] Alpha value.
  1913. * @param {Number} [shadow=null] A Shadow instance or null.
  1914. * @param {Number} [compositeOperation=null] A compositeOperation value or null.
  1915. * @param {Number} [matrix] A transformation matrix. Defaults to a new identity matrix.
  1916. * @constructor
  1917. **/
  1918. function DisplayProps(visible, alpha, shadow, compositeOperation, matrix) {
  1919. this.setValues(visible, alpha, shadow, compositeOperation, matrix);
  1920. // public properties:
  1921. // assigned in the setValues method.
  1922. /**
  1923. * Property representing the alpha that will be applied to a display object.
  1924. * @property alpha
  1925. * @type Number
  1926. **/
  1927. /**
  1928. * Property representing the shadow that will be applied to a display object.
  1929. * @property shadow
  1930. * @type Shadow
  1931. **/
  1932. /**
  1933. * Property representing the compositeOperation that will be applied to a display object.
  1934. * You can find a list of valid composite operations at:
  1935. * <a href="https://developer.mozilla.org/en/Canvas_tutorial/Compositing">https://developer.mozilla.org/en/Canvas_tutorial/Compositing</a>
  1936. * @property compositeOperation
  1937. * @type String
  1938. **/
  1939. /**
  1940. * Property representing the value for visible that will be applied to a display object.
  1941. * @property visible
  1942. * @type Boolean
  1943. **/
  1944. /**
  1945. * The transformation matrix that will be applied to a display object.
  1946. * @property matrix
  1947. * @type Matrix2D
  1948. **/
  1949. }
  1950. var p = DisplayProps.prototype;
  1951. // initialization:
  1952. /**
  1953. * Reinitializes the instance with the specified values.
  1954. * @method setValues
  1955. * @param {Number} [visible=true] Visible value.
  1956. * @param {Number} [alpha=1] Alpha value.
  1957. * @param {Number} [shadow=null] A Shadow instance or null.
  1958. * @param {Number} [compositeOperation=null] A compositeOperation value or null.
  1959. * @param {Number} [matrix] A transformation matrix. Defaults to an identity matrix.
  1960. * @return {DisplayProps} This instance. Useful for chaining method calls.
  1961. * @chainable
  1962. */
  1963. p.setValues = function (visible, alpha, shadow, compositeOperation, matrix) {
  1964. this.visible = visible == null ? true : !!visible;
  1965. this.alpha = alpha == null ? 1 : alpha;
  1966. this.shadow = shadow;
  1967. this.compositeOperation = compositeOperation;
  1968. this.matrix = matrix || (this.matrix&&this.matrix.identity()) || new createjs.Matrix2D();
  1969. return this;
  1970. };
  1971. // public methods:
  1972. /**
  1973. * Appends the specified display properties. This is generally used to apply a child's properties its parent's.
  1974. * @method append
  1975. * @param {Boolean} visible desired visible value
  1976. * @param {Number} alpha desired alpha value
  1977. * @param {Shadow} shadow desired shadow value
  1978. * @param {String} compositeOperation desired composite operation value
  1979. * @param {Matrix2D} [matrix] a Matrix2D instance
  1980. * @return {DisplayProps} This instance. Useful for chaining method calls.
  1981. * @chainable
  1982. */
  1983. p.append = function(visible, alpha, shadow, compositeOperation, matrix) {
  1984. this.alpha *= alpha;
  1985. this.shadow = shadow || this.shadow;
  1986. this.compositeOperation = compositeOperation || this.compositeOperation;
  1987. this.visible = this.visible && visible;
  1988. matrix&&this.matrix.appendMatrix(matrix);
  1989. return this;
  1990. };
  1991. /**
  1992. * Prepends the specified display properties. This is generally used to apply a parent's properties to a child's.
  1993. * For example, to get the combined display properties that would be applied to a child, you could use:
  1994. *
  1995. * var o = myDisplayObject;
  1996. * var props = new createjs.DisplayProps();
  1997. * do {
  1998. * // prepend each parent's props in turn:
  1999. * props.prepend(o.visible, o.alpha, o.shadow, o.compositeOperation, o.getMatrix());
  2000. * } while (o = o.parent);
  2001. *
  2002. * @method prepend
  2003. * @param {Boolean} visible desired visible value
  2004. * @param {Number} alpha desired alpha value
  2005. * @param {Shadow} shadow desired shadow value
  2006. * @param {String} compositeOperation desired composite operation value
  2007. * @param {Matrix2D} [matrix] a Matrix2D instance
  2008. * @return {DisplayProps} This instance. Useful for chaining method calls.
  2009. * @chainable
  2010. */
  2011. p.prepend = function(visible, alpha, shadow, compositeOperation, matrix) {
  2012. this.alpha *= alpha;
  2013. this.shadow = this.shadow || shadow;
  2014. this.compositeOperation = this.compositeOperation || compositeOperation;
  2015. this.visible = this.visible && visible;
  2016. matrix&&this.matrix.prependMatrix(matrix);
  2017. return this;
  2018. };
  2019. /**
  2020. * Resets this instance and its matrix to default values.
  2021. * @method identity
  2022. * @return {DisplayProps} This instance. Useful for chaining method calls.
  2023. * @chainable
  2024. */
  2025. p.identity = function() {
  2026. this.visible = true;
  2027. this.alpha = 1;
  2028. this.shadow = this.compositeOperation = null;
  2029. this.matrix.identity();
  2030. return this;
  2031. };
  2032. /**
  2033. * Returns a clone of the DisplayProps instance. Clones the associated matrix.
  2034. * @method clone
  2035. * @return {DisplayProps} a clone of the DisplayProps instance.
  2036. **/
  2037. p.clone = function() {
  2038. return new DisplayProps(this.alpha, this.shadow, this.compositeOperation, this.visible, this.matrix.clone());
  2039. };
  2040. // private methods:
  2041. createjs.DisplayProps = DisplayProps;
  2042. })();
  2043. //##############################################################################
  2044. // Point.js
  2045. //##############################################################################
  2046. this.createjs = this.createjs||{};
  2047. (function() {
  2048. "use strict";
  2049. // constructor:
  2050. /**
  2051. * Represents a point on a 2 dimensional x / y coordinate system.
  2052. *
  2053. * <h4>Example</h4>
  2054. *
  2055. * var point = new createjs.Point(0, 100);
  2056. *
  2057. * @class Point
  2058. * @param {Number} [x=0] X position.
  2059. * @param {Number} [y=0] Y position.
  2060. * @constructor
  2061. **/
  2062. function Point(x, y) {
  2063. this.setValues(x, y);
  2064. // public properties:
  2065. // assigned in the setValues method.
  2066. /**
  2067. * X position.
  2068. * @property x
  2069. * @type Number
  2070. **/
  2071. /**
  2072. * Y position.
  2073. * @property y
  2074. * @type Number
  2075. **/
  2076. }
  2077. var p = Point.prototype;
  2078. /**
  2079. * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`.
  2080. * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}}
  2081. * for details.
  2082. *
  2083. * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance.
  2084. *
  2085. * @method initialize
  2086. * @protected
  2087. * @deprecated
  2088. */
  2089. // p.initialize = function() {}; // searchable for devs wondering where it is.
  2090. // public methods:
  2091. /**
  2092. * Sets the specified values on this instance.
  2093. * @method setValues
  2094. * @param {Number} [x=0] X position.
  2095. * @param {Number} [y=0] Y position.
  2096. * @return {Point} This instance. Useful for chaining method calls.
  2097. * @chainable
  2098. */
  2099. p.setValues = function(x, y) {
  2100. this.x = x||0;
  2101. this.y = y||0;
  2102. return this;
  2103. };
  2104. /**
  2105. * Copies all properties from the specified point to this point.
  2106. * @method copy
  2107. * @param {Point} point The point to copy properties from.
  2108. * @return {Point} This point. Useful for chaining method calls.
  2109. * @chainable
  2110. */
  2111. p.copy = function(point) {
  2112. this.x = point.x;
  2113. this.y = point.y;
  2114. return this;
  2115. };
  2116. /**
  2117. * Returns a clone of the Point instance.
  2118. * @method clone
  2119. * @return {Point} a clone of the Point instance.
  2120. **/
  2121. p.clone = function() {
  2122. return new Point(this.x, this.y);
  2123. };
  2124. /**
  2125. * Returns a string representation of this object.
  2126. * @method toString
  2127. * @return {String} a string representation of the instance.
  2128. **/
  2129. p.toString = function() {
  2130. return "[Point (x="+this.x+" y="+this.y+")]";
  2131. };
  2132. createjs.Point = Point;
  2133. }());
  2134. //##############################################################################
  2135. // Rectangle.js
  2136. //##############################################################################
  2137. this.createjs = this.createjs||{};
  2138. (function() {
  2139. "use strict";
  2140. // constructor:
  2141. /**
  2142. * Represents a rectangle as defined by the points (x, y) and (x+width, y+height).
  2143. *
  2144. * <h4>Example</h4>
  2145. *
  2146. * var rect = new createjs.Rectangle(0, 0, 100, 100);
  2147. *
  2148. * @class Rectangle
  2149. * @param {Number} [x=0] X position.
  2150. * @param {Number} [y=0] Y position.
  2151. * @param {Number} [width=0] The width of the Rectangle.
  2152. * @param {Number} [height=0] The height of the Rectangle.
  2153. * @constructor
  2154. **/
  2155. function Rectangle(x, y, width, height) {
  2156. this.setValues(x, y, width, height);
  2157. // public properties:
  2158. // assigned in the setValues method.
  2159. /**
  2160. * X position.
  2161. * @property x
  2162. * @type Number
  2163. **/
  2164. /**
  2165. * Y position.
  2166. * @property y
  2167. * @type Number
  2168. **/
  2169. /**
  2170. * Width.
  2171. * @property width
  2172. * @type Number
  2173. **/
  2174. /**
  2175. * Height.
  2176. * @property height
  2177. * @type Number
  2178. **/
  2179. }
  2180. var p = Rectangle.prototype;
  2181. /**
  2182. * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`.
  2183. * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}}
  2184. * for details.
  2185. *
  2186. * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance.
  2187. *
  2188. * @method initialize
  2189. * @protected
  2190. * @deprecated
  2191. */
  2192. // p.initialize = function() {}; // searchable for devs wondering where it is.
  2193. // public methods:
  2194. /**
  2195. * Sets the specified values on this instance.
  2196. * @method setValues
  2197. * @param {Number} [x=0] X position.
  2198. * @param {Number} [y=0] Y position.
  2199. * @param {Number} [width=0] The width of the Rectangle.
  2200. * @param {Number} [height=0] The height of the Rectangle.
  2201. * @return {Rectangle} This instance. Useful for chaining method calls.
  2202. * @chainable
  2203. */
  2204. p.setValues = function(x, y, width, height) {
  2205. // don't forget to update docs in the constructor if these change:
  2206. this.x = x||0;
  2207. this.y = y||0;
  2208. this.width = width||0;
  2209. this.height = height||0;
  2210. return this;
  2211. };
  2212. /**
  2213. * Extends the rectangle's bounds to include the described point or rectangle.
  2214. * @method extend
  2215. * @param {Number} x X position of the point or rectangle.
  2216. * @param {Number} y Y position of the point or rectangle.
  2217. * @param {Number} [width=0] The width of the rectangle.
  2218. * @param {Number} [height=0] The height of the rectangle.
  2219. * @return {Rectangle} This instance. Useful for chaining method calls.
  2220. * @chainable
  2221. */
  2222. p.extend = function(x, y, width, height) {
  2223. width = width||0;
  2224. height = height||0;
  2225. if (x+width > this.x+this.width) { this.width = x+width-this.x; }
  2226. if (y+height > this.y+this.height) { this.height = y+height-this.y; }
  2227. if (x < this.x) { this.width += this.x-x; this.x = x; }
  2228. if (y < this.y) { this.height += this.y-y; this.y = y; }
  2229. return this;
  2230. };
  2231. /**
  2232. * Adds the specified padding to the rectangle's bounds.
  2233. * @method pad
  2234. * @param {Number} top
  2235. * @param {Number} left
  2236. * @param {Number} right
  2237. * @param {Number} bottom
  2238. * @return {Rectangle} This instance. Useful for chaining method calls.
  2239. * @chainable
  2240. */
  2241. p.pad = function(top, left, bottom, right) {
  2242. this.x -= left;
  2243. this.y -= top;
  2244. this.width += left+right;
  2245. this.height += top+bottom;
  2246. return this;
  2247. };
  2248. /**
  2249. * Copies all properties from the specified rectangle to this rectangle.
  2250. * @method copy
  2251. * @param {Rectangle} rectangle The rectangle to copy properties from.
  2252. * @return {Rectangle} This rectangle. Useful for chaining method calls.
  2253. * @chainable
  2254. */
  2255. p.copy = function(rectangle) {
  2256. return this.setValues(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
  2257. };
  2258. /**
  2259. * Returns true if this rectangle fully encloses the described point or rectangle.
  2260. * @method contains
  2261. * @param {Number} x X position of the point or rectangle.
  2262. * @param {Number} y Y position of the point or rectangle.
  2263. * @param {Number} [width=0] The width of the rectangle.
  2264. * @param {Number} [height=0] The height of the rectangle.
  2265. * @return {Boolean} True if the described point or rectangle is contained within this rectangle.
  2266. */
  2267. p.contains = function(x, y, width, height) {
  2268. width = width||0;
  2269. height = height||0;
  2270. return (x >= this.x && x+width <= this.x+this.width && y >= this.y && y+height <= this.y+this.height);
  2271. };
  2272. /**
  2273. * Returns a new rectangle which contains this rectangle and the specified rectangle.
  2274. * @method union
  2275. * @param {Rectangle} rect The rectangle to calculate a union with.
  2276. * @return {Rectangle} A new rectangle describing the union.
  2277. */
  2278. p.union = function(rect) {
  2279. return this.clone().extend(rect.x, rect.y, rect.width, rect.height);
  2280. };
  2281. /**
  2282. * Returns a new rectangle which describes the intersection (overlap) of this rectangle and the specified rectangle,
  2283. * or null if they do not intersect.
  2284. * @method intersection
  2285. * @param {Rectangle} rect The rectangle to calculate an intersection with.
  2286. * @return {Rectangle} A new rectangle describing the intersection or null.
  2287. */
  2288. p.intersection = function(rect) {
  2289. var x1 = rect.x, y1 = rect.y, x2 = x1+rect.width, y2 = y1+rect.height;
  2290. if (this.x > x1) { x1 = this.x; }
  2291. if (this.y > y1) { y1 = this.y; }
  2292. if (this.x + this.width < x2) { x2 = this.x + this.width; }
  2293. if (this.y + this.height < y2) { y2 = this.y + this.height; }
  2294. return (x2 <= x1 || y2 <= y1) ? null : new Rectangle(x1, y1, x2-x1, y2-y1);
  2295. };
  2296. /**
  2297. * Returns true if the specified rectangle intersects (has any overlap) with this rectangle.
  2298. * @method intersects
  2299. * @param {Rectangle} rect The rectangle to compare.
  2300. * @return {Boolean} True if the rectangles intersect.
  2301. */
  2302. p.intersects = function(rect) {
  2303. 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);
  2304. };
  2305. /**
  2306. * Returns true if the width or height are equal or less than 0.
  2307. * @method isEmpty
  2308. * @return {Boolean} True if the rectangle is empty.
  2309. */
  2310. p.isEmpty = function() {
  2311. return this.width <= 0 || this.height <= 0;
  2312. };
  2313. /**
  2314. * Returns a clone of the Rectangle instance.
  2315. * @method clone
  2316. * @return {Rectangle} a clone of the Rectangle instance.
  2317. **/
  2318. p.clone = function() {
  2319. return new Rectangle(this.x, this.y, this.width, this.height);
  2320. };
  2321. /**
  2322. * Returns a string representation of this object.
  2323. * @method toString
  2324. * @return {String} a string representation of the instance.
  2325. **/
  2326. p.toString = function() {
  2327. return "[Rectangle (x="+this.x+" y="+this.y+" width="+this.width+" height="+this.height+")]";
  2328. };
  2329. createjs.Rectangle = Rectangle;
  2330. }());
  2331. //##############################################################################
  2332. // ButtonHelper.js
  2333. //##############################################################################
  2334. this.createjs = this.createjs||{};
  2335. (function() {
  2336. "use strict";
  2337. // constructor:
  2338. /**
  2339. * The ButtonHelper is a helper class to create interactive buttons from {{#crossLink "MovieClip"}}{{/crossLink}} or
  2340. * {{#crossLink "Sprite"}}{{/crossLink}} instances. This class will intercept mouse events from an object, and
  2341. * automatically call {{#crossLink "Sprite/gotoAndStop"}}{{/crossLink}} or {{#crossLink "Sprite/gotoAndPlay"}}{{/crossLink}},
  2342. * to the respective animation labels, add a pointer cursor, and allows the user to define a hit state frame.
  2343. *
  2344. * The ButtonHelper instance does not need to be added to the stage, but a reference should be maintained to prevent
  2345. * garbage collection.
  2346. *
  2347. * Note that over states will not work unless you call {{#crossLink "Stage/enableMouseOver"}}{{/crossLink}}.
  2348. *
  2349. * <h4>Example</h4>
  2350. *
  2351. * var helper = new createjs.ButtonHelper(myInstance, "out", "over", "down", false, myInstance, "hit");
  2352. * myInstance.addEventListener("click", handleClick);
  2353. * function handleClick(event) {
  2354. * // Click Happened.
  2355. * }
  2356. *
  2357. * @class ButtonHelper
  2358. * @param {Sprite|MovieClip} target The instance to manage.
  2359. * @param {String} [outLabel="out"] The label or animation to go to when the user rolls out of the button.
  2360. * @param {String} [overLabel="over"] The label or animation to go to when the user rolls over the button.
  2361. * @param {String} [downLabel="down"] The label or animation to go to when the user presses the button.
  2362. * @param {Boolean} [play=false] If the helper should call "gotoAndPlay" or "gotoAndStop" on the button when changing
  2363. * states.
  2364. * @param {DisplayObject} [hitArea] An optional item to use as the hit state for the button. If this is not defined,
  2365. * then the button's visible states will be used instead. Note that the same instance as the "target" argument can be
  2366. * used for the hitState.
  2367. * @param {String} [hitLabel] The label or animation on the hitArea instance that defines the hitArea bounds. If this is
  2368. * null, then the default state of the hitArea will be used. *
  2369. * @constructor
  2370. */
  2371. function ButtonHelper(target, outLabel, overLabel, downLabel, play, hitArea, hitLabel) {
  2372. if (!target.addEventListener) { return; }
  2373. // public properties:
  2374. /**
  2375. * The target for this button helper.
  2376. * @property target
  2377. * @type MovieClip | Sprite
  2378. * @readonly
  2379. **/
  2380. this.target = target;
  2381. /**
  2382. * The label name or frame number to display when the user mouses out of the target. Defaults to "over".
  2383. * @property overLabel
  2384. * @type String | Number
  2385. **/
  2386. this.overLabel = overLabel == null ? "over" : overLabel;
  2387. /**
  2388. * The label name or frame number to display when the user mouses over the target. Defaults to "out".
  2389. * @property outLabel
  2390. * @type String | Number
  2391. **/
  2392. this.outLabel = outLabel == null ? "out" : outLabel;
  2393. /**
  2394. * The label name or frame number to display when the user presses on the target. Defaults to "down".
  2395. * @property downLabel
  2396. * @type String | Number
  2397. **/
  2398. this.downLabel = downLabel == null ? "down" : downLabel;
  2399. /**
  2400. * If true, then ButtonHelper will call gotoAndPlay, if false, it will use gotoAndStop. Default is false.
  2401. * @property play
  2402. * @default false
  2403. * @type Boolean
  2404. **/
  2405. this.play = play;
  2406. // private properties
  2407. /**
  2408. * @property _isPressed
  2409. * @type Boolean
  2410. * @protected
  2411. **/
  2412. this._isPressed = false;
  2413. /**
  2414. * @property _isOver
  2415. * @type Boolean
  2416. * @protected
  2417. **/
  2418. this._isOver = false;
  2419. /**
  2420. * @property _enabled
  2421. * @type Boolean
  2422. * @protected
  2423. **/
  2424. this._enabled = false;
  2425. // setup:
  2426. target.mouseChildren = false; // prevents issues when children are removed from the display list when state changes.
  2427. this.enabled = true;
  2428. this.handleEvent({});
  2429. if (hitArea) {
  2430. if (hitLabel) {
  2431. hitArea.actionsEnabled = false;
  2432. hitArea.gotoAndStop&&hitArea.gotoAndStop(hitLabel);
  2433. }
  2434. target.hitArea = hitArea;
  2435. }
  2436. }
  2437. var p = ButtonHelper.prototype;
  2438. /**
  2439. * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`.
  2440. * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}}
  2441. * for details.
  2442. *
  2443. * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance.
  2444. *
  2445. * @method initialize
  2446. * @protected
  2447. * @deprecated
  2448. */
  2449. // p.initialize = function() {}; // searchable for devs wondering where it is.
  2450. // getter / setters:
  2451. /**
  2452. * Use the {{#crossLink "ButtonHelper/enabled:property"}}{{/crossLink}} property instead.
  2453. * @method setEnabled
  2454. * @param {Boolean} value
  2455. * @deprecated
  2456. **/
  2457. p.setEnabled = function(value) { // TODO: deprecated.
  2458. if (value == this._enabled) { return; }
  2459. var o = this.target;
  2460. this._enabled = value;
  2461. if (value) {
  2462. o.cursor = "pointer";
  2463. o.addEventListener("rollover", this);
  2464. o.addEventListener("rollout", this);
  2465. o.addEventListener("mousedown", this);
  2466. o.addEventListener("pressup", this);
  2467. if (o._reset) { o.__reset = o._reset; o._reset = this._reset;}
  2468. } else {
  2469. o.cursor = null;
  2470. o.removeEventListener("rollover", this);
  2471. o.removeEventListener("rollout", this);
  2472. o.removeEventListener("mousedown", this);
  2473. o.removeEventListener("pressup", this);
  2474. if (o.__reset) { o._reset = o.__reset; delete(o.__reset); }
  2475. }
  2476. };
  2477. /**
  2478. * Use the {{#crossLink "ButtonHelper/enabled:property"}}{{/crossLink}} property instead.
  2479. * @method getEnabled
  2480. * @return {Boolean}
  2481. * @deprecated
  2482. **/
  2483. p.getEnabled = function() {
  2484. return this._enabled;
  2485. };
  2486. /**
  2487. * Enables or disables the button functionality on the target.
  2488. * @property enabled
  2489. * @type {Boolean}
  2490. **/
  2491. try {
  2492. Object.defineProperties(p, {
  2493. enabled: { get: p.getEnabled, set: p.setEnabled }
  2494. });
  2495. } catch (e) {} // TODO: use Log
  2496. // public methods:
  2497. /**
  2498. * Returns a string representation of this object.
  2499. * @method toString
  2500. * @return {String} a string representation of the instance.
  2501. **/
  2502. p.toString = function() {
  2503. return "[ButtonHelper]";
  2504. };
  2505. // private methods:
  2506. /**
  2507. * @method handleEvent
  2508. * @param {Object} evt The mouse event to handle.
  2509. * @protected
  2510. **/
  2511. p.handleEvent = function(evt) {
  2512. var label, t = this.target, type = evt.type;
  2513. if (type == "mousedown") {
  2514. this._isPressed = true;
  2515. label = this.downLabel;
  2516. } else if (type == "pressup") {
  2517. this._isPressed = false;
  2518. label = this._isOver ? this.overLabel : this.outLabel;
  2519. } else if (type == "rollover") {
  2520. this._isOver = true;
  2521. label = this._isPressed ? this.downLabel : this.overLabel;
  2522. } else { // rollout and default
  2523. this._isOver = false;
  2524. label = this._isPressed ? this.overLabel : this.outLabel;
  2525. }
  2526. if (this.play) {
  2527. t.gotoAndPlay&&t.gotoAndPlay(label);
  2528. } else {
  2529. t.gotoAndStop&&t.gotoAndStop(label);
  2530. }
  2531. };
  2532. /**
  2533. * Injected into target. Preserves the paused state through a reset.
  2534. * @method _reset
  2535. * @protected
  2536. **/
  2537. p._reset = function() {
  2538. // TODO: explore better ways to handle this issue. This is hacky & disrupts object signatures.
  2539. var p = this.paused;
  2540. this.__reset();
  2541. this.paused = p;
  2542. };
  2543. createjs.ButtonHelper = ButtonHelper;
  2544. }());
  2545. //##############################################################################
  2546. // Shadow.js
  2547. //##############################################################################
  2548. this.createjs = this.createjs||{};
  2549. (function() {
  2550. "use strict";
  2551. // constructor:
  2552. /**
  2553. * This class encapsulates the properties required to define a shadow to apply to a {{#crossLink "DisplayObject"}}{{/crossLink}}
  2554. * via its <code>shadow</code> property.
  2555. *
  2556. * <h4>Example</h4>
  2557. *
  2558. * myImage.shadow = new createjs.Shadow("#000000", 5, 5, 10);
  2559. *
  2560. * @class Shadow
  2561. * @constructor
  2562. * @param {String} color The color of the shadow. This can be any valid CSS color value.
  2563. * @param {Number} offsetX The x offset of the shadow in pixels.
  2564. * @param {Number} offsetY The y offset of the shadow in pixels.
  2565. * @param {Number} blur The size of the blurring effect.
  2566. **/
  2567. function Shadow(color, offsetX, offsetY, blur) {
  2568. // public properties:
  2569. /**
  2570. * The color of the shadow. This can be any valid CSS color value.
  2571. * @property color
  2572. * @type String
  2573. * @default null
  2574. */
  2575. this.color = color||"black";
  2576. /** The x offset of the shadow.
  2577. * @property offsetX
  2578. * @type Number
  2579. * @default 0
  2580. */
  2581. this.offsetX = offsetX||0;
  2582. /** The y offset of the shadow.
  2583. * @property offsetY
  2584. * @type Number
  2585. * @default 0
  2586. */
  2587. this.offsetY = offsetY||0;
  2588. /** The blur of the shadow.
  2589. * @property blur
  2590. * @type Number
  2591. * @default 0
  2592. */
  2593. this.blur = blur||0;
  2594. }
  2595. var p = Shadow.prototype;
  2596. /**
  2597. * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`.
  2598. * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}}
  2599. * for details.
  2600. *
  2601. * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance.
  2602. *
  2603. * @method initialize
  2604. * @protected
  2605. * @deprecated
  2606. */
  2607. // p.initialize = function() {}; // searchable for devs wondering where it is.
  2608. // static public properties:
  2609. /**
  2610. * An identity shadow object (all properties are set to 0).
  2611. * @property identity
  2612. * @type Shadow
  2613. * @static
  2614. * @final
  2615. * @readonly
  2616. **/
  2617. Shadow.identity = new Shadow("transparent", 0, 0, 0);
  2618. // public methods:
  2619. /**
  2620. * Returns a string representation of this object.
  2621. * @method toString
  2622. * @return {String} a string representation of the instance.
  2623. **/
  2624. p.toString = function() {
  2625. return "[Shadow]";
  2626. };
  2627. /**
  2628. * Returns a clone of this Shadow instance.
  2629. * @method clone
  2630. * @return {Shadow} A clone of the current Shadow instance.
  2631. **/
  2632. p.clone = function() {
  2633. return new Shadow(this.color, this.offsetX, this.offsetY, this.blur);
  2634. };
  2635. createjs.Shadow = Shadow;
  2636. }());
  2637. //##############################################################################
  2638. // SpriteSheet.js
  2639. //##############################################################################
  2640. this.createjs = this.createjs||{};
  2641. (function() {
  2642. "use strict";
  2643. // constructor:
  2644. /**
  2645. * Encapsulates the properties and methods associated with a sprite sheet. A sprite sheet is a series of images (usually
  2646. * animation frames) combined into a larger image (or images). For example, an animation consisting of eight 100x100
  2647. * images could be combined into a single 400x200 sprite sheet (4 frames across by 2 high).
  2648. *
  2649. * The data passed to the SpriteSheet constructor defines:
  2650. * <ol>
  2651. * <li> The source image or images to use.</li>
  2652. * <li> The positions of individual image frames.</li>
  2653. * <li> Sequences of frames that form named animations. Optional.</li>
  2654. * <li> The target playback framerate. Optional.</li>
  2655. * </ol>
  2656. * <h3>SpriteSheet Format</h3>
  2657. * SpriteSheets are an object with two required properties (`images` and `frames`), and two optional properties
  2658. * (`framerate` and `animations`). This makes them easy to define in javascript code, or in JSON.
  2659. *
  2660. * <h4>images</h4>
  2661. * An array of source images. Images can be either an HTMlimage
  2662. * instance, or a uri to an image. The former is recommended to control preloading.
  2663. *
  2664. * images: [image1, "path/to/image2.png"],
  2665. *
  2666. * <h4>frames</h4>
  2667. * Defines the individual frames. There are two supported formats for frame data:
  2668. * When all of the frames are the same size (in a grid), use an object with `width`, `height`, `regX`, `regY`,
  2669. * and `count` properties.
  2670. *
  2671. * <ul>
  2672. * <li>`width` & `height` are required and specify the dimensions of the frames</li>
  2673. * <li>`regX` & `regY` indicate the registration point or "origin" of the frames</li>
  2674. * <li>`spacing` indicate the spacing between frames</li>
  2675. * <li>`margin` specify the margin around the image(s)</li>
  2676. * <li>`count` allows you to specify the total number of frames in the spritesheet; if omitted, this will
  2677. * be calculated based on the dimensions of the source images and the frames. Frames will be assigned
  2678. * indexes based on their position in the source images (left to right, top to bottom).</li>
  2679. * </ul>
  2680. *
  2681. * frames: {width:64, height:64, count:20, regX: 32, regY:64, spacing:0, margin:0}
  2682. *
  2683. * If the frames are of different sizes, use an array of frame definitions. Each definition is itself an array
  2684. * with 4 required and 3 optional entries, in the order:
  2685. *
  2686. * <ul>
  2687. * <li>The first four, `x`, `y`, `width`, and `height` are required and define the frame rectangle.</li>
  2688. * <li>The fifth, `imageIndex`, specifies the index of the source image (defaults to 0)</li>
  2689. * <li>The last two, `regX` and `regY` specify the registration point of the frame</li>
  2690. * </ul>
  2691. *
  2692. * frames: [
  2693. * // x, y, width, height, imageIndex*, regX*, regY*
  2694. * [64, 0, 96, 64],
  2695. * [0, 0, 64, 64, 1, 32, 32]
  2696. * // etc.
  2697. * ]
  2698. *
  2699. * <h4>animations</h4>
  2700. * Optional. An object defining sequences of frames to play as named animations. Each property corresponds to an
  2701. * animation of the same name. Each animation must specify the frames to play, and may
  2702. * also include a relative playback `speed` (ex. 2 would playback at double speed, 0.5 at half), and
  2703. * the name of the `next` animation to sequence to after it completes.
  2704. *
  2705. * There are three formats supported for defining the frames in an animation, which can be mixed and matched as appropriate:
  2706. * <ol>
  2707. * <li>for a single frame animation, you can simply specify the frame index
  2708. *
  2709. * animations: {
  2710. * sit: 7
  2711. * }
  2712. *
  2713. * </li>
  2714. * <li>
  2715. * for an animation of consecutive frames, you can use an array with two required, and two optional entries
  2716. * in the order: `start`, `end`, `next`, and `speed`. This will play the frames from start to end inclusive.
  2717. *
  2718. * animations: {
  2719. * // start, end, next*, speed*
  2720. * run: [0, 8],
  2721. * jump: [9, 12, "run", 2]
  2722. * }
  2723. *
  2724. * </li>
  2725. * <li>
  2726. * for non-consecutive frames, you can use an object with a `frames` property defining an array of frame
  2727. * indexes to play in order. The object can also specify `next` and `speed` properties.
  2728. *
  2729. * animations: {
  2730. * walk: {
  2731. * frames: [1,2,3,3,2,1]
  2732. * },
  2733. * shoot: {
  2734. * frames: [1,4,5,6],
  2735. * next: "walk",
  2736. * speed: 0.5
  2737. * }
  2738. * }
  2739. *
  2740. * </li>
  2741. * </ol>
  2742. * <strong>Note:</strong> the `speed` property was added in EaselJS 0.7.0. Earlier versions had a `frequency`
  2743. * property instead, which was the inverse of `speed`. For example, a value of "4" would be 1/4 normal speed in
  2744. * earlier versions, but is 4x normal speed in EaselJS 0.7.0+.
  2745. *
  2746. * <h4>framerate</h4>
  2747. * Optional. Indicates the default framerate to play this spritesheet at in frames per second. See
  2748. * {{#crossLink "SpriteSheet/framerate:property"}}{{/crossLink}} for more information.
  2749. *
  2750. * framerate: 20
  2751. *
  2752. * Note that the Sprite framerate will only work if the stage update method is provided with the {{#crossLink "Ticker/tick:event"}}{{/crossLink}}
  2753. * event generated by the {{#crossLink "Ticker"}}{{/crossLink}}.
  2754. *
  2755. * createjs.Ticker.on("tick", handleTick);
  2756. * function handleTick(event) {
  2757. * stage.update(event);
  2758. * }
  2759. *
  2760. * <h3>Example</h3>
  2761. * To define a simple sprite sheet, with a single image "sprites.jpg" arranged in a regular 50x50 grid with three
  2762. * animations: "stand" showing the first frame, "run" looping frame 1-5 inclusive, and "jump" playing frame 6-8 and
  2763. * sequencing back to run.
  2764. *
  2765. * var data = {
  2766. * images: ["sprites.jpg"],
  2767. * frames: {width:50, height:50},
  2768. * animations: {
  2769. * stand:0,
  2770. * run:[1,5],
  2771. * jump:[6,8,"run"]
  2772. * }
  2773. * };
  2774. * var spriteSheet = new createjs.SpriteSheet(data);
  2775. * var animation = new createjs.Sprite(spriteSheet, "run");
  2776. *
  2777. * <h3>Generating SpriteSheet Images</h3>
  2778. * Spritesheets can be created manually by combining images in PhotoShop, and specifying the frame size or
  2779. * coordinates manually, however there are a number of tools that facilitate this.
  2780. * <ul>
  2781. * <li>Exporting SpriteSheets or HTML5 content from Flash Pro supports the EaselJS SpriteSheet format.</li>
  2782. * <li>The popular <a href="https://www.codeandweb.com/texturepacker/easeljs" target="_blank">Texture Packer</a> has
  2783. * EaselJS support.
  2784. * <li>SWF animations in Flash can be exported to SpriteSheets using <a href="http://createjs.com/zoe" target="_blank"></a></li>
  2785. * </ul>
  2786. *
  2787. * <h3>Cross Origin Issues</h3>
  2788. * <strong>Warning:</strong> Images loaded cross-origin will throw cross-origin security errors when interacted with
  2789. * using:
  2790. * <ul>
  2791. * <li>a mouse</li>
  2792. * <li>methods such as {{#crossLink "Container/getObjectUnderPoint"}}{{/crossLink}}</li>
  2793. * <li>Filters (see {{#crossLink "Filter"}}{{/crossLink}})</li>
  2794. * <li>caching (see {{#crossLink "DisplayObject/cache"}}{{/crossLink}})</li>
  2795. * </ul>
  2796. * You can get around this by setting `crossOrigin` property on your images before passing them to EaselJS, or
  2797. * setting the `crossOrigin` property on PreloadJS' LoadQueue or LoadItems.
  2798. *
  2799. * var image = new Image();
  2800. * img.crossOrigin="Anonymous";
  2801. * img.src = "http://server-with-CORS-support.com/path/to/image.jpg";
  2802. *
  2803. * If you pass string paths to SpriteSheets, they will not work cross-origin. The server that stores the image must
  2804. * support cross-origin requests, or this will not work. For more information, check out
  2805. * <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS" target="_blank">CORS overview on MDN</a>.
  2806. *
  2807. * @class SpriteSheet
  2808. * @constructor
  2809. * @param {Object} data An object describing the SpriteSheet data.
  2810. * @extends EventDispatcher
  2811. **/
  2812. function SpriteSheet(data) {
  2813. this.EventDispatcher_constructor();
  2814. // public properties:
  2815. /**
  2816. * Indicates whether all images are finished loading.
  2817. * @property complete
  2818. * @type Boolean
  2819. * @readonly
  2820. **/
  2821. this.complete = true;
  2822. /**
  2823. * Specifies the framerate to use by default for Sprite instances using the SpriteSheet. See the Sprite class
  2824. * {{#crossLink "Sprite/framerate:property"}}{{/crossLink}} for more information.
  2825. * @property framerate
  2826. * @type Number
  2827. **/
  2828. this.framerate = 0;
  2829. // private properties:
  2830. /**
  2831. * @property _animations
  2832. * @protected
  2833. * @type Array
  2834. **/
  2835. this._animations = null;
  2836. /**
  2837. * @property _frames
  2838. * @protected
  2839. * @type Array
  2840. **/
  2841. this._frames = null;
  2842. /**
  2843. * @property _images
  2844. * @protected
  2845. * @type Array
  2846. **/
  2847. this._images = null;
  2848. /**
  2849. * @property _data
  2850. * @protected
  2851. * @type Object
  2852. **/
  2853. this._data = null;
  2854. /**
  2855. * @property _loadCount
  2856. * @protected
  2857. * @type Number
  2858. **/
  2859. this._loadCount = 0;
  2860. // only used for simple frame defs:
  2861. /**
  2862. * @property _frameHeight
  2863. * @protected
  2864. * @type Number
  2865. **/
  2866. this._frameHeight = 0;
  2867. /**
  2868. * @property _frameWidth
  2869. * @protected
  2870. * @type Number
  2871. **/
  2872. this._frameWidth = 0;
  2873. /**
  2874. * @property _numFrames
  2875. * @protected
  2876. * @type Number
  2877. **/
  2878. this._numFrames = 0;
  2879. /**
  2880. * @property _regX
  2881. * @protected
  2882. * @type Number
  2883. **/
  2884. this._regX = 0;
  2885. /**
  2886. * @property _regY
  2887. * @protected
  2888. * @type Number
  2889. **/
  2890. this._regY = 0;
  2891. /**
  2892. * @property _spacing
  2893. * @protected
  2894. * @type Number
  2895. **/
  2896. this._spacing = 0;
  2897. /**
  2898. * @property _margin
  2899. * @protected
  2900. * @type Number
  2901. **/
  2902. this._margin = 0;
  2903. // setup:
  2904. this._parseData(data);
  2905. }
  2906. var p = createjs.extend(SpriteSheet, createjs.EventDispatcher);
  2907. // TODO: deprecated
  2908. // p.initialize = function() {}; // searchable for devs wondering where it is. REMOVED. See docs for details.
  2909. // events:
  2910. /**
  2911. * Dispatched when all images are loaded. Note that this only fires if the images
  2912. * were not fully loaded when the sprite sheet was initialized. You should check the complete property
  2913. * to prior to adding a listener. Ex.
  2914. *
  2915. * var sheet = new createjs.SpriteSheet(data);
  2916. * if (!sheet.complete) {
  2917. * // not preloaded, listen for the complete event:
  2918. * sheet.addEventListener("complete", handler);
  2919. * }
  2920. *
  2921. * @event complete
  2922. * @param {Object} target The object that dispatched the event.
  2923. * @param {String} type The event type.
  2924. * @since 0.6.0
  2925. */
  2926. /**
  2927. * Dispatched when getFrame is called with a valid frame index. This is primarily intended for use by {{#crossLink "SpriteSheetBuilder"}}{{/crossLink}}
  2928. * when doing on-demand rendering.
  2929. * @event getframe
  2930. * @param {Number} index The frame index.
  2931. * @param {Object} frame The frame object that getFrame will return.
  2932. */
  2933. /**
  2934. * Dispatched when an image encounters an error. A SpriteSheet will dispatch an error event for each image that
  2935. * encounters an error, and will still dispatch a {{#crossLink "SpriteSheet/complete:event"}}{{/crossLink}}
  2936. * event once all images are finished processing, even if an error is encountered.
  2937. * @event error
  2938. * @param {String} src The source of the image that failed to load.
  2939. * @since 0.8.2
  2940. */
  2941. // getter / setters:
  2942. /**
  2943. * Use the {{#crossLink "SpriteSheet/animations:property"}}{{/crossLink}} property instead.
  2944. * @method getAnimations
  2945. * @return {Array}
  2946. * @deprecated
  2947. **/
  2948. p.getAnimations = function() {
  2949. return this._animations.slice();
  2950. };
  2951. /**
  2952. * Returns an array of all available animation names available on this sprite sheet as strings.
  2953. * @property animations
  2954. * @type {Array}
  2955. * @readonly
  2956. **/
  2957. try {
  2958. Object.defineProperties(p, {
  2959. animations: { get: p.getAnimations }
  2960. });
  2961. } catch (e) {}
  2962. // public methods:
  2963. /**
  2964. * Returns the total number of frames in the specified animation, or in the whole sprite
  2965. * sheet if the animation param is omitted. Returns 0 if the spritesheet relies on calculated frame counts, and
  2966. * the images have not been fully loaded.
  2967. * @method getNumFrames
  2968. * @param {String} animation The name of the animation to get a frame count for.
  2969. * @return {Number} The number of frames in the animation, or in the entire sprite sheet if the animation param is omitted.
  2970. */
  2971. p.getNumFrames = function(animation) {
  2972. if (animation == null) {
  2973. return this._frames ? this._frames.length : this._numFrames || 0;
  2974. } else {
  2975. var data = this._data[animation];
  2976. if (data == null) { return 0; }
  2977. else { return data.frames.length; }
  2978. }
  2979. };
  2980. /**
  2981. * Returns an object defining the specified animation. The returned object contains:<UL>
  2982. * <li>frames: an array of the frame ids in the animation</li>
  2983. * <li>speed: the playback speed for this animation</li>
  2984. * <li>name: the name of the animation</li>
  2985. * <li>next: the default animation to play next. If the animation loops, the name and next property will be the
  2986. * same.</li>
  2987. * </UL>
  2988. * @method getAnimation
  2989. * @param {String} name The name of the animation to get.
  2990. * @return {Object} a generic object with frames, speed, name, and next properties.
  2991. **/
  2992. p.getAnimation = function(name) {
  2993. return this._data[name];
  2994. };
  2995. /**
  2996. * Returns an object specifying the image and source rect of the specified frame. The returned object has:<UL>
  2997. * <li>an image property holding a reference to the image object in which the frame is found</li>
  2998. * <li>a rect property containing a Rectangle instance which defines the boundaries for the frame within that
  2999. * image.</li>
  3000. * <li> A regX and regY property corresponding to the regX/Y values for the frame.
  3001. * </UL>
  3002. * @method getFrame
  3003. * @param {Number} frameIndex The index of the frame.
  3004. * @return {Object} a generic object with image and rect properties. Returns null if the frame does not exist.
  3005. **/
  3006. p.getFrame = function(frameIndex) {
  3007. var frame;
  3008. if (this._frames && (frame=this._frames[frameIndex])) { return frame; }
  3009. return null;
  3010. };
  3011. /**
  3012. * Returns a {{#crossLink "Rectangle"}}{{/crossLink}} instance defining the bounds of the specified frame relative
  3013. * to the origin. For example, a 90 x 70 frame with a regX of 50 and a regY of 40 would return:
  3014. *
  3015. * [x=-50, y=-40, width=90, height=70]
  3016. *
  3017. * @method getFrameBounds
  3018. * @param {Number} frameIndex The index of the frame.
  3019. * @param {Rectangle} [rectangle] A Rectangle instance to copy the values into. By default a new instance is created.
  3020. * @return {Rectangle} A Rectangle instance. Returns null if the frame does not exist, or the image is not fully loaded.
  3021. **/
  3022. p.getFrameBounds = function(frameIndex, rectangle) {
  3023. var frame = this.getFrame(frameIndex);
  3024. return frame ? (rectangle||new createjs.Rectangle()).setValues(-frame.regX, -frame.regY, frame.rect.width, frame.rect.height) : null;
  3025. };
  3026. /**
  3027. * Returns a string representation of this object.
  3028. * @method toString
  3029. * @return {String} a string representation of the instance.
  3030. **/
  3031. p.toString = function() {
  3032. return "[SpriteSheet]";
  3033. };
  3034. /**
  3035. * SpriteSheet cannot be cloned. A SpriteSheet can be shared by multiple Sprite instances without cloning it.
  3036. * @method clone
  3037. **/
  3038. p.clone = function() {
  3039. throw("SpriteSheet cannot be cloned.")
  3040. };
  3041. // private methods:
  3042. /**
  3043. * @method _parseData
  3044. * @param {Object} data An object describing the SpriteSheet data.
  3045. * @protected
  3046. **/
  3047. p._parseData = function(data) {
  3048. var i,l,o,a;
  3049. if (data == null) { return; }
  3050. this.framerate = data.framerate||0;
  3051. // parse images:
  3052. if (data.images && (l=data.images.length) > 0) {
  3053. a = this._images = [];
  3054. for (i=0; i<l; i++) {
  3055. var img = data.images[i];
  3056. if (typeof img == "string") {
  3057. var src = img;
  3058. img = document.createElement("img");
  3059. img.src = src;
  3060. }
  3061. a.push(img);
  3062. if (!img.getContext && !img.naturalWidth) {
  3063. this._loadCount++;
  3064. this.complete = false;
  3065. (function(o, src) { img.onload = function() { o._handleImageLoad(src); } })(this, src);
  3066. (function(o, src) { img.onerror = function() { o._handleImageError(src); } })(this, src);
  3067. }
  3068. }
  3069. }
  3070. // parse frames:
  3071. if (data.frames == null) { // nothing
  3072. } else if (Array.isArray(data.frames)) {
  3073. this._frames = [];
  3074. a = data.frames;
  3075. for (i=0,l=a.length;i<l;i++) {
  3076. var arr = a[i];
  3077. 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 });
  3078. }
  3079. } else {
  3080. o = data.frames;
  3081. this._frameWidth = o.width;
  3082. this._frameHeight = o.height;
  3083. this._regX = o.regX||0;
  3084. this._regY = o.regY||0;
  3085. this._spacing = o.spacing||0;
  3086. this._margin = o.margin||0;
  3087. this._numFrames = o.count;
  3088. if (this._loadCount == 0) { this._calculateFrames(); }
  3089. }
  3090. // parse animations:
  3091. this._animations = [];
  3092. if ((o=data.animations) != null) {
  3093. this._data = {};
  3094. var name;
  3095. for (name in o) {
  3096. var anim = {name:name};
  3097. var obj = o[name];
  3098. if (typeof obj == "number") { // single frame
  3099. a = anim.frames = [obj];
  3100. } else if (Array.isArray(obj)) { // simple
  3101. if (obj.length == 1) { anim.frames = [obj[0]]; }
  3102. else {
  3103. anim.speed = obj[3];
  3104. anim.next = obj[2];
  3105. a = anim.frames = [];
  3106. for (i=obj[0];i<=obj[1];i++) {
  3107. a.push(i);
  3108. }
  3109. }
  3110. } else { // complex
  3111. anim.speed = obj.speed;
  3112. anim.next = obj.next;
  3113. var frames = obj.frames;
  3114. a = anim.frames = (typeof frames == "number") ? [frames] : frames.slice(0);
  3115. }
  3116. if (anim.next === true || anim.next === undefined) { anim.next = name; } // loop
  3117. if (anim.next === false || (a.length < 2 && anim.next == name)) { anim.next = null; } // stop
  3118. if (!anim.speed) { anim.speed = 1; }
  3119. this._animations.push(name);
  3120. this._data[name] = anim;
  3121. }
  3122. }
  3123. };
  3124. /**
  3125. * @method _handleImageLoad
  3126. * @protected
  3127. **/
  3128. p._handleImageLoad = function(src) {
  3129. if (--this._loadCount == 0) {
  3130. this._calculateFrames();
  3131. this.complete = true;
  3132. this.dispatchEvent("complete");
  3133. }
  3134. };
  3135. /**
  3136. * @method _handleImageError
  3137. * @protected
  3138. */
  3139. p._handleImageError = function (src) {
  3140. var errorEvent = new createjs.Event("error");
  3141. errorEvent.src = src;
  3142. this.dispatchEvent(errorEvent);
  3143. // Complete is still dispatched.
  3144. if (--this._loadCount == 0) {
  3145. this.dispatchEvent("complete");
  3146. }
  3147. };
  3148. /**
  3149. * @method _calculateFrames
  3150. * @protected
  3151. **/
  3152. p._calculateFrames = function() {
  3153. if (this._frames || this._frameWidth == 0) { return; }
  3154. this._frames = [];
  3155. var maxFrames = this._numFrames || 100000; // if we go over this, something is wrong.
  3156. var frameCount = 0, frameWidth = this._frameWidth, frameHeight = this._frameHeight;
  3157. var spacing = this._spacing, margin = this._margin;
  3158. imgLoop:
  3159. for (var i=0, imgs=this._images; i<imgs.length; i++) {
  3160. var img = imgs[i], imgW = img.width, imgH = img.height;
  3161. var y = margin;
  3162. while (y <= imgH-margin-frameHeight) {
  3163. var x = margin;
  3164. while (x <= imgW-margin-frameWidth) {
  3165. if (frameCount >= maxFrames) { break imgLoop; }
  3166. frameCount++;
  3167. this._frames.push({
  3168. image: img,
  3169. rect: new createjs.Rectangle(x, y, frameWidth, frameHeight),
  3170. regX: this._regX,
  3171. regY: this._regY
  3172. });
  3173. x += frameWidth+spacing;
  3174. }
  3175. y += frameHeight+spacing;
  3176. }
  3177. }
  3178. this._numFrames = frameCount;
  3179. };
  3180. createjs.SpriteSheet = createjs.promote(SpriteSheet, "EventDispatcher");
  3181. }());
  3182. //##############################################################################
  3183. // Graphics.js
  3184. //##############################################################################
  3185. this.createjs = this.createjs||{};
  3186. (function() {
  3187. "use strict";
  3188. // constructor:
  3189. /**
  3190. * The Graphics class exposes an easy to use API for generating vector drawing instructions and drawing them to a
  3191. * specified context. Note that you can use Graphics without any dependency on the EaselJS framework by calling {{#crossLink "Graphics/draw"}}{{/crossLink}}
  3192. * directly, or it can be used with the {{#crossLink "Shape"}}{{/crossLink}} object to draw vector graphics within the
  3193. * context of an EaselJS display list.
  3194. *
  3195. * There are two approaches to working with Graphics object: calling methods on a Graphics instance (the "Graphics API"), or
  3196. * instantiating Graphics command objects and adding them to the graphics queue via {{#crossLink "Graphics/append"}}{{/crossLink}}.
  3197. * The former abstracts the latter, simplifying beginning and ending paths, fills, and strokes.
  3198. *
  3199. * var g = new createjs.Graphics();
  3200. * g.setStrokeStyle(1);
  3201. * g.beginStroke("#000000");
  3202. * g.beginFill("red");
  3203. * g.drawCircle(0,0,30);
  3204. *
  3205. * All drawing methods in Graphics return the Graphics instance, so they can be chained together. For example,
  3206. * the following line of code would generate the instructions to draw a rectangle with a red stroke and blue fill:
  3207. *
  3208. * myGraphics.beginStroke("red").beginFill("blue").drawRect(20, 20, 100, 50);
  3209. *
  3210. * Each graphics API call generates a command object (see below). The last command to be created can be accessed via
  3211. * {{#crossLink "Graphics/command:property"}}{{/crossLink}}:
  3212. *
  3213. * var fillCommand = myGraphics.beginFill("red").command;
  3214. * // ... later, update the fill style/color:
  3215. * fillCommand.style = "blue";
  3216. * // or change it to a bitmap fill:
  3217. * fillCommand.bitmap(myImage);
  3218. *
  3219. * For more direct control of rendering, you can instantiate and append command objects to the graphics queue directly. In this case, you
  3220. * need to manage path creation manually, and ensure that fill/stroke is applied to a defined path:
  3221. *
  3222. * // start a new path. Graphics.beginCmd is a reusable BeginPath instance:
  3223. * myGraphics.append(createjs.Graphics.beginCmd);
  3224. * // we need to define the path before applying the fill:
  3225. * var circle = new createjs.Graphics.Circle(0,0,30);
  3226. * myGraphics.append(circle);
  3227. * // fill the path we just defined:
  3228. * var fill = new createjs.Graphics.Fill("red");
  3229. * myGraphics.append(fill);
  3230. *
  3231. * These approaches can be used together, for example to insert a custom command:
  3232. *
  3233. * myGraphics.beginFill("red");
  3234. * var customCommand = new CustomSpiralCommand(etc);
  3235. * myGraphics.append(customCommand);
  3236. * myGraphics.beginFill("blue");
  3237. * myGraphics.drawCircle(0, 0, 30);
  3238. *
  3239. * See {{#crossLink "Graphics/append"}}{{/crossLink}} for more info on creating custom commands.
  3240. *
  3241. * <h4>Tiny API</h4>
  3242. * The Graphics class also includes a "tiny API", which is one or two-letter methods that are shortcuts for all of the
  3243. * Graphics methods. These methods are great for creating compact instructions, and is used by the Toolkit for CreateJS
  3244. * to generate readable code. All tiny methods are marked as protected, so you can view them by enabling protected
  3245. * descriptions in the docs.
  3246. *
  3247. * <table>
  3248. * <tr><td><b>Tiny</b></td><td><b>Method</b></td><td><b>Tiny</b></td><td><b>Method</b></td></tr>
  3249. * <tr><td>mt</td><td>{{#crossLink "Graphics/moveTo"}}{{/crossLink}} </td>
  3250. * <td>lt</td> <td>{{#crossLink "Graphics/lineTo"}}{{/crossLink}}</td></tr>
  3251. * <tr><td>a/at</td><td>{{#crossLink "Graphics/arc"}}{{/crossLink}} / {{#crossLink "Graphics/arcTo"}}{{/crossLink}} </td>
  3252. * <td>bt</td><td>{{#crossLink "Graphics/bezierCurveTo"}}{{/crossLink}} </td></tr>
  3253. * <tr><td>qt</td><td>{{#crossLink "Graphics/quadraticCurveTo"}}{{/crossLink}} (also curveTo)</td>
  3254. * <td>r</td><td>{{#crossLink "Graphics/rect"}}{{/crossLink}} </td></tr>
  3255. * <tr><td>cp</td><td>{{#crossLink "Graphics/closePath"}}{{/crossLink}} </td>
  3256. * <td>c</td><td>{{#crossLink "Graphics/clear"}}{{/crossLink}} </td></tr>
  3257. * <tr><td>f</td><td>{{#crossLink "Graphics/beginFill"}}{{/crossLink}} </td>
  3258. * <td>lf</td><td>{{#crossLink "Graphics/beginLinearGradientFill"}}{{/crossLink}} </td></tr>
  3259. * <tr><td>rf</td><td>{{#crossLink "Graphics/beginRadialGradientFill"}}{{/crossLink}} </td>
  3260. * <td>bf</td><td>{{#crossLink "Graphics/beginBitmapFill"}}{{/crossLink}} </td></tr>
  3261. * <tr><td>ef</td><td>{{#crossLink "Graphics/endFill"}}{{/crossLink}} </td>
  3262. * <td>ss / sd</td><td>{{#crossLink "Graphics/setStrokeStyle"}}{{/crossLink}} / {{#crossLink "Graphics/setStrokeDash"}}{{/crossLink}} </td></tr>
  3263. * <tr><td>s</td><td>{{#crossLink "Graphics/beginStroke"}}{{/crossLink}} </td>
  3264. * <td>ls</td><td>{{#crossLink "Graphics/beginLinearGradientStroke"}}{{/crossLink}} </td></tr>
  3265. * <tr><td>rs</td><td>{{#crossLink "Graphics/beginRadialGradientStroke"}}{{/crossLink}} </td>
  3266. * <td>bs</td><td>{{#crossLink "Graphics/beginBitmapStroke"}}{{/crossLink}} </td></tr>
  3267. * <tr><td>es</td><td>{{#crossLink "Graphics/endStroke"}}{{/crossLink}} </td>
  3268. * <td>dr</td><td>{{#crossLink "Graphics/drawRect"}}{{/crossLink}} </td></tr>
  3269. * <tr><td>rr</td><td>{{#crossLink "Graphics/drawRoundRect"}}{{/crossLink}} </td>
  3270. * <td>rc</td><td>{{#crossLink "Graphics/drawRoundRectComplex"}}{{/crossLink}} </td></tr>
  3271. * <tr><td>dc</td><td>{{#crossLink "Graphics/drawCircle"}}{{/crossLink}} </td>
  3272. * <td>de</td><td>{{#crossLink "Graphics/drawEllipse"}}{{/crossLink}} </td></tr>
  3273. * <tr><td>dp</td><td>{{#crossLink "Graphics/drawPolyStar"}}{{/crossLink}} </td>
  3274. * <td>p</td><td>{{#crossLink "Graphics/decodePath"}}{{/crossLink}} </td></tr>
  3275. * </table>
  3276. *
  3277. * Here is the above example, using the tiny API instead.
  3278. *
  3279. * myGraphics.s("red").f("blue").r(20, 20, 100, 50);
  3280. *
  3281. * @class Graphics
  3282. * @constructor
  3283. **/
  3284. function Graphics() {
  3285. // public properties
  3286. /**
  3287. * Holds a reference to the last command that was created or appended. For example, you could retain a reference
  3288. * to a Fill command in order to dynamically update the color later by using:
  3289. *
  3290. * var myFill = myGraphics.beginFill("red").command;
  3291. * // update color later:
  3292. * myFill.style = "yellow";
  3293. *
  3294. * @property command
  3295. * @type Object
  3296. **/
  3297. this.command = null;
  3298. // private properties
  3299. /**
  3300. * @property _stroke
  3301. * @protected
  3302. * @type {Stroke}
  3303. **/
  3304. this._stroke = null;
  3305. /**
  3306. * @property _strokeStyle
  3307. * @protected
  3308. * @type {StrokeStyle}
  3309. **/
  3310. this._strokeStyle = null;
  3311. /**
  3312. * @property _oldStrokeStyle
  3313. * @protected
  3314. * @type {StrokeStyle}
  3315. **/
  3316. this._oldStrokeStyle = null;
  3317. /**
  3318. * @property _strokeDash
  3319. * @protected
  3320. * @type {StrokeDash}
  3321. **/
  3322. this._strokeDash = null;
  3323. /**
  3324. * @property _oldStrokeDash
  3325. * @protected
  3326. * @type {StrokeDash}
  3327. **/
  3328. this._oldStrokeDash = null;
  3329. /**
  3330. * @property _strokeIgnoreScale
  3331. * @protected
  3332. * @type Boolean
  3333. **/
  3334. this._strokeIgnoreScale = false;
  3335. /**
  3336. * @property _fill
  3337. * @protected
  3338. * @type {Fill}
  3339. **/
  3340. this._fill = null;
  3341. /**
  3342. * @property _instructions
  3343. * @protected
  3344. * @type {Array}
  3345. **/
  3346. this._instructions = [];
  3347. /**
  3348. * Indicates the last instruction index that was committed.
  3349. * @property _commitIndex
  3350. * @protected
  3351. * @type {Number}
  3352. **/
  3353. this._commitIndex = 0;
  3354. /**
  3355. * Uncommitted instructions.
  3356. * @property _activeInstructions
  3357. * @protected
  3358. * @type {Array}
  3359. **/
  3360. this._activeInstructions = [];
  3361. /**
  3362. * This indicates that there have been changes to the activeInstruction list since the last updateInstructions call.
  3363. * @property _dirty
  3364. * @protected
  3365. * @type {Boolean}
  3366. * @default false
  3367. **/
  3368. this._dirty = false;
  3369. /**
  3370. * Index to draw from if a store operation has happened.
  3371. * @property _storeIndex
  3372. * @protected
  3373. * @type {Number}
  3374. * @default 0
  3375. **/
  3376. this._storeIndex = 0;
  3377. // setup:
  3378. this.clear();
  3379. }
  3380. var p = Graphics.prototype;
  3381. var G = Graphics; // shortcut
  3382. /**
  3383. * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`.
  3384. * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}}
  3385. * for details.
  3386. *
  3387. * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance.
  3388. *
  3389. * @method initialize
  3390. * @protected
  3391. * @deprecated
  3392. */
  3393. // p.initialize = function() {}; // searchable for devs wondering where it is.
  3394. // static public methods:
  3395. /**
  3396. * Returns a CSS compatible color string based on the specified RGB numeric color values in the format
  3397. * "rgba(255,255,255,1.0)", or if alpha is null then in the format "rgb(255,255,255)". For example,
  3398. *
  3399. * createjs.Graphics.getRGB(50, 100, 150, 0.5);
  3400. * // Returns "rgba(50,100,150,0.5)"
  3401. *
  3402. * It also supports passing a single hex color value as the first param, and an optional alpha value as the second
  3403. * param. For example,
  3404. *
  3405. * createjs.Graphics.getRGB(0xFF00FF, 0.2);
  3406. * // Returns "rgba(255,0,255,0.2)"
  3407. *
  3408. * @method getRGB
  3409. * @static
  3410. * @param {Number} r The red component for the color, between 0 and 0xFF (255).
  3411. * @param {Number} g The green component for the color, between 0 and 0xFF (255).
  3412. * @param {Number} b The blue component for the color, between 0 and 0xFF (255).
  3413. * @param {Number} [alpha] The alpha component for the color where 0 is fully transparent and 1 is fully opaque.
  3414. * @return {String} A CSS compatible color string based on the specified RGB numeric color values in the format
  3415. * "rgba(255,255,255,1.0)", or if alpha is null then in the format "rgb(255,255,255)".
  3416. **/
  3417. Graphics.getRGB = function(r, g, b, alpha) {
  3418. if (r != null && b == null) {
  3419. alpha = g;
  3420. b = r&0xFF;
  3421. g = r>>8&0xFF;
  3422. r = r>>16&0xFF;
  3423. }
  3424. if (alpha == null) {
  3425. return "rgb("+r+","+g+","+b+")";
  3426. } else {
  3427. return "rgba("+r+","+g+","+b+","+alpha+")";
  3428. }
  3429. };
  3430. /**
  3431. * Returns a CSS compatible color string based on the specified HSL numeric color values in the format "hsla(360,100,100,1.0)",
  3432. * or if alpha is null then in the format "hsl(360,100,100)".
  3433. *
  3434. * createjs.Graphics.getHSL(150, 100, 70);
  3435. * // Returns "hsl(150,100,70)"
  3436. *
  3437. * @method getHSL
  3438. * @static
  3439. * @param {Number} hue The hue component for the color, between 0 and 360.
  3440. * @param {Number} saturation The saturation component for the color, between 0 and 100.
  3441. * @param {Number} lightness The lightness component for the color, between 0 and 100.
  3442. * @param {Number} [alpha] The alpha component for the color where 0 is fully transparent and 1 is fully opaque.
  3443. * @return {String} A CSS compatible color string based on the specified HSL numeric color values in the format
  3444. * "hsla(360,100,100,1.0)", or if alpha is null then in the format "hsl(360,100,100)".
  3445. **/
  3446. Graphics.getHSL = function(hue, saturation, lightness, alpha) {
  3447. if (alpha == null) {
  3448. return "hsl("+(hue%360)+","+saturation+"%,"+lightness+"%)";
  3449. } else {
  3450. return "hsla("+(hue%360)+","+saturation+"%,"+lightness+"%,"+alpha+")";
  3451. }
  3452. };
  3453. // static properties:
  3454. /**
  3455. * A reusable instance of {{#crossLink "Graphics/BeginPath"}}{{/crossLink}} to avoid
  3456. * unnecessary instantiation.
  3457. * @property beginCmd
  3458. * @type {Graphics.BeginPath}
  3459. * @static
  3460. **/
  3461. // defined at the bottom of this file.
  3462. /**
  3463. * Map of Base64 characters to values. Used by {{#crossLink "Graphics/decodePath"}}{{/crossLink}}.
  3464. * @property BASE_64
  3465. * @static
  3466. * @final
  3467. * @readonly
  3468. * @type {Object}
  3469. **/
  3470. 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};
  3471. /**
  3472. * Maps numeric values for the caps parameter of {{#crossLink "Graphics/setStrokeStyle"}}{{/crossLink}} to
  3473. * corresponding string values. This is primarily for use with the tiny API. The mappings are as follows: 0 to
  3474. * "butt", 1 to "round", and 2 to "square".
  3475. * For example, to set the line caps to "square":
  3476. *
  3477. * myGraphics.ss(16, 2);
  3478. *
  3479. * @property STROKE_CAPS_MAP
  3480. * @static
  3481. * @final
  3482. * @readonly
  3483. * @type {Array}
  3484. **/
  3485. Graphics.STROKE_CAPS_MAP = ["butt", "round", "square"];
  3486. /**
  3487. * Maps numeric values for the joints parameter of {{#crossLink "Graphics/setStrokeStyle"}}{{/crossLink}} to
  3488. * corresponding string values. This is primarily for use with the tiny API. The mappings are as follows: 0 to
  3489. * "miter", 1 to "round", and 2 to "bevel".
  3490. * For example, to set the line joints to "bevel":
  3491. *
  3492. * myGraphics.ss(16, 0, 2);
  3493. *
  3494. * @property STROKE_JOINTS_MAP
  3495. * @static
  3496. * @final
  3497. * @readonly
  3498. * @type {Array}
  3499. **/
  3500. Graphics.STROKE_JOINTS_MAP = ["miter", "round", "bevel"];
  3501. /**
  3502. * @property _ctx
  3503. * @static
  3504. * @protected
  3505. * @type {CanvasRenderingContext2D}
  3506. **/
  3507. var canvas = (createjs.createCanvas?createjs.createCanvas():document.createElement("canvas"));
  3508. if (canvas.getContext) {
  3509. Graphics._ctx = canvas.getContext("2d");
  3510. canvas.width = canvas.height = 1;
  3511. }
  3512. // getter / setters:
  3513. /**
  3514. * Use the {{#crossLink "Graphics/instructions:property"}}{{/crossLink}} property instead.
  3515. * @method getInstructions
  3516. * @return {Array}
  3517. * @deprecated
  3518. **/
  3519. p.getInstructions = function() {
  3520. this._updateInstructions();
  3521. return this._instructions;
  3522. };
  3523. /**
  3524. * Returns the graphics instructions array. Each entry is a graphics command object (ex. Graphics.Fill, Graphics.Rect)
  3525. * Modifying the returned array directly is not recommended, and is likely to result in unexpected behaviour.
  3526. *
  3527. * This property is mainly intended for introspection of the instructions (ex. for graphics export).
  3528. * @property instructions
  3529. * @type {Array}
  3530. * @readonly
  3531. **/
  3532. try {
  3533. Object.defineProperties(p, {
  3534. instructions: { get: p.getInstructions }
  3535. });
  3536. } catch (e) {}
  3537. // public methods:
  3538. /**
  3539. * Returns true if this Graphics instance has no drawing commands.
  3540. * @method isEmpty
  3541. * @return {Boolean} Returns true if this Graphics instance has no drawing commands.
  3542. **/
  3543. p.isEmpty = function() {
  3544. return !(this._instructions.length || this._activeInstructions.length);
  3545. };
  3546. /**
  3547. * Draws the display object into the specified context ignoring its visible, alpha, shadow, and transform.
  3548. * Returns true if the draw was handled (useful for overriding functionality).
  3549. *
  3550. * NOTE: This method is mainly for internal use, though it may be useful for advanced uses.
  3551. * @method draw
  3552. * @param {CanvasRenderingContext2D} ctx The canvas 2D context object to draw into.
  3553. * @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.
  3554. **/
  3555. p.draw = function(ctx, data) {
  3556. this._updateInstructions();
  3557. var instr = this._instructions;
  3558. for (var i=this._storeIndex, l=instr.length; i<l; i++) {
  3559. instr[i].exec(ctx, data);
  3560. }
  3561. };
  3562. /**
  3563. * Draws only the path described for this Graphics instance, skipping any non-path instructions, including fill and
  3564. * stroke descriptions. Used for <code>DisplayObject.mask</code> to draw the clipping path, for example.
  3565. *
  3566. * NOTE: This method is mainly for internal use, though it may be useful for advanced uses.
  3567. * @method drawAsPath
  3568. * @param {CanvasRenderingContext2D} ctx The canvas 2D context object to draw into.
  3569. **/
  3570. p.drawAsPath = function(ctx) {
  3571. this._updateInstructions();
  3572. var instr, instrs = this._instructions;
  3573. for (var i=this._storeIndex, l=instrs.length; i<l; i++) {
  3574. // the first command is always a beginPath command.
  3575. if ((instr = instrs[i]).path !== false) { instr.exec(ctx); }
  3576. }
  3577. };
  3578. // public methods that map directly to context 2D calls:
  3579. /**
  3580. * Moves the drawing point to the specified position. A tiny API method "mt" also exists.
  3581. * @method moveTo
  3582. * @param {Number} x The x coordinate the drawing point should move to.
  3583. * @param {Number} y The y coordinate the drawing point should move to.
  3584. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls).
  3585. * @chainable
  3586. **/
  3587. p.moveTo = function(x, y) {
  3588. return this.append(new G.MoveTo(x,y), true);
  3589. };
  3590. /**
  3591. * Draws a line from the current drawing point to the specified position, which become the new current drawing
  3592. * point. Note that you *must* call {{#crossLink "Graphics/moveTo"}}{{/crossLink}} before the first `lineTo()`.
  3593. * A tiny API method "lt" also exists.
  3594. *
  3595. * For detailed information, read the
  3596. * <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#complex-shapes-(paths)">
  3597. * whatwg spec</a>.
  3598. * @method lineTo
  3599. * @param {Number} x The x coordinate the drawing point should draw to.
  3600. * @param {Number} y The y coordinate the drawing point should draw to.
  3601. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  3602. * @chainable
  3603. **/
  3604. p.lineTo = function(x, y) {
  3605. return this.append(new G.LineTo(x,y));
  3606. };
  3607. /**
  3608. * Draws an arc with the specified control points and radius. For detailed information, read the
  3609. * <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-arcto">
  3610. * whatwg spec</a>. A tiny API method "at" also exists.
  3611. * @method arcTo
  3612. * @param {Number} x1
  3613. * @param {Number} y1
  3614. * @param {Number} x2
  3615. * @param {Number} y2
  3616. * @param {Number} radius
  3617. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  3618. * @chainable
  3619. **/
  3620. p.arcTo = function(x1, y1, x2, y2, radius) {
  3621. return this.append(new G.ArcTo(x1, y1, x2, y2, radius));
  3622. };
  3623. /**
  3624. * Draws an arc defined by the radius, startAngle and endAngle arguments, centered at the position (x, y). For
  3625. * example, to draw a full circle with a radius of 20 centered at (100, 100):
  3626. *
  3627. * arc(100, 100, 20, 0, Math.PI*2);
  3628. *
  3629. * For detailed information, read the
  3630. * <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-arc">whatwg spec</a>.
  3631. * A tiny API method "a" also exists.
  3632. * @method arc
  3633. * @param {Number} x
  3634. * @param {Number} y
  3635. * @param {Number} radius
  3636. * @param {Number} startAngle Measured in radians.
  3637. * @param {Number} endAngle Measured in radians.
  3638. * @param {Boolean} anticlockwise
  3639. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  3640. * @chainable
  3641. **/
  3642. p.arc = function(x, y, radius, startAngle, endAngle, anticlockwise) {
  3643. return this.append(new G.Arc(x, y, radius, startAngle, endAngle, anticlockwise));
  3644. };
  3645. /**
  3646. * Draws a quadratic curve from the current drawing point to (x, y) using the control point (cpx, cpy). For detailed
  3647. * information, read the <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-quadraticcurveto">
  3648. * whatwg spec</a>. A tiny API method "qt" also exists.
  3649. * @method quadraticCurveTo
  3650. * @param {Number} cpx
  3651. * @param {Number} cpy
  3652. * @param {Number} x
  3653. * @param {Number} y
  3654. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  3655. * @chainable
  3656. **/
  3657. p.quadraticCurveTo = function(cpx, cpy, x, y) {
  3658. return this.append(new G.QuadraticCurveTo(cpx, cpy, x, y));
  3659. };
  3660. /**
  3661. * Draws a bezier curve from the current drawing point to (x, y) using the control points (cp1x, cp1y) and (cp2x,
  3662. * cp2y). For detailed information, read the
  3663. * <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-beziercurveto">
  3664. * whatwg spec</a>. A tiny API method "bt" also exists.
  3665. * @method bezierCurveTo
  3666. * @param {Number} cp1x
  3667. * @param {Number} cp1y
  3668. * @param {Number} cp2x
  3669. * @param {Number} cp2y
  3670. * @param {Number} x
  3671. * @param {Number} y
  3672. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  3673. * @chainable
  3674. **/
  3675. p.bezierCurveTo = function(cp1x, cp1y, cp2x, cp2y, x, y) {
  3676. return this.append(new G.BezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y));
  3677. };
  3678. /**
  3679. * Draws a rectangle at (x, y) with the specified width and height using the current fill and/or stroke.
  3680. * For detailed information, read the
  3681. * <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-rect">
  3682. * whatwg spec</a>. A tiny API method "r" also exists.
  3683. * @method rect
  3684. * @param {Number} x
  3685. * @param {Number} y
  3686. * @param {Number} w Width of the rectangle
  3687. * @param {Number} h Height of the rectangle
  3688. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  3689. * @chainable
  3690. **/
  3691. p.rect = function(x, y, w, h) {
  3692. return this.append(new G.Rect(x, y, w, h));
  3693. };
  3694. /**
  3695. * Closes the current path, effectively drawing a line from the current drawing point to the first drawing point specified
  3696. * since the fill or stroke was last set. A tiny API method "cp" also exists.
  3697. * @method closePath
  3698. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  3699. * @chainable
  3700. **/
  3701. p.closePath = function() {
  3702. return this._activeInstructions.length ? this.append(new G.ClosePath()) : this;
  3703. };
  3704. // public methods that roughly map to Flash graphics APIs:
  3705. /**
  3706. * Clears all drawing instructions, effectively resetting this Graphics instance. Any line and fill styles will need
  3707. * to be redefined to draw shapes following a clear call. A tiny API method "c" also exists.
  3708. * @method clear
  3709. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  3710. * @chainable
  3711. **/
  3712. p.clear = function() {
  3713. this._instructions.length = this._activeInstructions.length = this._commitIndex = 0;
  3714. this._strokeStyle = this._oldStrokeStyle = this._stroke = this._fill = this._strokeDash = this._oldStrokeDash = null;
  3715. this._dirty = this._strokeIgnoreScale = false;
  3716. return this;
  3717. };
  3718. /**
  3719. * Begins a fill with the specified color. This ends the current sub-path. A tiny API method "f" also exists.
  3720. * @method beginFill
  3721. * @param {String} color A CSS compatible color value (ex. "red", "#FF0000", or "rgba(255,0,0,0.5)"). Setting to
  3722. * null will result in no fill.
  3723. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  3724. * @chainable
  3725. **/
  3726. p.beginFill = function(color) {
  3727. return this._setFill(color ? new G.Fill(color) : null);
  3728. };
  3729. /**
  3730. * Begins a linear gradient fill defined by the line (x0, y0) to (x1, y1). This ends the current sub-path. For
  3731. * example, the following code defines a black to white vertical gradient ranging from 20px to 120px, and draws a
  3732. * square to display it:
  3733. *
  3734. * myGraphics.beginLinearGradientFill(["#000","#FFF"], [0, 1], 0, 20, 0, 120).drawRect(20, 20, 120, 120);
  3735. *
  3736. * A tiny API method "lf" also exists.
  3737. * @method beginLinearGradientFill
  3738. * @param {Array} colors An array of CSS compatible color values. For example, ["#F00","#00F"] would define a gradient
  3739. * drawing from red to blue.
  3740. * @param {Array} ratios An array of gradient positions which correspond to the colors. For example, [0.1, 0.9] would draw
  3741. * the first color to 10% then interpolating to the second color at 90%.
  3742. * @param {Number} x0 The position of the first point defining the line that defines the gradient direction and size.
  3743. * @param {Number} y0 The position of the first point defining the line that defines the gradient direction and size.
  3744. * @param {Number} x1 The position of the second point defining the line that defines the gradient direction and size.
  3745. * @param {Number} y1 The position of the second point defining the line that defines the gradient direction and size.
  3746. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  3747. * @chainable
  3748. **/
  3749. p.beginLinearGradientFill = function(colors, ratios, x0, y0, x1, y1) {
  3750. return this._setFill(new G.Fill().linearGradient(colors, ratios, x0, y0, x1, y1));
  3751. };
  3752. /**
  3753. * Begins a radial gradient fill. This ends the current sub-path. For example, the following code defines a red to
  3754. * blue radial gradient centered at (100, 100), with a radius of 50, and draws a circle to display it:
  3755. *
  3756. * myGraphics.beginRadialGradientFill(["#F00","#00F"], [0, 1], 100, 100, 0, 100, 100, 50).drawCircle(100, 100, 50);
  3757. *
  3758. * A tiny API method "rf" also exists.
  3759. * @method beginRadialGradientFill
  3760. * @param {Array} colors An array of CSS compatible color values. For example, ["#F00","#00F"] would define
  3761. * a gradient drawing from red to blue.
  3762. * @param {Array} ratios An array of gradient positions which correspond to the colors. For example, [0.1,
  3763. * 0.9] would draw the first color to 10% then interpolating to the second color at 90%.
  3764. * @param {Number} x0 Center position of the inner circle that defines the gradient.
  3765. * @param {Number} y0 Center position of the inner circle that defines the gradient.
  3766. * @param {Number} r0 Radius of the inner circle that defines the gradient.
  3767. * @param {Number} x1 Center position of the outer circle that defines the gradient.
  3768. * @param {Number} y1 Center position of the outer circle that defines the gradient.
  3769. * @param {Number} r1 Radius of the outer circle that defines the gradient.
  3770. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  3771. * @chainable
  3772. **/
  3773. p.beginRadialGradientFill = function(colors, ratios, x0, y0, r0, x1, y1, r1) {
  3774. return this._setFill(new G.Fill().radialGradient(colors, ratios, x0, y0, r0, x1, y1, r1));
  3775. };
  3776. /**
  3777. * Begins a pattern fill using the specified image. This ends the current sub-path. A tiny API method "bf" also
  3778. * exists.
  3779. * @method beginBitmapFill
  3780. * @param {HTMLImageElement | HTMLCanvasElement | HTMLVideoElement} image The Image, Canvas, or Video object to use
  3781. * as the pattern. Must be loaded prior to creating a bitmap fill, or the fill will be empty.
  3782. * @param {String} repetition Optional. Indicates whether to repeat the image in the fill area. One of "repeat",
  3783. * "repeat-x", "repeat-y", or "no-repeat". Defaults to "repeat". Note that Firefox does not support "repeat-x" or
  3784. * "repeat-y" (latest tests were in FF 20.0), and will default to "repeat".
  3785. * @param {Matrix2D} matrix Optional. Specifies a transformation matrix for the bitmap fill. This transformation
  3786. * will be applied relative to the parent transform.
  3787. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  3788. * @chainable
  3789. **/
  3790. p.beginBitmapFill = function(image, repetition, matrix) {
  3791. return this._setFill(new G.Fill(null,matrix).bitmap(image, repetition));
  3792. };
  3793. /**
  3794. * Ends the current sub-path, and begins a new one with no fill. Functionally identical to <code>beginFill(null)</code>.
  3795. * A tiny API method "ef" also exists.
  3796. * @method endFill
  3797. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  3798. * @chainable
  3799. **/
  3800. p.endFill = function() {
  3801. return this.beginFill();
  3802. };
  3803. /**
  3804. * Sets the stroke style. Like all drawing methods, this can be chained, so you can define
  3805. * the stroke style and color in a single line of code like so:
  3806. *
  3807. * myGraphics.setStrokeStyle(8,"round").beginStroke("#F00");
  3808. *
  3809. * A tiny API method "ss" also exists.
  3810. * @method setStrokeStyle
  3811. * @param {Number} thickness The width of the stroke.
  3812. * @param {String | Number} [caps=0] Indicates the type of caps to use at the end of lines. One of butt,
  3813. * round, or square. Defaults to "butt". Also accepts the values 0 (butt), 1 (round), and 2 (square) for use with
  3814. * the tiny API.
  3815. * @param {String | Number} [joints=0] Specifies the type of joints that should be used where two lines meet.
  3816. * One of bevel, round, or miter. Defaults to "miter". Also accepts the values 0 (miter), 1 (round), and 2 (bevel)
  3817. * for use with the tiny API.
  3818. * @param {Number} [miterLimit=10] If joints is set to "miter", then you can specify a miter limit ratio which
  3819. * controls at what point a mitered joint will be clipped.
  3820. * @param {Boolean} [ignoreScale=false] If true, the stroke will be drawn at the specified thickness regardless
  3821. * of active transformations.
  3822. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  3823. * @chainable
  3824. **/
  3825. p.setStrokeStyle = function(thickness, caps, joints, miterLimit, ignoreScale) {
  3826. this._updateInstructions(true);
  3827. this._strokeStyle = this.command = new G.StrokeStyle(thickness, caps, joints, miterLimit, ignoreScale);
  3828. // ignoreScale lives on Stroke, not StrokeStyle, so we do a little trickery:
  3829. if (this._stroke) { this._stroke.ignoreScale = ignoreScale; }
  3830. this._strokeIgnoreScale = ignoreScale;
  3831. return this;
  3832. };
  3833. /**
  3834. * Sets or clears the stroke dash pattern.
  3835. *
  3836. * myGraphics.setStrokeDash([20, 10], 0);
  3837. *
  3838. * A tiny API method `sd` also exists.
  3839. * @method setStrokeDash
  3840. * @param {Array} [segments] An array specifying the dash pattern, alternating between line and gap.
  3841. * For example, `[20,10]` would create a pattern of 20 pixel lines with 10 pixel gaps between them.
  3842. * Passing null or an empty array will clear the existing stroke dash.
  3843. * @param {Number} [offset=0] The offset of the dash pattern. For example, you could increment this value to create a "marching ants" effect.
  3844. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  3845. * @chainable
  3846. **/
  3847. p.setStrokeDash = function(segments, offset) {
  3848. this._updateInstructions(true);
  3849. this._strokeDash = this.command = new G.StrokeDash(segments, offset);
  3850. return this;
  3851. };
  3852. /**
  3853. * Begins a stroke with the specified color. This ends the current sub-path. A tiny API method "s" also exists.
  3854. * @method beginStroke
  3855. * @param {String} color A CSS compatible color value (ex. "#FF0000", "red", or "rgba(255,0,0,0.5)"). Setting to
  3856. * null will result in no stroke.
  3857. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  3858. * @chainable
  3859. **/
  3860. p.beginStroke = function(color) {
  3861. return this._setStroke(color ? new G.Stroke(color) : null);
  3862. };
  3863. /**
  3864. * Begins a linear gradient stroke defined by the line (x0, y0) to (x1, y1). This ends the current sub-path. For
  3865. * example, the following code defines a black to white vertical gradient ranging from 20px to 120px, and draws a
  3866. * square to display it:
  3867. *
  3868. * myGraphics.setStrokeStyle(10).
  3869. * beginLinearGradientStroke(["#000","#FFF"], [0, 1], 0, 20, 0, 120).drawRect(20, 20, 120, 120);
  3870. *
  3871. * A tiny API method "ls" also exists.
  3872. * @method beginLinearGradientStroke
  3873. * @param {Array} colors An array of CSS compatible color values. For example, ["#F00","#00F"] would define
  3874. * a gradient drawing from red to blue.
  3875. * @param {Array} ratios An array of gradient positions which correspond to the colors. For example, [0.1,
  3876. * 0.9] would draw the first color to 10% then interpolating to the second color at 90%.
  3877. * @param {Number} x0 The position of the first point defining the line that defines the gradient direction and size.
  3878. * @param {Number} y0 The position of the first point defining the line that defines the gradient direction and size.
  3879. * @param {Number} x1 The position of the second point defining the line that defines the gradient direction and size.
  3880. * @param {Number} y1 The position of the second point defining the line that defines the gradient direction and size.
  3881. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  3882. * @chainable
  3883. **/
  3884. p.beginLinearGradientStroke = function(colors, ratios, x0, y0, x1, y1) {
  3885. return this._setStroke(new G.Stroke().linearGradient(colors, ratios, x0, y0, x1, y1));
  3886. };
  3887. /**
  3888. * Begins a radial gradient stroke. This ends the current sub-path. For example, the following code defines a red to
  3889. * blue radial gradient centered at (100, 100), with a radius of 50, and draws a rectangle to display it:
  3890. *
  3891. * myGraphics.setStrokeStyle(10)
  3892. * .beginRadialGradientStroke(["#F00","#00F"], [0, 1], 100, 100, 0, 100, 100, 50)
  3893. * .drawRect(50, 90, 150, 110);
  3894. *
  3895. * A tiny API method "rs" also exists.
  3896. * @method beginRadialGradientStroke
  3897. * @param {Array} colors An array of CSS compatible color values. For example, ["#F00","#00F"] would define
  3898. * a gradient drawing from red to blue.
  3899. * @param {Array} ratios An array of gradient positions which correspond to the colors. For example, [0.1,
  3900. * 0.9] would draw the first color to 10% then interpolating to the second color at 90%, then draw the second color
  3901. * to 100%.
  3902. * @param {Number} x0 Center position of the inner circle that defines the gradient.
  3903. * @param {Number} y0 Center position of the inner circle that defines the gradient.
  3904. * @param {Number} r0 Radius of the inner circle that defines the gradient.
  3905. * @param {Number} x1 Center position of the outer circle that defines the gradient.
  3906. * @param {Number} y1 Center position of the outer circle that defines the gradient.
  3907. * @param {Number} r1 Radius of the outer circle that defines the gradient.
  3908. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  3909. * @chainable
  3910. **/
  3911. p.beginRadialGradientStroke = function(colors, ratios, x0, y0, r0, x1, y1, r1) {
  3912. return this._setStroke(new G.Stroke().radialGradient(colors, ratios, x0, y0, r0, x1, y1, r1));
  3913. };
  3914. /**
  3915. * Begins a pattern fill using the specified image. This ends the current sub-path. Note that unlike bitmap fills,
  3916. * strokes do not currently support a matrix parameter due to limitations in the canvas API. A tiny API method "bs"
  3917. * also exists.
  3918. * @method beginBitmapStroke
  3919. * @param {HTMLImageElement | HTMLCanvasElement | HTMLVideoElement} image The Image, Canvas, or Video object to use
  3920. * as the pattern. Must be loaded prior to creating a bitmap fill, or the fill will be empty.
  3921. * @param {String} [repetition=repeat] Optional. Indicates whether to repeat the image in the fill area. One of
  3922. * "repeat", "repeat-x", "repeat-y", or "no-repeat". Defaults to "repeat".
  3923. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  3924. * @chainable
  3925. **/
  3926. p.beginBitmapStroke = function(image, repetition) {
  3927. // NOTE: matrix is not supported for stroke because transforms on strokes also affect the drawn stroke width.
  3928. return this._setStroke(new G.Stroke().bitmap(image, repetition));
  3929. };
  3930. /**
  3931. * Ends the current sub-path, and begins a new one with no stroke. Functionally identical to <code>beginStroke(null)</code>.
  3932. * A tiny API method "es" also exists.
  3933. * @method endStroke
  3934. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  3935. * @chainable
  3936. **/
  3937. p.endStroke = function() {
  3938. return this.beginStroke();
  3939. };
  3940. /**
  3941. * Maps the familiar ActionScript <code>curveTo()</code> method to the functionally similar {{#crossLink "Graphics/quadraticCurveTo"}}{{/crossLink}}
  3942. * method.
  3943. * @method quadraticCurveTo
  3944. * @param {Number} cpx
  3945. * @param {Number} cpy
  3946. * @param {Number} x
  3947. * @param {Number} y
  3948. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  3949. * @chainable
  3950. **/
  3951. p.curveTo = p.quadraticCurveTo;
  3952. /**
  3953. *
  3954. * Maps the familiar ActionScript <code>drawRect()</code> method to the functionally similar {{#crossLink "Graphics/rect"}}{{/crossLink}}
  3955. * method.
  3956. * @method drawRect
  3957. * @param {Number} x
  3958. * @param {Number} y
  3959. * @param {Number} w Width of the rectangle
  3960. * @param {Number} h Height of the rectangle
  3961. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  3962. * @chainable
  3963. **/
  3964. p.drawRect = p.rect;
  3965. /**
  3966. * Draws a rounded rectangle with all corners with the specified radius.
  3967. * @method drawRoundRect
  3968. * @param {Number} x
  3969. * @param {Number} y
  3970. * @param {Number} w
  3971. * @param {Number} h
  3972. * @param {Number} radius Corner radius.
  3973. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  3974. * @chainable
  3975. **/
  3976. p.drawRoundRect = function(x, y, w, h, radius) {
  3977. return this.drawRoundRectComplex(x, y, w, h, radius, radius, radius, radius);
  3978. };
  3979. /**
  3980. * Draws a rounded rectangle with different corner radii. Supports positive and negative corner radii. A tiny API
  3981. * method "rc" also exists.
  3982. * @method drawRoundRectComplex
  3983. * @param {Number} x The horizontal coordinate to draw the round rect.
  3984. * @param {Number} y The vertical coordinate to draw the round rect.
  3985. * @param {Number} w The width of the round rect.
  3986. * @param {Number} h The height of the round rect.
  3987. * @param {Number} radiusTL Top left corner radius.
  3988. * @param {Number} radiusTR Top right corner radius.
  3989. * @param {Number} radiusBR Bottom right corner radius.
  3990. * @param {Number} radiusBL Bottom left corner radius.
  3991. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  3992. * @chainable
  3993. **/
  3994. p.drawRoundRectComplex = function(x, y, w, h, radiusTL, radiusTR, radiusBR, radiusBL) {
  3995. return this.append(new G.RoundRect(x, y, w, h, radiusTL, radiusTR, radiusBR, radiusBL));
  3996. };
  3997. /**
  3998. * Draws a circle with the specified radius at (x, y).
  3999. *
  4000. * var g = new createjs.Graphics();
  4001. * g.setStrokeStyle(1);
  4002. * g.beginStroke(createjs.Graphics.getRGB(0,0,0));
  4003. * g.beginFill(createjs.Graphics.getRGB(255,0,0));
  4004. * g.drawCircle(0,0,3);
  4005. *
  4006. * var s = new createjs.Shape(g);
  4007. * s.x = 100;
  4008. * s.y = 100;
  4009. *
  4010. * stage.addChild(s);
  4011. * stage.update();
  4012. *
  4013. * A tiny API method "dc" also exists.
  4014. * @method drawCircle
  4015. * @param {Number} x x coordinate center point of circle.
  4016. * @param {Number} y y coordinate center point of circle.
  4017. * @param {Number} radius Radius of circle.
  4018. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4019. * @chainable
  4020. **/
  4021. p.drawCircle = function(x, y, radius) {
  4022. return this.append(new G.Circle(x, y, radius));
  4023. };
  4024. /**
  4025. * Draws an ellipse (oval) with a specified width (w) and height (h). Similar to {{#crossLink "Graphics/drawCircle"}}{{/crossLink}},
  4026. * except the width and height can be different. A tiny API method "de" also exists.
  4027. * @method drawEllipse
  4028. * @param {Number} x The left coordinate point of the ellipse. Note that this is different from {{#crossLink "Graphics/drawCircle"}}{{/crossLink}}
  4029. * which draws from center.
  4030. * @param {Number} y The top coordinate point of the ellipse. Note that this is different from {{#crossLink "Graphics/drawCircle"}}{{/crossLink}}
  4031. * which draws from the center.
  4032. * @param {Number} w The height (horizontal diameter) of the ellipse. The horizontal radius will be half of this
  4033. * number.
  4034. * @param {Number} h The width (vertical diameter) of the ellipse. The vertical radius will be half of this number.
  4035. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4036. * @chainable
  4037. **/
  4038. p.drawEllipse = function(x, y, w, h) {
  4039. return this.append(new G.Ellipse(x, y, w, h));
  4040. };
  4041. /**
  4042. * Draws a star if pointSize is greater than 0, or a regular polygon if pointSize is 0 with the specified number of
  4043. * points. For example, the following code will draw a familiar 5 pointed star shape centered at 100, 100 and with a
  4044. * radius of 50:
  4045. *
  4046. * myGraphics.beginFill("#FF0").drawPolyStar(100, 100, 50, 5, 0.6, -90);
  4047. * // Note: -90 makes the first point vertical
  4048. *
  4049. * A tiny API method "dp" also exists.
  4050. *
  4051. * @method drawPolyStar
  4052. * @param {Number} x Position of the center of the shape.
  4053. * @param {Number} y Position of the center of the shape.
  4054. * @param {Number} radius The outer radius of the shape.
  4055. * @param {Number} sides The number of points on the star or sides on the polygon.
  4056. * @param {Number} pointSize The depth or "pointy-ness" of the star points. A pointSize of 0 will draw a regular
  4057. * polygon (no points), a pointSize of 1 will draw nothing because the points are infinitely pointy.
  4058. * @param {Number} angle The angle of the first point / corner. For example a value of 0 will draw the first point
  4059. * directly to the right of the center.
  4060. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4061. * @chainable
  4062. **/
  4063. p.drawPolyStar = function(x, y, radius, sides, pointSize, angle) {
  4064. return this.append(new G.PolyStar(x, y, radius, sides, pointSize, angle));
  4065. };
  4066. // TODO: deprecated.
  4067. /**
  4068. * Removed in favour of using custom command objects with {{#crossLink "Graphics/append"}}{{/crossLink}}.
  4069. * @method inject
  4070. * @deprecated
  4071. **/
  4072. /**
  4073. * Appends a graphics command object to the graphics queue. Command objects expose an "exec" method
  4074. * that accepts two parameters: the Context2D to operate on, and an arbitrary data object passed into
  4075. * {{#crossLink "Graphics/draw"}}{{/crossLink}}. The latter will usually be the Shape instance that called draw.
  4076. *
  4077. * This method is used internally by Graphics methods, such as drawCircle, but can also be used directly to insert
  4078. * built-in or custom graphics commands. For example:
  4079. *
  4080. * // attach data to our shape, so we can access it during the draw:
  4081. * myShape.color = "red";
  4082. *
  4083. * // append a Circle command object:
  4084. * myShape.graphics.append(new createjs.Graphics.Circle(50, 50, 30));
  4085. *
  4086. * // append a custom command object with an exec method that sets the fill style
  4087. * // based on the shape's data, and then fills the circle.
  4088. * myShape.graphics.append({exec:function(ctx, shape) {
  4089. * ctx.fillStyle = shape.color;
  4090. * ctx.fill();
  4091. * }});
  4092. *
  4093. * @method append
  4094. * @param {Object} command A graphics command object exposing an "exec" method.
  4095. * @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.
  4096. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4097. * @chainable
  4098. **/
  4099. p.append = function(command, clean) {
  4100. this._activeInstructions.push(command);
  4101. this.command = command;
  4102. if (!clean) { this._dirty = true; }
  4103. return this;
  4104. };
  4105. /**
  4106. * Decodes a compact encoded path string into a series of draw instructions.
  4107. * This format is not intended to be human readable, and is meant for use by authoring tools.
  4108. * The format uses a base64 character set, with each character representing 6 bits, to define a series of draw
  4109. * commands.
  4110. *
  4111. * Each command is comprised of a single "header" character followed by a variable number of alternating x and y
  4112. * position values. Reading the header bits from left to right (most to least significant): bits 1 to 3 specify the
  4113. * type of operation (0-moveTo, 1-lineTo, 2-quadraticCurveTo, 3-bezierCurveTo, 4-closePath, 5-7 unused). Bit 4
  4114. * indicates whether position values use 12 bits (2 characters) or 18 bits (3 characters), with a one indicating the
  4115. * latter. Bits 5 and 6 are currently unused.
  4116. *
  4117. * Following the header is a series of 0 (closePath), 2 (moveTo, lineTo), 4 (quadraticCurveTo), or 6 (bezierCurveTo)
  4118. * parameters. These parameters are alternating x/y positions represented by 2 or 3 characters (as indicated by the
  4119. * 4th bit in the command char). These characters consist of a 1 bit sign (1 is negative, 0 is positive), followed
  4120. * by an 11 (2 char) or 17 (3 char) bit integer value. All position values are in tenths of a pixel. Except in the
  4121. * case of move operations which are absolute, this value is a delta from the previous x or y position (as
  4122. * appropriate).
  4123. *
  4124. * For example, the string "A3cAAMAu4AAA" represents a line starting at -150,0 and ending at 150,0.
  4125. * <br />A - bits 000000. First 3 bits (000) indicate a moveTo operation. 4th bit (0) indicates 2 chars per
  4126. * parameter.
  4127. * <br />n0 - 110111011100. Absolute x position of -150.0px. First bit indicates a negative value, remaining bits
  4128. * indicate 1500 tenths of a pixel.
  4129. * <br />AA - 000000000000. Absolute y position of 0.
  4130. * <br />I - 001100. First 3 bits (001) indicate a lineTo operation. 4th bit (1) indicates 3 chars per parameter.
  4131. * <br />Au4 - 000000101110111000. An x delta of 300.0px, which is added to the previous x value of -150.0px to
  4132. * provide an absolute position of +150.0px.
  4133. * <br />AAA - 000000000000000000. A y delta value of 0.
  4134. *
  4135. * A tiny API method "p" also exists.
  4136. * @method decodePath
  4137. * @param {String} str The path string to decode.
  4138. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4139. * @chainable
  4140. **/
  4141. p.decodePath = function(str) {
  4142. var instructions = [this.moveTo, this.lineTo, this.quadraticCurveTo, this.bezierCurveTo, this.closePath];
  4143. var paramCount = [2, 2, 4, 6, 0];
  4144. var i=0, l=str.length;
  4145. var params = [];
  4146. var x=0, y=0;
  4147. var base64 = Graphics.BASE_64;
  4148. while (i<l) {
  4149. var c = str.charAt(i);
  4150. var n = base64[c];
  4151. var fi = n>>3; // highest order bits 1-3 code for operation.
  4152. var f = instructions[fi];
  4153. // check that we have a valid instruction & that the unused bits are empty:
  4154. if (!f || (n&3)) { throw("bad path data (@"+i+"): "+c); }
  4155. var pl = paramCount[fi];
  4156. if (!fi) { x=y=0; } // move operations reset the position.
  4157. params.length = 0;
  4158. i++;
  4159. var charCount = (n>>2&1)+2; // 4th header bit indicates number size for this operation.
  4160. for (var p=0; p<pl; p++) {
  4161. var num = base64[str.charAt(i)];
  4162. var sign = (num>>5) ? -1 : 1;
  4163. num = ((num&31)<<6)|(base64[str.charAt(i+1)]);
  4164. if (charCount == 3) { num = (num<<6)|(base64[str.charAt(i+2)]); }
  4165. num = sign*num/10;
  4166. if (p%2) { x = (num += x); }
  4167. else { y = (num += y); }
  4168. params[p] = num;
  4169. i += charCount;
  4170. }
  4171. f.apply(this,params);
  4172. }
  4173. return this;
  4174. };
  4175. /**
  4176. * Stores all graphics commands so they won't be executed in future draws. Calling store() a second time adds to
  4177. * the existing store. This also affects `drawAsPath()`.
  4178. *
  4179. * This is useful in cases where you are creating vector graphics in an iterative manner (ex. generative art), so
  4180. * that only new graphics need to be drawn (which can provide huge performance benefits), but you wish to retain all
  4181. * of the vector instructions for later use (ex. scaling, modifying, or exporting).
  4182. *
  4183. * Note that calling store() will force the active path (if any) to be ended in a manner similar to changing
  4184. * the fill or stroke.
  4185. *
  4186. * For example, consider a application where the user draws lines with the mouse. As each line segment (or collection of
  4187. * segments) are added to a Shape, it can be rasterized using {{#crossLink "DisplayObject/updateCache"}}{{/crossLink}},
  4188. * and then stored, so that it can be redrawn at a different scale when the application is resized, or exported to SVG.
  4189. *
  4190. * // set up cache:
  4191. * myShape.cache(0,0,500,500,scale);
  4192. *
  4193. * // when the user drags, draw a new line:
  4194. * myShape.graphics.moveTo(oldX,oldY).lineTo(newX,newY);
  4195. * // then draw it into the existing cache:
  4196. * myShape.updateCache("source-over");
  4197. * // store the new line, so it isn't redrawn next time:
  4198. * myShape.store();
  4199. *
  4200. * // then, when the window resizes, we can re-render at a different scale:
  4201. * // first, unstore all our lines:
  4202. * myShape.unstore();
  4203. * // then cache using the new scale:
  4204. * myShape.cache(0,0,500,500,newScale);
  4205. * // finally, store the existing commands again:
  4206. * myShape.store();
  4207. *
  4208. * @method store
  4209. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4210. * @chainable
  4211. **/
  4212. p.store = function() {
  4213. this._updateInstructions(true);
  4214. this._storeIndex = this._instructions.length;
  4215. return this;
  4216. };
  4217. /**
  4218. * Unstores any graphics commands that were previously stored using {{#crossLink "Graphics/store"}}{{/crossLink}}
  4219. * so that they will be executed in subsequent draw calls.
  4220. *
  4221. * @method unstore
  4222. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4223. * @chainable
  4224. **/
  4225. p.unstore = function() {
  4226. this._storeIndex = 0;
  4227. return this;
  4228. };
  4229. /**
  4230. * Returns a clone of this Graphics instance. Note that the individual command objects are not cloned.
  4231. * @method clone
  4232. * @return {Graphics} A clone of the current Graphics instance.
  4233. **/
  4234. p.clone = function() {
  4235. var o = new Graphics();
  4236. o.command = this.command;
  4237. o._stroke = this._stroke;
  4238. o._strokeStyle = this._strokeStyle;
  4239. o._strokeDash = this._strokeDash;
  4240. o._strokeIgnoreScale = this._strokeIgnoreScale;
  4241. o._fill = this._fill;
  4242. o._instructions = this._instructions.slice();
  4243. o._commitIndex = this._commitIndex;
  4244. o._activeInstructions = this._activeInstructions.slice();
  4245. o._dirty = this._dirty;
  4246. o._storeIndex = this._storeIndex;
  4247. return o;
  4248. };
  4249. /**
  4250. * Returns a string representation of this object.
  4251. * @method toString
  4252. * @return {String} a string representation of the instance.
  4253. **/
  4254. p.toString = function() {
  4255. return "[Graphics]";
  4256. };
  4257. // tiny API:
  4258. /**
  4259. * Shortcut to moveTo.
  4260. * @method mt
  4261. * @param {Number} x The x coordinate the drawing point should move to.
  4262. * @param {Number} y The y coordinate the drawing point should move to.
  4263. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls).
  4264. * @chainable
  4265. * @protected
  4266. **/
  4267. p.mt = p.moveTo;
  4268. /**
  4269. * Shortcut to lineTo.
  4270. * @method lt
  4271. * @param {Number} x The x coordinate the drawing point should draw to.
  4272. * @param {Number} y The y coordinate the drawing point should draw to.
  4273. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4274. * @chainable
  4275. * @protected
  4276. **/
  4277. p.lt = p.lineTo;
  4278. /**
  4279. * Shortcut to arcTo.
  4280. * @method at
  4281. * @param {Number} x1
  4282. * @param {Number} y1
  4283. * @param {Number} x2
  4284. * @param {Number} y2
  4285. * @param {Number} radius
  4286. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4287. * @chainable
  4288. * @protected
  4289. **/
  4290. p.at = p.arcTo;
  4291. /**
  4292. * Shortcut to bezierCurveTo.
  4293. * @method bt
  4294. * @param {Number} cp1x
  4295. * @param {Number} cp1y
  4296. * @param {Number} cp2x
  4297. * @param {Number} cp2y
  4298. * @param {Number} x
  4299. * @param {Number} y
  4300. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4301. * @chainable
  4302. * @protected
  4303. **/
  4304. p.bt = p.bezierCurveTo;
  4305. /**
  4306. * Shortcut to quadraticCurveTo / curveTo.
  4307. * @method qt
  4308. * @param {Number} cpx
  4309. * @param {Number} cpy
  4310. * @param {Number} x
  4311. * @param {Number} y
  4312. * @protected
  4313. * @chainable
  4314. **/
  4315. p.qt = p.quadraticCurveTo;
  4316. /**
  4317. * Shortcut to arc.
  4318. * @method a
  4319. * @param {Number} x
  4320. * @param {Number} y
  4321. * @param {Number} radius
  4322. * @param {Number} startAngle Measured in radians.
  4323. * @param {Number} endAngle Measured in radians.
  4324. * @param {Boolean} anticlockwise
  4325. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4326. * @protected
  4327. * @chainable
  4328. **/
  4329. p.a = p.arc;
  4330. /**
  4331. * Shortcut to rect.
  4332. * @method r
  4333. * @param {Number} x
  4334. * @param {Number} y
  4335. * @param {Number} w Width of the rectangle
  4336. * @param {Number} h Height of the rectangle
  4337. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4338. * @chainable
  4339. * @protected
  4340. **/
  4341. p.r = p.rect;
  4342. /**
  4343. * Shortcut to closePath.
  4344. * @method cp
  4345. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4346. * @chainable
  4347. * @protected
  4348. **/
  4349. p.cp = p.closePath;
  4350. /**
  4351. * Shortcut to clear.
  4352. * @method c
  4353. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4354. * @chainable
  4355. * @protected
  4356. **/
  4357. p.c = p.clear;
  4358. /**
  4359. * Shortcut to beginFill.
  4360. * @method f
  4361. * @param {String} color A CSS compatible color value (ex. "red", "#FF0000", or "rgba(255,0,0,0.5)"). Setting to
  4362. * null will result in no fill.
  4363. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4364. * @chainable
  4365. * @protected
  4366. **/
  4367. p.f = p.beginFill;
  4368. /**
  4369. * Shortcut to beginLinearGradientFill.
  4370. * @method lf
  4371. * @param {Array} colors An array of CSS compatible color values. For example, ["#F00","#00F"] would define a gradient
  4372. * drawing from red to blue.
  4373. * @param {Array} ratios An array of gradient positions which correspond to the colors. For example, [0.1, 0.9] would draw
  4374. * the first color to 10% then interpolating to the second color at 90%.
  4375. * @param {Number} x0 The position of the first point defining the line that defines the gradient direction and size.
  4376. * @param {Number} y0 The position of the first point defining the line that defines the gradient direction and size.
  4377. * @param {Number} x1 The position of the second point defining the line that defines the gradient direction and size.
  4378. * @param {Number} y1 The position of the second point defining the line that defines the gradient direction and size.
  4379. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4380. * @chainable
  4381. * @protected
  4382. **/
  4383. p.lf = p.beginLinearGradientFill;
  4384. /**
  4385. * Shortcut to beginRadialGradientFill.
  4386. * @method rf
  4387. * @param {Array} colors An array of CSS compatible color values. For example, ["#F00","#00F"] would define
  4388. * a gradient drawing from red to blue.
  4389. * @param {Array} ratios An array of gradient positions which correspond to the colors. For example, [0.1,
  4390. * 0.9] would draw the first color to 10% then interpolating to the second color at 90%.
  4391. * @param {Number} x0 Center position of the inner circle that defines the gradient.
  4392. * @param {Number} y0 Center position of the inner circle that defines the gradient.
  4393. * @param {Number} r0 Radius of the inner circle that defines the gradient.
  4394. * @param {Number} x1 Center position of the outer circle that defines the gradient.
  4395. * @param {Number} y1 Center position of the outer circle that defines the gradient.
  4396. * @param {Number} r1 Radius of the outer circle that defines the gradient.
  4397. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4398. * @chainable
  4399. * @protected
  4400. **/
  4401. p.rf = p.beginRadialGradientFill;
  4402. /**
  4403. * Shortcut to beginBitmapFill.
  4404. * @method bf
  4405. * @param {HTMLImageElement | HTMLCanvasElement | HTMLVideoElement} image The Image, Canvas, or Video object to use
  4406. * as the pattern.
  4407. * @param {String} repetition Optional. Indicates whether to repeat the image in the fill area. One of "repeat",
  4408. * "repeat-x", "repeat-y", or "no-repeat". Defaults to "repeat". Note that Firefox does not support "repeat-x" or
  4409. * "repeat-y" (latest tests were in FF 20.0), and will default to "repeat".
  4410. * @param {Matrix2D} matrix Optional. Specifies a transformation matrix for the bitmap fill. This transformation
  4411. * will be applied relative to the parent transform.
  4412. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4413. * @chainable
  4414. * @protected
  4415. **/
  4416. p.bf = p.beginBitmapFill;
  4417. /**
  4418. * Shortcut to endFill.
  4419. * @method ef
  4420. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4421. * @chainable
  4422. * @protected
  4423. **/
  4424. p.ef = p.endFill;
  4425. /**
  4426. * Shortcut to setStrokeStyle.
  4427. * @method ss
  4428. * @param {Number} thickness The width of the stroke.
  4429. * @param {String | Number} [caps=0] Indicates the type of caps to use at the end of lines. One of butt,
  4430. * round, or square. Defaults to "butt". Also accepts the values 0 (butt), 1 (round), and 2 (square) for use with
  4431. * the tiny API.
  4432. * @param {String | Number} [joints=0] Specifies the type of joints that should be used where two lines meet.
  4433. * One of bevel, round, or miter. Defaults to "miter". Also accepts the values 0 (miter), 1 (round), and 2 (bevel)
  4434. * for use with the tiny API.
  4435. * @param {Number} [miterLimit=10] If joints is set to "miter", then you can specify a miter limit ratio which
  4436. * controls at what point a mitered joint will be clipped.
  4437. * @param {Boolean} [ignoreScale=false] If true, the stroke will be drawn at the specified thickness regardless
  4438. * of active transformations.
  4439. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4440. * @chainable
  4441. * @protected
  4442. **/
  4443. p.ss = p.setStrokeStyle;
  4444. /**
  4445. * Shortcut to setStrokeDash.
  4446. * @method sd
  4447. * @param {Array} [segments] An array specifying the dash pattern, alternating between line and gap.
  4448. * For example, [20,10] would create a pattern of 20 pixel lines with 10 pixel gaps between them.
  4449. * Passing null or an empty array will clear any existing dash.
  4450. * @param {Number} [offset=0] The offset of the dash pattern. For example, you could increment this value to create a "marching ants" effect.
  4451. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4452. * @chainable
  4453. * @protected
  4454. **/
  4455. p.sd = p.setStrokeDash;
  4456. /**
  4457. * Shortcut to beginStroke.
  4458. * @method s
  4459. * @param {String} color A CSS compatible color value (ex. "#FF0000", "red", or "rgba(255,0,0,0.5)"). Setting to
  4460. * null will result in no stroke.
  4461. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4462. * @chainable
  4463. * @protected
  4464. **/
  4465. p.s = p.beginStroke;
  4466. /**
  4467. * Shortcut to beginLinearGradientStroke.
  4468. * @method ls
  4469. * @param {Array} colors An array of CSS compatible color values. For example, ["#F00","#00F"] would define
  4470. * a gradient drawing from red to blue.
  4471. * @param {Array} ratios An array of gradient positions which correspond to the colors. For example, [0.1,
  4472. * 0.9] would draw the first color to 10% then interpolating to the second color at 90%.
  4473. * @param {Number} x0 The position of the first point defining the line that defines the gradient direction and size.
  4474. * @param {Number} y0 The position of the first point defining the line that defines the gradient direction and size.
  4475. * @param {Number} x1 The position of the second point defining the line that defines the gradient direction and size.
  4476. * @param {Number} y1 The position of the second point defining the line that defines the gradient direction and size.
  4477. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4478. * @chainable
  4479. * @protected
  4480. **/
  4481. p.ls = p.beginLinearGradientStroke;
  4482. /**
  4483. * Shortcut to beginRadialGradientStroke.
  4484. * @method rs
  4485. * @param {Array} colors An array of CSS compatible color values. For example, ["#F00","#00F"] would define
  4486. * a gradient drawing from red to blue.
  4487. * @param {Array} ratios An array of gradient positions which correspond to the colors. For example, [0.1,
  4488. * 0.9] would draw the first color to 10% then interpolating to the second color at 90%, then draw the second color
  4489. * to 100%.
  4490. * @param {Number} x0 Center position of the inner circle that defines the gradient.
  4491. * @param {Number} y0 Center position of the inner circle that defines the gradient.
  4492. * @param {Number} r0 Radius of the inner circle that defines the gradient.
  4493. * @param {Number} x1 Center position of the outer circle that defines the gradient.
  4494. * @param {Number} y1 Center position of the outer circle that defines the gradient.
  4495. * @param {Number} r1 Radius of the outer circle that defines the gradient.
  4496. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4497. * @chainable
  4498. * @protected
  4499. **/
  4500. p.rs = p.beginRadialGradientStroke;
  4501. /**
  4502. * Shortcut to beginBitmapStroke.
  4503. * @method bs
  4504. * @param {HTMLImageElement | HTMLCanvasElement | HTMLVideoElement} image The Image, Canvas, or Video object to use
  4505. * as the pattern.
  4506. * @param {String} [repetition=repeat] Optional. Indicates whether to repeat the image in the fill area. One of
  4507. * "repeat", "repeat-x", "repeat-y", or "no-repeat". Defaults to "repeat".
  4508. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4509. * @chainable
  4510. * @protected
  4511. **/
  4512. p.bs = p.beginBitmapStroke;
  4513. /**
  4514. * Shortcut to endStroke.
  4515. * @method es
  4516. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4517. * @chainable
  4518. * @protected
  4519. **/
  4520. p.es = p.endStroke;
  4521. /**
  4522. * Shortcut to drawRect.
  4523. * @method dr
  4524. * @param {Number} x
  4525. * @param {Number} y
  4526. * @param {Number} w Width of the rectangle
  4527. * @param {Number} h Height of the rectangle
  4528. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4529. * @chainable
  4530. * @protected
  4531. **/
  4532. p.dr = p.drawRect;
  4533. /**
  4534. * Shortcut to drawRoundRect.
  4535. * @method rr
  4536. * @param {Number} x
  4537. * @param {Number} y
  4538. * @param {Number} w
  4539. * @param {Number} h
  4540. * @param {Number} radius Corner radius.
  4541. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4542. * @chainable
  4543. * @protected
  4544. **/
  4545. p.rr = p.drawRoundRect;
  4546. /**
  4547. * Shortcut to drawRoundRectComplex.
  4548. * @method rc
  4549. * @param {Number} x The horizontal coordinate to draw the round rect.
  4550. * @param {Number} y The vertical coordinate to draw the round rect.
  4551. * @param {Number} w The width of the round rect.
  4552. * @param {Number} h The height of the round rect.
  4553. * @param {Number} radiusTL Top left corner radius.
  4554. * @param {Number} radiusTR Top right corner radius.
  4555. * @param {Number} radiusBR Bottom right corner radius.
  4556. * @param {Number} radiusBL Bottom left corner radius.
  4557. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4558. * @chainable
  4559. * @protected
  4560. **/
  4561. p.rc = p.drawRoundRectComplex;
  4562. /**
  4563. * Shortcut to drawCircle.
  4564. * @method dc
  4565. * @param {Number} x x coordinate center point of circle.
  4566. * @param {Number} y y coordinate center point of circle.
  4567. * @param {Number} radius Radius of circle.
  4568. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4569. * @chainable
  4570. * @protected
  4571. **/
  4572. p.dc = p.drawCircle;
  4573. /**
  4574. * Shortcut to drawEllipse.
  4575. * @method de
  4576. * @param {Number} x The left coordinate point of the ellipse. Note that this is different from {{#crossLink "Graphics/drawCircle"}}{{/crossLink}}
  4577. * which draws from center.
  4578. * @param {Number} y The top coordinate point of the ellipse. Note that this is different from {{#crossLink "Graphics/drawCircle"}}{{/crossLink}}
  4579. * which draws from the center.
  4580. * @param {Number} w The height (horizontal diameter) of the ellipse. The horizontal radius will be half of this
  4581. * number.
  4582. * @param {Number} h The width (vertical diameter) of the ellipse. The vertical radius will be half of this number.
  4583. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4584. * @chainable
  4585. * @protected
  4586. **/
  4587. p.de = p.drawEllipse;
  4588. /**
  4589. * Shortcut to drawPolyStar.
  4590. * @method dp
  4591. * @param {Number} x Position of the center of the shape.
  4592. * @param {Number} y Position of the center of the shape.
  4593. * @param {Number} radius The outer radius of the shape.
  4594. * @param {Number} sides The number of points on the star or sides on the polygon.
  4595. * @param {Number} pointSize The depth or "pointy-ness" of the star points. A pointSize of 0 will draw a regular
  4596. * polygon (no points), a pointSize of 1 will draw nothing because the points are infinitely pointy.
  4597. * @param {Number} angle The angle of the first point / corner. For example a value of 0 will draw the first point
  4598. * directly to the right of the center.
  4599. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4600. * @chainable
  4601. * @protected
  4602. **/
  4603. p.dp = p.drawPolyStar;
  4604. /**
  4605. * Shortcut to decodePath.
  4606. * @method p
  4607. * @param {String} str The path string to decode.
  4608. * @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
  4609. * @chainable
  4610. * @protected
  4611. **/
  4612. p.p = p.decodePath;
  4613. // private methods:
  4614. /**
  4615. * @method _updateInstructions
  4616. * @param commit
  4617. * @protected
  4618. **/
  4619. p._updateInstructions = function(commit) {
  4620. var instr = this._instructions, active = this._activeInstructions, commitIndex = this._commitIndex;
  4621. if (this._dirty && active.length) {
  4622. instr.length = commitIndex; // remove old, uncommitted commands
  4623. instr.push(Graphics.beginCmd);
  4624. var l = active.length, ll = instr.length;
  4625. instr.length = ll+l;
  4626. for (var i=0; i<l; i++) { instr[i+ll] = active[i]; }
  4627. if (this._fill) { instr.push(this._fill); }
  4628. if (this._stroke) {
  4629. // doesn't need to be re-applied if it hasn't changed.
  4630. if (this._strokeDash !== this._oldStrokeDash) {
  4631. this._oldStrokeDash = this._strokeDash;
  4632. instr.push(this._strokeDash);
  4633. }
  4634. if (this._strokeStyle !== this._oldStrokeStyle) {
  4635. this._oldStrokeStyle = this._strokeStyle;
  4636. instr.push(this._strokeStyle);
  4637. }
  4638. instr.push(this._stroke);
  4639. }
  4640. this._dirty = false;
  4641. }
  4642. if (commit) {
  4643. active.length = 0;
  4644. this._commitIndex = instr.length;
  4645. }
  4646. };
  4647. /**
  4648. * @method _setFill
  4649. * @param fill
  4650. * @protected
  4651. **/
  4652. p._setFill = function(fill) {
  4653. this._updateInstructions(true);
  4654. this.command = this._fill = fill;
  4655. return this;
  4656. };
  4657. /**
  4658. * @method _setStroke
  4659. * @param stroke
  4660. * @protected
  4661. **/
  4662. p._setStroke = function(stroke) {
  4663. this._updateInstructions(true);
  4664. if (this.command = this._stroke = stroke) {
  4665. stroke.ignoreScale = this._strokeIgnoreScale;
  4666. }
  4667. return this;
  4668. };
  4669. // Command Objects:
  4670. /**
  4671. * @namespace Graphics
  4672. */
  4673. /**
  4674. * 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.
  4675. * @class LineTo
  4676. * @constructor
  4677. * @param {Number} x
  4678. * @param {Number} y
  4679. **/
  4680. /**
  4681. * @property x
  4682. * @type Number
  4683. */
  4684. /**
  4685. * @property y
  4686. * @type Number
  4687. */
  4688. /**
  4689. * Execute the Graphics command in the provided Canvas context.
  4690. * @method exec
  4691. * @param {CanvasRenderingContext2D} ctx The canvas rendering context
  4692. */
  4693. (G.LineTo = function(x, y) {
  4694. this.x = x; this.y = y;
  4695. }).prototype.exec = function(ctx) { ctx.lineTo(this.x,this.y); };
  4696. /**
  4697. * Graphics command object. See {{#crossLink "Graphics/moveTo"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information.
  4698. * @class MoveTo
  4699. * @constructor
  4700. * @param {Number} x
  4701. * @param {Number} y
  4702. **/
  4703. /**
  4704. * @property x
  4705. * @type Number
  4706. */
  4707. /**
  4708. * @property y
  4709. * @type Number
  4710. */
  4711. /**
  4712. * @method exec
  4713. * @param {CanvasRenderingContext2D} ctx
  4714. */
  4715. (G.MoveTo = function(x, y) {
  4716. this.x = x; this.y = y;
  4717. }).prototype.exec = function(ctx) { ctx.moveTo(this.x, this.y); };
  4718. /**
  4719. * Graphics command object. See {{#crossLink "Graphics/arcTo"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information.
  4720. * @class ArcTo
  4721. * @constructor
  4722. * @param {Number} x1
  4723. * @param {Number} y1
  4724. * @param {Number} x2
  4725. * @param {Number} y2
  4726. * @param {Number} radius
  4727. **/
  4728. /**
  4729. * @property x1
  4730. * @type Number
  4731. */
  4732. /**
  4733. * @property y1
  4734. * @type Number
  4735. */
  4736. /**
  4737. * @property x2
  4738. * @type Number
  4739. */
  4740. /**
  4741. * @property y2
  4742. * @type Number
  4743. */
  4744. /**
  4745. * @property radius
  4746. * @type Number
  4747. */
  4748. /**
  4749. * Execute the Graphics command in the provided Canvas context.
  4750. * @method exec
  4751. * @param {CanvasRenderingContext2D} ctx The canvas rendering context
  4752. */
  4753. (G.ArcTo = function(x1, y1, x2, y2, radius) {
  4754. this.x1 = x1; this.y1 = y1;
  4755. this.x2 = x2; this.y2 = y2;
  4756. this.radius = radius;
  4757. }).prototype.exec = function(ctx) { ctx.arcTo(this.x1, this.y1, this.x2, this.y2, this.radius); };
  4758. /**
  4759. * Graphics command object. See {{#crossLink "Graphics/arc"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information.
  4760. * @class Arc
  4761. * @constructor
  4762. * @param {Number} x
  4763. * @param {Number} y
  4764. * @param {Number} radius
  4765. * @param {Number} startAngle
  4766. * @param {Number} endAngle
  4767. * @param {Number} anticlockwise
  4768. **/
  4769. /**
  4770. * @property x
  4771. * @type Number
  4772. */
  4773. /**
  4774. * @property y
  4775. * @type Number
  4776. */
  4777. /**
  4778. * @property radius
  4779. * @type Number
  4780. */
  4781. /**
  4782. * @property startAngle
  4783. * @type Number
  4784. */
  4785. /**
  4786. * @property endAngle
  4787. * @type Number
  4788. */
  4789. /**
  4790. * @property anticlockwise
  4791. * @type Number
  4792. */
  4793. /**
  4794. * Execute the Graphics command in the provided Canvas context.
  4795. * @method exec
  4796. * @param {CanvasRenderingContext2D} ctx The canvas rendering context
  4797. */
  4798. (G.Arc = function(x, y, radius, startAngle, endAngle, anticlockwise) {
  4799. this.x = x; this.y = y;
  4800. this.radius = radius;
  4801. this.startAngle = startAngle; this.endAngle = endAngle;
  4802. this.anticlockwise = !!anticlockwise;
  4803. }).prototype.exec = function(ctx) { ctx.arc(this.x, this.y, this.radius, this.startAngle, this.endAngle, this.anticlockwise); };
  4804. /**
  4805. * Graphics command object. See {{#crossLink "Graphics/quadraticCurveTo"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information.
  4806. * @class QuadraticCurveTo
  4807. * @constructor
  4808. * @param {Number} cpx
  4809. * @param {Number} cpy
  4810. * @param {Number} x
  4811. * @param {Number} y
  4812. **/
  4813. /**
  4814. * @property cpx
  4815. * @type Number
  4816. */
  4817. /**
  4818. * @property cpy
  4819. * @type Number
  4820. */
  4821. /**
  4822. * @property x
  4823. * @type Number
  4824. */
  4825. /**
  4826. * @property y
  4827. * @type Number
  4828. */
  4829. /**
  4830. * Execute the Graphics command in the provided Canvas context.
  4831. * @method exec
  4832. * @param {CanvasRenderingContext2D} ctx The canvas rendering context
  4833. */
  4834. (G.QuadraticCurveTo = function(cpx, cpy, x, y) {
  4835. this.cpx = cpx; this.cpy = cpy;
  4836. this.x = x; this.y = y;
  4837. }).prototype.exec = function(ctx) { ctx.quadraticCurveTo(this.cpx, this.cpy, this.x, this.y); };
  4838. /**
  4839. * Graphics command object. See {{#crossLink "Graphics/bezierCurveTo"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information.
  4840. * @class BezierCurveTo
  4841. * @constructor
  4842. * @param {Number} cp1x
  4843. * @param {Number} cp1y
  4844. * @param {Number} cp2x
  4845. * @param {Number} cp2y
  4846. * @param {Number} x
  4847. * @param {Number} y
  4848. **/
  4849. /**
  4850. * @property cp1x
  4851. * @type Number
  4852. */
  4853. /**
  4854. * @property cp1y
  4855. * @type Number
  4856. */
  4857. /**
  4858. * @property cp2x
  4859. * @type Number
  4860. */
  4861. /**
  4862. * @property cp2y
  4863. * @type Number
  4864. */
  4865. /**
  4866. * @property x
  4867. * @type Number
  4868. */
  4869. /**
  4870. * @property y
  4871. * @type Number
  4872. */
  4873. /**
  4874. * Execute the Graphics command in the provided Canvas context.
  4875. * @method exec
  4876. * @param {CanvasRenderingContext2D} ctx The canvas rendering context
  4877. */
  4878. (G.BezierCurveTo = function(cp1x, cp1y, cp2x, cp2y, x, y) {
  4879. this.cp1x = cp1x; this.cp1y = cp1y;
  4880. this.cp2x = cp2x; this.cp2y = cp2y;
  4881. this.x = x; this.y = y;
  4882. }).prototype.exec = function(ctx) { ctx.bezierCurveTo(this.cp1x, this.cp1y, this.cp2x, this.cp2y, this.x, this.y); };
  4883. /**
  4884. * Graphics command object. See {{#crossLink "Graphics/rect"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information.
  4885. * @class Rect
  4886. * @constructor
  4887. * @param {Number} x
  4888. * @param {Number} y
  4889. * @param {Number} w
  4890. * @param {Number} h
  4891. **/
  4892. /**
  4893. * @property x
  4894. * @type Number
  4895. */
  4896. /**
  4897. * @property y
  4898. * @type Number
  4899. */
  4900. /**
  4901. * @property w
  4902. * @type Number
  4903. */
  4904. /**
  4905. * @property h
  4906. * @type Number
  4907. */
  4908. /**
  4909. * Execute the Graphics command in the provided Canvas context.
  4910. * @method exec
  4911. * @param {CanvasRenderingContext2D} ctx The canvas rendering context
  4912. */
  4913. (G.Rect = function(x, y, w, h) {
  4914. this.x = x; this.y = y;
  4915. this.w = w; this.h = h;
  4916. }).prototype.exec = function(ctx) { ctx.rect(this.x, this.y, this.w, this.h); };
  4917. /**
  4918. * Graphics command object. See {{#crossLink "Graphics/closePath"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information.
  4919. * @class ClosePath
  4920. * @constructor
  4921. **/
  4922. /**
  4923. * Execute the Graphics command in the provided Canvas context.
  4924. * @method exec
  4925. * @param {CanvasRenderingContext2D} ctx The canvas rendering context
  4926. */
  4927. (G.ClosePath = function() {
  4928. }).prototype.exec = function(ctx) { ctx.closePath(); };
  4929. /**
  4930. * Graphics command object to begin a new path. See {{#crossLink "Graphics"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information.
  4931. * @class BeginPath
  4932. * @constructor
  4933. **/
  4934. /**
  4935. * Execute the Graphics command in the provided Canvas context.
  4936. * @method exec
  4937. * @param {CanvasRenderingContext2D} ctx The canvas rendering context
  4938. */
  4939. (G.BeginPath = function() {
  4940. }).prototype.exec = function(ctx) { ctx.beginPath(); };
  4941. /**
  4942. * Graphics command object. See {{#crossLink "Graphics/beginFill"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information.
  4943. * @class Fill
  4944. * @constructor
  4945. * @param {Object} style A valid Context2D fillStyle.
  4946. * @param {Matrix2D} matrix
  4947. **/
  4948. /**
  4949. * A valid Context2D fillStyle.
  4950. * @property style
  4951. * @type Object
  4952. */
  4953. /**
  4954. * @property matrix
  4955. * @type Matrix2D
  4956. */
  4957. /**
  4958. * Execute the Graphics command in the provided Canvas context.
  4959. * @method exec
  4960. * @param {CanvasRenderingContext2D} ctx The canvas rendering context
  4961. */
  4962. p = (G.Fill = function(style, matrix) {
  4963. this.style = style;
  4964. this.matrix = matrix;
  4965. }).prototype;
  4966. p.exec = function(ctx) {
  4967. if (!this.style) { return; }
  4968. ctx.fillStyle = this.style;
  4969. var mtx = this.matrix;
  4970. if (mtx) { ctx.save(); ctx.transform(mtx.a, mtx.b, mtx.c, mtx.d, mtx.tx, mtx.ty); }
  4971. ctx.fill();
  4972. if (mtx) { ctx.restore(); }
  4973. };
  4974. /**
  4975. * Creates a linear gradient style and assigns it to {{#crossLink "Fill/style:property"}}{{/crossLink}}.
  4976. * See {{#crossLink "Graphics/beginLinearGradientFill"}}{{/crossLink}} for more information.
  4977. * @method linearGradient
  4978. * @param {Array} colors
  4979. *
  4980. * @param {Array} ratios
  4981. * @param {Number} x0
  4982. * @param {Number} y0
  4983. * @param {Number} x1
  4984. * @param {Number} y1
  4985. * @return {Fill} Returns this Fill object for chaining or assignment.
  4986. */
  4987. p.linearGradient = function(colors, ratios, x0, y0, x1, y1) {
  4988. var o = this.style = Graphics._ctx.createLinearGradient(x0, y0, x1, y1);
  4989. for (var i=0, l=colors.length; i<l; i++) { o.addColorStop(ratios[i], colors[i]); }
  4990. o.props = {colors:colors, ratios:ratios, x0:x0, y0:y0, x1:x1, y1:y1, type:"linear"};
  4991. return this;
  4992. };
  4993. /**
  4994. * Creates a radial gradient style and assigns it to {{#crossLink "Fill/style:property"}}{{/crossLink}}.
  4995. * See {{#crossLink "Graphics/beginRadialGradientFill"}}{{/crossLink}} for more information.
  4996. * @method radialGradient
  4997. * @param {Array} colors
  4998. * @param {Array} ratios
  4999. * @param {Number} x0
  5000. * @param {Number} y0
  5001. * @param {Number} r0
  5002. * @param {Number} x1
  5003. * @param {Number} y1
  5004. * @param {Number} r1
  5005. * @return {Fill} Returns this Fill object for chaining or assignment.
  5006. */
  5007. p.radialGradient = function(colors, ratios, x0, y0, r0, x1, y1, r1) {
  5008. var o = this.style = Graphics._ctx.createRadialGradient(x0, y0, r0, x1, y1, r1);
  5009. for (var i=0, l=colors.length; i<l; i++) { o.addColorStop(ratios[i], colors[i]); }
  5010. o.props = {colors:colors, ratios:ratios, x0:x0, y0:y0, r0:r0, x1:x1, y1:y1, r1:r1, type:"radial"};
  5011. return this;
  5012. };
  5013. /**
  5014. * Creates a bitmap fill style and assigns it to the {{#crossLink "Fill/style:property"}}{{/crossLink}}.
  5015. * See {{#crossLink "Graphics/beginBitmapFill"}}{{/crossLink}} for more information.
  5016. * @method bitmap
  5017. * @param {HTMLImageElement | HTMLCanvasElement | HTMLVideoElement} image Must be loaded prior to creating a bitmap fill, or the fill will be empty.
  5018. * @param {String} [repetition] One of: repeat, repeat-x, repeat-y, or no-repeat.
  5019. * @return {Fill} Returns this Fill object for chaining or assignment.
  5020. */
  5021. p.bitmap = function(image, repetition) {
  5022. if (image.naturalWidth || image.getContext || image.readyState >= 2) {
  5023. var o = this.style = Graphics._ctx.createPattern(image, repetition || "");
  5024. o.props = {image: image, repetition: repetition, type: "bitmap"};
  5025. }
  5026. return this;
  5027. };
  5028. p.path = false;
  5029. /**
  5030. * Graphics command object. See {{#crossLink "Graphics/beginStroke"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information.
  5031. * @class Stroke
  5032. * @constructor
  5033. * @param {Object} style A valid Context2D fillStyle.
  5034. * @param {Boolean} ignoreScale
  5035. **/
  5036. /**
  5037. * A valid Context2D strokeStyle.
  5038. * @property style
  5039. * @type Object
  5040. */
  5041. /**
  5042. * @property ignoreScale
  5043. * @type Boolean
  5044. */
  5045. /**
  5046. * Execute the Graphics command in the provided Canvas context.
  5047. * @method exec
  5048. * @param {CanvasRenderingContext2D} ctx The canvas rendering context
  5049. */
  5050. p = (G.Stroke = function(style, ignoreScale) {
  5051. this.style = style;
  5052. this.ignoreScale = ignoreScale;
  5053. }).prototype;
  5054. p.exec = function(ctx) {
  5055. if (!this.style) { return; }
  5056. ctx.strokeStyle = this.style;
  5057. if (this.ignoreScale) { ctx.save(); ctx.setTransform(1,0,0,1,0,0); }
  5058. ctx.stroke();
  5059. if (this.ignoreScale) { ctx.restore(); }
  5060. };
  5061. /**
  5062. * Creates a linear gradient style and assigns it to {{#crossLink "Stroke/style:property"}}{{/crossLink}}.
  5063. * See {{#crossLink "Graphics/beginLinearGradientStroke"}}{{/crossLink}} for more information.
  5064. * @method linearGradient
  5065. * @param {Array} colors
  5066. * @param {Array} ratios
  5067. * @param {Number} x0
  5068. * @param {Number} y0
  5069. * @param {Number} x1
  5070. * @param {Number} y1
  5071. * @return {Fill} Returns this Stroke object for chaining or assignment.
  5072. */
  5073. p.linearGradient = G.Fill.prototype.linearGradient;
  5074. /**
  5075. * Creates a radial gradient style and assigns it to {{#crossLink "Stroke/style:property"}}{{/crossLink}}.
  5076. * See {{#crossLink "Graphics/beginRadialGradientStroke"}}{{/crossLink}} for more information.
  5077. * @method radialGradient
  5078. * @param {Array} colors
  5079. * @param {Array} ratios
  5080. * @param {Number} x0
  5081. * @param {Number} y0
  5082. * @param {Number} r0
  5083. * @param {Number} x1
  5084. * @param {Number} y1
  5085. * @param {Number} r1
  5086. * @return {Fill} Returns this Stroke object for chaining or assignment.
  5087. */
  5088. p.radialGradient = G.Fill.prototype.radialGradient;
  5089. /**
  5090. * Creates a bitmap fill style and assigns it to {{#crossLink "Stroke/style:property"}}{{/crossLink}}.
  5091. * See {{#crossLink "Graphics/beginBitmapStroke"}}{{/crossLink}} for more information.
  5092. * @method bitmap
  5093. * @param {HTMLImageElement} image
  5094. * @param {String} [repetition] One of: repeat, repeat-x, repeat-y, or no-repeat.
  5095. * @return {Fill} Returns this Stroke object for chaining or assignment.
  5096. */
  5097. p.bitmap = G.Fill.prototype.bitmap;
  5098. p.path = false;
  5099. /**
  5100. * Graphics command object. See {{#crossLink "Graphics/setStrokeStyle"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information.
  5101. * @class StrokeStyle
  5102. * @constructor
  5103. * @param {Number} width
  5104. * @param {String} [caps=butt]
  5105. * @param {String} [joints=miter]
  5106. * @param {Number} [miterLimit=10]
  5107. * @param {Boolean} [ignoreScale=false]
  5108. **/
  5109. /**
  5110. * @property width
  5111. * @type Number
  5112. */
  5113. /**
  5114. * One of: butt, round, square
  5115. * @property caps
  5116. * @type String
  5117. */
  5118. /**
  5119. * One of: round, bevel, miter
  5120. * @property joints
  5121. * @type String
  5122. */
  5123. /**
  5124. * @property miterLimit
  5125. * @type Number
  5126. */
  5127. /**
  5128. * Execute the Graphics command in the provided Canvas context.
  5129. * @method exec
  5130. * @param {CanvasRenderingContext2D} ctx The canvas rendering context
  5131. */
  5132. p = (G.StrokeStyle = function(width, caps, joints, miterLimit, ignoreScale) {
  5133. this.width = width;
  5134. this.caps = caps;
  5135. this.joints = joints;
  5136. this.miterLimit = miterLimit;
  5137. this.ignoreScale = ignoreScale;
  5138. }).prototype;
  5139. p.exec = function(ctx) {
  5140. ctx.lineWidth = (this.width == null ? "1" : this.width);
  5141. ctx.lineCap = (this.caps == null ? "butt" : (isNaN(this.caps) ? this.caps : Graphics.STROKE_CAPS_MAP[this.caps]));
  5142. ctx.lineJoin = (this.joints == null ? "miter" : (isNaN(this.joints) ? this.joints : Graphics.STROKE_JOINTS_MAP[this.joints]));
  5143. ctx.miterLimit = (this.miterLimit == null ? "10" : this.miterLimit);
  5144. ctx.ignoreScale = (this.ignoreScale == null ? false : this.ignoreScale);
  5145. };
  5146. p.path = false;
  5147. /**
  5148. * Graphics command object. See {{#crossLink "Graphics/setStrokeDash"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information.
  5149. * @class StrokeDash
  5150. * @constructor
  5151. * @param {Array} [segments]
  5152. * @param {Number} [offset=0]
  5153. **/
  5154. /**
  5155. * @property segments
  5156. * @type Array
  5157. */
  5158. /**
  5159. * @property offset
  5160. * @type Number
  5161. */
  5162. /**
  5163. * Execute the Graphics command in the provided Canvas context.
  5164. * @method exec
  5165. * @param {CanvasRenderingContext2D} ctx The canvas rendering context
  5166. */
  5167. (G.StrokeDash = function(segments, offset) {
  5168. this.segments = segments;
  5169. this.offset = offset||0;
  5170. }).prototype.exec = function(ctx) {
  5171. if (ctx.setLineDash) { // feature detection.
  5172. ctx.setLineDash(this.segments|| G.StrokeDash.EMPTY_SEGMENTS); // instead of [] to reduce churn.
  5173. ctx.lineDashOffset = this.offset||0;
  5174. }
  5175. };
  5176. /**
  5177. * The default value for segments (ie. no dash).
  5178. * @property EMPTY_SEGMENTS
  5179. * @static
  5180. * @final
  5181. * @readonly
  5182. * @protected
  5183. * @type {Array}
  5184. **/
  5185. G.StrokeDash.EMPTY_SEGMENTS = [];
  5186. /**
  5187. * Graphics command object. See {{#crossLink "Graphics/drawRoundRectComplex"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information.
  5188. * @class RoundRect
  5189. * @constructor
  5190. * @param {Number} x
  5191. * @param {Number} y
  5192. * @param {Number} w
  5193. * @param {Number} h
  5194. * @param {Number} radiusTL
  5195. * @param {Number} radiusTR
  5196. * @param {Number} radiusBR
  5197. * @param {Number} radiusBL
  5198. **/
  5199. /**
  5200. * @property x
  5201. * @type Number
  5202. */
  5203. /**
  5204. * @property y
  5205. * @type Number
  5206. */
  5207. /**
  5208. * @property w
  5209. * @type Number
  5210. */
  5211. /**
  5212. * @property h
  5213. * @type Number
  5214. */
  5215. /**
  5216. * @property radiusTL
  5217. * @type Number
  5218. */
  5219. /**
  5220. * @property radiusTR
  5221. * @type Number
  5222. */
  5223. /**
  5224. * @property radiusBR
  5225. * @type Number
  5226. */
  5227. /**
  5228. * @property radiusBL
  5229. * @type Number
  5230. */
  5231. /**
  5232. * Execute the Graphics command in the provided Canvas context.
  5233. * @method exec
  5234. * @param {CanvasRenderingContext2D} ctx The canvas rendering context
  5235. */
  5236. (G.RoundRect = function(x, y, w, h, radiusTL, radiusTR, radiusBR, radiusBL) {
  5237. this.x = x; this.y = y;
  5238. this.w = w; this.h = h;
  5239. this.radiusTL = radiusTL; this.radiusTR = radiusTR;
  5240. this.radiusBR = radiusBR; this.radiusBL = radiusBL;
  5241. }).prototype.exec = function(ctx) {
  5242. var max = (w<h?w:h)/2;
  5243. var mTL=0, mTR=0, mBR=0, mBL=0;
  5244. var x = this.x, y = this.y, w = this.w, h = this.h;
  5245. var rTL = this.radiusTL, rTR = this.radiusTR, rBR = this.radiusBR, rBL = this.radiusBL;
  5246. if (rTL < 0) { rTL *= (mTL=-1); }
  5247. if (rTL > max) { rTL = max; }
  5248. if (rTR < 0) { rTR *= (mTR=-1); }
  5249. if (rTR > max) { rTR = max; }
  5250. if (rBR < 0) { rBR *= (mBR=-1); }
  5251. if (rBR > max) { rBR = max; }
  5252. if (rBL < 0) { rBL *= (mBL=-1); }
  5253. if (rBL > max) { rBL = max; }
  5254. ctx.moveTo(x+w-rTR, y);
  5255. ctx.arcTo(x+w+rTR*mTR, y-rTR*mTR, x+w, y+rTR, rTR);
  5256. ctx.lineTo(x+w, y+h-rBR);
  5257. ctx.arcTo(x+w+rBR*mBR, y+h+rBR*mBR, x+w-rBR, y+h, rBR);
  5258. ctx.lineTo(x+rBL, y+h);
  5259. ctx.arcTo(x-rBL*mBL, y+h+rBL*mBL, x, y+h-rBL, rBL);
  5260. ctx.lineTo(x, y+rTL);
  5261. ctx.arcTo(x-rTL*mTL, y-rTL*mTL, x+rTL, y, rTL);
  5262. ctx.closePath();
  5263. };
  5264. /**
  5265. * Graphics command object. See {{#crossLink "Graphics/drawCircle"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information.
  5266. * @class Circle
  5267. * @constructor
  5268. * @param {Number} x
  5269. * @param {Number} y
  5270. * @param {Number} radius
  5271. **/
  5272. /**
  5273. * @property x
  5274. * @type Number
  5275. */
  5276. /**
  5277. * @property y
  5278. * @type Number
  5279. */
  5280. /**
  5281. * @property radius
  5282. * @type Number
  5283. */
  5284. /**
  5285. * Execute the Graphics command in the provided Canvas context.
  5286. * @method exec
  5287. * @param {CanvasRenderingContext2D} ctx The canvas rendering context
  5288. */
  5289. (G.Circle = function(x, y, radius) {
  5290. this.x = x; this.y = y;
  5291. this.radius = radius;
  5292. }).prototype.exec = function(ctx) { ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2); };
  5293. /**
  5294. * Graphics command object. See {{#crossLink "Graphics/drawEllipse"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information.
  5295. * @class Ellipse
  5296. * @constructor
  5297. * @param {Number} x
  5298. * @param {Number} y
  5299. * @param {Number} w
  5300. * @param {Number} h
  5301. **/
  5302. /**
  5303. * @property x
  5304. * @type Number
  5305. */
  5306. /**
  5307. * @property y
  5308. * @type Number
  5309. */
  5310. /**
  5311. * @property w
  5312. * @type Number
  5313. */
  5314. /**
  5315. * @property h
  5316. * @type Number
  5317. */
  5318. /**
  5319. * Execute the Graphics command in the provided Canvas context.
  5320. * @method exec
  5321. * @param {CanvasRenderingContext2D} ctx The canvas rendering context
  5322. */
  5323. (G.Ellipse = function(x, y, w, h) {
  5324. this.x = x; this.y = y;
  5325. this.w = w; this.h = h;
  5326. }).prototype.exec = function(ctx) {
  5327. var x = this.x, y = this.y;
  5328. var w = this.w, h = this.h;
  5329. var k = 0.5522848;
  5330. var ox = (w / 2) * k;
  5331. var oy = (h / 2) * k;
  5332. var xe = x + w;
  5333. var ye = y + h;
  5334. var xm = x + w / 2;
  5335. var ym = y + h / 2;
  5336. ctx.moveTo(x, ym);
  5337. ctx.bezierCurveTo(x, ym-oy, xm-ox, y, xm, y);
  5338. ctx.bezierCurveTo(xm+ox, y, xe, ym-oy, xe, ym);
  5339. ctx.bezierCurveTo(xe, ym+oy, xm+ox, ye, xm, ye);
  5340. ctx.bezierCurveTo(xm-ox, ye, x, ym+oy, x, ym);
  5341. };
  5342. /**
  5343. * Graphics command object. See {{#crossLink "Graphics/drawPolyStar"}}{{/crossLink}} and {{#crossLink "Graphics/append"}}{{/crossLink}} for more information.
  5344. * @class PolyStar
  5345. * @constructor
  5346. * @param {Number} x
  5347. * @param {Number} y
  5348. * @param {Number} radius
  5349. * @param {Number} sides
  5350. * @param {Number} pointSize
  5351. * @param {Number} angle
  5352. **/
  5353. /**
  5354. * @property x
  5355. * @type Number
  5356. */
  5357. /**
  5358. * @property y
  5359. * @type Number
  5360. */
  5361. /**
  5362. * @property radius
  5363. * @type Number
  5364. */
  5365. /**
  5366. * @property sides
  5367. * @type Number
  5368. */
  5369. /**
  5370. * @property pointSize
  5371. * @type Number
  5372. */
  5373. /**
  5374. * @property angle
  5375. * @type Number
  5376. */
  5377. /**
  5378. * Execute the Graphics command in the provided Canvas context.
  5379. * @method exec
  5380. * @param {CanvasRenderingContext2D} ctx The canvas rendering context
  5381. */
  5382. (G.PolyStar = function(x, y, radius, sides, pointSize, angle) {
  5383. this.x = x; this.y = y;
  5384. this.radius = radius;
  5385. this.sides = sides;
  5386. this.pointSize = pointSize;
  5387. this.angle = angle;
  5388. }).prototype.exec = function(ctx) {
  5389. var x = this.x, y = this.y;
  5390. var radius = this.radius;
  5391. var angle = (this.angle||0)/180*Math.PI;
  5392. var sides = this.sides;
  5393. var ps = 1-(this.pointSize||0);
  5394. var a = Math.PI/sides;
  5395. ctx.moveTo(x+Math.cos(angle)*radius, y+Math.sin(angle)*radius);
  5396. for (var i=0; i<sides; i++) {
  5397. angle += a;
  5398. if (ps != 1) {
  5399. ctx.lineTo(x+Math.cos(angle)*radius*ps, y+Math.sin(angle)*radius*ps);
  5400. }
  5401. angle += a;
  5402. ctx.lineTo(x+Math.cos(angle)*radius, y+Math.sin(angle)*radius);
  5403. }
  5404. ctx.closePath();
  5405. };
  5406. // docced above.
  5407. Graphics.beginCmd = new G.BeginPath(); // so we don't have to instantiate multiple instances.
  5408. createjs.Graphics = Graphics;
  5409. }());
  5410. //##############################################################################
  5411. // DisplayObject.js
  5412. //##############################################################################
  5413. this.createjs = this.createjs||{};
  5414. (function() {
  5415. "use strict";
  5416. // constructor:
  5417. /**
  5418. * DisplayObject is an abstract class that should not be constructed directly. Instead construct subclasses such as
  5419. * {{#crossLink "Container"}}{{/crossLink}}, {{#crossLink "Bitmap"}}{{/crossLink}}, and {{#crossLink "Shape"}}{{/crossLink}}.
  5420. * DisplayObject is the base class for all display classes in the EaselJS library. It defines the core properties and
  5421. * methods that are shared between all display objects, such as transformation properties (x, y, scaleX, scaleY, etc),
  5422. * caching, and mouse handlers.
  5423. * @class DisplayObject
  5424. * @extends EventDispatcher
  5425. * @constructor
  5426. **/
  5427. function DisplayObject() {
  5428. this.EventDispatcher_constructor();
  5429. // public properties:
  5430. /**
  5431. * The alpha (transparency) for this display object. 0 is fully transparent, 1 is fully opaque.
  5432. * @property alpha
  5433. * @type {Number}
  5434. * @default 1
  5435. **/
  5436. this.alpha = 1;
  5437. /**
  5438. * If a cache is active, this returns the canvas that holds the cached version of this display object. See {{#crossLink "cache"}}{{/crossLink}}
  5439. * for more information.
  5440. * @property cacheCanvas
  5441. * @type {HTMLCanvasElement | Object}
  5442. * @default null
  5443. * @readonly
  5444. **/
  5445. this.cacheCanvas = null;
  5446. /**
  5447. * Returns an ID number that uniquely identifies the current cache for this display object. This can be used to
  5448. * determine if the cache has changed since a previous check.
  5449. * @property cacheID
  5450. * @type {Number}
  5451. * @default 0
  5452. */
  5453. this.cacheID = 0;
  5454. /**
  5455. * Unique ID for this display object. Makes display objects easier for some uses.
  5456. * @property id
  5457. * @type {Number}
  5458. * @default -1
  5459. **/
  5460. this.id = createjs.UID.get();
  5461. /**
  5462. * Indicates whether to include this object when running mouse interactions. Setting this to `false` for children
  5463. * of a {{#crossLink "Container"}}{{/crossLink}} will cause events on the Container to not fire when that child is
  5464. * clicked. Setting this property to `false` does not prevent the {{#crossLink "Container/getObjectsUnderPoint"}}{{/crossLink}}
  5465. * method from returning the child.
  5466. *
  5467. * <strong>Note:</strong> In EaselJS 0.7.0, the mouseEnabled property will not work properly with nested Containers. Please
  5468. * 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
  5469. * provided in the next release of EaselJS.
  5470. * @property mouseEnabled
  5471. * @type {Boolean}
  5472. * @default true
  5473. **/
  5474. this.mouseEnabled = true;
  5475. /**
  5476. * If false, the tick will not run on this display object (or its children). This can provide some performance benefits.
  5477. * In addition to preventing the "tick" event from being dispatched, it will also prevent tick related updates
  5478. * on some display objects (ex. Sprite & MovieClip frame advancing, DOMElement visibility handling).
  5479. * @property tickEnabled
  5480. * @type Boolean
  5481. * @default true
  5482. **/
  5483. this.tickEnabled = true;
  5484. /**
  5485. * An optional name for this display object. Included in {{#crossLink "DisplayObject/toString"}}{{/crossLink}} . Useful for
  5486. * debugging.
  5487. * @property name
  5488. * @type {String}
  5489. * @default null
  5490. **/
  5491. this.name = null;
  5492. /**
  5493. * A reference to the {{#crossLink "Container"}}{{/crossLink}} or {{#crossLink "Stage"}}{{/crossLink}} object that
  5494. * contains this display object, or null if it has not been added
  5495. * to one.
  5496. * @property parent
  5497. * @final
  5498. * @type {Container}
  5499. * @default null
  5500. * @readonly
  5501. **/
  5502. this.parent = null;
  5503. /**
  5504. * The left offset for this display object's registration point. For example, to make a 100x100px Bitmap rotate
  5505. * around its center, you would set regX and {{#crossLink "DisplayObject/regY:property"}}{{/crossLink}} to 50.
  5506. * @property regX
  5507. * @type {Number}
  5508. * @default 0
  5509. **/
  5510. this.regX = 0;
  5511. /**
  5512. * The y offset for this display object's registration point. For example, to make a 100x100px Bitmap rotate around
  5513. * its center, you would set {{#crossLink "DisplayObject/regX:property"}}{{/crossLink}} and regY to 50.
  5514. * @property regY
  5515. * @type {Number}
  5516. * @default 0
  5517. **/
  5518. this.regY = 0;
  5519. /**
  5520. * The rotation in degrees for this display object.
  5521. * @property rotation
  5522. * @type {Number}
  5523. * @default 0
  5524. **/
  5525. this.rotation = 0;
  5526. /**
  5527. * The factor to stretch this display object horizontally. For example, setting scaleX to 2 will stretch the display
  5528. * object to twice its nominal width. To horizontally flip an object, set the scale to a negative number.
  5529. * @property scaleX
  5530. * @type {Number}
  5531. * @default 1
  5532. **/
  5533. this.scaleX = 1;
  5534. /**
  5535. * The factor to stretch this display object vertically. For example, setting scaleY to 0.5 will stretch the display
  5536. * object to half its nominal height. To vertically flip an object, set the scale to a negative number.
  5537. * @property scaleY
  5538. * @type {Number}
  5539. * @default 1
  5540. **/
  5541. this.scaleY = 1;
  5542. /**
  5543. * The factor to skew this display object horizontally.
  5544. * @property skewX
  5545. * @type {Number}
  5546. * @default 0
  5547. **/
  5548. this.skewX = 0;
  5549. /**
  5550. * The factor to skew this display object vertically.
  5551. * @property skewY
  5552. * @type {Number}
  5553. * @default 0
  5554. **/
  5555. this.skewY = 0;
  5556. /**
  5557. * A shadow object that defines the shadow to render on this display object. Set to `null` to remove a shadow. If
  5558. * null, this property is inherited from the parent container.
  5559. * @property shadow
  5560. * @type {Shadow}
  5561. * @default null
  5562. **/
  5563. this.shadow = null;
  5564. /**
  5565. * Indicates whether this display object should be rendered to the canvas and included when running the Stage
  5566. * {{#crossLink "Stage/getObjectsUnderPoint"}}{{/crossLink}} method.
  5567. * @property visible
  5568. * @type {Boolean}
  5569. * @default true
  5570. **/
  5571. this.visible = true;
  5572. /**
  5573. * The x (horizontal) position of the display object, relative to its parent.
  5574. * @property x
  5575. * @type {Number}
  5576. * @default 0
  5577. **/
  5578. this.x = 0;
  5579. /** The y (vertical) position of the display object, relative to its parent.
  5580. * @property y
  5581. * @type {Number}
  5582. * @default 0
  5583. **/
  5584. this.y = 0;
  5585. /**
  5586. * If set, defines the transformation for this display object, overriding all other transformation properties
  5587. * (x, y, rotation, scale, skew).
  5588. * @property transformMatrix
  5589. * @type {Matrix2D}
  5590. * @default null
  5591. **/
  5592. this.transformMatrix = null;
  5593. /**
  5594. * The composite operation indicates how the pixels of this display object will be composited with the elements
  5595. * behind it. If `null`, this property is inherited from the parent container. For more information, read the
  5596. * <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#compositing">
  5597. * whatwg spec on compositing</a>.
  5598. * @property compositeOperation
  5599. * @type {String}
  5600. * @default null
  5601. **/
  5602. this.compositeOperation = null;
  5603. /**
  5604. * Indicates whether the display object should be drawn to a whole pixel when
  5605. * {{#crossLink "Stage/snapToPixelEnabled"}}{{/crossLink}} is true. To enable/disable snapping on whole
  5606. * categories of display objects, set this value on the prototype (Ex. Text.prototype.snapToPixel = true).
  5607. * @property snapToPixel
  5608. * @type {Boolean}
  5609. * @default true
  5610. **/
  5611. this.snapToPixel = true;
  5612. /**
  5613. * An array of Filter objects to apply to this display object. Filters are only applied / updated when {{#crossLink "cache"}}{{/crossLink}}
  5614. * or {{#crossLink "updateCache"}}{{/crossLink}} is called on the display object, and only apply to the area that is
  5615. * cached.
  5616. * @property filters
  5617. * @type {Array}
  5618. * @default null
  5619. **/
  5620. this.filters = null;
  5621. /**
  5622. * A Shape instance that defines a vector mask (clipping path) for this display object. The shape's transformation
  5623. * will be applied relative to the display object's parent coordinates (as if it were a child of the parent).
  5624. * @property mask
  5625. * @type {Shape}
  5626. * @default null
  5627. */
  5628. this.mask = null;
  5629. /**
  5630. * A display object that will be tested when checking mouse interactions or testing {{#crossLink "Container/getObjectsUnderPoint"}}{{/crossLink}}.
  5631. * The hit area will have its transformation applied relative to this display object's coordinate space (as though
  5632. * the hit test object were a child of this display object and relative to its regX/Y). The hitArea will be tested
  5633. * using only its own `alpha` value regardless of the alpha value on the target display object, or the target's
  5634. * ancestors (parents).
  5635. *
  5636. * If set on a {{#crossLink "Container"}}{{/crossLink}}, children of the Container will not receive mouse events.
  5637. * This is similar to setting {{#crossLink "mouseChildren"}}{{/crossLink}} to false.
  5638. *
  5639. * Note that hitArea is NOT currently used by the `hitTest()` method, nor is it supported for {{#crossLink "Stage"}}{{/crossLink}}.
  5640. * @property hitArea
  5641. * @type {DisplayObject}
  5642. * @default null
  5643. */
  5644. this.hitArea = null;
  5645. /**
  5646. * A CSS cursor (ex. "pointer", "help", "text", etc) that will be displayed when the user hovers over this display
  5647. * object. You must enable mouseover events using the {{#crossLink "Stage/enableMouseOver"}}{{/crossLink}} method to
  5648. * use this property. Setting a non-null cursor on a Container will override the cursor set on its descendants.
  5649. * @property cursor
  5650. * @type {String}
  5651. * @default null
  5652. */
  5653. this.cursor = null;
  5654. // private properties:
  5655. /**
  5656. * @property _cacheOffsetX
  5657. * @protected
  5658. * @type {Number}
  5659. * @default 0
  5660. **/
  5661. this._cacheOffsetX = 0;
  5662. /**
  5663. * @property _cacheOffsetY
  5664. * @protected
  5665. * @type {Number}
  5666. * @default 0
  5667. **/
  5668. this._cacheOffsetY = 0;
  5669. /**
  5670. * @property _filterOffsetX
  5671. * @protected
  5672. * @type {Number}
  5673. * @default 0
  5674. **/
  5675. this._filterOffsetX = 0;
  5676. /**
  5677. * @property _filterOffsetY
  5678. * @protected
  5679. * @type {Number}
  5680. * @default 0
  5681. **/
  5682. this._filterOffsetY = 0;
  5683. /**
  5684. * @property _cacheScale
  5685. * @protected
  5686. * @type {Number}
  5687. * @default 1
  5688. **/
  5689. this._cacheScale = 1;
  5690. /**
  5691. * @property _cacheDataURLID
  5692. * @protected
  5693. * @type {Number}
  5694. * @default 0
  5695. */
  5696. this._cacheDataURLID = 0;
  5697. /**
  5698. * @property _cacheDataURL
  5699. * @protected
  5700. * @type {String}
  5701. * @default null
  5702. */
  5703. this._cacheDataURL = null;
  5704. /**
  5705. * @property _props
  5706. * @protected
  5707. * @type {DisplayObject}
  5708. * @default null
  5709. **/
  5710. this._props = new createjs.DisplayProps();
  5711. /**
  5712. * @property _rectangle
  5713. * @protected
  5714. * @type {Rectangle}
  5715. * @default null
  5716. **/
  5717. this._rectangle = new createjs.Rectangle();
  5718. /**
  5719. * @property _bounds
  5720. * @protected
  5721. * @type {Rectangle}
  5722. * @default null
  5723. **/
  5724. this._bounds = null;
  5725. }
  5726. var p = createjs.extend(DisplayObject, createjs.EventDispatcher);
  5727. // TODO: deprecated
  5728. // p.initialize = function() {}; // searchable for devs wondering where it is. REMOVED. See docs for details.
  5729. // static properties:
  5730. /**
  5731. * Listing of mouse event names. Used in _hasMouseEventListener.
  5732. * @property _MOUSE_EVENTS
  5733. * @protected
  5734. * @static
  5735. * @type {Array}
  5736. **/
  5737. DisplayObject._MOUSE_EVENTS = ["click","dblclick","mousedown","mouseout","mouseover","pressmove","pressup","rollout","rollover"];
  5738. /**
  5739. * Suppresses errors generated when using features like hitTest, mouse events, and {{#crossLink "getObjectsUnderPoint"}}{{/crossLink}}
  5740. * with cross domain content.
  5741. * @property suppressCrossDomainErrors
  5742. * @static
  5743. * @type {Boolean}
  5744. * @default false
  5745. **/
  5746. DisplayObject.suppressCrossDomainErrors = false;
  5747. /**
  5748. * @property _snapToPixelEnabled
  5749. * @protected
  5750. * @static
  5751. * @type {Boolean}
  5752. * @default false
  5753. **/
  5754. DisplayObject._snapToPixelEnabled = false; // stage.snapToPixelEnabled is temporarily copied here during a draw to provide global access.
  5755. /**
  5756. * @property _hitTestCanvas
  5757. * @type {HTMLCanvasElement | Object}
  5758. * @static
  5759. * @protected
  5760. **/
  5761. /**
  5762. * @property _hitTestContext
  5763. * @type {CanvasRenderingContext2D}
  5764. * @static
  5765. * @protected
  5766. **/
  5767. var canvas = createjs.createCanvas?createjs.createCanvas():document.createElement("canvas"); // prevent errors on load in browsers without canvas.
  5768. if (canvas.getContext) {
  5769. DisplayObject._hitTestCanvas = canvas;
  5770. DisplayObject._hitTestContext = canvas.getContext("2d");
  5771. canvas.width = canvas.height = 1;
  5772. }
  5773. /**
  5774. * @property _nextCacheID
  5775. * @type {Number}
  5776. * @static
  5777. * @protected
  5778. **/
  5779. DisplayObject._nextCacheID = 1;
  5780. // events:
  5781. /**
  5782. * Dispatched when the user presses their left mouse button over the display object. See the
  5783. * {{#crossLink "MouseEvent"}}{{/crossLink}} class for a listing of event properties.
  5784. * @event mousedown
  5785. * @since 0.6.0
  5786. */
  5787. /**
  5788. * Dispatched when the user presses their left mouse button and then releases it while over the display object.
  5789. * See the {{#crossLink "MouseEvent"}}{{/crossLink}} class for a listing of event properties.
  5790. * @event click
  5791. * @since 0.6.0
  5792. */
  5793. /**
  5794. * Dispatched when the user double clicks their left mouse button over this display object.
  5795. * See the {{#crossLink "MouseEvent"}}{{/crossLink}} class for a listing of event properties.
  5796. * @event dblclick
  5797. * @since 0.6.0
  5798. */
  5799. /**
  5800. * Dispatched when the user's mouse enters this display object. This event must be enabled using
  5801. * {{#crossLink "Stage/enableMouseOver"}}{{/crossLink}}. See also {{#crossLink "DisplayObject/rollover:event"}}{{/crossLink}}.
  5802. * See the {{#crossLink "MouseEvent"}}{{/crossLink}} class for a listing of event properties.
  5803. * @event mouseover
  5804. * @since 0.6.0
  5805. */
  5806. /**
  5807. * Dispatched when the user's mouse leaves this display object. This event must be enabled using
  5808. * {{#crossLink "Stage/enableMouseOver"}}{{/crossLink}}. See also {{#crossLink "DisplayObject/rollout:event"}}{{/crossLink}}.
  5809. * See the {{#crossLink "MouseEvent"}}{{/crossLink}} class for a listing of event properties.
  5810. * @event mouseout
  5811. * @since 0.6.0
  5812. */
  5813. /**
  5814. * This event is similar to {{#crossLink "DisplayObject/mouseover:event"}}{{/crossLink}}, with the following
  5815. * differences: it does not bubble, and it considers {{#crossLink "Container"}}{{/crossLink}} instances as an
  5816. * aggregate of their content.
  5817. *
  5818. * For example, myContainer contains two overlapping children: shapeA and shapeB. The user moves their mouse over
  5819. * shapeA and then directly on to shapeB. With a listener for {{#crossLink "mouseover:event"}}{{/crossLink}} on
  5820. * myContainer, two events would be received, each targeting a child element:<OL>
  5821. * <LI>when the mouse enters shapeA (target=shapeA)</LI>
  5822. * <LI>when the mouse enters shapeB (target=shapeB)</LI>
  5823. * </OL>
  5824. * However, with a listener for "rollover" instead, only a single event is received when the mouse first enters
  5825. * the aggregate myContainer content (target=myContainer).
  5826. *
  5827. * This event must be enabled using {{#crossLink "Stage/enableMouseOver"}}{{/crossLink}}.
  5828. * See the {{#crossLink "MouseEvent"}}{{/crossLink}} class for a listing of event properties.
  5829. * @event rollover
  5830. * @since 0.7.0
  5831. */
  5832. /**
  5833. * This event is similar to {{#crossLink "DisplayObject/mouseout:event"}}{{/crossLink}}, with the following
  5834. * differences: it does not bubble, and it considers {{#crossLink "Container"}}{{/crossLink}} instances as an
  5835. * aggregate of their content.
  5836. *
  5837. * For example, myContainer contains two overlapping children: shapeA and shapeB. The user moves their mouse over
  5838. * shapeA, then directly on to shapeB, then off both. With a listener for {{#crossLink "mouseout:event"}}{{/crossLink}}
  5839. * on myContainer, two events would be received, each targeting a child element:<OL>
  5840. * <LI>when the mouse leaves shapeA (target=shapeA)</LI>
  5841. * <LI>when the mouse leaves shapeB (target=shapeB)</LI>
  5842. * </OL>
  5843. * However, with a listener for "rollout" instead, only a single event is received when the mouse leaves
  5844. * the aggregate myContainer content (target=myContainer).
  5845. *
  5846. * This event must be enabled using {{#crossLink "Stage/enableMouseOver"}}{{/crossLink}}.
  5847. * See the {{#crossLink "MouseEvent"}}{{/crossLink}} class for a listing of event properties.
  5848. * @event rollout
  5849. * @since 0.7.0
  5850. */
  5851. /**
  5852. * After a {{#crossLink "DisplayObject/mousedown:event"}}{{/crossLink}} occurs on a display object, a pressmove
  5853. * event will be generated on that object whenever the mouse moves until the mouse press is released. This can be
  5854. * useful for dragging and similar operations.
  5855. * @event pressmove
  5856. * @since 0.7.0
  5857. */
  5858. /**
  5859. * After a {{#crossLink "DisplayObject/mousedown:event"}}{{/crossLink}} occurs on a display object, a pressup event
  5860. * will be generated on that object when that mouse press is released. This can be useful for dragging and similar
  5861. * operations.
  5862. * @event pressup
  5863. * @since 0.7.0
  5864. */
  5865. /**
  5866. * Dispatched when the display object is added to a parent container.
  5867. * @event added
  5868. */
  5869. /**
  5870. * Dispatched when the display object is removed from its parent container.
  5871. * @event removed
  5872. */
  5873. /**
  5874. * Dispatched on each display object on a stage whenever the stage updates. This occurs immediately before the
  5875. * rendering (draw) pass. When {{#crossLink "Stage/update"}}{{/crossLink}} is called, first all display objects on
  5876. * the stage dispatch the tick event, then all of the display objects are drawn to stage. Children will have their
  5877. * {{#crossLink "tick:event"}}{{/crossLink}} event dispatched in order of their depth prior to the event being
  5878. * dispatched on their parent.
  5879. * @event tick
  5880. * @param {Object} target The object that dispatched the event.
  5881. * @param {String} type The event type.
  5882. * @param {Array} params An array containing any arguments that were passed to the Stage.update() method. For
  5883. * example if you called stage.update("hello"), then the params would be ["hello"].
  5884. * @since 0.6.0
  5885. */
  5886. // getter / setters:
  5887. /**
  5888. * Use the {{#crossLink "DisplayObject/stage:property"}}{{/crossLink}} property instead.
  5889. * @method getStage
  5890. * @return {Stage}
  5891. * @deprecated
  5892. **/
  5893. p.getStage = function() {
  5894. // uses dynamic access to avoid circular dependencies;
  5895. var o = this, _Stage = createjs["Stage"];
  5896. while (o.parent) { o = o.parent; }
  5897. if (o instanceof _Stage) { return o; }
  5898. return null;
  5899. };
  5900. /**
  5901. * Returns the Stage instance that this display object will be rendered on, or null if it has not been added to one.
  5902. * @property stage
  5903. * @type {Stage}
  5904. * @readonly
  5905. **/
  5906. try {
  5907. Object.defineProperties(p, {
  5908. stage: { get: p.getStage }
  5909. });
  5910. } catch (e) {}
  5911. // public methods:
  5912. /**
  5913. * Returns true or false indicating whether the display object would be visible if drawn to a canvas.
  5914. * This does not account for whether it would be visible within the boundaries of the stage.
  5915. *
  5916. * NOTE: This method is mainly for internal use, though it may be useful for advanced uses.
  5917. * @method isVisible
  5918. * @return {Boolean} Boolean indicating whether the display object would be visible if drawn to a canvas
  5919. **/
  5920. p.isVisible = function() {
  5921. return !!(this.visible && this.alpha > 0 && this.scaleX != 0 && this.scaleY != 0);
  5922. };
  5923. /**
  5924. * Draws the display object into the specified context ignoring its visible, alpha, shadow, and transform.
  5925. * Returns <code>true</code> if the draw was handled (useful for overriding functionality).
  5926. *
  5927. * NOTE: This method is mainly for internal use, though it may be useful for advanced uses.
  5928. * @method draw
  5929. * @param {CanvasRenderingContext2D} ctx The canvas 2D context object to draw into.
  5930. * @param {Boolean} [ignoreCache=false] Indicates whether the draw operation should ignore any current cache. For example,
  5931. * used for drawing the cache (to prevent it from simply drawing an existing cache back into itself).
  5932. * @return {Boolean}
  5933. **/
  5934. p.draw = function(ctx, ignoreCache) {
  5935. var cacheCanvas = this.cacheCanvas;
  5936. if (ignoreCache || !cacheCanvas) { return false; }
  5937. var scale = this._cacheScale;
  5938. ctx.drawImage(cacheCanvas, this._cacheOffsetX+this._filterOffsetX, this._cacheOffsetY+this._filterOffsetY, cacheCanvas.width/scale, cacheCanvas.height/scale);
  5939. return true;
  5940. };
  5941. /**
  5942. * Applies this display object's transformation, alpha, globalCompositeOperation, clipping path (mask), and shadow
  5943. * to the specified context. This is typically called prior to {{#crossLink "DisplayObject/draw"}}{{/crossLink}}.
  5944. * @method updateContext
  5945. * @param {CanvasRenderingContext2D} ctx The canvas 2D to update.
  5946. **/
  5947. p.updateContext = function(ctx) {
  5948. var o=this, mask=o.mask, mtx= o._props.matrix;
  5949. if (mask && mask.graphics && !mask.graphics.isEmpty()) {
  5950. mask.getMatrix(mtx);
  5951. ctx.transform(mtx.a, mtx.b, mtx.c, mtx.d, mtx.tx, mtx.ty);
  5952. mask.graphics.drawAsPath(ctx);
  5953. ctx.clip();
  5954. mtx.invert();
  5955. ctx.transform(mtx.a, mtx.b, mtx.c, mtx.d, mtx.tx, mtx.ty);
  5956. }
  5957. this.getMatrix(mtx);
  5958. var tx = mtx.tx, ty = mtx.ty;
  5959. if (DisplayObject._snapToPixelEnabled && o.snapToPixel) {
  5960. tx = tx + (tx < 0 ? -0.5 : 0.5) | 0;
  5961. ty = ty + (ty < 0 ? -0.5 : 0.5) | 0;
  5962. }
  5963. ctx.transform(mtx.a, mtx.b, mtx.c, mtx.d, tx, ty);
  5964. ctx.globalAlpha *= o.alpha;
  5965. if (o.compositeOperation) { ctx.globalCompositeOperation = o.compositeOperation; }
  5966. if (o.shadow) { this._applyShadow(ctx, o.shadow); }
  5967. };
  5968. /**
  5969. * Draws the display object into a new canvas, which is then used for subsequent draws. For complex content
  5970. * that does not change frequently (ex. a Container with many children that do not move, or a complex vector Shape),
  5971. * this can provide for much faster rendering because the content does not need to be re-rendered each tick. The
  5972. * cached display object can be moved, rotated, faded, etc freely, however if its content changes, you must
  5973. * manually update the cache by calling <code>updateCache()</code> or <code>cache()</code> again. You must specify
  5974. * the cache area via the x, y, w, and h parameters. This defines the rectangle that will be rendered and cached
  5975. * using this display object's coordinates.
  5976. *
  5977. * <h4>Example</h4>
  5978. * For example if you defined a Shape that drew a circle at 0, 0 with a radius of 25:
  5979. *
  5980. * var shape = new createjs.Shape();
  5981. * shape.graphics.beginFill("#ff0000").drawCircle(0, 0, 25);
  5982. * myShape.cache(-25, -25, 50, 50);
  5983. *
  5984. * Note that filters need to be defined <em>before</em> the cache is applied. Check out the {{#crossLink "Filter"}}{{/crossLink}}
  5985. * class for more information. Some filters (ex. BlurFilter) will not work as expected in conjunction with the scale param.
  5986. *
  5987. * Usually, the resulting cacheCanvas will have the dimensions width*scale by height*scale, however some filters (ex. BlurFilter)
  5988. * will add padding to the canvas dimensions.
  5989. *
  5990. * @method cache
  5991. * @param {Number} x The x coordinate origin for the cache region.
  5992. * @param {Number} y The y coordinate origin for the cache region.
  5993. * @param {Number} width The width of the cache region.
  5994. * @param {Number} height The height of the cache region.
  5995. * @param {Number} [scale=1] The scale at which the cache will be created. For example, if you cache a vector shape using
  5996. * myShape.cache(0,0,100,100,2) then the resulting cacheCanvas will be 200x200 px. This lets you scale and rotate
  5997. * cached elements with greater fidelity. Default is 1.
  5998. **/
  5999. p.cache = function(x, y, width, height, scale) {
  6000. // draw to canvas.
  6001. scale = scale||1;
  6002. if (!this.cacheCanvas) { this.cacheCanvas = createjs.createCanvas?createjs.createCanvas():document.createElement("canvas"); }
  6003. this._cacheWidth = width;
  6004. this._cacheHeight = height;
  6005. this._cacheOffsetX = x;
  6006. this._cacheOffsetY = y;
  6007. this._cacheScale = scale;
  6008. this.updateCache();
  6009. };
  6010. /**
  6011. * Redraws the display object to its cache. Calling updateCache without an active cache will throw an error.
  6012. * If compositeOperation is null the current cache will be cleared prior to drawing. Otherwise the display object
  6013. * will be drawn over the existing cache using the specified compositeOperation.
  6014. *
  6015. * <h4>Example</h4>
  6016. * Clear the current graphics of a cached shape, draw some new instructions, and then update the cache. The new line
  6017. * will be drawn on top of the old one.
  6018. *
  6019. * // Not shown: Creating the shape, and caching it.
  6020. * shapeInstance.clear();
  6021. * shapeInstance.setStrokeStyle(3).beginStroke("#ff0000").moveTo(100, 100).lineTo(200,200);
  6022. * shapeInstance.updateCache();
  6023. *
  6024. * @method updateCache
  6025. * @param {String} compositeOperation The compositeOperation to use, or null to clear the cache and redraw it.
  6026. * <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#compositing">
  6027. * whatwg spec on compositing</a>.
  6028. **/
  6029. p.updateCache = function(compositeOperation) {
  6030. var cacheCanvas = this.cacheCanvas;
  6031. if (!cacheCanvas) { throw "cache() must be called before updateCache()"; }
  6032. var scale = this._cacheScale, offX = this._cacheOffsetX*scale, offY = this._cacheOffsetY*scale;
  6033. var w = this._cacheWidth, h = this._cacheHeight, ctx = cacheCanvas.getContext("2d");
  6034. var fBounds = this._getFilterBounds();
  6035. offX += (this._filterOffsetX = fBounds.x);
  6036. offY += (this._filterOffsetY = fBounds.y);
  6037. w = Math.ceil(w*scale) + fBounds.width;
  6038. h = Math.ceil(h*scale) + fBounds.height;
  6039. if (w != cacheCanvas.width || h != cacheCanvas.height) {
  6040. // TODO: it would be nice to preserve the content if there is a compositeOperation.
  6041. cacheCanvas.width = w;
  6042. cacheCanvas.height = h;
  6043. } else if (!compositeOperation) {
  6044. ctx.clearRect(0, 0, w+1, h+1);
  6045. }
  6046. ctx.save();
  6047. ctx.globalCompositeOperation = compositeOperation;
  6048. ctx.setTransform(scale, 0, 0, scale, -offX, -offY);
  6049. this.draw(ctx, true);
  6050. // TODO: filters and cache scale don't play well together at present.
  6051. this._applyFilters();
  6052. ctx.restore();
  6053. this.cacheID = DisplayObject._nextCacheID++;
  6054. };
  6055. /**
  6056. * Clears the current cache. See {{#crossLink "DisplayObject/cache"}}{{/crossLink}} for more information.
  6057. * @method uncache
  6058. **/
  6059. p.uncache = function() {
  6060. this._cacheDataURL = this.cacheCanvas = null;
  6061. this.cacheID = this._cacheOffsetX = this._cacheOffsetY = this._filterOffsetX = this._filterOffsetY = 0;
  6062. this._cacheScale = 1;
  6063. };
  6064. /**
  6065. * Returns a data URL for the cache, or null if this display object is not cached.
  6066. * Uses cacheID to ensure a new data URL is not generated if the cache has not changed.
  6067. * @method getCacheDataURL
  6068. * @return {String} The image data url for the cache.
  6069. **/
  6070. p.getCacheDataURL = function() {
  6071. if (!this.cacheCanvas) { return null; }
  6072. if (this.cacheID != this._cacheDataURLID) { this._cacheDataURL = this.cacheCanvas.toDataURL(); }
  6073. return this._cacheDataURL;
  6074. };
  6075. /**
  6076. * Transforms the specified x and y position from the coordinate space of the display object
  6077. * to the global (stage) coordinate space. For example, this could be used to position an HTML label
  6078. * over a specific point on a nested display object. Returns a Point instance with x and y properties
  6079. * correlating to the transformed coordinates on the stage.
  6080. *
  6081. * <h4>Example</h4>
  6082. *
  6083. * displayObject.x = 300;
  6084. * displayObject.y = 200;
  6085. * stage.addChild(displayObject);
  6086. * var point = displayObject.localToGlobal(100, 100);
  6087. * // Results in x=400, y=300
  6088. *
  6089. * @method localToGlobal
  6090. * @param {Number} x The x position in the source display object to transform.
  6091. * @param {Number} y The y position in the source display object to transform.
  6092. * @param {Point | Object} [pt] An object to copy the result into. If omitted a new Point object with x/y properties will be returned.
  6093. * @return {Point} A Point instance with x and y properties correlating to the transformed coordinates
  6094. * on the stage.
  6095. **/
  6096. p.localToGlobal = function(x, y, pt) {
  6097. return this.getConcatenatedMatrix(this._props.matrix).transformPoint(x,y, pt||new createjs.Point());
  6098. };
  6099. /**
  6100. * Transforms the specified x and y position from the global (stage) coordinate space to the
  6101. * coordinate space of the display object. For example, this could be used to determine
  6102. * the current mouse position within the display object. Returns a Point instance with x and y properties
  6103. * correlating to the transformed position in the display object's coordinate space.
  6104. *
  6105. * <h4>Example</h4>
  6106. *
  6107. * displayObject.x = 300;
  6108. * displayObject.y = 200;
  6109. * stage.addChild(displayObject);
  6110. * var point = displayObject.globalToLocal(100, 100);
  6111. * // Results in x=-200, y=-100
  6112. *
  6113. * @method globalToLocal
  6114. * @param {Number} x The x position on the stage to transform.
  6115. * @param {Number} y The y position on the stage to transform.
  6116. * @param {Point | Object} [pt] An object to copy the result into. If omitted a new Point object with x/y properties will be returned.
  6117. * @return {Point} A Point instance with x and y properties correlating to the transformed position in the
  6118. * display object's coordinate space.
  6119. **/
  6120. p.globalToLocal = function(x, y, pt) {
  6121. return this.getConcatenatedMatrix(this._props.matrix).invert().transformPoint(x,y, pt||new createjs.Point());
  6122. };
  6123. /**
  6124. * Transforms the specified x and y position from the coordinate space of this display object to the coordinate
  6125. * space of the target display object. Returns a Point instance with x and y properties correlating to the
  6126. * transformed position in the target's coordinate space. Effectively the same as using the following code with
  6127. * {{#crossLink "DisplayObject/localToGlobal"}}{{/crossLink}} and {{#crossLink "DisplayObject/globalToLocal"}}{{/crossLink}}.
  6128. *
  6129. * var pt = this.localToGlobal(x, y);
  6130. * pt = target.globalToLocal(pt.x, pt.y);
  6131. *
  6132. * @method localToLocal
  6133. * @param {Number} x The x position in the source display object to transform.
  6134. * @param {Number} y The y position on the source display object to transform.
  6135. * @param {DisplayObject} target The target display object to which the coordinates will be transformed.
  6136. * @param {Point | Object} [pt] An object to copy the result into. If omitted a new Point object with x/y properties will be returned.
  6137. * @return {Point} Returns a Point instance with x and y properties correlating to the transformed position
  6138. * in the target's coordinate space.
  6139. **/
  6140. p.localToLocal = function(x, y, target, pt) {
  6141. pt = this.localToGlobal(x, y, pt);
  6142. return target.globalToLocal(pt.x, pt.y, pt);
  6143. };
  6144. /**
  6145. * Shortcut method to quickly set the transform properties on the display object. All parameters are optional.
  6146. * Omitted parameters will have the default value set.
  6147. *
  6148. * <h4>Example</h4>
  6149. *
  6150. * displayObject.setTransform(100, 100, 2, 2);
  6151. *
  6152. * @method setTransform
  6153. * @param {Number} [x=0] The horizontal translation (x position) in pixels
  6154. * @param {Number} [y=0] The vertical translation (y position) in pixels
  6155. * @param {Number} [scaleX=1] The horizontal scale, as a percentage of 1
  6156. * @param {Number} [scaleY=1] the vertical scale, as a percentage of 1
  6157. * @param {Number} [rotation=0] The rotation, in degrees
  6158. * @param {Number} [skewX=0] The horizontal skew factor
  6159. * @param {Number} [skewY=0] The vertical skew factor
  6160. * @param {Number} [regX=0] The horizontal registration point in pixels
  6161. * @param {Number} [regY=0] The vertical registration point in pixels
  6162. * @return {DisplayObject} Returns this instance. Useful for chaining commands.
  6163. * @chainable
  6164. */
  6165. p.setTransform = function(x, y, scaleX, scaleY, rotation, skewX, skewY, regX, regY) {
  6166. this.x = x || 0;
  6167. this.y = y || 0;
  6168. this.scaleX = scaleX == null ? 1 : scaleX;
  6169. this.scaleY = scaleY == null ? 1 : scaleY;
  6170. this.rotation = rotation || 0;
  6171. this.skewX = skewX || 0;
  6172. this.skewY = skewY || 0;
  6173. this.regX = regX || 0;
  6174. this.regY = regY || 0;
  6175. return this;
  6176. };
  6177. /**
  6178. * Returns a matrix based on this object's current transform.
  6179. * @method getMatrix
  6180. * @param {Matrix2D} matrix Optional. A Matrix2D object to populate with the calculated values. If null, a new
  6181. * Matrix object is returned.
  6182. * @return {Matrix2D} A matrix representing this display object's transform.
  6183. **/
  6184. p.getMatrix = function(matrix) {
  6185. var o = this, mtx = matrix&&matrix.identity() || new createjs.Matrix2D();
  6186. 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);
  6187. };
  6188. /**
  6189. * Generates a Matrix2D object representing the combined transform of the display object and all of its
  6190. * parent Containers up to the highest level ancestor (usually the {{#crossLink "Stage"}}{{/crossLink}}). This can
  6191. * be used to transform positions between coordinate spaces, such as with {{#crossLink "DisplayObject/localToGlobal"}}{{/crossLink}}
  6192. * and {{#crossLink "DisplayObject/globalToLocal"}}{{/crossLink}}.
  6193. * @method getConcatenatedMatrix
  6194. * @param {Matrix2D} [matrix] A {{#crossLink "Matrix2D"}}{{/crossLink}} object to populate with the calculated values.
  6195. * If null, a new Matrix2D object is returned.
  6196. * @return {Matrix2D} The combined matrix.
  6197. **/
  6198. p.getConcatenatedMatrix = function(matrix) {
  6199. var o = this, mtx = this.getMatrix(matrix);
  6200. while (o = o.parent) {
  6201. mtx.prependMatrix(o.getMatrix(o._props.matrix));
  6202. }
  6203. return mtx;
  6204. };
  6205. /**
  6206. * Generates a DisplayProps object representing the combined display properties of the object and all of its
  6207. * parent Containers up to the highest level ancestor (usually the {{#crossLink "Stage"}}{{/crossLink}}).
  6208. * @method getConcatenatedDisplayProps
  6209. * @param {DisplayProps} [props] A {{#crossLink "DisplayProps"}}{{/crossLink}} object to populate with the calculated values.
  6210. * If null, a new DisplayProps object is returned.
  6211. * @return {DisplayProps} The combined display properties.
  6212. **/
  6213. p.getConcatenatedDisplayProps = function(props) {
  6214. props = props ? props.identity() : new createjs.DisplayProps();
  6215. var o = this, mtx = o.getMatrix(props.matrix);
  6216. do {
  6217. props.prepend(o.visible, o.alpha, o.shadow, o.compositeOperation);
  6218. // 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.
  6219. // this could be simplified (ie. just done as part of the prepend above) if we switched to using a pool.
  6220. if (o != this) { mtx.prependMatrix(o.getMatrix(o._props.matrix)); }
  6221. } while (o = o.parent);
  6222. return props;
  6223. };
  6224. /**
  6225. * Tests whether the display object intersects the specified point in <em>local</em> coordinates (ie. draws a pixel
  6226. * with alpha > 0 at the specified position). This ignores the alpha, shadow, hitArea, mask, and compositeOperation
  6227. * of the display object.
  6228. *
  6229. * <h4>Example</h4>
  6230. *
  6231. * var myShape = new createjs.Shape();
  6232. * myShape.graphics.beginFill("red").drawRect(100, 100, 20, 50);
  6233. *
  6234. * console.log(myShape.hitTest(10,10); // false
  6235. * console.log(myShape.hitTest(110, 25); // true
  6236. *
  6237. * Note that to use Stage coordinates (such as {{#crossLink "Stage/mouseX:property"}}{{/crossLink}}), they must
  6238. * first be converted to local coordinates:
  6239. *
  6240. * stage.addEventListener("stagemousedown", handleMouseDown);
  6241. * function handleMouseDown(event) {
  6242. * var p = myShape.globalToLocal(stage.mouseX, stage.mouseY);
  6243. * var hit = myShape.hitTest(p.x, p.y);
  6244. * }
  6245. *
  6246. * Shape-to-shape collision is not currently supported by EaselJS.
  6247. *
  6248. * @method hitTest
  6249. * @param {Number} x The x position to check in the display object's local coordinates.
  6250. * @param {Number} y The y position to check in the display object's local coordinates.
  6251. * @return {Boolean} A Boolean indicating whether a visible portion of the DisplayObject intersect the specified
  6252. * local Point.
  6253. */
  6254. p.hitTest = function(x, y) {
  6255. var ctx = DisplayObject._hitTestContext;
  6256. ctx.setTransform(1, 0, 0, 1, -x, -y);
  6257. this.draw(ctx);
  6258. var hit = this._testHit(ctx);
  6259. ctx.setTransform(1, 0, 0, 1, 0, 0);
  6260. ctx.clearRect(0, 0, 2, 2);
  6261. return hit;
  6262. };
  6263. /**
  6264. * Provides a chainable shortcut method for setting a number of properties on the instance.
  6265. *
  6266. * <h4>Example</h4>
  6267. *
  6268. * var myGraphics = new createjs.Graphics().beginFill("#ff0000").drawCircle(0, 0, 25);
  6269. * var shape = stage.addChild(new createjs.Shape()).set({graphics:myGraphics, x:100, y:100, alpha:0.5});
  6270. *
  6271. * @method set
  6272. * @param {Object} props A generic object containing properties to copy to the DisplayObject instance.
  6273. * @return {DisplayObject} Returns the instance the method is called on (useful for chaining calls.)
  6274. * @chainable
  6275. */
  6276. p.set = function(props) {
  6277. for (var n in props) { this[n] = props[n]; }
  6278. return this;
  6279. };
  6280. /**
  6281. * Returns a rectangle representing this object's bounds in its local coordinate system (ie. with no transformation).
  6282. * Objects that have been cached will return the bounds of the cache.
  6283. *
  6284. * Not all display objects can calculate their own bounds (ex. Shape). For these objects, you can use
  6285. * {{#crossLink "DisplayObject/setBounds"}}{{/crossLink}} so that they are included when calculating Container
  6286. * bounds.
  6287. *
  6288. * <table>
  6289. * <tr><td><b>All</b></td><td>
  6290. * All display objects support setting bounds manually using setBounds(). Likewise, display objects that
  6291. * have been cached using cache() will return the bounds of their cache. Manual and cache bounds will override
  6292. * the automatic calculations listed below.
  6293. * </td></tr>
  6294. * <tr><td><b>Bitmap</b></td><td>
  6295. * Returns the width and height of the sourceRect (if specified) or image, extending from (x=0,y=0).
  6296. * </td></tr>
  6297. * <tr><td><b>Sprite</b></td><td>
  6298. * Returns the bounds of the current frame. May have non-zero x/y if a frame registration point was specified
  6299. * in the spritesheet data. See also {{#crossLink "SpriteSheet/getFrameBounds"}}{{/crossLink}}
  6300. * </td></tr>
  6301. * <tr><td><b>Container</b></td><td>
  6302. * Returns the aggregate (combined) bounds of all children that return a non-null value from getBounds().
  6303. * </td></tr>
  6304. * <tr><td><b>Shape</b></td><td>
  6305. * Does not currently support automatic bounds calculations. Use setBounds() to manually define bounds.
  6306. * </td></tr>
  6307. * <tr><td><b>Text</b></td><td>
  6308. * Returns approximate bounds. Horizontal values (x/width) are quite accurate, but vertical values (y/height) are
  6309. * not, especially when using textBaseline values other than "top".
  6310. * </td></tr>
  6311. * <tr><td><b>BitmapText</b></td><td>
  6312. * Returns approximate bounds. Values will be more accurate if spritesheet frame registration points are close
  6313. * to (x=0,y=0).
  6314. * </td></tr>
  6315. * </table>
  6316. *
  6317. * Bounds can be expensive to calculate for some objects (ex. text, or containers with many children), and
  6318. * are recalculated each time you call getBounds(). You can prevent recalculation on static objects by setting the
  6319. * bounds explicitly:
  6320. *
  6321. * var bounds = obj.getBounds();
  6322. * obj.setBounds(bounds.x, bounds.y, bounds.width, bounds.height);
  6323. * // getBounds will now use the set values, instead of recalculating
  6324. *
  6325. * To reduce memory impact, the returned Rectangle instance may be reused internally; clone the instance or copy its
  6326. * values if you need to retain it.
  6327. *
  6328. * var myBounds = obj.getBounds().clone();
  6329. * // OR:
  6330. * myRect.copy(obj.getBounds());
  6331. *
  6332. * @method getBounds
  6333. * @return {Rectangle} A Rectangle instance representing the bounds, or null if bounds are not available for this
  6334. * object.
  6335. **/
  6336. p.getBounds = function() {
  6337. if (this._bounds) { return this._rectangle.copy(this._bounds); }
  6338. var cacheCanvas = this.cacheCanvas;
  6339. if (cacheCanvas) {
  6340. var scale = this._cacheScale;
  6341. return this._rectangle.setValues(this._cacheOffsetX, this._cacheOffsetY, cacheCanvas.width/scale, cacheCanvas.height/scale);
  6342. }
  6343. return null;
  6344. };
  6345. /**
  6346. * Returns a rectangle representing this object's bounds in its parent's coordinate system (ie. with transformations applied).
  6347. * Objects that have been cached will return the transformed bounds of the cache.
  6348. *
  6349. * Not all display objects can calculate their own bounds (ex. Shape). For these objects, you can use
  6350. * {{#crossLink "DisplayObject/setBounds"}}{{/crossLink}} so that they are included when calculating Container
  6351. * bounds.
  6352. *
  6353. * To reduce memory impact, the returned Rectangle instance may be reused internally; clone the instance or copy its
  6354. * values if you need to retain it.
  6355. *
  6356. * Container instances calculate aggregate bounds for all children that return bounds via getBounds.
  6357. * @method getTransformedBounds
  6358. * @return {Rectangle} A Rectangle instance representing the bounds, or null if bounds are not available for this object.
  6359. **/
  6360. p.getTransformedBounds = function() {
  6361. return this._getBounds();
  6362. };
  6363. /**
  6364. * Allows you to manually specify the bounds of an object that either cannot calculate their own bounds (ex. Shape &
  6365. * Text) for future reference, or so the object can be included in Container bounds. Manually set bounds will always
  6366. * override calculated bounds.
  6367. *
  6368. * The bounds should be specified in the object's local (untransformed) coordinates. For example, a Shape instance
  6369. * with a 25px radius circle centered at 0,0 would have bounds of (-25, -25, 50, 50).
  6370. * @method setBounds
  6371. * @param {Number} x The x origin of the bounds. Pass null to remove the manual bounds.
  6372. * @param {Number} y The y origin of the bounds.
  6373. * @param {Number} width The width of the bounds.
  6374. * @param {Number} height The height of the bounds.
  6375. **/
  6376. p.setBounds = function(x, y, width, height) {
  6377. if (x == null) { this._bounds = x; }
  6378. this._bounds = (this._bounds || new createjs.Rectangle()).setValues(x, y, width, height);
  6379. };
  6380. /**
  6381. * Returns a clone of this DisplayObject. Some properties that are specific to this instance's current context are
  6382. * reverted to their defaults (for example .parent). Caches are not maintained across clones, and some elements
  6383. * are copied by reference (masks, individual filter instances, hit area)
  6384. * @method clone
  6385. * @return {DisplayObject} A clone of the current DisplayObject instance.
  6386. **/
  6387. p.clone = function() {
  6388. return this._cloneProps(new DisplayObject());
  6389. };
  6390. /**
  6391. * Returns a string representation of this object.
  6392. * @method toString
  6393. * @return {String} a string representation of the instance.
  6394. **/
  6395. p.toString = function() {
  6396. return "[DisplayObject (name="+ this.name +")]";
  6397. };
  6398. // private methods:
  6399. // separated so it can be used more easily in subclasses:
  6400. /**
  6401. * @method _cloneProps
  6402. * @param {DisplayObject} o The DisplayObject instance which will have properties from the current DisplayObject
  6403. * instance copied into.
  6404. * @return {DisplayObject} o
  6405. * @protected
  6406. **/
  6407. p._cloneProps = function(o) {
  6408. o.alpha = this.alpha;
  6409. o.mouseEnabled = this.mouseEnabled;
  6410. o.tickEnabled = this.tickEnabled;
  6411. o.name = this.name;
  6412. o.regX = this.regX;
  6413. o.regY = this.regY;
  6414. o.rotation = this.rotation;
  6415. o.scaleX = this.scaleX;
  6416. o.scaleY = this.scaleY;
  6417. o.shadow = this.shadow;
  6418. o.skewX = this.skewX;
  6419. o.skewY = this.skewY;
  6420. o.visible = this.visible;
  6421. o.x = this.x;
  6422. o.y = this.y;
  6423. o.compositeOperation = this.compositeOperation;
  6424. o.snapToPixel = this.snapToPixel;
  6425. o.filters = this.filters==null?null:this.filters.slice(0);
  6426. o.mask = this.mask;
  6427. o.hitArea = this.hitArea;
  6428. o.cursor = this.cursor;
  6429. o._bounds = this._bounds;
  6430. return o;
  6431. };
  6432. /**
  6433. * @method _applyShadow
  6434. * @protected
  6435. * @param {CanvasRenderingContext2D} ctx
  6436. * @param {Shadow} shadow
  6437. **/
  6438. p._applyShadow = function(ctx, shadow) {
  6439. shadow = shadow || Shadow.identity;
  6440. ctx.shadowColor = shadow.color;
  6441. ctx.shadowOffsetX = shadow.offsetX;
  6442. ctx.shadowOffsetY = shadow.offsetY;
  6443. ctx.shadowBlur = shadow.blur;
  6444. };
  6445. /**
  6446. * @method _tick
  6447. * @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.
  6448. * @protected
  6449. **/
  6450. p._tick = function(evtObj) {
  6451. // because tick can be really performance sensitive, check for listeners before calling dispatchEvent.
  6452. var ls = this._listeners;
  6453. if (ls && ls["tick"]) {
  6454. // reset & reuse the event object to avoid construction / GC costs:
  6455. evtObj.target = null;
  6456. evtObj.propagationStopped = evtObj.immediatePropagationStopped = false;
  6457. this.dispatchEvent(evtObj);
  6458. }
  6459. };
  6460. /**
  6461. * @method _testHit
  6462. * @protected
  6463. * @param {CanvasRenderingContext2D} ctx
  6464. * @return {Boolean}
  6465. **/
  6466. p._testHit = function(ctx) {
  6467. try {
  6468. var hit = ctx.getImageData(0, 0, 1, 1).data[3] > 1;
  6469. } catch (e) {
  6470. if (!DisplayObject.suppressCrossDomainErrors) {
  6471. throw "An error has occurred. This is most likely due to security restrictions on reading canvas pixel data with local or cross-domain images.";
  6472. }
  6473. }
  6474. return hit;
  6475. };
  6476. /**
  6477. * @method _applyFilters
  6478. * @protected
  6479. **/
  6480. p._applyFilters = function() {
  6481. if (!this.filters || this.filters.length == 0 || !this.cacheCanvas) { return; }
  6482. var l = this.filters.length;
  6483. var ctx = this.cacheCanvas.getContext("2d");
  6484. var w = this.cacheCanvas.width;
  6485. var h = this.cacheCanvas.height;
  6486. for (var i=0; i<l; i++) {
  6487. this.filters[i].applyFilter(ctx, 0, 0, w, h);
  6488. }
  6489. };
  6490. /**
  6491. * @method _getFilterBounds
  6492. * @return {Rectangle}
  6493. * @protected
  6494. **/
  6495. p._getFilterBounds = function(rect) {
  6496. var l, filters = this.filters, bounds = this._rectangle.setValues(0,0,0,0);
  6497. if (!filters || !(l=filters.length)) { return bounds; }
  6498. for (var i=0; i<l; i++) {
  6499. var f = this.filters[i];
  6500. f.getBounds&&f.getBounds(bounds);
  6501. }
  6502. return bounds;
  6503. };
  6504. /**
  6505. * @method _getBounds
  6506. * @param {Matrix2D} matrix
  6507. * @param {Boolean} ignoreTransform If true, does not apply this object's transform.
  6508. * @return {Rectangle}
  6509. * @protected
  6510. **/
  6511. p._getBounds = function(matrix, ignoreTransform){
  6512. return this._transformBounds(this.getBounds(), matrix, ignoreTransform);
  6513. };
  6514. /**
  6515. * @method _transformBounds
  6516. * @param {Rectangle} bounds
  6517. * @param {Matrix2D} matrix
  6518. * @param {Boolean} ignoreTransform
  6519. * @return {Rectangle}
  6520. * @protected
  6521. **/
  6522. p._transformBounds = function(bounds, matrix, ignoreTransform) {
  6523. if (!bounds) { return bounds; }
  6524. var x = bounds.x, y = bounds.y, width = bounds.width, height = bounds.height, mtx = this._props.matrix;
  6525. mtx = ignoreTransform ? mtx.identity() : this.getMatrix(mtx);
  6526. if (x || y) { mtx.appendTransform(0,0,1,1,0,0,0,-x,-y); } // TODO: simplify this.
  6527. if (matrix) { mtx.prependMatrix(matrix); }
  6528. var x_a = width*mtx.a, x_b = width*mtx.b;
  6529. var y_c = height*mtx.c, y_d = height*mtx.d;
  6530. var tx = mtx.tx, ty = mtx.ty;
  6531. var minX = tx, maxX = tx, minY = ty, maxY = ty;
  6532. if ((x = x_a + tx) < minX) { minX = x; } else if (x > maxX) { maxX = x; }
  6533. if ((x = x_a + y_c + tx) < minX) { minX = x; } else if (x > maxX) { maxX = x; }
  6534. if ((x = y_c + tx) < minX) { minX = x; } else if (x > maxX) { maxX = x; }
  6535. if ((y = x_b + ty) < minY) { minY = y; } else if (y > maxY) { maxY = y; }
  6536. if ((y = x_b + y_d + ty) < minY) { minY = y; } else if (y > maxY) { maxY = y; }
  6537. if ((y = y_d + ty) < minY) { minY = y; } else if (y > maxY) { maxY = y; }
  6538. return bounds.setValues(minX, minY, maxX-minX, maxY-minY);
  6539. };
  6540. /**
  6541. * Indicates whether the display object has any mouse event listeners or a cursor.
  6542. * @method _isMouseOpaque
  6543. * @return {Boolean}
  6544. * @protected
  6545. **/
  6546. p._hasMouseEventListener = function() {
  6547. var evts = DisplayObject._MOUSE_EVENTS;
  6548. for (var i= 0, l=evts.length; i<l; i++) {
  6549. if (this.hasEventListener(evts[i])) { return true; }
  6550. }
  6551. return !!this.cursor;
  6552. };
  6553. createjs.DisplayObject = createjs.promote(DisplayObject, "EventDispatcher");
  6554. }());
  6555. //##############################################################################
  6556. // Container.js
  6557. //##############################################################################
  6558. this.createjs = this.createjs||{};
  6559. (function() {
  6560. "use strict";
  6561. // constructor:
  6562. /**
  6563. * A Container is a nestable display list that allows you to work with compound display elements. For example you could
  6564. * group arm, leg, torso and head {{#crossLink "Bitmap"}}{{/crossLink}} instances together into a Person Container, and
  6565. * transform them as a group, while still being able to move the individual parts relative to each other. Children of
  6566. * containers have their <code>transform</code> and <code>alpha</code> properties concatenated with their parent
  6567. * Container.
  6568. *
  6569. * For example, a {{#crossLink "Shape"}}{{/crossLink}} with x=100 and alpha=0.5, placed in a Container with <code>x=50</code>
  6570. * and <code>alpha=0.7</code> will be rendered to the canvas at <code>x=150</code> and <code>alpha=0.35</code>.
  6571. * Containers have some overhead, so you generally shouldn't create a Container to hold a single child.
  6572. *
  6573. * <h4>Example</h4>
  6574. *
  6575. * var container = new createjs.Container();
  6576. * container.addChild(bitmapInstance, shapeInstance);
  6577. * container.x = 100;
  6578. *
  6579. * @class Container
  6580. * @extends DisplayObject
  6581. * @constructor
  6582. **/
  6583. function Container() {
  6584. this.DisplayObject_constructor();
  6585. // public properties:
  6586. /**
  6587. * The array of children in the display list. You should usually use the child management methods such as
  6588. * {{#crossLink "Container/addChild"}}{{/crossLink}}, {{#crossLink "Container/removeChild"}}{{/crossLink}},
  6589. * {{#crossLink "Container/swapChildren"}}{{/crossLink}}, etc, rather than accessing this directly, but it is
  6590. * included for advanced uses.
  6591. * @property children
  6592. * @type Array
  6593. * @default null
  6594. **/
  6595. this.children = [];
  6596. /**
  6597. * Indicates whether the children of this container are independently enabled for mouse/pointer interaction.
  6598. * If false, the children will be aggregated under the container - for example, a click on a child shape would
  6599. * trigger a click event on the container.
  6600. * @property mouseChildren
  6601. * @type Boolean
  6602. * @default true
  6603. **/
  6604. this.mouseChildren = true;
  6605. /**
  6606. * If false, the tick will not be propagated to children of this Container. This can provide some performance benefits.
  6607. * In addition to preventing the "tick" event from being dispatched, it will also prevent tick related updates
  6608. * on some display objects (ex. Sprite & MovieClip frame advancing, DOMElement visibility handling).
  6609. * @property tickChildren
  6610. * @type Boolean
  6611. * @default true
  6612. **/
  6613. this.tickChildren = true;
  6614. }
  6615. var p = createjs.extend(Container, createjs.DisplayObject);
  6616. // getter / setters:
  6617. /**
  6618. * Use the {{#crossLink "Container/numChildren:property"}}{{/crossLink}} property instead.
  6619. * @method getNumChildren
  6620. * @return {Number}
  6621. * @deprecated
  6622. **/
  6623. p.getNumChildren = function() {
  6624. return this.children.length;
  6625. };
  6626. /**
  6627. * Returns the number of children in the container.
  6628. * @property numChildren
  6629. * @type {Number}
  6630. * @readonly
  6631. **/
  6632. try {
  6633. Object.defineProperties(p, {
  6634. numChildren: { get: p.getNumChildren }
  6635. });
  6636. } catch (e) {}
  6637. // public methods:
  6638. /**
  6639. * Constructor alias for backwards compatibility. This method will be removed in future versions.
  6640. * Subclasses should be updated to use {{#crossLink "Utility Methods/extends"}}{{/crossLink}}.
  6641. * @method initialize
  6642. * @deprecated in favour of `createjs.promote()`
  6643. **/
  6644. p.initialize = Container; // TODO: deprecated.
  6645. /**
  6646. * Returns true or false indicating whether the display object would be visible if drawn to a canvas.
  6647. * This does not account for whether it would be visible within the boundaries of the stage.
  6648. *
  6649. * NOTE: This method is mainly for internal use, though it may be useful for advanced uses.
  6650. * @method isVisible
  6651. * @return {Boolean} Boolean indicating whether the display object would be visible if drawn to a canvas
  6652. **/
  6653. p.isVisible = function() {
  6654. var hasContent = this.cacheCanvas || this.children.length;
  6655. return !!(this.visible && this.alpha > 0 && this.scaleX != 0 && this.scaleY != 0 && hasContent);
  6656. };
  6657. /**
  6658. * Draws the display object into the specified context ignoring its visible, alpha, shadow, and transform.
  6659. * Returns true if the draw was handled (useful for overriding functionality).
  6660. *
  6661. * NOTE: This method is mainly for internal use, though it may be useful for advanced uses.
  6662. * @method draw
  6663. * @param {CanvasRenderingContext2D} ctx The canvas 2D context object to draw into.
  6664. * @param {Boolean} [ignoreCache=false] Indicates whether the draw operation should ignore any current cache.
  6665. * For example, used for drawing the cache (to prevent it from simply drawing an existing cache back
  6666. * into itself).
  6667. **/
  6668. p.draw = function(ctx, ignoreCache) {
  6669. if (this.DisplayObject_draw(ctx, ignoreCache)) { return true; }
  6670. // this ensures we don't have issues with display list changes that occur during a draw:
  6671. var list = this.children.slice();
  6672. for (var i=0,l=list.length; i<l; i++) {
  6673. var child = list[i];
  6674. if (!child.isVisible()) { continue; }
  6675. // draw the child:
  6676. ctx.save();
  6677. child.updateContext(ctx);
  6678. child.draw(ctx);
  6679. ctx.restore();
  6680. }
  6681. return true;
  6682. };
  6683. /**
  6684. * Adds a child to the top of the display list.
  6685. *
  6686. * <h4>Example</h4>
  6687. *
  6688. * container.addChild(bitmapInstance);
  6689. *
  6690. * You can also add multiple children at once:
  6691. *
  6692. * container.addChild(bitmapInstance, shapeInstance, textInstance);
  6693. *
  6694. * @method addChild
  6695. * @param {DisplayObject} child The display object to add.
  6696. * @return {DisplayObject} The child that was added, or the last child if multiple children were added.
  6697. **/
  6698. p.addChild = function(child) {
  6699. if (child == null) { return child; }
  6700. var l = arguments.length;
  6701. if (l > 1) {
  6702. for (var i=0; i<l; i++) { this.addChild(arguments[i]); }
  6703. return arguments[l-1];
  6704. }
  6705. if (child.parent) { child.parent.removeChild(child); }
  6706. child.parent = this;
  6707. this.children.push(child);
  6708. child.dispatchEvent("added");
  6709. return child;
  6710. };
  6711. /**
  6712. * Adds a child to the display list at the specified index, bumping children at equal or greater indexes up one, and
  6713. * setting its parent to this Container.
  6714. *
  6715. * <h4>Example</h4>
  6716. *
  6717. * addChildAt(child1, index);
  6718. *
  6719. * You can also add multiple children, such as:
  6720. *
  6721. * addChildAt(child1, child2, ..., index);
  6722. *
  6723. * The index must be between 0 and numChildren. For example, to add myShape under otherShape in the display list,
  6724. * you could use:
  6725. *
  6726. * container.addChildAt(myShape, container.getChildIndex(otherShape));
  6727. *
  6728. * This would also bump otherShape's index up by one. Fails silently if the index is out of range.
  6729. *
  6730. * @method addChildAt
  6731. * @param {DisplayObject} child The display object to add.
  6732. * @param {Number} index The index to add the child at.
  6733. * @return {DisplayObject} Returns the last child that was added, or the last child if multiple children were added.
  6734. **/
  6735. p.addChildAt = function(child, index) {
  6736. var l = arguments.length;
  6737. var indx = arguments[l-1]; // can't use the same name as the index param or it replaces arguments[1]
  6738. if (indx < 0 || indx > this.children.length) { return arguments[l-2]; }
  6739. if (l > 2) {
  6740. for (var i=0; i<l-1; i++) { this.addChildAt(arguments[i], indx+i); }
  6741. return arguments[l-2];
  6742. }
  6743. if (child.parent) { child.parent.removeChild(child); }
  6744. child.parent = this;
  6745. this.children.splice(index, 0, child);
  6746. child.dispatchEvent("added");
  6747. return child;
  6748. };
  6749. /**
  6750. * Removes the specified child from the display list. Note that it is faster to use removeChildAt() if the index is
  6751. * already known.
  6752. *
  6753. * <h4>Example</h4>
  6754. *
  6755. * container.removeChild(child);
  6756. *
  6757. * You can also remove multiple children:
  6758. *
  6759. * removeChild(child1, child2, ...);
  6760. *
  6761. * Returns true if the child (or children) was removed, or false if it was not in the display list.
  6762. * @method removeChild
  6763. * @param {DisplayObject} child The child to remove.
  6764. * @return {Boolean} true if the child (or children) was removed, or false if it was not in the display list.
  6765. **/
  6766. p.removeChild = function(child) {
  6767. var l = arguments.length;
  6768. if (l > 1) {
  6769. var good = true;
  6770. for (var i=0; i<l; i++) { good = good && this.removeChild(arguments[i]); }
  6771. return good;
  6772. }
  6773. return this.removeChildAt(createjs.indexOf(this.children, child));
  6774. };
  6775. /**
  6776. * Removes the child at the specified index from the display list, and sets its parent to null.
  6777. *
  6778. * <h4>Example</h4>
  6779. *
  6780. * container.removeChildAt(2);
  6781. *
  6782. * You can also remove multiple children:
  6783. *
  6784. * container.removeChild(2, 7, ...)
  6785. *
  6786. * Returns true if the child (or children) was removed, or false if any index was out of range.
  6787. * @method removeChildAt
  6788. * @param {Number} index The index of the child to remove.
  6789. * @return {Boolean} true if the child (or children) was removed, or false if any index was out of range.
  6790. **/
  6791. p.removeChildAt = function(index) {
  6792. var l = arguments.length;
  6793. if (l > 1) {
  6794. var a = [];
  6795. for (var i=0; i<l; i++) { a[i] = arguments[i]; }
  6796. a.sort(function(a, b) { return b-a; });
  6797. var good = true;
  6798. for (var i=0; i<l; i++) { good = good && this.removeChildAt(a[i]); }
  6799. return good;
  6800. }
  6801. if (index < 0 || index > this.children.length-1) { return false; }
  6802. var child = this.children[index];
  6803. if (child) { child.parent = null; }
  6804. this.children.splice(index, 1);
  6805. child.dispatchEvent("removed");
  6806. return true;
  6807. };
  6808. /**
  6809. * Removes all children from the display list.
  6810. *
  6811. * <h4>Example</h4>
  6812. *
  6813. * container.removeAllChildren();
  6814. *
  6815. * @method removeAllChildren
  6816. **/
  6817. p.removeAllChildren = function() {
  6818. var kids = this.children;
  6819. while (kids.length) { this.removeChildAt(0); }
  6820. };
  6821. /**
  6822. * Returns the child at the specified index.
  6823. *
  6824. * <h4>Example</h4>
  6825. *
  6826. * container.getChildAt(2);
  6827. *
  6828. * @method getChildAt
  6829. * @param {Number} index The index of the child to return.
  6830. * @return {DisplayObject} The child at the specified index. Returns null if there is no child at the index.
  6831. **/
  6832. p.getChildAt = function(index) {
  6833. return this.children[index];
  6834. };
  6835. /**
  6836. * Returns the child with the specified name.
  6837. * @method getChildByName
  6838. * @param {String} name The name of the child to return.
  6839. * @return {DisplayObject} The child with the specified name.
  6840. **/
  6841. p.getChildByName = function(name) {
  6842. var kids = this.children;
  6843. for (var i=0,l=kids.length;i<l;i++) {
  6844. if(kids[i].name == name) { return kids[i]; }
  6845. }
  6846. return null;
  6847. };
  6848. /**
  6849. * Performs an array sort operation on the child list.
  6850. *
  6851. * <h4>Example: Display children with a higher y in front.</h4>
  6852. *
  6853. * var sortFunction = function(obj1, obj2, options) {
  6854. * if (obj1.y > obj2.y) { return 1; }
  6855. * if (obj1.y < obj2.y) { return -1; }
  6856. * return 0;
  6857. * }
  6858. * container.sortChildren(sortFunction);
  6859. *
  6860. * @method sortChildren
  6861. * @param {Function} sortFunction the function to use to sort the child list. See JavaScript's <code>Array.sort</code>
  6862. * documentation for details.
  6863. **/
  6864. p.sortChildren = function(sortFunction) {
  6865. this.children.sort(sortFunction);
  6866. };
  6867. /**
  6868. * Returns the index of the specified child in the display list, or -1 if it is not in the display list.
  6869. *
  6870. * <h4>Example</h4>
  6871. *
  6872. * var index = container.getChildIndex(child);
  6873. *
  6874. * @method getChildIndex
  6875. * @param {DisplayObject} child The child to return the index of.
  6876. * @return {Number} The index of the specified child. -1 if the child is not found.
  6877. **/
  6878. p.getChildIndex = function(child) {
  6879. return createjs.indexOf(this.children, child);
  6880. };
  6881. /**
  6882. * Swaps the children at the specified indexes. Fails silently if either index is out of range.
  6883. * @method swapChildrenAt
  6884. * @param {Number} index1
  6885. * @param {Number} index2
  6886. **/
  6887. p.swapChildrenAt = function(index1, index2) {
  6888. var kids = this.children;
  6889. var o1 = kids[index1];
  6890. var o2 = kids[index2];
  6891. if (!o1 || !o2) { return; }
  6892. kids[index1] = o2;
  6893. kids[index2] = o1;
  6894. };
  6895. /**
  6896. * Swaps the specified children's depth in the display list. Fails silently if either child is not a child of this
  6897. * Container.
  6898. * @method swapChildren
  6899. * @param {DisplayObject} child1
  6900. * @param {DisplayObject} child2
  6901. **/
  6902. p.swapChildren = function(child1, child2) {
  6903. var kids = this.children;
  6904. var index1,index2;
  6905. for (var i=0,l=kids.length;i<l;i++) {
  6906. if (kids[i] == child1) { index1 = i; }
  6907. if (kids[i] == child2) { index2 = i; }
  6908. if (index1 != null && index2 != null) { break; }
  6909. }
  6910. if (i==l) { return; } // TODO: throw error?
  6911. kids[index1] = child2;
  6912. kids[index2] = child1;
  6913. };
  6914. /**
  6915. * 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.
  6916. * @param {DisplayObject} child
  6917. * @param {Number} index
  6918. * @method setChildIndex
  6919. **/
  6920. p.setChildIndex = function(child, index) {
  6921. var kids = this.children, l=kids.length;
  6922. if (child.parent != this || index < 0 || index >= l) { return; }
  6923. for (var i=0;i<l;i++) {
  6924. if (kids[i] == child) { break; }
  6925. }
  6926. if (i==l || i == index) { return; }
  6927. kids.splice(i,1);
  6928. kids.splice(index,0,child);
  6929. };
  6930. /**
  6931. * Returns true if the specified display object either is this container or is a descendent (child, grandchild, etc)
  6932. * of this container.
  6933. * @method contains
  6934. * @param {DisplayObject} child The DisplayObject to be checked.
  6935. * @return {Boolean} true if the specified display object either is this container or is a descendent.
  6936. **/
  6937. p.contains = function(child) {
  6938. while (child) {
  6939. if (child == this) { return true; }
  6940. child = child.parent;
  6941. }
  6942. return false;
  6943. };
  6944. /**
  6945. * Tests whether the display object intersects the specified local point (ie. draws a pixel with alpha > 0 at the
  6946. * specified position). This ignores the alpha, shadow and compositeOperation of the display object, and all
  6947. * transform properties including regX/Y.
  6948. * @method hitTest
  6949. * @param {Number} x The x position to check in the display object's local coordinates.
  6950. * @param {Number} y The y position to check in the display object's local coordinates.
  6951. * @return {Boolean} A Boolean indicating whether there is a visible section of a DisplayObject that overlaps the specified
  6952. * coordinates.
  6953. **/
  6954. p.hitTest = function(x, y) {
  6955. // TODO: optimize to use the fast cache check where possible.
  6956. return (this.getObjectUnderPoint(x, y) != null);
  6957. };
  6958. /**
  6959. * Returns an array of all display objects under the specified coordinates that are in this container's display
  6960. * list. This routine ignores any display objects with {{#crossLink "DisplayObject/mouseEnabled:property"}}{{/crossLink}}
  6961. * set to `false`. The array will be sorted in order of visual depth, with the top-most display object at index 0.
  6962. * This uses shape based hit detection, and can be an expensive operation to run, so it is best to use it carefully.
  6963. * For example, if testing for objects under the mouse, test on tick (instead of on {{#crossLink "DisplayObject/mousemove:event"}}{{/crossLink}}),
  6964. * and only if the mouse's position has changed.
  6965. *
  6966. * <ul>
  6967. * <li>By default (mode=0) this method evaluates all display objects.</li>
  6968. * <li>By setting the `mode` parameter to `1`, the {{#crossLink "DisplayObject/mouseEnabled:property"}}{{/crossLink}}
  6969. * and {{#crossLink "mouseChildren:property"}}{{/crossLink}} properties will be respected.</li>
  6970. * <li>Setting the `mode` to `2` additionally excludes display objects that do not have active mouse event
  6971. * listeners or a {{#crossLink "DisplayObject:cursor:property"}}{{/crossLink}} property. That is, only objects
  6972. * that would normally intercept mouse interaction will be included. This can significantly improve performance
  6973. * in some cases by reducing the number of display objects that need to be tested.</li>
  6974. * </li>
  6975. *
  6976. * This method accounts for both {{#crossLink "DisplayObject/hitArea:property"}}{{/crossLink}} and {{#crossLink "DisplayObject/mask:property"}}{{/crossLink}}.
  6977. * @method getObjectsUnderPoint
  6978. * @param {Number} x The x position in the container to test.
  6979. * @param {Number} y The y position in the container to test.
  6980. * @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.
  6981. * @return {Array} An Array of DisplayObjects under the specified coordinates.
  6982. **/
  6983. p.getObjectsUnderPoint = function(x, y, mode) {
  6984. var arr = [];
  6985. var pt = this.localToGlobal(x, y);
  6986. this._getObjectsUnderPoint(pt.x, pt.y, arr, mode>0, mode==1);
  6987. return arr;
  6988. };
  6989. /**
  6990. * Similar to {{#crossLink "Container/getObjectsUnderPoint"}}{{/crossLink}}, but returns only the top-most display
  6991. * object. This runs significantly faster than <code>getObjectsUnderPoint()</code>, but is still potentially an expensive
  6992. * operation. See {{#crossLink "Container/getObjectsUnderPoint"}}{{/crossLink}} for more information.
  6993. * @method getObjectUnderPoint
  6994. * @param {Number} x The x position in the container to test.
  6995. * @param {Number} y The y position in the container to test.
  6996. * @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.
  6997. * @return {DisplayObject} The top-most display object under the specified coordinates.
  6998. **/
  6999. p.getObjectUnderPoint = function(x, y, mode) {
  7000. var pt = this.localToGlobal(x, y);
  7001. return this._getObjectsUnderPoint(pt.x, pt.y, null, mode>0, mode==1);
  7002. };
  7003. /**
  7004. * Docced in superclass.
  7005. */
  7006. p.getBounds = function() {
  7007. return this._getBounds(null, true);
  7008. };
  7009. /**
  7010. * Docced in superclass.
  7011. */
  7012. p.getTransformedBounds = function() {
  7013. return this._getBounds();
  7014. };
  7015. /**
  7016. * Returns a clone of this Container. Some properties that are specific to this instance's current context are
  7017. * reverted to their defaults (for example .parent).
  7018. * @method clone
  7019. * @param {Boolean} [recursive=false] If true, all of the descendants of this container will be cloned recursively. If false, the
  7020. * properties of the container will be cloned, but the new instance will not have any children.
  7021. * @return {Container} A clone of the current Container instance.
  7022. **/
  7023. p.clone = function(recursive) {
  7024. var o = this._cloneProps(new Container());
  7025. if (recursive) { this._cloneChildren(o); }
  7026. return o;
  7027. };
  7028. /**
  7029. * Returns a string representation of this object.
  7030. * @method toString
  7031. * @return {String} a string representation of the instance.
  7032. **/
  7033. p.toString = function() {
  7034. return "[Container (name="+ this.name +")]";
  7035. };
  7036. // private methods:
  7037. /**
  7038. * @method _tick
  7039. * @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.
  7040. * @protected
  7041. **/
  7042. p._tick = function(evtObj) {
  7043. if (this.tickChildren) {
  7044. for (var i=this.children.length-1; i>=0; i--) {
  7045. var child = this.children[i];
  7046. if (child.tickEnabled && child._tick) { child._tick(evtObj); }
  7047. }
  7048. }
  7049. this.DisplayObject__tick(evtObj);
  7050. };
  7051. /**
  7052. * Recursively clones all children of this container, and adds them to the target container.
  7053. * @method cloneChildren
  7054. * @protected
  7055. * @param {Container} o The target container.
  7056. **/
  7057. p._cloneChildren = function(o) {
  7058. if (o.children.length) { o.removeAllChildren(); }
  7059. var arr = o.children;
  7060. for (var i=0, l=this.children.length; i<l; i++) {
  7061. var clone = this.children[i].clone(true);
  7062. clone.parent = o;
  7063. arr.push(clone);
  7064. }
  7065. };
  7066. /**
  7067. * @method _getObjectsUnderPoint
  7068. * @param {Number} x
  7069. * @param {Number} y
  7070. * @param {Array} arr
  7071. * @param {Boolean} mouse If true, it will respect mouse interaction properties like mouseEnabled, mouseChildren, and active listeners.
  7072. * @param {Boolean} activeListener If true, there is an active mouse event listener on a parent object.
  7073. * @param {Number} currentDepth Indicates the current depth of the search.
  7074. * @return {DisplayObject}
  7075. * @protected
  7076. **/
  7077. p._getObjectsUnderPoint = function(x, y, arr, mouse, activeListener, currentDepth) {
  7078. currentDepth = currentDepth || 0;
  7079. if (!currentDepth && !this._testMask(this, x, y)) { return null; }
  7080. var mtx, ctx = createjs.DisplayObject._hitTestContext;
  7081. activeListener = activeListener || (mouse&&this._hasMouseEventListener());
  7082. // draw children one at a time, and check if we get a hit:
  7083. var children = this.children, l = children.length;
  7084. for (var i=l-1; i>=0; i--) {
  7085. var child = children[i];
  7086. var hitArea = child.hitArea;
  7087. if (!child.visible || (!hitArea && !child.isVisible()) || (mouse && !child.mouseEnabled)) { continue; }
  7088. if (!hitArea && !this._testMask(child, x, y)) { continue; }
  7089. // if a child container has a hitArea then we only need to check its hitArea, so we can treat it as a normal DO:
  7090. if (!hitArea && child instanceof Container) {
  7091. var result = child._getObjectsUnderPoint(x, y, arr, mouse, activeListener, currentDepth+1);
  7092. if (!arr && result) { return (mouse && !this.mouseChildren) ? this : result; }
  7093. } else {
  7094. if (mouse && !activeListener && !child._hasMouseEventListener()) { continue; }
  7095. // 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.
  7096. var props = child.getConcatenatedDisplayProps(child._props);
  7097. mtx = props.matrix;
  7098. if (hitArea) {
  7099. mtx.appendMatrix(hitArea.getMatrix(hitArea._props.matrix));
  7100. props.alpha = hitArea.alpha;
  7101. }
  7102. ctx.globalAlpha = props.alpha;
  7103. ctx.setTransform(mtx.a, mtx.b, mtx.c, mtx.d, mtx.tx-x, mtx.ty-y);
  7104. (hitArea||child).draw(ctx);
  7105. if (!this._testHit(ctx)) { continue; }
  7106. ctx.setTransform(1, 0, 0, 1, 0, 0);
  7107. ctx.clearRect(0, 0, 2, 2);
  7108. if (arr) { arr.push(child); }
  7109. else { return (mouse && !this.mouseChildren) ? this : child; }
  7110. }
  7111. }
  7112. return null;
  7113. };
  7114. /**
  7115. * @method _testMask
  7116. * @param {DisplayObject} target
  7117. * @param {Number} x
  7118. * @param {Number} y
  7119. * @return {Boolean} Indicates whether the x/y is within the masked region.
  7120. * @protected
  7121. **/
  7122. p._testMask = function(target, x, y) {
  7123. var mask = target.mask;
  7124. if (!mask || !mask.graphics || mask.graphics.isEmpty()) { return true; }
  7125. var mtx = this._props.matrix, parent = target.parent;
  7126. mtx = parent ? parent.getConcatenatedMatrix(mtx) : mtx.identity();
  7127. mtx = mask.getMatrix(mask._props.matrix).prependMatrix(mtx);
  7128. var ctx = createjs.DisplayObject._hitTestContext;
  7129. ctx.setTransform(mtx.a, mtx.b, mtx.c, mtx.d, mtx.tx-x, mtx.ty-y);
  7130. // draw the mask as a solid fill:
  7131. mask.graphics.drawAsPath(ctx);
  7132. ctx.fillStyle = "#000";
  7133. ctx.fill();
  7134. if (!this._testHit(ctx)) { return false; }
  7135. ctx.setTransform(1, 0, 0, 1, 0, 0);
  7136. ctx.clearRect(0, 0, 2, 2);
  7137. return true;
  7138. };
  7139. /**
  7140. * @method _getBounds
  7141. * @param {Matrix2D} matrix
  7142. * @param {Boolean} ignoreTransform If true, does not apply this object's transform.
  7143. * @return {Rectangle}
  7144. * @protected
  7145. **/
  7146. p._getBounds = function(matrix, ignoreTransform) {
  7147. var bounds = this.DisplayObject_getBounds();
  7148. if (bounds) { return this._transformBounds(bounds, matrix, ignoreTransform); }
  7149. var mtx = this._props.matrix;
  7150. mtx = ignoreTransform ? mtx.identity() : this.getMatrix(mtx);
  7151. if (matrix) { mtx.prependMatrix(matrix); }
  7152. var l = this.children.length, rect=null;
  7153. for (var i=0; i<l; i++) {
  7154. var child = this.children[i];
  7155. if (!child.visible || !(bounds = child._getBounds(mtx))) { continue; }
  7156. if (rect) { rect.extend(bounds.x, bounds.y, bounds.width, bounds.height); }
  7157. else { rect = bounds.clone(); }
  7158. }
  7159. return rect;
  7160. };
  7161. createjs.Container = createjs.promote(Container, "DisplayObject");
  7162. }());
  7163. //##############################################################################
  7164. // Stage.js
  7165. //##############################################################################
  7166. this.createjs = this.createjs||{};
  7167. (function() {
  7168. "use strict";
  7169. // constructor:
  7170. /**
  7171. * A stage is the root level {{#crossLink "Container"}}{{/crossLink}} for a display list. Each time its {{#crossLink "Stage/tick"}}{{/crossLink}}
  7172. * method is called, it will render its display list to its target canvas.
  7173. *
  7174. * <h4>Example</h4>
  7175. * This example creates a stage, adds a child to it, then uses {{#crossLink "Ticker"}}{{/crossLink}} to update the child
  7176. * and redraw the stage using {{#crossLink "Stage/update"}}{{/crossLink}}.
  7177. *
  7178. * var stage = new createjs.Stage("canvasElementId");
  7179. * var image = new createjs.Bitmap("imagePath.png");
  7180. * stage.addChild(image);
  7181. * createjs.Ticker.addEventListener("tick", handleTick);
  7182. * function handleTick(event) {
  7183. * image.x += 10;
  7184. * stage.update();
  7185. * }
  7186. *
  7187. * @class Stage
  7188. * @extends Container
  7189. * @constructor
  7190. * @param {HTMLCanvasElement | String | Object} canvas A canvas object that the Stage will render to, or the string id
  7191. * of a canvas object in the current document.
  7192. **/
  7193. function Stage(canvas) {
  7194. this.Container_constructor();
  7195. // public properties:
  7196. /**
  7197. * Indicates whether the stage should automatically clear the canvas before each render. You can set this to <code>false</code>
  7198. * to manually control clearing (for generative art, or when pointing multiple stages at the same canvas for
  7199. * example).
  7200. *
  7201. * <h4>Example</h4>
  7202. *
  7203. * var stage = new createjs.Stage("canvasId");
  7204. * stage.autoClear = false;
  7205. *
  7206. * @property autoClear
  7207. * @type Boolean
  7208. * @default true
  7209. **/
  7210. this.autoClear = true;
  7211. /**
  7212. * The canvas the stage will render to. Multiple stages can share a single canvas, but you must disable autoClear for all but the
  7213. * first stage that will be ticked (or they will clear each other's render).
  7214. *
  7215. * When changing the canvas property you must disable the events on the old canvas, and enable events on the
  7216. * new canvas or mouse events will not work as expected. For example:
  7217. *
  7218. * myStage.enableDOMEvents(false);
  7219. * myStage.canvas = anotherCanvas;
  7220. * myStage.enableDOMEvents(true);
  7221. *
  7222. * @property canvas
  7223. * @type HTMLCanvasElement | Object
  7224. **/
  7225. this.canvas = (typeof canvas == "string") ? document.getElementById(canvas) : canvas;
  7226. /**
  7227. * The current mouse X position on the canvas. If the mouse leaves the canvas, this will indicate the most recent
  7228. * position over the canvas, and mouseInBounds will be set to false.
  7229. * @property mouseX
  7230. * @type Number
  7231. * @readonly
  7232. **/
  7233. this.mouseX = 0;
  7234. /**
  7235. * The current mouse Y position on the canvas. If the mouse leaves the canvas, this will indicate the most recent
  7236. * position over the canvas, and mouseInBounds will be set to false.
  7237. * @property mouseY
  7238. * @type Number
  7239. * @readonly
  7240. **/
  7241. this.mouseY = 0;
  7242. /**
  7243. * Specifies the area of the stage to affect when calling update. This can be use to selectively
  7244. * re-draw specific regions of the canvas. If null, the whole canvas area is drawn.
  7245. * @property drawRect
  7246. * @type {Rectangle}
  7247. */
  7248. this.drawRect = null;
  7249. /**
  7250. * Indicates whether display objects should be rendered on whole pixels. You can set the
  7251. * {{#crossLink "DisplayObject/snapToPixel"}}{{/crossLink}} property of
  7252. * display objects to false to enable/disable this behaviour on a per instance basis.
  7253. * @property snapToPixelEnabled
  7254. * @type Boolean
  7255. * @default false
  7256. **/
  7257. this.snapToPixelEnabled = false;
  7258. /**
  7259. * Indicates whether the mouse is currently within the bounds of the canvas.
  7260. * @property mouseInBounds
  7261. * @type Boolean
  7262. * @default false
  7263. **/
  7264. this.mouseInBounds = false;
  7265. /**
  7266. * If true, tick callbacks will be called on all display objects on the stage prior to rendering to the canvas.
  7267. * @property tickOnUpdate
  7268. * @type Boolean
  7269. * @default true
  7270. **/
  7271. this.tickOnUpdate = true;
  7272. /**
  7273. * If true, mouse move events will continue to be called when the mouse leaves the target canvas. See
  7274. * {{#crossLink "Stage/mouseInBounds:property"}}{{/crossLink}}, and {{#crossLink "MouseEvent"}}{{/crossLink}}
  7275. * x/y/rawX/rawY.
  7276. * @property mouseMoveOutside
  7277. * @type Boolean
  7278. * @default false
  7279. **/
  7280. this.mouseMoveOutside = false;
  7281. /**
  7282. * Prevents selection of other elements in the html page if the user clicks and drags, or double clicks on the canvas.
  7283. * This works by calling `preventDefault()` on any mousedown events (or touch equivalent) originating on the canvas.
  7284. * @property preventSelection
  7285. * @type Boolean
  7286. * @default true
  7287. **/
  7288. this.preventSelection = true;
  7289. /**
  7290. * The hitArea property is not supported for Stage.
  7291. * @property hitArea
  7292. * @type {DisplayObject}
  7293. * @default null
  7294. */
  7295. // private properties:
  7296. /**
  7297. * Holds objects with data for each active pointer id. Each object has the following properties:
  7298. * x, y, event, target, overTarget, overX, overY, inBounds, posEvtObj (native event that last updated position)
  7299. * @property _pointerData
  7300. * @type {Object}
  7301. * @private
  7302. */
  7303. this._pointerData = {};
  7304. /**
  7305. * Number of active pointers.
  7306. * @property _pointerCount
  7307. * @type {Object}
  7308. * @private
  7309. */
  7310. this._pointerCount = 0;
  7311. /**
  7312. * The ID of the primary pointer.
  7313. * @property _primaryPointerID
  7314. * @type {Object}
  7315. * @private
  7316. */
  7317. this._primaryPointerID = null;
  7318. /**
  7319. * @property _mouseOverIntervalID
  7320. * @protected
  7321. * @type Number
  7322. **/
  7323. this._mouseOverIntervalID = null;
  7324. /**
  7325. * @property _nextStage
  7326. * @protected
  7327. * @type Stage
  7328. **/
  7329. this._nextStage = null;
  7330. /**
  7331. * @property _prevStage
  7332. * @protected
  7333. * @type Stage
  7334. **/
  7335. this._prevStage = null;
  7336. // initialize:
  7337. this.enableDOMEvents(true);
  7338. }
  7339. var p = createjs.extend(Stage, createjs.Container);
  7340. /**
  7341. * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`.
  7342. * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}}
  7343. * for details.
  7344. *
  7345. * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance.
  7346. *
  7347. * @method initialize
  7348. * @protected
  7349. * @deprecated
  7350. */
  7351. // p.initialize = function() {}; // searchable for devs wondering where it is.
  7352. // events:
  7353. /**
  7354. * Dispatched when the user moves the mouse over the canvas.
  7355. * See the {{#crossLink "MouseEvent"}}{{/crossLink}} class for a listing of event properties.
  7356. * @event stagemousemove
  7357. * @since 0.6.0
  7358. */
  7359. /**
  7360. * Dispatched when the user presses their left mouse button on the canvas. See the {{#crossLink "MouseEvent"}}{{/crossLink}}
  7361. * class for a listing of event properties.
  7362. * @event stagemousedown
  7363. * @since 0.6.0
  7364. */
  7365. /**
  7366. * 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).
  7367. * You can use {{#crossLink "Stage/mouseInBounds:property"}}{{/crossLink}} to check whether the mouse is currently within the stage bounds.
  7368. * See the {{#crossLink "MouseEvent"}}{{/crossLink}} class for a listing of event properties.
  7369. * @event stagemouseup
  7370. * @since 0.6.0
  7371. */
  7372. /**
  7373. * Dispatched when the mouse moves from within the canvas area (mouseInBounds == true) to outside it (mouseInBounds == false).
  7374. * This is currently only dispatched for mouse input (not touch). See the {{#crossLink "MouseEvent"}}{{/crossLink}}
  7375. * class for a listing of event properties.
  7376. * @event mouseleave
  7377. * @since 0.7.0
  7378. */
  7379. /**
  7380. * Dispatched when the mouse moves into the canvas area (mouseInBounds == false) from outside it (mouseInBounds == true).
  7381. * This is currently only dispatched for mouse input (not touch). See the {{#crossLink "MouseEvent"}}{{/crossLink}}
  7382. * class for a listing of event properties.
  7383. * @event mouseenter
  7384. * @since 0.7.0
  7385. */
  7386. /**
  7387. * Dispatched each update immediately before the tick event is propagated through the display list.
  7388. * You can call preventDefault on the event object to cancel propagating the tick event.
  7389. * @event tickstart
  7390. * @since 0.7.0
  7391. */
  7392. /**
  7393. * Dispatched each update immediately after the tick event is propagated through the display list. Does not fire if
  7394. * tickOnUpdate is false. Precedes the "drawstart" event.
  7395. * @event tickend
  7396. * @since 0.7.0
  7397. */
  7398. /**
  7399. * Dispatched each update immediately before the canvas is cleared and the display list is drawn to it.
  7400. * You can call preventDefault on the event object to cancel the draw.
  7401. * @event drawstart
  7402. * @since 0.7.0
  7403. */
  7404. /**
  7405. * Dispatched each update immediately after the display list is drawn to the canvas and the canvas context is restored.
  7406. * @event drawend
  7407. * @since 0.7.0
  7408. */
  7409. // getter / setters:
  7410. /**
  7411. * Specifies a target stage that will have mouse / touch interactions relayed to it after this stage handles them.
  7412. * This can be useful in cases where you have multiple layered canvases and want user interactions
  7413. * events to pass through. For example, this would relay mouse events from topStage to bottomStage:
  7414. *
  7415. * topStage.nextStage = bottomStage;
  7416. *
  7417. * To disable relaying, set nextStage to null.
  7418. *
  7419. * MouseOver, MouseOut, RollOver, and RollOut interactions are also passed through using the mouse over settings
  7420. * of the top-most stage, but are only processed if the target stage has mouse over interactions enabled.
  7421. * Considerations when using roll over in relay targets:<OL>
  7422. * <LI> The top-most (first) stage must have mouse over interactions enabled (via enableMouseOver)</LI>
  7423. * <LI> All stages that wish to participate in mouse over interaction must enable them via enableMouseOver</LI>
  7424. * <LI> All relay targets will share the frequency value of the top-most stage</LI>
  7425. * </OL>
  7426. * To illustrate, in this example the targetStage would process mouse over interactions at 10hz (despite passing
  7427. * 30 as it's desired frequency):
  7428. * topStage.nextStage = targetStage;
  7429. * topStage.enableMouseOver(10);
  7430. * targetStage.enableMouseOver(30);
  7431. *
  7432. * If the target stage's canvas is completely covered by this stage's canvas, you may also want to disable its
  7433. * DOM events using:
  7434. *
  7435. * targetStage.enableDOMEvents(false);
  7436. *
  7437. * @property nextStage
  7438. * @type {Stage}
  7439. **/
  7440. p._get_nextStage = function() {
  7441. return this._nextStage;
  7442. };
  7443. p._set_nextStage = function(value) {
  7444. if (this._nextStage) { this._nextStage._prevStage = null; }
  7445. if (value) { value._prevStage = this; }
  7446. this._nextStage = value;
  7447. };
  7448. try {
  7449. Object.defineProperties(p, {
  7450. nextStage: { get: p._get_nextStage, set: p._set_nextStage }
  7451. });
  7452. } catch (e) {} // TODO: use Log
  7453. // public methods:
  7454. /**
  7455. * Each time the update method is called, the stage will call {{#crossLink "Stage/tick"}}{{/crossLink}}
  7456. * unless {{#crossLink "Stage/tickOnUpdate:property"}}{{/crossLink}} is set to false,
  7457. * and then render the display list to the canvas.
  7458. *
  7459. * @method update
  7460. * @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.
  7461. **/
  7462. p.update = function(props) {
  7463. if (!this.canvas) { return; }
  7464. if (this.tickOnUpdate) { this.tick(props); }
  7465. if (this.dispatchEvent("drawstart", false, true) === false) { return; }
  7466. createjs.DisplayObject._snapToPixelEnabled = this.snapToPixelEnabled;
  7467. var r = this.drawRect, ctx = this.canvas.getContext("2d");
  7468. ctx.setTransform(1, 0, 0, 1, 0, 0);
  7469. if (this.autoClear) {
  7470. if (r) { ctx.clearRect(r.x, r.y, r.width, r.height); }
  7471. else { ctx.clearRect(0, 0, this.canvas.width+1, this.canvas.height+1); }
  7472. }
  7473. ctx.save();
  7474. if (this.drawRect) {
  7475. ctx.beginPath();
  7476. ctx.rect(r.x, r.y, r.width, r.height);
  7477. ctx.clip();
  7478. }
  7479. this.updateContext(ctx);
  7480. this.draw(ctx, false);
  7481. ctx.restore();
  7482. this.dispatchEvent("drawend");
  7483. };
  7484. /**
  7485. * Propagates a tick event through the display list. This is automatically called by {{#crossLink "Stage/update"}}{{/crossLink}}
  7486. * unless {{#crossLink "Stage/tickOnUpdate:property"}}{{/crossLink}} is set to false.
  7487. *
  7488. * If a props object is passed to `tick()`, then all of its properties will be copied to the event object that is
  7489. * propagated to listeners.
  7490. *
  7491. * Some time-based features in EaselJS (for example {{#crossLink "Sprite/framerate"}}{{/crossLink}} require that
  7492. * a {{#crossLink "Ticker/tick:event"}}{{/crossLink}} event object (or equivalent object with a delta property) be
  7493. * passed as the `props` parameter to `tick()`. For example:
  7494. *
  7495. * Ticker.on("tick", handleTick);
  7496. * function handleTick(evtObj) {
  7497. * // clone the event object from Ticker, and add some custom data to it:
  7498. * var evt = evtObj.clone().set({greeting:"hello", name:"world"});
  7499. *
  7500. * // pass it to stage.update():
  7501. * myStage.update(evt); // subsequently calls tick() with the same param
  7502. * }
  7503. *
  7504. * // ...
  7505. * myDisplayObject.on("tick", handleDisplayObjectTick);
  7506. * function handleDisplayObjectTick(evt) {
  7507. * console.log(evt.delta); // the delta property from the Ticker tick event object
  7508. * console.log(evt.greeting, evt.name); // custom data: "hello world"
  7509. * }
  7510. *
  7511. * @method tick
  7512. * @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.
  7513. **/
  7514. p.tick = function(props) {
  7515. if (!this.tickEnabled || this.dispatchEvent("tickstart", false, true) === false) { return; }
  7516. var evtObj = new createjs.Event("tick");
  7517. if (props) {
  7518. for (var n in props) {
  7519. if (props.hasOwnProperty(n)) { evtObj[n] = props[n]; }
  7520. }
  7521. }
  7522. this._tick(evtObj);
  7523. this.dispatchEvent("tickend");
  7524. };
  7525. /**
  7526. * Default event handler that calls the Stage {{#crossLink "Stage/update"}}{{/crossLink}} method when a {{#crossLink "DisplayObject/tick:event"}}{{/crossLink}}
  7527. * event is received. This allows you to register a Stage instance as a event listener on {{#crossLink "Ticker"}}{{/crossLink}}
  7528. * directly, using:
  7529. *
  7530. * Ticker.addEventListener("tick", myStage");
  7531. *
  7532. * Note that if you subscribe to ticks using this pattern, then the tick event object will be passed through to
  7533. * display object tick handlers, instead of <code>delta</code> and <code>paused</code> parameters.
  7534. * @property handleEvent
  7535. * @type Function
  7536. **/
  7537. p.handleEvent = function(evt) {
  7538. if (evt.type == "tick") { this.update(evt); }
  7539. };
  7540. /**
  7541. * Clears the target canvas. Useful if {{#crossLink "Stage/autoClear:property"}}{{/crossLink}} is set to `false`.
  7542. * @method clear
  7543. **/
  7544. p.clear = function() {
  7545. if (!this.canvas) { return; }
  7546. var ctx = this.canvas.getContext("2d");
  7547. ctx.setTransform(1, 0, 0, 1, 0, 0);
  7548. ctx.clearRect(0, 0, this.canvas.width+1, this.canvas.height+1);
  7549. };
  7550. /**
  7551. * Returns a data url that contains a Base64-encoded image of the contents of the stage. The returned data url can
  7552. * be specified as the src value of an image element.
  7553. * @method toDataURL
  7554. * @param {String} [backgroundColor] The background color to be used for the generated image. Any valid CSS color
  7555. * value is allowed. The default value is a transparent background.
  7556. * @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
  7557. * is passed in, or if the browser does not support the specified MIME type, the default value will be used.
  7558. * @return {String} a Base64 encoded image.
  7559. **/
  7560. p.toDataURL = function(backgroundColor, mimeType) {
  7561. var data, ctx = this.canvas.getContext('2d'), w = this.canvas.width, h = this.canvas.height;
  7562. if (backgroundColor) {
  7563. data = ctx.getImageData(0, 0, w, h);
  7564. var compositeOperation = ctx.globalCompositeOperation;
  7565. ctx.globalCompositeOperation = "destination-over";
  7566. ctx.fillStyle = backgroundColor;
  7567. ctx.fillRect(0, 0, w, h);
  7568. }
  7569. var dataURL = this.canvas.toDataURL(mimeType||"image/png");
  7570. if(backgroundColor) {
  7571. ctx.putImageData(data, 0, 0);
  7572. ctx.globalCompositeOperation = compositeOperation;
  7573. }
  7574. return dataURL;
  7575. };
  7576. /**
  7577. * Enables or disables (by passing a frequency of 0) mouse over ({{#crossLink "DisplayObject/mouseover:event"}}{{/crossLink}}
  7578. * and {{#crossLink "DisplayObject/mouseout:event"}}{{/crossLink}}) and roll over events ({{#crossLink "DisplayObject/rollover:event"}}{{/crossLink}}
  7579. * and {{#crossLink "DisplayObject/rollout:event"}}{{/crossLink}}) for this stage's display list. These events can
  7580. * be expensive to generate, so they are disabled by default. The frequency of the events can be controlled
  7581. * independently of mouse move events via the optional `frequency` parameter.
  7582. *
  7583. * <h4>Example</h4>
  7584. *
  7585. * var stage = new createjs.Stage("canvasId");
  7586. * stage.enableMouseOver(10); // 10 updates per second
  7587. *
  7588. * @method enableMouseOver
  7589. * @param {Number} [frequency=20] Optional param specifying the maximum number of times per second to broadcast
  7590. * mouse over/out events. Set to 0 to disable mouse over events completely. Maximum is 50. A lower frequency is less
  7591. * responsive, but uses less CPU.
  7592. **/
  7593. p.enableMouseOver = function(frequency) {
  7594. if (this._mouseOverIntervalID) {
  7595. clearInterval(this._mouseOverIntervalID);
  7596. this._mouseOverIntervalID = null;
  7597. if (frequency == 0) {
  7598. this._testMouseOver(true);
  7599. }
  7600. }
  7601. if (frequency == null) { frequency = 20; }
  7602. else if (frequency <= 0) { return; }
  7603. var o = this;
  7604. this._mouseOverIntervalID = setInterval(function(){ o._testMouseOver(); }, 1000/Math.min(50,frequency));
  7605. };
  7606. /**
  7607. * Enables or disables the event listeners that stage adds to DOM elements (window, document and canvas). It is good
  7608. * practice to disable events when disposing of a Stage instance, otherwise the stage will continue to receive
  7609. * events from the page.
  7610. *
  7611. * When changing the canvas property you must disable the events on the old canvas, and enable events on the
  7612. * new canvas or mouse events will not work as expected. For example:
  7613. *
  7614. * myStage.enableDOMEvents(false);
  7615. * myStage.canvas = anotherCanvas;
  7616. * myStage.enableDOMEvents(true);
  7617. *
  7618. * @method enableDOMEvents
  7619. * @param {Boolean} [enable=true] Indicates whether to enable or disable the events. Default is true.
  7620. **/
  7621. p.enableDOMEvents = function(enable) {
  7622. if (enable == null) { enable = true; }
  7623. var n, o, ls = this._eventListeners;
  7624. if (!enable && ls) {
  7625. for (n in ls) {
  7626. o = ls[n];
  7627. o.t.removeEventListener(n, o.f, false);
  7628. }
  7629. this._eventListeners = null;
  7630. } else if (enable && !ls && this.canvas) {
  7631. var t = window.addEventListener ? window : document;
  7632. var _this = this;
  7633. ls = this._eventListeners = {};
  7634. ls["mouseup"] = {t:t, f:function(e) { _this._handleMouseUp(e)} };
  7635. ls["mousemove"] = {t:t, f:function(e) { _this._handleMouseMove(e)} };
  7636. ls["dblclick"] = {t:this.canvas, f:function(e) { _this._handleDoubleClick(e)} };
  7637. ls["mousedown"] = {t:this.canvas, f:function(e) { _this._handleMouseDown(e)} };
  7638. for (n in ls) {
  7639. o = ls[n];
  7640. o.t.addEventListener(n, o.f, false);
  7641. }
  7642. }
  7643. };
  7644. /**
  7645. * Stage instances cannot be cloned.
  7646. * @method clone
  7647. **/
  7648. p.clone = function() {
  7649. throw("Stage cannot be cloned.");
  7650. };
  7651. /**
  7652. * Returns a string representation of this object.
  7653. * @method toString
  7654. * @return {String} a string representation of the instance.
  7655. **/
  7656. p.toString = function() {
  7657. return "[Stage (name="+ this.name +")]";
  7658. };
  7659. // private methods:
  7660. /**
  7661. * @method _getElementRect
  7662. * @protected
  7663. * @param {HTMLElement} e
  7664. **/
  7665. p._getElementRect = function(e) {
  7666. var bounds;
  7667. try { bounds = e.getBoundingClientRect(); } // this can fail on disconnected DOM elements in IE9
  7668. catch (err) { bounds = {top: e.offsetTop, left: e.offsetLeft, width:e.offsetWidth, height:e.offsetHeight}; }
  7669. var offX = (window.pageXOffset || document.scrollLeft || 0) - (document.clientLeft || document.body.clientLeft || 0);
  7670. var offY = (window.pageYOffset || document.scrollTop || 0) - (document.clientTop || document.body.clientTop || 0);
  7671. var styles = window.getComputedStyle ? getComputedStyle(e,null) : e.currentStyle; // IE <9 compatibility.
  7672. var padL = parseInt(styles.paddingLeft)+parseInt(styles.borderLeftWidth);
  7673. var padT = parseInt(styles.paddingTop)+parseInt(styles.borderTopWidth);
  7674. var padR = parseInt(styles.paddingRight)+parseInt(styles.borderRightWidth);
  7675. var padB = parseInt(styles.paddingBottom)+parseInt(styles.borderBottomWidth);
  7676. // note: in some browsers bounds properties are read only.
  7677. return {
  7678. left: bounds.left+offX+padL,
  7679. right: bounds.right+offX-padR,
  7680. top: bounds.top+offY+padT,
  7681. bottom: bounds.bottom+offY-padB
  7682. }
  7683. };
  7684. /**
  7685. * @method _getPointerData
  7686. * @protected
  7687. * @param {Number} id
  7688. **/
  7689. p._getPointerData = function(id) {
  7690. var data = this._pointerData[id];
  7691. if (!data) { data = this._pointerData[id] = {x:0,y:0}; }
  7692. return data;
  7693. };
  7694. /**
  7695. * @method _handleMouseMove
  7696. * @protected
  7697. * @param {MouseEvent} e
  7698. **/
  7699. p._handleMouseMove = function(e) {
  7700. if(!e){ e = window.event; }
  7701. this._handlePointerMove(-1, e, e.pageX, e.pageY);
  7702. };
  7703. /**
  7704. * @method _handlePointerMove
  7705. * @protected
  7706. * @param {Number} id
  7707. * @param {Event} e
  7708. * @param {Number} pageX
  7709. * @param {Number} pageY
  7710. * @param {Stage} owner Indicates that the event has already been captured & handled by the indicated stage.
  7711. **/
  7712. p._handlePointerMove = function(id, e, pageX, pageY, owner) {
  7713. if (this._prevStage && owner === undefined) { return; } // redundant listener.
  7714. if (!this.canvas) { return; }
  7715. var nextStage=this._nextStage, o=this._getPointerData(id);
  7716. var inBounds = o.inBounds;
  7717. this._updatePointerPosition(id, e, pageX, pageY);
  7718. if (inBounds || o.inBounds || this.mouseMoveOutside) {
  7719. if (id === -1 && o.inBounds == !inBounds) {
  7720. this._dispatchMouseEvent(this, (inBounds ? "mouseleave" : "mouseenter"), false, id, o, e);
  7721. }
  7722. this._dispatchMouseEvent(this, "stagemousemove", false, id, o, e);
  7723. this._dispatchMouseEvent(o.target, "pressmove", true, id, o, e);
  7724. }
  7725. nextStage&&nextStage._handlePointerMove(id, e, pageX, pageY, null);
  7726. };
  7727. /**
  7728. * @method _updatePointerPosition
  7729. * @protected
  7730. * @param {Number} id
  7731. * @param {Event} e
  7732. * @param {Number} pageX
  7733. * @param {Number} pageY
  7734. **/
  7735. p._updatePointerPosition = function(id, e, pageX, pageY) {
  7736. var rect = this._getElementRect(this.canvas);
  7737. pageX -= rect.left;
  7738. pageY -= rect.top;
  7739. var w = this.canvas.width;
  7740. var h = this.canvas.height;
  7741. pageX /= (rect.right-rect.left)/w;
  7742. pageY /= (rect.bottom-rect.top)/h;
  7743. var o = this._getPointerData(id);
  7744. if (o.inBounds = (pageX >= 0 && pageY >= 0 && pageX <= w-1 && pageY <= h-1)) {
  7745. o.x = pageX;
  7746. o.y = pageY;
  7747. } else if (this.mouseMoveOutside) {
  7748. o.x = pageX < 0 ? 0 : (pageX > w-1 ? w-1 : pageX);
  7749. o.y = pageY < 0 ? 0 : (pageY > h-1 ? h-1 : pageY);
  7750. }
  7751. o.posEvtObj = e;
  7752. o.rawX = pageX;
  7753. o.rawY = pageY;
  7754. if (id === this._primaryPointerID || id === -1) {
  7755. this.mouseX = o.x;
  7756. this.mouseY = o.y;
  7757. this.mouseInBounds = o.inBounds;
  7758. }
  7759. };
  7760. /**
  7761. * @method _handleMouseUp
  7762. * @protected
  7763. * @param {MouseEvent} e
  7764. **/
  7765. p._handleMouseUp = function(e) {
  7766. this._handlePointerUp(-1, e, false);
  7767. };
  7768. /**
  7769. * @method _handlePointerUp
  7770. * @protected
  7771. * @param {Number} id
  7772. * @param {Event} e
  7773. * @param {Boolean} clear
  7774. * @param {Stage} owner Indicates that the event has already been captured & handled by the indicated stage.
  7775. **/
  7776. p._handlePointerUp = function(id, e, clear, owner) {
  7777. var nextStage = this._nextStage, o = this._getPointerData(id);
  7778. if (this._prevStage && owner === undefined) { return; } // redundant listener.
  7779. var target=null, oTarget = o.target;
  7780. if (!owner && (oTarget || nextStage)) { target = this._getObjectsUnderPoint(o.x, o.y, null, true); }
  7781. if (o.down) { this._dispatchMouseEvent(this, "stagemouseup", false, id, o, e, target); o.down = false; }
  7782. if (target == oTarget) { this._dispatchMouseEvent(oTarget, "click", true, id, o, e); }
  7783. this._dispatchMouseEvent(oTarget, "pressup", true, id, o, e);
  7784. if (clear) {
  7785. if (id==this._primaryPointerID) { this._primaryPointerID = null; }
  7786. delete(this._pointerData[id]);
  7787. } else { o.target = null; }
  7788. nextStage&&nextStage._handlePointerUp(id, e, clear, owner || target && this);
  7789. };
  7790. /**
  7791. * @method _handleMouseDown
  7792. * @protected
  7793. * @param {MouseEvent} e
  7794. **/
  7795. p._handleMouseDown = function(e) {
  7796. this._handlePointerDown(-1, e, e.pageX, e.pageY);
  7797. };
  7798. /**
  7799. * @method _handlePointerDown
  7800. * @protected
  7801. * @param {Number} id
  7802. * @param {Event} e
  7803. * @param {Number} pageX
  7804. * @param {Number} pageY
  7805. * @param {Stage} owner Indicates that the event has already been captured & handled by the indicated stage.
  7806. **/
  7807. p._handlePointerDown = function(id, e, pageX, pageY, owner) {
  7808. if (this.preventSelection) { e.preventDefault(); }
  7809. if (this._primaryPointerID == null || id === -1) { this._primaryPointerID = id; } // mouse always takes over.
  7810. if (pageY != null) { this._updatePointerPosition(id, e, pageX, pageY); }
  7811. var target = null, nextStage = this._nextStage, o = this._getPointerData(id);
  7812. if (!owner) { target = o.target = this._getObjectsUnderPoint(o.x, o.y, null, true); }
  7813. if (o.inBounds) { this._dispatchMouseEvent(this, "stagemousedown", false, id, o, e, target); o.down = true; }
  7814. this._dispatchMouseEvent(target, "mousedown", true, id, o, e);
  7815. nextStage&&nextStage._handlePointerDown(id, e, pageX, pageY, owner || target && this);
  7816. };
  7817. /**
  7818. * @method _testMouseOver
  7819. * @param {Boolean} clear If true, clears the mouseover / rollover (ie. no target)
  7820. * @param {Stage} owner Indicates that the event has already been captured & handled by the indicated stage.
  7821. * @param {Stage} eventTarget The stage that the cursor is actively over.
  7822. * @protected
  7823. **/
  7824. p._testMouseOver = function(clear, owner, eventTarget) {
  7825. if (this._prevStage && owner === undefined) { return; } // redundant listener.
  7826. var nextStage = this._nextStage;
  7827. if (!this._mouseOverIntervalID) {
  7828. // not enabled for mouseover, but should still relay the event.
  7829. nextStage&&nextStage._testMouseOver(clear, owner, eventTarget);
  7830. return;
  7831. }
  7832. var o = this._getPointerData(-1);
  7833. // only update if the mouse position has changed. This provides a lot of optimization, but has some trade-offs.
  7834. if (!o || (!clear && this.mouseX == this._mouseOverX && this.mouseY == this._mouseOverY && this.mouseInBounds)) { return; }
  7835. var e = o.posEvtObj;
  7836. var isEventTarget = eventTarget || e&&(e.target == this.canvas);
  7837. var target=null, common = -1, cursor="", t, i, l;
  7838. if (!owner && (clear || this.mouseInBounds && isEventTarget)) {
  7839. target = this._getObjectsUnderPoint(this.mouseX, this.mouseY, null, true);
  7840. this._mouseOverX = this.mouseX;
  7841. this._mouseOverY = this.mouseY;
  7842. }
  7843. var oldList = this._mouseOverTarget||[];
  7844. var oldTarget = oldList[oldList.length-1];
  7845. var list = this._mouseOverTarget = [];
  7846. // generate ancestor list and check for cursor:
  7847. t = target;
  7848. while (t) {
  7849. list.unshift(t);
  7850. if (!cursor) { cursor = t.cursor; }
  7851. t = t.parent;
  7852. }
  7853. this.canvas.style.cursor = cursor;
  7854. if (!owner && eventTarget) { eventTarget.canvas.style.cursor = cursor; }
  7855. // find common ancestor:
  7856. for (i=0,l=list.length; i<l; i++) {
  7857. if (list[i] != oldList[i]) { break; }
  7858. common = i;
  7859. }
  7860. if (oldTarget != target) {
  7861. this._dispatchMouseEvent(oldTarget, "mouseout", true, -1, o, e, target);
  7862. }
  7863. for (i=oldList.length-1; i>common; i--) {
  7864. this._dispatchMouseEvent(oldList[i], "rollout", false, -1, o, e, target);
  7865. }
  7866. for (i=list.length-1; i>common; i--) {
  7867. this._dispatchMouseEvent(list[i], "rollover", false, -1, o, e, oldTarget);
  7868. }
  7869. if (oldTarget != target) {
  7870. this._dispatchMouseEvent(target, "mouseover", true, -1, o, e, oldTarget);
  7871. }
  7872. nextStage&&nextStage._testMouseOver(clear, owner || target && this, eventTarget || isEventTarget && this);
  7873. };
  7874. /**
  7875. * @method _handleDoubleClick
  7876. * @protected
  7877. * @param {MouseEvent} e
  7878. * @param {Stage} owner Indicates that the event has already been captured & handled by the indicated stage.
  7879. **/
  7880. p._handleDoubleClick = function(e, owner) {
  7881. var target=null, nextStage=this._nextStage, o=this._getPointerData(-1);
  7882. if (!owner) {
  7883. target = this._getObjectsUnderPoint(o.x, o.y, null, true);
  7884. this._dispatchMouseEvent(target, "dblclick", true, -1, o, e);
  7885. }
  7886. nextStage&&nextStage._handleDoubleClick(e, owner || target && this);
  7887. };
  7888. /**
  7889. * @method _dispatchMouseEvent
  7890. * @protected
  7891. * @param {DisplayObject} target
  7892. * @param {String} type
  7893. * @param {Boolean} bubbles
  7894. * @param {Number} pointerId
  7895. * @param {Object} o
  7896. * @param {MouseEvent} [nativeEvent]
  7897. * @param {DisplayObject} [relatedTarget]
  7898. **/
  7899. p._dispatchMouseEvent = function(target, type, bubbles, pointerId, o, nativeEvent, relatedTarget) {
  7900. // TODO: might be worth either reusing MouseEvent instances, or adding a willTrigger method to avoid GC.
  7901. if (!target || (!bubbles && !target.hasEventListener(type))) { return; }
  7902. /*
  7903. // TODO: account for stage transformations?
  7904. this._mtx = this.getConcatenatedMatrix(this._mtx).invert();
  7905. var pt = this._mtx.transformPoint(o.x, o.y);
  7906. var evt = new createjs.MouseEvent(type, bubbles, false, pt.x, pt.y, nativeEvent, pointerId, pointerId==this._primaryPointerID || pointerId==-1, o.rawX, o.rawY);
  7907. */
  7908. var evt = new createjs.MouseEvent(type, bubbles, false, o.x, o.y, nativeEvent, pointerId, pointerId === this._primaryPointerID || pointerId === -1, o.rawX, o.rawY, relatedTarget);
  7909. target.dispatchEvent(evt);
  7910. };
  7911. createjs.Stage = createjs.promote(Stage, "Container");
  7912. }());
  7913. //##############################################################################
  7914. // Bitmap.js
  7915. //##############################################################################
  7916. this.createjs = this.createjs||{};
  7917. (function() {
  7918. /**
  7919. * A Bitmap represents an Image, Canvas, or Video in the display list. A Bitmap can be instantiated using an existing
  7920. * HTML element, or a string.
  7921. *
  7922. * <h4>Example</h4>
  7923. *
  7924. * var bitmap = new createjs.Bitmap("imagePath.jpg");
  7925. *
  7926. * <strong>Notes:</strong>
  7927. * <ol>
  7928. * <li>When a string path or image tag that is not yet loaded is used, the stage may need to be redrawn before it
  7929. * will be displayed.</li>
  7930. * <li>Bitmaps with an SVG source currently will not respect an alpha value other than 0 or 1. To get around this,
  7931. * the Bitmap can be cached.</li>
  7932. * <li>Bitmaps with an SVG source will taint the canvas with cross-origin data, which prevents interactivity. This
  7933. * happens in all browsers except recent Firefox builds.</li>
  7934. * <li>Images loaded cross-origin will throw cross-origin security errors when interacted with using a mouse, using
  7935. * methods such as `getObjectUnderPoint`, or using filters, or caching. You can get around this by setting
  7936. * `crossOrigin` flags on your images before passing them to EaselJS, eg: `img.crossOrigin="Anonymous";`</li>
  7937. * </ol>
  7938. *
  7939. * @class Bitmap
  7940. * @extends DisplayObject
  7941. * @constructor
  7942. * @param {HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | String} imageOrUri The source object or URI to an image to
  7943. * display. This can be either an Image, Canvas, or Video object, or a string URI to an image file to load and use.
  7944. * If it is a URI, a new Image object will be constructed and assigned to the .image property.
  7945. **/
  7946. function Bitmap(imageOrUri) {
  7947. this.DisplayObject_constructor();
  7948. // public properties:
  7949. /**
  7950. * The image to render. This can be an Image, a Canvas, or a Video. Not all browsers (especially
  7951. * mobile browsers) support drawing video to a canvas.
  7952. * @property image
  7953. * @type HTMLImageElement | HTMLCanvasElement | HTMLVideoElement
  7954. **/
  7955. if (typeof imageOrUri == "string") {
  7956. this.image = document.createElement("img");
  7957. this.image.src = imageOrUri;
  7958. } else {
  7959. this.image = imageOrUri;
  7960. }
  7961. /**
  7962. * Specifies an area of the source image to draw. If omitted, the whole image will be drawn.
  7963. * Note that video sources must have a width / height set to work correctly with `sourceRect`.
  7964. * @property sourceRect
  7965. * @type Rectangle
  7966. * @default null
  7967. */
  7968. this.sourceRect = null;
  7969. }
  7970. var p = createjs.extend(Bitmap, createjs.DisplayObject);
  7971. // public methods:
  7972. /**
  7973. * Constructor alias for backwards compatibility. This method will be removed in future versions.
  7974. * Subclasses should be updated to use {{#crossLink "Utility Methods/extends"}}{{/crossLink}}.
  7975. * @method initialize
  7976. * @deprecated in favour of `createjs.promote()`
  7977. **/
  7978. p.initialize = Bitmap; // TODO: deprecated.
  7979. /**
  7980. * Returns true or false indicating whether the display object would be visible if drawn to a canvas.
  7981. * This does not account for whether it would be visible within the boundaries of the stage.
  7982. *
  7983. * NOTE: This method is mainly for internal use, though it may be useful for advanced uses.
  7984. * @method isVisible
  7985. * @return {Boolean} Boolean indicating whether the display object would be visible if drawn to a canvas
  7986. **/
  7987. p.isVisible = function() {
  7988. var image = this.image;
  7989. var hasContent = this.cacheCanvas || (image && (image.naturalWidth || image.getContext || image.readyState >= 2));
  7990. return !!(this.visible && this.alpha > 0 && this.scaleX != 0 && this.scaleY != 0 && hasContent);
  7991. };
  7992. /**
  7993. * Draws the display object into the specified context ignoring its visible, alpha, shadow, and transform.
  7994. * Returns true if the draw was handled (useful for overriding functionality).
  7995. *
  7996. * NOTE: This method is mainly for internal use, though it may be useful for advanced uses.
  7997. * @method draw
  7998. * @param {CanvasRenderingContext2D} ctx The canvas 2D context object to draw into.
  7999. * @param {Boolean} [ignoreCache=false] Indicates whether the draw operation should ignore any current cache.
  8000. * For example, used for drawing the cache (to prevent it from simply drawing an existing cache back
  8001. * into itself).
  8002. * @return {Boolean}
  8003. **/
  8004. p.draw = function(ctx, ignoreCache) {
  8005. if (this.DisplayObject_draw(ctx, ignoreCache) || !this.image) { return true; }
  8006. var img = this.image, rect = this.sourceRect;
  8007. if (rect) {
  8008. // some browsers choke on out of bound values, so we'll fix them:
  8009. 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;
  8010. if (x1 < 0) { x -= x1; x1 = 0; }
  8011. if (x2 > w) { x2 = w; }
  8012. if (y1 < 0) { y -= y1; y1 = 0; }
  8013. if (y2 > h) { y2 = h; }
  8014. ctx.drawImage(img, x1, y1, x2-x1, y2-y1, x, y, x2-x1, y2-y1);
  8015. } else {
  8016. ctx.drawImage(img, 0, 0);
  8017. }
  8018. return true;
  8019. };
  8020. //Note, the doc sections below document using the specified APIs (from DisplayObject) from
  8021. //Bitmap. This is why they have no method implementations.
  8022. /**
  8023. * Because the content of a Bitmap is already in a simple format, cache is unnecessary for Bitmap instances.
  8024. * You should <b>not</b> cache Bitmap instances as it can degrade performance.
  8025. *
  8026. * <strong>However: If you want to use a filter on a Bitmap, you <em>MUST</em> cache it, or it will not work.</strong>
  8027. * To see the API for caching, please visit the DisplayObject {{#crossLink "DisplayObject/cache"}}{{/crossLink}}
  8028. * method.
  8029. * @method cache
  8030. **/
  8031. /**
  8032. * Because the content of a Bitmap is already in a simple format, cache is unnecessary for Bitmap instances.
  8033. * You should <b>not</b> cache Bitmap instances as it can degrade performance.
  8034. *
  8035. * <strong>However: If you want to use a filter on a Bitmap, you <em>MUST</em> cache it, or it will not work.</strong>
  8036. * To see the API for caching, please visit the DisplayObject {{#crossLink "DisplayObject/cache"}}{{/crossLink}}
  8037. * method.
  8038. * @method updateCache
  8039. **/
  8040. /**
  8041. * Because the content of a Bitmap is already in a simple format, cache is unnecessary for Bitmap instances.
  8042. * You should <b>not</b> cache Bitmap instances as it can degrade performance.
  8043. *
  8044. * <strong>However: If you want to use a filter on a Bitmap, you <em>MUST</em> cache it, or it will not work.</strong>
  8045. * To see the API for caching, please visit the DisplayObject {{#crossLink "DisplayObject/cache"}}{{/crossLink}}
  8046. * method.
  8047. * @method uncache
  8048. **/
  8049. /**
  8050. * Docced in superclass.
  8051. */
  8052. p.getBounds = function() {
  8053. var rect = this.DisplayObject_getBounds();
  8054. if (rect) { return rect; }
  8055. var image = this.image, o = this.sourceRect || image;
  8056. var hasContent = (image && (image.naturalWidth || image.getContext || image.readyState >= 2));
  8057. return hasContent ? this._rectangle.setValues(0, 0, o.width, o.height) : null;
  8058. };
  8059. /**
  8060. * Returns a clone of the Bitmap instance.
  8061. * @method clone
  8062. * @return {Bitmap} a clone of the Bitmap instance.
  8063. **/
  8064. p.clone = function() {
  8065. var o = new Bitmap(this.image);
  8066. if (this.sourceRect) { o.sourceRect = this.sourceRect.clone(); }
  8067. this._cloneProps(o);
  8068. return o;
  8069. };
  8070. /**
  8071. * Returns a string representation of this object.
  8072. * @method toString
  8073. * @return {String} a string representation of the instance.
  8074. **/
  8075. p.toString = function() {
  8076. return "[Bitmap (name="+ this.name +")]";
  8077. };
  8078. createjs.Bitmap = createjs.promote(Bitmap, "DisplayObject");
  8079. }());
  8080. //##############################################################################
  8081. // Sprite.js
  8082. //##############################################################################
  8083. this.createjs = this.createjs||{};
  8084. (function() {
  8085. "use strict";
  8086. // constructor:
  8087. /**
  8088. * Displays a frame or sequence of frames (ie. an animation) from a SpriteSheet instance. A sprite sheet is a series of
  8089. * images (usually animation frames) combined into a single image. For example, an animation consisting of 8 100x100
  8090. * images could be combined into a 400x200 sprite sheet (4 frames across by 2 high). You can display individual frames,
  8091. * play frames as an animation, and even sequence animations together.
  8092. *
  8093. * See the {{#crossLink "SpriteSheet"}}{{/crossLink}} class for more information on setting up frames and animations.
  8094. *
  8095. * <h4>Example</h4>
  8096. *
  8097. * var instance = new createjs.Sprite(spriteSheet);
  8098. * instance.gotoAndStop("frameName");
  8099. *
  8100. * Until {{#crossLink "Sprite/gotoAndStop"}}{{/crossLink}} or {{#crossLink "Sprite/gotoAndPlay"}}{{/crossLink}} is called,
  8101. * only the first defined frame defined in the sprite sheet will be displayed.
  8102. *
  8103. * @class Sprite
  8104. * @extends DisplayObject
  8105. * @constructor
  8106. * @param {SpriteSheet} spriteSheet The SpriteSheet instance to play back. This includes the source image(s), frame
  8107. * dimensions, and frame data. See {{#crossLink "SpriteSheet"}}{{/crossLink}} for more information.
  8108. * @param {String|Number} [frameOrAnimation] The frame number or animation to play initially.
  8109. **/
  8110. function Sprite(spriteSheet, frameOrAnimation) {
  8111. this.DisplayObject_constructor();
  8112. // public properties:
  8113. /**
  8114. * The frame index that will be drawn when draw is called. Note that with some {{#crossLink "SpriteSheet"}}{{/crossLink}}
  8115. * definitions, this will advance non-sequentially. This will always be an integer value.
  8116. * @property currentFrame
  8117. * @type {Number}
  8118. * @default 0
  8119. * @readonly
  8120. **/
  8121. this.currentFrame = 0;
  8122. /**
  8123. * Returns the name of the currently playing animation.
  8124. * @property currentAnimation
  8125. * @type {String}
  8126. * @final
  8127. * @readonly
  8128. **/
  8129. this.currentAnimation = null;
  8130. /**
  8131. * Prevents the animation from advancing each tick automatically. For example, you could create a sprite
  8132. * sheet of icons, set paused to true, and display the appropriate icon by setting <code>currentFrame</code>.
  8133. * @property paused
  8134. * @type {Boolean}
  8135. * @default false
  8136. **/
  8137. this.paused = true;
  8138. /**
  8139. * The SpriteSheet instance to play back. This includes the source image, frame dimensions, and frame
  8140. * data. See {{#crossLink "SpriteSheet"}}{{/crossLink}} for more information.
  8141. * @property spriteSheet
  8142. * @type {SpriteSheet}
  8143. * @readonly
  8144. **/
  8145. this.spriteSheet = spriteSheet;
  8146. /**
  8147. * Specifies the current frame index within the currently playing animation. When playing normally, this will increase
  8148. * from 0 to n-1, where n is the number of frames in the current animation.
  8149. *
  8150. * This could be a non-integer value if
  8151. * using time-based playback (see {{#crossLink "Sprite/framerate"}}{{/crossLink}}, or if the animation's speed is
  8152. * not an integer.
  8153. * @property currentAnimationFrame
  8154. * @type {Number}
  8155. * @default 0
  8156. **/
  8157. this.currentAnimationFrame = 0;
  8158. /**
  8159. * By default Sprite instances advance one frame per tick. Specifying a framerate for the Sprite (or its related
  8160. * SpriteSheet) will cause it to advance based on elapsed time between ticks as appropriate to maintain the target
  8161. * framerate.
  8162. *
  8163. * For example, if a Sprite with a framerate of 10 is placed on a Stage being updated at 40fps, then the Sprite will
  8164. * advance roughly one frame every 4 ticks. This will not be exact, because the time between each tick will
  8165. * vary slightly between frames.
  8166. *
  8167. * This feature is dependent on the tick event object (or an object with an appropriate "delta" property) being
  8168. * passed into {{#crossLink "Stage/update"}}{{/crossLink}}.
  8169. * @property framerate
  8170. * @type {Number}
  8171. * @default 0
  8172. **/
  8173. this.framerate = 0;
  8174. // private properties:
  8175. /**
  8176. * Current animation object.
  8177. * @property _animation
  8178. * @protected
  8179. * @type {Object}
  8180. * @default null
  8181. **/
  8182. this._animation = null;
  8183. /**
  8184. * Current frame index.
  8185. * @property _currentFrame
  8186. * @protected
  8187. * @type {Number}
  8188. * @default null
  8189. **/
  8190. this._currentFrame = null;
  8191. /**
  8192. * Skips the next auto advance. Used by gotoAndPlay to avoid immediately jumping to the next frame
  8193. * @property _skipAdvance
  8194. * @protected
  8195. * @type {Boolean}
  8196. * @default false
  8197. **/
  8198. this._skipAdvance = false;
  8199. if (frameOrAnimation != null) { this.gotoAndPlay(frameOrAnimation); }
  8200. }
  8201. var p = createjs.extend(Sprite, createjs.DisplayObject);
  8202. /**
  8203. * Constructor alias for backwards compatibility. This method will be removed in future versions.
  8204. * Subclasses should be updated to use {{#crossLink "Utility Methods/extends"}}{{/crossLink}}.
  8205. * @method initialize
  8206. * @deprecated in favour of `createjs.promote()`
  8207. **/
  8208. p.initialize = Sprite; // TODO: Deprecated. This is for backwards support of FlashCC spritesheet export.
  8209. // events:
  8210. /**
  8211. * Dispatched when an animation reaches its ends.
  8212. * @event animationend
  8213. * @param {Object} target The object that dispatched the event.
  8214. * @param {String} type The event type.
  8215. * @param {String} name The name of the animation that just ended.
  8216. * @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.
  8217. * @since 0.6.0
  8218. */
  8219. /**
  8220. * Dispatched any time the current frame changes. For example, this could be due to automatic advancement on a tick,
  8221. * or calling gotoAndPlay() or gotoAndStop().
  8222. * @event change
  8223. * @param {Object} target The object that dispatched the event.
  8224. * @param {String} type The event type.
  8225. */
  8226. // public methods:
  8227. /**
  8228. * Returns true or false indicating whether the display object would be visible if drawn to a canvas.
  8229. * This does not account for whether it would be visible within the boundaries of the stage.
  8230. * NOTE: This method is mainly for internal use, though it may be useful for advanced uses.
  8231. * @method isVisible
  8232. * @return {Boolean} Boolean indicating whether the display object would be visible if drawn to a canvas
  8233. **/
  8234. p.isVisible = function() {
  8235. var hasContent = this.cacheCanvas || this.spriteSheet.complete;
  8236. return !!(this.visible && this.alpha > 0 && this.scaleX != 0 && this.scaleY != 0 && hasContent);
  8237. };
  8238. /**
  8239. * Draws the display object into the specified context ignoring its visible, alpha, shadow, and transform.
  8240. * Returns true if the draw was handled (useful for overriding functionality).
  8241. * NOTE: This method is mainly for internal use, though it may be useful for advanced uses.
  8242. * @method draw
  8243. * @param {CanvasRenderingContext2D} ctx The canvas 2D context object to draw into.
  8244. * @param {Boolean} ignoreCache Indicates whether the draw operation should ignore any current cache.
  8245. * For example, used for drawing the cache (to prevent it from simply drawing an existing cache back
  8246. * into itself).
  8247. **/
  8248. p.draw = function(ctx, ignoreCache) {
  8249. if (this.DisplayObject_draw(ctx, ignoreCache)) { return true; }
  8250. this._normalizeFrame();
  8251. var o = this.spriteSheet.getFrame(this._currentFrame|0);
  8252. if (!o) { return false; }
  8253. var rect = o.rect;
  8254. 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); }
  8255. return true;
  8256. };
  8257. //Note, the doc sections below document using the specified APIs (from DisplayObject) from
  8258. //Bitmap. This is why they have no method implementations.
  8259. /**
  8260. * Because the content of a Sprite is already in a raster format, cache is unnecessary for Sprite instances.
  8261. * You should not cache Sprite instances as it can degrade performance.
  8262. * @method cache
  8263. **/
  8264. /**
  8265. * Because the content of a Sprite is already in a raster format, cache is unnecessary for Sprite instances.
  8266. * You should not cache Sprite instances as it can degrade performance.
  8267. * @method updateCache
  8268. **/
  8269. /**
  8270. * Because the content of a Sprite is already in a raster format, cache is unnecessary for Sprite instances.
  8271. * You should not cache Sprite instances as it can degrade performance.
  8272. * @method uncache
  8273. **/
  8274. /**
  8275. * Play (unpause) the current animation. The Sprite will be paused if either {{#crossLink "Sprite/stop"}}{{/crossLink}}
  8276. * or {{#crossLink "Sprite/gotoAndStop"}}{{/crossLink}} is called. Single frame animations will remain
  8277. * unchanged.
  8278. * @method play
  8279. **/
  8280. p.play = function() {
  8281. this.paused = false;
  8282. };
  8283. /**
  8284. * Stop playing a running animation. The Sprite will be playing if {{#crossLink "Sprite/gotoAndPlay"}}{{/crossLink}}
  8285. * is called. Note that calling {{#crossLink "Sprite/gotoAndPlay"}}{{/crossLink}} or {{#crossLink "Sprite/play"}}{{/crossLink}}
  8286. * will resume playback.
  8287. * @method stop
  8288. **/
  8289. p.stop = function() {
  8290. this.paused = true;
  8291. };
  8292. /**
  8293. * Sets paused to false and plays the specified animation name, named frame, or frame number.
  8294. * @method gotoAndPlay
  8295. * @param {String|Number} frameOrAnimation The frame number or animation name that the playhead should move to
  8296. * and begin playing.
  8297. **/
  8298. p.gotoAndPlay = function(frameOrAnimation) {
  8299. this.paused = false;
  8300. this._skipAdvance = true;
  8301. this._goto(frameOrAnimation);
  8302. };
  8303. /**
  8304. * Sets paused to true and seeks to the specified animation name, named frame, or frame number.
  8305. * @method gotoAndStop
  8306. * @param {String|Number} frameOrAnimation The frame number or animation name that the playhead should move to
  8307. * and stop.
  8308. **/
  8309. p.gotoAndStop = function(frameOrAnimation) {
  8310. this.paused = true;
  8311. this._goto(frameOrAnimation);
  8312. };
  8313. /**
  8314. * Advances the playhead. This occurs automatically each tick by default.
  8315. * @param [time] {Number} The amount of time in ms to advance by. Only applicable if framerate is set on the Sprite
  8316. * or its SpriteSheet.
  8317. * @method advance
  8318. */
  8319. p.advance = function(time) {
  8320. var fps = this.framerate || this.spriteSheet.framerate;
  8321. var t = (fps && time != null) ? time/(1000/fps) : 1;
  8322. this._normalizeFrame(t);
  8323. };
  8324. /**
  8325. * Returns a {{#crossLink "Rectangle"}}{{/crossLink}} instance defining the bounds of the current frame relative to
  8326. * the origin. For example, a 90 x 70 frame with <code>regX=50</code> and <code>regY=40</code> would return a
  8327. * rectangle with [x=-50, y=-40, width=90, height=70]. This ignores transformations on the display object.
  8328. *
  8329. * Also see the SpriteSheet {{#crossLink "SpriteSheet/getFrameBounds"}}{{/crossLink}} method.
  8330. * @method getBounds
  8331. * @return {Rectangle} A Rectangle instance. Returns null if the frame does not exist, or the image is not fully
  8332. * loaded.
  8333. **/
  8334. p.getBounds = function() {
  8335. // TODO: should this normalizeFrame?
  8336. return this.DisplayObject_getBounds() || this.spriteSheet.getFrameBounds(this.currentFrame, this._rectangle);
  8337. };
  8338. /**
  8339. * Returns a clone of the Sprite instance. Note that the same SpriteSheet is shared between cloned
  8340. * instances.
  8341. * @method clone
  8342. * @return {Sprite} a clone of the Sprite instance.
  8343. **/
  8344. p.clone = function() {
  8345. return this._cloneProps(new Sprite(this.spriteSheet));
  8346. };
  8347. /**
  8348. * Returns a string representation of this object.
  8349. * @method toString
  8350. * @return {String} a string representation of the instance.
  8351. **/
  8352. p.toString = function() {
  8353. return "[Sprite (name="+ this.name +")]";
  8354. };
  8355. // private methods:
  8356. /**
  8357. * @method _cloneProps
  8358. * @param {Sprite} o
  8359. * @return {Sprite} o
  8360. * @protected
  8361. **/
  8362. p._cloneProps = function(o) {
  8363. this.DisplayObject__cloneProps(o);
  8364. o.currentFrame = this.currentFrame;
  8365. o.currentAnimation = this.currentAnimation;
  8366. o.paused = this.paused;
  8367. o.currentAnimationFrame = this.currentAnimationFrame;
  8368. o.framerate = this.framerate;
  8369. o._animation = this._animation;
  8370. o._currentFrame = this._currentFrame;
  8371. o._skipAdvance = this._skipAdvance;
  8372. return o;
  8373. };
  8374. /**
  8375. * Advances the <code>currentFrame</code> if paused is not true. This is called automatically when the {{#crossLink "Stage"}}{{/crossLink}}
  8376. * ticks.
  8377. * @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.
  8378. * @protected
  8379. * @method _tick
  8380. **/
  8381. p._tick = function(evtObj) {
  8382. if (!this.paused) {
  8383. if (!this._skipAdvance) { this.advance(evtObj&&evtObj.delta); }
  8384. this._skipAdvance = false;
  8385. }
  8386. this.DisplayObject__tick(evtObj);
  8387. };
  8388. /**
  8389. * Normalizes the current frame, advancing animations and dispatching callbacks as appropriate.
  8390. * @protected
  8391. * @method _normalizeFrame
  8392. **/
  8393. p._normalizeFrame = function(frameDelta) {
  8394. frameDelta = frameDelta || 0;
  8395. var animation = this._animation;
  8396. var paused = this.paused;
  8397. var frame = this._currentFrame;
  8398. var l;
  8399. if (animation) {
  8400. var speed = animation.speed || 1;
  8401. var animFrame = this.currentAnimationFrame;
  8402. l = animation.frames.length;
  8403. if (animFrame + frameDelta * speed >= l) {
  8404. var next = animation.next;
  8405. if (this._dispatchAnimationEnd(animation, frame, paused, next, l - 1)) {
  8406. // something changed in the event stack, so we shouldn't make any more changes here.
  8407. return;
  8408. } else if (next) {
  8409. // sequence. Automatically calls _normalizeFrame again with the remaining frames.
  8410. return this._goto(next, frameDelta - (l - animFrame) / speed);
  8411. } else {
  8412. // end.
  8413. this.paused = true;
  8414. animFrame = animation.frames.length - 1;
  8415. }
  8416. } else {
  8417. animFrame += frameDelta * speed;
  8418. }
  8419. this.currentAnimationFrame = animFrame;
  8420. this._currentFrame = animation.frames[animFrame | 0]
  8421. } else {
  8422. frame = (this._currentFrame += frameDelta);
  8423. l = this.spriteSheet.getNumFrames();
  8424. if (frame >= l && l > 0) {
  8425. if (!this._dispatchAnimationEnd(animation, frame, paused, l - 1)) {
  8426. // looped.
  8427. if ((this._currentFrame -= l) >= l) { return this._normalizeFrame(); }
  8428. }
  8429. }
  8430. }
  8431. frame = this._currentFrame | 0;
  8432. if (this.currentFrame != frame) {
  8433. this.currentFrame = frame;
  8434. this.dispatchEvent("change");
  8435. }
  8436. };
  8437. /**
  8438. * Dispatches the "animationend" event. Returns true if a handler changed the animation (ex. calling {{#crossLink "Sprite/stop"}}{{/crossLink}},
  8439. * {{#crossLink "Sprite/gotoAndPlay"}}{{/crossLink}}, etc.)
  8440. * @property _dispatchAnimationEnd
  8441. * @private
  8442. * @type {Function}
  8443. **/
  8444. p._dispatchAnimationEnd = function(animation, frame, paused, next, end) {
  8445. var name = animation ? animation.name : null;
  8446. if (this.hasEventListener("animationend")) {
  8447. var evt = new createjs.Event("animationend");
  8448. evt.name = name;
  8449. evt.next = next;
  8450. this.dispatchEvent(evt);
  8451. }
  8452. // did the animation get changed in the event stack?:
  8453. var changed = (this._animation != animation || this._currentFrame != frame);
  8454. // if the animation hasn't changed, but the sprite was paused, then we want to stick to the last frame:
  8455. if (!changed && !paused && this.paused) { this.currentAnimationFrame = end; changed = true; }
  8456. return changed;
  8457. };
  8458. /**
  8459. * Moves the playhead to the specified frame number or animation.
  8460. * @method _goto
  8461. * @param {String|Number} frameOrAnimation The frame number or animation that the playhead should move to.
  8462. * @param {Boolean} [frame] The frame of the animation to go to. Defaults to 0.
  8463. * @protected
  8464. **/
  8465. p._goto = function(frameOrAnimation, frame) {
  8466. this.currentAnimationFrame = 0;
  8467. if (isNaN(frameOrAnimation)) {
  8468. var data = this.spriteSheet.getAnimation(frameOrAnimation);
  8469. if (data) {
  8470. this._animation = data;
  8471. this.currentAnimation = frameOrAnimation;
  8472. this._normalizeFrame(frame);
  8473. }
  8474. } else {
  8475. this.currentAnimation = this._animation = null;
  8476. this._currentFrame = frameOrAnimation;
  8477. this._normalizeFrame();
  8478. }
  8479. };
  8480. createjs.Sprite = createjs.promote(Sprite, "DisplayObject");
  8481. }());
  8482. //##############################################################################
  8483. // Shape.js
  8484. //##############################################################################
  8485. this.createjs = this.createjs||{};
  8486. (function() {
  8487. "use strict";
  8488. // constructor:
  8489. /**
  8490. * A Shape allows you to display vector art in the display list. It composites a {{#crossLink "Graphics"}}{{/crossLink}}
  8491. * instance which exposes all of the vector drawing methods. The Graphics instance can be shared between multiple Shape
  8492. * instances to display the same vector graphics with different positions or transforms.
  8493. *
  8494. * If the vector art will not
  8495. * change between draws, you may want to use the {{#crossLink "DisplayObject/cache"}}{{/crossLink}} method to reduce the
  8496. * rendering cost.
  8497. *
  8498. * <h4>Example</h4>
  8499. *
  8500. * var graphics = new createjs.Graphics().beginFill("#ff0000").drawRect(0, 0, 100, 100);
  8501. * var shape = new createjs.Shape(graphics);
  8502. *
  8503. * //Alternatively use can also use the graphics property of the Shape class to renderer the same as above.
  8504. * var shape = new createjs.Shape();
  8505. * shape.graphics.beginFill("#ff0000").drawRect(0, 0, 100, 100);
  8506. *
  8507. * @class Shape
  8508. * @extends DisplayObject
  8509. * @constructor
  8510. * @param {Graphics} graphics Optional. The graphics instance to display. If null, a new Graphics instance will be created.
  8511. **/
  8512. function Shape(graphics) {
  8513. this.DisplayObject_constructor();
  8514. // public properties:
  8515. /**
  8516. * The graphics instance to display.
  8517. * @property graphics
  8518. * @type Graphics
  8519. **/
  8520. this.graphics = graphics ? graphics : new createjs.Graphics();
  8521. }
  8522. var p = createjs.extend(Shape, createjs.DisplayObject);
  8523. // TODO: deprecated
  8524. // p.initialize = function() {}; // searchable for devs wondering where it is. REMOVED. See docs for details.
  8525. // public methods:
  8526. /**
  8527. * Returns true or false indicating whether the Shape would be visible if drawn to a canvas.
  8528. * This does not account for whether it would be visible within the boundaries of the stage.
  8529. * NOTE: This method is mainly for internal use, though it may be useful for advanced uses.
  8530. * @method isVisible
  8531. * @return {Boolean} Boolean indicating whether the Shape would be visible if drawn to a canvas
  8532. **/
  8533. p.isVisible = function() {
  8534. var hasContent = this.cacheCanvas || (this.graphics && !this.graphics.isEmpty());
  8535. return !!(this.visible && this.alpha > 0 && this.scaleX != 0 && this.scaleY != 0 && hasContent);
  8536. };
  8537. /**
  8538. * Draws the Shape into the specified context ignoring its visible, alpha, shadow, and transform. Returns true if
  8539. * the draw was handled (useful for overriding functionality).
  8540. *
  8541. * <i>NOTE: This method is mainly for internal use, though it may be useful for advanced uses.</i>
  8542. * @method draw
  8543. * @param {CanvasRenderingContext2D} ctx The canvas 2D context object to draw into.
  8544. * @param {Boolean} [ignoreCache=false] Indicates whether the draw operation should ignore any current cache. For example,
  8545. * used for drawing the cache (to prevent it from simply drawing an existing cache back into itself).
  8546. * @return {Boolean}
  8547. **/
  8548. p.draw = function(ctx, ignoreCache) {
  8549. if (this.DisplayObject_draw(ctx, ignoreCache)) { return true; }
  8550. this.graphics.draw(ctx, this);
  8551. return true;
  8552. };
  8553. /**
  8554. * Returns a clone of this Shape. Some properties that are specific to this instance's current context are reverted to
  8555. * their defaults (for example .parent).
  8556. * @method clone
  8557. * @param {Boolean} recursive If true, this Shape's {{#crossLink "Graphics"}}{{/crossLink}} instance will also be
  8558. * cloned. If false, the Graphics instance will be shared with the new Shape.
  8559. **/
  8560. p.clone = function(recursive) {
  8561. var g = (recursive && this.graphics) ? this.graphics.clone() : this.graphics;
  8562. return this._cloneProps(new Shape(g));
  8563. };
  8564. /**
  8565. * Returns a string representation of this object.
  8566. * @method toString
  8567. * @return {String} a string representation of the instance.
  8568. **/
  8569. p.toString = function() {
  8570. return "[Shape (name="+ this.name +")]";
  8571. };
  8572. createjs.Shape = createjs.promote(Shape, "DisplayObject");
  8573. }());
  8574. //##############################################################################
  8575. // Text.js
  8576. //##############################################################################
  8577. this.createjs = this.createjs||{};
  8578. (function() {
  8579. "use strict";
  8580. // constructor:
  8581. /**
  8582. * Display one or more lines of dynamic text (not user editable) in the display list. Line wrapping support (using the
  8583. * lineWidth) is very basic, wrapping on spaces and tabs only. Note that as an alternative to Text, you can position HTML
  8584. * text above or below the canvas relative to items in the display list using the {{#crossLink "DisplayObject/localToGlobal"}}{{/crossLink}}
  8585. * method, or using {{#crossLink "DOMElement"}}{{/crossLink}}.
  8586. *
  8587. * <b>Please note that Text does not support HTML text, and can only display one font style at a time.</b> To use
  8588. * multiple font styles, you will need to create multiple text instances, and position them manually.
  8589. *
  8590. * <h4>Example</h4>
  8591. *
  8592. * var text = new createjs.Text("Hello World", "20px Arial", "#ff7700");
  8593. * text.x = 100;
  8594. * text.textBaseline = "alphabetic";
  8595. *
  8596. * CreateJS Text supports web fonts (the same rules as Canvas). The font must be loaded and supported by the browser
  8597. * before it can be displayed.
  8598. *
  8599. * <strong>Note:</strong> Text can be expensive to generate, so cache instances where possible. Be aware that not all
  8600. * browsers will render Text exactly the same.
  8601. * @class Text
  8602. * @extends DisplayObject
  8603. * @constructor
  8604. * @param {String} [text] The text to display.
  8605. * @param {String} [font] The font style to use. Any valid value for the CSS font attribute is acceptable (ex. "bold
  8606. * 36px Arial").
  8607. * @param {String} [color] The color to draw the text in. Any valid value for the CSS color attribute is acceptable (ex.
  8608. * "#F00", "red", or "#FF0000").
  8609. **/
  8610. function Text(text, font, color) {
  8611. this.DisplayObject_constructor();
  8612. // public properties:
  8613. /**
  8614. * The text to display.
  8615. * @property text
  8616. * @type String
  8617. **/
  8618. this.text = text;
  8619. /**
  8620. * The font style to use. Any valid value for the CSS font attribute is acceptable (ex. "bold 36px Arial").
  8621. * @property font
  8622. * @type String
  8623. **/
  8624. this.font = font;
  8625. /**
  8626. * The color to draw the text in. Any valid value for the CSS color attribute is acceptable (ex. "#F00"). Default is "#000".
  8627. * It will also accept valid canvas fillStyle values.
  8628. * @property color
  8629. * @type String
  8630. **/
  8631. this.color = color;
  8632. /**
  8633. * The horizontal text alignment. Any of "start", "end", "left", "right", and "center". For detailed
  8634. * information view the
  8635. * <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#text-styles">
  8636. * whatwg spec</a>. Default is "left".
  8637. * @property textAlign
  8638. * @type String
  8639. **/
  8640. this.textAlign = "left";
  8641. /**
  8642. * The vertical alignment point on the font. Any of "top", "hanging", "middle", "alphabetic", "ideographic", or
  8643. * "bottom". For detailed information view the <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#text-styles">
  8644. * whatwg spec</a>. Default is "top".
  8645. * @property textBaseline
  8646. * @type String
  8647. */
  8648. this.textBaseline = "top";
  8649. /**
  8650. * The maximum width to draw the text. If maxWidth is specified (not null), the text will be condensed or
  8651. * shrunk to make it fit in this width. For detailed information view the
  8652. * <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#text-styles">
  8653. * whatwg spec</a>.
  8654. * @property maxWidth
  8655. * @type Number
  8656. */
  8657. this.maxWidth = null;
  8658. /**
  8659. * If greater than 0, the text will be drawn as a stroke (outline) of the specified width.
  8660. * @property outline
  8661. * @type Number
  8662. **/
  8663. this.outline = 0;
  8664. /**
  8665. * Indicates the line height (vertical distance between baselines) for multi-line text. If null or 0,
  8666. * the value of getMeasuredLineHeight is used.
  8667. * @property lineHeight
  8668. * @type Number
  8669. **/
  8670. this.lineHeight = 0;
  8671. /**
  8672. * Indicates the maximum width for a line of text before it is wrapped to multiple lines. If null,
  8673. * the text will not be wrapped.
  8674. * @property lineWidth
  8675. * @type Number
  8676. **/
  8677. this.lineWidth = null;
  8678. }
  8679. var p = createjs.extend(Text, createjs.DisplayObject);
  8680. // TODO: deprecated
  8681. // p.initialize = function() {}; // searchable for devs wondering where it is. REMOVED. See docs for details.
  8682. // static properties:
  8683. /**
  8684. * @property _workingContext
  8685. * @type CanvasRenderingContext2D
  8686. * @private
  8687. **/
  8688. var canvas = (createjs.createCanvas?createjs.createCanvas():document.createElement("canvas"));
  8689. if (canvas.getContext) { Text._workingContext = canvas.getContext("2d"); canvas.width = canvas.height = 1; }
  8690. // constants:
  8691. /**
  8692. * Lookup table for the ratio to offset bounds x calculations based on the textAlign property.
  8693. * @property H_OFFSETS
  8694. * @type Object
  8695. * @protected
  8696. * @static
  8697. **/
  8698. Text.H_OFFSETS = {start: 0, left: 0, center: -0.5, end: -1, right: -1};
  8699. /**
  8700. * Lookup table for the ratio to offset bounds y calculations based on the textBaseline property.
  8701. * @property H_OFFSETS
  8702. * @type Object
  8703. * @protected
  8704. * @static
  8705. **/
  8706. Text.V_OFFSETS = {top: 0, hanging: -0.01, middle: -0.4, alphabetic: -0.8, ideographic: -0.85, bottom: -1};
  8707. // public methods:
  8708. /**
  8709. * Returns true or false indicating whether the display object would be visible if drawn to a canvas.
  8710. * This does not account for whether it would be visible within the boundaries of the stage.
  8711. * NOTE: This method is mainly for internal use, though it may be useful for advanced uses.
  8712. * @method isVisible
  8713. * @return {Boolean} Whether the display object would be visible if drawn to a canvas
  8714. **/
  8715. p.isVisible = function() {
  8716. var hasContent = this.cacheCanvas || (this.text != null && this.text !== "");
  8717. return !!(this.visible && this.alpha > 0 && this.scaleX != 0 && this.scaleY != 0 && hasContent);
  8718. };
  8719. /**
  8720. * Draws the Text into the specified context ignoring its visible, alpha, shadow, and transform.
  8721. * Returns true if the draw was handled (useful for overriding functionality).
  8722. * NOTE: This method is mainly for internal use, though it may be useful for advanced uses.
  8723. * @method draw
  8724. * @param {CanvasRenderingContext2D} ctx The canvas 2D context object to draw into.
  8725. * @param {Boolean} ignoreCache Indicates whether the draw operation should ignore any current cache.
  8726. * For example, used for drawing the cache (to prevent it from simply drawing an existing cache back
  8727. * into itself).
  8728. **/
  8729. p.draw = function(ctx, ignoreCache) {
  8730. if (this.DisplayObject_draw(ctx, ignoreCache)) { return true; }
  8731. var col = this.color || "#000";
  8732. if (this.outline) { ctx.strokeStyle = col; ctx.lineWidth = this.outline*1; }
  8733. else { ctx.fillStyle = col; }
  8734. this._drawText(this._prepContext(ctx));
  8735. return true;
  8736. };
  8737. /**
  8738. * Returns the measured, untransformed width of the text without wrapping. Use getBounds for a more robust value.
  8739. * @method getMeasuredWidth
  8740. * @return {Number} The measured, untransformed width of the text.
  8741. **/
  8742. p.getMeasuredWidth = function() {
  8743. return this._getMeasuredWidth(this.text);
  8744. };
  8745. /**
  8746. * Returns an approximate line height of the text, ignoring the lineHeight property. This is based on the measured
  8747. * width of a "M" character multiplied by 1.2, which provides an approximate line height for most fonts.
  8748. * @method getMeasuredLineHeight
  8749. * @return {Number} an approximate line height of the text, ignoring the lineHeight property. This is
  8750. * based on the measured width of a "M" character multiplied by 1.2, which approximates em for most fonts.
  8751. **/
  8752. p.getMeasuredLineHeight = function() {
  8753. return this._getMeasuredWidth("M")*1.2;
  8754. };
  8755. /**
  8756. * Returns the approximate height of multi-line text by multiplying the number of lines against either the
  8757. * <code>lineHeight</code> (if specified) or {{#crossLink "Text/getMeasuredLineHeight"}}{{/crossLink}}. Note that
  8758. * this operation requires the text flowing logic to run, which has an associated CPU cost.
  8759. * @method getMeasuredHeight
  8760. * @return {Number} The approximate height of the untransformed multi-line text.
  8761. **/
  8762. p.getMeasuredHeight = function() {
  8763. return this._drawText(null,{}).height;
  8764. };
  8765. /**
  8766. * Docced in superclass.
  8767. */
  8768. p.getBounds = function() {
  8769. var rect = this.DisplayObject_getBounds();
  8770. if (rect) { return rect; }
  8771. if (this.text == null || this.text === "") { return null; }
  8772. var o = this._drawText(null, {});
  8773. var w = (this.maxWidth && this.maxWidth < o.width) ? this.maxWidth : o.width;
  8774. var x = w * Text.H_OFFSETS[this.textAlign||"left"];
  8775. var lineHeight = this.lineHeight||this.getMeasuredLineHeight();
  8776. var y = lineHeight * Text.V_OFFSETS[this.textBaseline||"top"];
  8777. return this._rectangle.setValues(x, y, w, o.height);
  8778. };
  8779. /**
  8780. * Returns an object with width, height, and lines properties. The width and height are the visual width and height
  8781. * of the drawn text. The lines property contains an array of strings, one for
  8782. * each line of text that will be drawn, accounting for line breaks and wrapping. These strings have trailing
  8783. * whitespace removed.
  8784. * @method getMetrics
  8785. * @return {Object} An object with width, height, and lines properties.
  8786. **/
  8787. p.getMetrics = function() {
  8788. var o = {lines:[]};
  8789. o.lineHeight = this.lineHeight || this.getMeasuredLineHeight();
  8790. o.vOffset = o.lineHeight * Text.V_OFFSETS[this.textBaseline||"top"];
  8791. return this._drawText(null, o, o.lines);
  8792. };
  8793. /**
  8794. * Returns a clone of the Text instance.
  8795. * @method clone
  8796. * @return {Text} a clone of the Text instance.
  8797. **/
  8798. p.clone = function() {
  8799. return this._cloneProps(new Text(this.text, this.font, this.color));
  8800. };
  8801. /**
  8802. * Returns a string representation of this object.
  8803. * @method toString
  8804. * @return {String} a string representation of the instance.
  8805. **/
  8806. p.toString = function() {
  8807. return "[Text (text="+ (this.text.length > 20 ? this.text.substr(0, 17)+"..." : this.text) +")]";
  8808. };
  8809. // private methods:
  8810. /**
  8811. * @method _cloneProps
  8812. * @param {Text} o
  8813. * @protected
  8814. * @return {Text} o
  8815. **/
  8816. p._cloneProps = function(o) {
  8817. this.DisplayObject__cloneProps(o);
  8818. o.textAlign = this.textAlign;
  8819. o.textBaseline = this.textBaseline;
  8820. o.maxWidth = this.maxWidth;
  8821. o.outline = this.outline;
  8822. o.lineHeight = this.lineHeight;
  8823. o.lineWidth = this.lineWidth;
  8824. return o;
  8825. };
  8826. /**
  8827. * @method _getWorkingContext
  8828. * @param {CanvasRenderingContext2D} ctx
  8829. * @return {CanvasRenderingContext2D}
  8830. * @protected
  8831. **/
  8832. p._prepContext = function(ctx) {
  8833. ctx.font = this.font||"10px sans-serif";
  8834. ctx.textAlign = this.textAlign||"left";
  8835. ctx.textBaseline = this.textBaseline||"top";
  8836. return ctx;
  8837. };
  8838. /**
  8839. * Draws multiline text.
  8840. * @method _drawText
  8841. * @param {CanvasRenderingContext2D} ctx
  8842. * @param {Object} o
  8843. * @param {Array} lines
  8844. * @return {Object}
  8845. * @protected
  8846. **/
  8847. p._drawText = function(ctx, o, lines) {
  8848. var paint = !!ctx;
  8849. if (!paint) {
  8850. ctx = Text._workingContext;
  8851. ctx.save();
  8852. this._prepContext(ctx);
  8853. }
  8854. var lineHeight = this.lineHeight||this.getMeasuredLineHeight();
  8855. var maxW = 0, count = 0;
  8856. var hardLines = String(this.text).split(/(?:\r\n|\r|\n)/);
  8857. for (var i=0, l=hardLines.length; i<l; i++) {
  8858. var str = hardLines[i];
  8859. var w = null;
  8860. if (this.lineWidth != null && (w = ctx.measureText(str).width) > this.lineWidth) {
  8861. // text wrapping:
  8862. var words = str.split(/(\s)/);
  8863. str = words[0];
  8864. w = ctx.measureText(str).width;
  8865. for (var j=1, jl=words.length; j<jl; j+=2) {
  8866. // Line needs to wrap:
  8867. var wordW = ctx.measureText(words[j] + words[j+1]).width;
  8868. if (w + wordW > this.lineWidth) {
  8869. if (paint) { this._drawTextLine(ctx, str, count*lineHeight); }
  8870. if (lines) { lines.push(str); }
  8871. if (w > maxW) { maxW = w; }
  8872. str = words[j+1];
  8873. w = ctx.measureText(str).width;
  8874. count++;
  8875. } else {
  8876. str += words[j] + words[j+1];
  8877. w += wordW;
  8878. }
  8879. }
  8880. }
  8881. if (paint) { this._drawTextLine(ctx, str, count*lineHeight); }
  8882. if (lines) { lines.push(str); }
  8883. if (o && w == null) { w = ctx.measureText(str).width; }
  8884. if (w > maxW) { maxW = w; }
  8885. count++;
  8886. }
  8887. if (o) {
  8888. o.width = maxW;
  8889. o.height = count*lineHeight;
  8890. }
  8891. if (!paint) { ctx.restore(); }
  8892. return o;
  8893. };
  8894. /**
  8895. * @method _drawTextLine
  8896. * @param {CanvasRenderingContext2D} ctx
  8897. * @param {String} text
  8898. * @param {Number} y
  8899. * @protected
  8900. **/
  8901. p._drawTextLine = function(ctx, text, y) {
  8902. // Chrome 17 will fail to draw the text if the last param is included but null, so we feed it a large value instead:
  8903. if (this.outline) { ctx.strokeText(text, 0, y, this.maxWidth||0xFFFF); }
  8904. else { ctx.fillText(text, 0, y, this.maxWidth||0xFFFF); }
  8905. };
  8906. /**
  8907. * @method _getMeasuredWidth
  8908. * @param {String} text
  8909. * @protected
  8910. **/
  8911. p._getMeasuredWidth = function(text) {
  8912. var ctx = Text._workingContext;
  8913. ctx.save();
  8914. var w = this._prepContext(ctx).measureText(text).width;
  8915. ctx.restore();
  8916. return w;
  8917. };
  8918. createjs.Text = createjs.promote(Text, "DisplayObject");
  8919. }());
  8920. //##############################################################################
  8921. // BitmapText.js
  8922. //##############################################################################
  8923. this.createjs = this.createjs || {};
  8924. (function () {
  8925. "use strict";
  8926. // constructor:
  8927. /**
  8928. * Displays text using bitmap glyphs defined in a sprite sheet. Multi-line text is supported
  8929. * using new line characters, but automatic wrapping is not supported. See the
  8930. * {{#crossLink "BitmapText/spriteSheet:property"}}{{/crossLink}}
  8931. * property for more information on defining glyphs.
  8932. *
  8933. * <strong>Important:</strong> BitmapText extends Container, but is not designed to be used as one.
  8934. * As such, methods like addChild and removeChild are disabled.
  8935. * @class BitmapText
  8936. * @extends DisplayObject
  8937. * @param {String} [text=""] The text to display.
  8938. * @param {SpriteSheet} [spriteSheet=null] The spritesheet that defines the character glyphs.
  8939. * @constructor
  8940. **/
  8941. function BitmapText(text, spriteSheet) {
  8942. this.Container_constructor();
  8943. // public properties:
  8944. /**
  8945. * The text to display.
  8946. * @property text
  8947. * @type String
  8948. * @default ""
  8949. **/
  8950. this.text = text||"";
  8951. /**
  8952. * A SpriteSheet instance that defines the glyphs for this bitmap text. Each glyph/character
  8953. * should have a single frame animation defined in the sprite sheet named the same as
  8954. * corresponding character. For example, the following animation definition:
  8955. *
  8956. * "A": {frames: [0]}
  8957. *
  8958. * would indicate that the frame at index 0 of the spritesheet should be drawn for the "A" character. The short form
  8959. * is also acceptable:
  8960. *
  8961. * "A": 0
  8962. *
  8963. * Note that if a character in the text is not found in the sprite sheet, it will also
  8964. * try to use the alternate case (upper or lower).
  8965. *
  8966. * See SpriteSheet for more information on defining sprite sheet data.
  8967. * @property spriteSheet
  8968. * @type SpriteSheet
  8969. * @default null
  8970. **/
  8971. this.spriteSheet = spriteSheet;
  8972. /**
  8973. * The height of each line of text. If 0, then it will use a line height calculated
  8974. * by checking for the height of the "1", "T", or "L" character (in that order). If
  8975. * those characters are not defined, it will use the height of the first frame of the
  8976. * sprite sheet.
  8977. * @property lineHeight
  8978. * @type Number
  8979. * @default 0
  8980. **/
  8981. this.lineHeight = 0;
  8982. /**
  8983. * This spacing (in pixels) will be added after each character in the output.
  8984. * @property letterSpacing
  8985. * @type Number
  8986. * @default 0
  8987. **/
  8988. this.letterSpacing = 0;
  8989. /**
  8990. * If a space character is not defined in the sprite sheet, then empty pixels equal to
  8991. * spaceWidth will be inserted instead. If 0, then it will use a value calculated
  8992. * by checking for the width of the "1", "l", "E", or "A" character (in that order). If
  8993. * those characters are not defined, it will use the width of the first frame of the
  8994. * sprite sheet.
  8995. * @property spaceWidth
  8996. * @type Number
  8997. * @default 0
  8998. **/
  8999. this.spaceWidth = 0;
  9000. // private properties:
  9001. /**
  9002. * @property _oldProps
  9003. * @type Object
  9004. * @protected
  9005. **/
  9006. this._oldProps = {text:0,spriteSheet:0,lineHeight:0,letterSpacing:0,spaceWidth:0};
  9007. }
  9008. var p = createjs.extend(BitmapText, createjs.Container);
  9009. /**
  9010. * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`.
  9011. * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}}
  9012. * for details.
  9013. *
  9014. * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance.
  9015. *
  9016. * @method initialize
  9017. * @protected
  9018. * @deprecated
  9019. */
  9020. // p.initialize = function() {}; // searchable for devs wondering where it is.
  9021. // static properties:
  9022. /**
  9023. * BitmapText uses Sprite instances to draw text. To reduce the creation and destruction of instances (and thus garbage collection), it maintains
  9024. * an internal object pool of sprite instances to reuse. Increasing this value can cause more sprites to be
  9025. * retained, slightly increasing memory use, but reducing instantiation.
  9026. * @property maxPoolSize
  9027. * @type Number
  9028. * @static
  9029. * @default 100
  9030. **/
  9031. BitmapText.maxPoolSize = 100;
  9032. /**
  9033. * Sprite object pool.
  9034. * @type {Array}
  9035. * @static
  9036. * @private
  9037. */
  9038. BitmapText._spritePool = [];
  9039. // public methods:
  9040. /**
  9041. * Docced in superclass.
  9042. **/
  9043. p.draw = function(ctx, ignoreCache) {
  9044. if (this.DisplayObject_draw(ctx, ignoreCache)) { return; }
  9045. this._updateText();
  9046. this.Container_draw(ctx, ignoreCache);
  9047. };
  9048. /**
  9049. * Docced in superclass.
  9050. **/
  9051. p.getBounds = function() {
  9052. this._updateText();
  9053. return this.Container_getBounds();
  9054. };
  9055. /**
  9056. * Returns true or false indicating whether the display object would be visible if drawn to a canvas.
  9057. * This does not account for whether it would be visible within the boundaries of the stage.
  9058. * NOTE: This method is mainly for internal use, though it may be useful for advanced uses.
  9059. * @method isVisible
  9060. * @return {Boolean} Boolean indicating whether the display object would be visible if drawn to a canvas
  9061. **/
  9062. p.isVisible = function() {
  9063. var hasContent = this.cacheCanvas || (this.spriteSheet && this.spriteSheet.complete && this.text);
  9064. return !!(this.visible && this.alpha > 0 && this.scaleX !== 0 && this.scaleY !== 0 && hasContent);
  9065. };
  9066. p.clone = function() {
  9067. return this._cloneProps(new BitmapText(this.text, this.spriteSheet));
  9068. };
  9069. /**
  9070. * <strong>Disabled in BitmapText.</strong>
  9071. * @method addChild
  9072. **/
  9073. /**
  9074. * <strong>Disabled in BitmapText.</strong>
  9075. * @method addChildAt
  9076. **/
  9077. /**
  9078. * <strong>Disabled in BitmapText.</strong>
  9079. * @method removeChild
  9080. **/
  9081. /**
  9082. * <strong>Disabled in BitmapText.</strong>
  9083. * @method removeChildAt
  9084. **/
  9085. /**
  9086. * <strong>Disabled in BitmapText.</strong>
  9087. * @method removeAllChildren
  9088. **/
  9089. p.addChild = p.addChildAt = p.removeChild = p.removeChildAt = p.removeAllChildren = function() {};
  9090. // private methods:
  9091. /**
  9092. * @method _cloneProps
  9093. * @param {BitmapText} o
  9094. * @return {BitmapText} o
  9095. * @protected
  9096. **/
  9097. p._cloneProps = function(o) {
  9098. this.Container__cloneProps(o);
  9099. o.lineHeight = this.lineHeight;
  9100. o.letterSpacing = this.letterSpacing;
  9101. o.spaceWidth = this.spaceWidth;
  9102. return o;
  9103. };
  9104. /**
  9105. * @method _getFrameIndex
  9106. * @param {String} character
  9107. * @param {SpriteSheet} spriteSheet
  9108. * @return {Number}
  9109. * @protected
  9110. **/
  9111. p._getFrameIndex = function(character, spriteSheet) {
  9112. var c, o = spriteSheet.getAnimation(character);
  9113. if (!o) {
  9114. (character != (c = character.toUpperCase())) || (character != (c = character.toLowerCase())) || (c=null);
  9115. if (c) { o = spriteSheet.getAnimation(c); }
  9116. }
  9117. return o && o.frames[0];
  9118. };
  9119. /**
  9120. * @method _getFrame
  9121. * @param {String} character
  9122. * @param {SpriteSheet} spriteSheet
  9123. * @return {Object}
  9124. * @protected
  9125. **/
  9126. p._getFrame = function(character, spriteSheet) {
  9127. var index = this._getFrameIndex(character, spriteSheet);
  9128. return index == null ? index : spriteSheet.getFrame(index);
  9129. };
  9130. /**
  9131. * @method _getLineHeight
  9132. * @param {SpriteSheet} ss
  9133. * @return {Number}
  9134. * @protected
  9135. **/
  9136. p._getLineHeight = function(ss) {
  9137. var frame = this._getFrame("1",ss) || this._getFrame("T",ss) || this._getFrame("L",ss) || ss.getFrame(0);
  9138. return frame ? frame.rect.height : 1;
  9139. };
  9140. /**
  9141. * @method _getSpaceWidth
  9142. * @param {SpriteSheet} ss
  9143. * @return {Number}
  9144. * @protected
  9145. **/
  9146. p._getSpaceWidth = function(ss) {
  9147. var frame = this._getFrame("1",ss) || this._getFrame("l",ss) || this._getFrame("e",ss) || this._getFrame("a",ss) || ss.getFrame(0);
  9148. return frame ? frame.rect.width : 1;
  9149. };
  9150. /**
  9151. * @method _drawText
  9152. * @protected
  9153. **/
  9154. p._updateText = function() {
  9155. var x=0, y=0, o=this._oldProps, change=false, spaceW=this.spaceWidth, lineH=this.lineHeight, ss=this.spriteSheet;
  9156. var pool=BitmapText._spritePool, kids=this.children, childIndex=0, numKids=kids.length, sprite;
  9157. for (var n in o) {
  9158. if (o[n] != this[n]) {
  9159. o[n] = this[n];
  9160. change = true;
  9161. }
  9162. }
  9163. if (!change) { return; }
  9164. var hasSpace = !!this._getFrame(" ", ss);
  9165. if (!hasSpace && !spaceW) { spaceW = this._getSpaceWidth(ss); }
  9166. if (!lineH) { lineH = this._getLineHeight(ss); }
  9167. for(var i=0, l=this.text.length; i<l; i++) {
  9168. var character = this.text.charAt(i);
  9169. if (character == " " && !hasSpace) {
  9170. x += spaceW;
  9171. continue;
  9172. } else if (character=="\n" || character=="\r") {
  9173. if (character=="\r" && this.text.charAt(i+1) == "\n") { i++; } // crlf
  9174. x = 0;
  9175. y += lineH;
  9176. continue;
  9177. }
  9178. var index = this._getFrameIndex(character, ss);
  9179. if (index == null) { continue; }
  9180. if (childIndex < numKids) {
  9181. sprite = kids[childIndex];
  9182. } else {
  9183. kids.push(sprite = pool.length ? pool.pop() : new createjs.Sprite());
  9184. sprite.parent = this;
  9185. numKids++;
  9186. }
  9187. sprite.spriteSheet = ss;
  9188. sprite.gotoAndStop(index);
  9189. sprite.x = x;
  9190. sprite.y = y;
  9191. childIndex++;
  9192. x += sprite.getBounds().width + this.letterSpacing;
  9193. }
  9194. while (numKids > childIndex) {
  9195. // faster than removeChild.
  9196. pool.push(sprite = kids.pop());
  9197. sprite.parent = null;
  9198. numKids--;
  9199. }
  9200. if (pool.length > BitmapText.maxPoolSize) { pool.length = BitmapText.maxPoolSize; }
  9201. };
  9202. createjs.BitmapText = createjs.promote(BitmapText, "Container");
  9203. }());
  9204. //##############################################################################
  9205. // MovieClip.js
  9206. //##############################################################################
  9207. this.createjs = this.createjs||{};
  9208. (function() {
  9209. "use strict";
  9210. // constructor:
  9211. /**
  9212. * The MovieClip class associates a TweenJS Timeline with an EaselJS {{#crossLink "Container"}}{{/crossLink}}. It allows
  9213. * you to create objects which encapsulate timeline animations, state changes, and synched actions. Due to the
  9214. * complexities inherent in correctly setting up a MovieClip, it is largely intended for tool output and is not included
  9215. * in the main EaselJS library.
  9216. *
  9217. * Currently MovieClip only works properly if it is tick based (as opposed to time based) though some concessions have
  9218. * been made to support time-based timelines in the future.
  9219. *
  9220. * <h4>Example</h4>
  9221. * This example animates two shapes back and forth. The grey shape starts on the left, but we jump to a mid-point in
  9222. * the animation using {{#crossLink "MovieClip/gotoAndPlay"}}{{/crossLink}}.
  9223. *
  9224. * var stage = new createjs.Stage("canvas");
  9225. * createjs.Ticker.addEventListener("tick", stage);
  9226. *
  9227. * var mc = new createjs.MovieClip(null, 0, true, {start:20});
  9228. * stage.addChild(mc);
  9229. *
  9230. * var child1 = new createjs.Shape(
  9231. * new createjs.Graphics().beginFill("#999999")
  9232. * .drawCircle(30,30,30));
  9233. * var child2 = new createjs.Shape(
  9234. * new createjs.Graphics().beginFill("#5a9cfb")
  9235. * .drawCircle(30,30,30));
  9236. *
  9237. * mc.timeline.addTween(
  9238. * createjs.Tween.get(child1)
  9239. * .to({x:0}).to({x:60}, 50).to({x:0}, 50));
  9240. * mc.timeline.addTween(
  9241. * createjs.Tween.get(child2)
  9242. * .to({x:60}).to({x:0}, 50).to({x:60}, 50));
  9243. *
  9244. * mc.gotoAndPlay("start");
  9245. *
  9246. * It is recommended to use <code>tween.to()</code> to animate and set properties (use no duration to have it set
  9247. * immediately), and the <code>tween.wait()</code> method to create delays between animations. Note that using the
  9248. * <code>tween.set()</code> method to affect properties will likely not provide the desired result.
  9249. *
  9250. * @class MovieClip
  9251. * @main MovieClip
  9252. * @extends Container
  9253. * @constructor
  9254. * @param {String} [mode=independent] Initial value for the mode property. One of {{#crossLink "MovieClip/INDEPENDENT:property"}}{{/crossLink}},
  9255. * {{#crossLink "MovieClip/SINGLE_FRAME:property"}}{{/crossLink}}, or {{#crossLink "MovieClip/SYNCHED:property"}}{{/crossLink}}.
  9256. * The default is {{#crossLink "MovieClip/INDEPENDENT:property"}}{{/crossLink}}.
  9257. * @param {Number} [startPosition=0] Initial value for the {{#crossLink "MovieClip/startPosition:property"}}{{/crossLink}}
  9258. * property.
  9259. * @param {Boolean} [loop=true] Initial value for the {{#crossLink "MovieClip/loop:property"}}{{/crossLink}}
  9260. * property. The default is `true`.
  9261. * @param {Object} [labels=null] A hash of labels to pass to the {{#crossLink "MovieClip/timeline:property"}}{{/crossLink}}
  9262. * instance associated with this MovieClip. Labels only need to be passed if they need to be used.
  9263. **/
  9264. function MovieClip(mode, startPosition, loop, labels) {
  9265. this.Container_constructor();
  9266. !MovieClip.inited&&MovieClip.init(); // static init
  9267. // public properties:
  9268. /**
  9269. * Controls how this MovieClip advances its time. Must be one of 0 (INDEPENDENT), 1 (SINGLE_FRAME), or 2 (SYNCHED).
  9270. * See each constant for a description of the behaviour.
  9271. * @property mode
  9272. * @type String
  9273. * @default null
  9274. **/
  9275. this.mode = mode||MovieClip.INDEPENDENT;
  9276. /**
  9277. * Specifies what the first frame to play in this movieclip, or the only frame to display if mode is SINGLE_FRAME.
  9278. * @property startPosition
  9279. * @type Number
  9280. * @default 0
  9281. */
  9282. this.startPosition = startPosition || 0;
  9283. /**
  9284. * Indicates whether this MovieClip should loop when it reaches the end of its timeline.
  9285. * @property loop
  9286. * @type Boolean
  9287. * @default true
  9288. */
  9289. this.loop = loop;
  9290. /**
  9291. * The current frame of the movieclip.
  9292. * @property currentFrame
  9293. * @type Number
  9294. * @default 0
  9295. * @readonly
  9296. */
  9297. this.currentFrame = 0;
  9298. /**
  9299. * The TweenJS Timeline that is associated with this MovieClip. This is created automatically when the MovieClip
  9300. * instance is initialized. Animations are created by adding <a href="http://tweenjs.com">TweenJS</a> Tween
  9301. * instances to the timeline.
  9302. *
  9303. * <h4>Example</h4>
  9304. *
  9305. * var tween = createjs.Tween.get(target).to({x:0}).to({x:100}, 30);
  9306. * var mc = new createjs.MovieClip();
  9307. * mc.timeline.addTween(tween);
  9308. *
  9309. * Elements can be added and removed from the timeline by toggling an "_off" property
  9310. * using the <code>tweenInstance.to()</code> method. Note that using <code>Tween.set</code> is not recommended to
  9311. * create MovieClip animations. The following example will toggle the target off on frame 0, and then back on for
  9312. * frame 1. You can use the "visible" property to achieve the same effect.
  9313. *
  9314. * var tween = createjs.Tween.get(target).to({_off:false})
  9315. * .wait(1).to({_off:true})
  9316. * .wait(1).to({_off:false});
  9317. *
  9318. * @property timeline
  9319. * @type Timeline
  9320. * @default null
  9321. */
  9322. this.timeline = new createjs.Timeline(null, labels, {paused:true, position:startPosition, useTicks:true});
  9323. /**
  9324. * If true, the MovieClip's position will not advance when ticked.
  9325. * @property paused
  9326. * @type Boolean
  9327. * @default false
  9328. */
  9329. this.paused = false;
  9330. /**
  9331. * If true, actions in this MovieClip's tweens will be run when the playhead advances.
  9332. * @property actionsEnabled
  9333. * @type Boolean
  9334. * @default true
  9335. */
  9336. this.actionsEnabled = true;
  9337. /**
  9338. * If true, the MovieClip will automatically be reset to its first frame whenever the timeline adds
  9339. * it back onto the display list. This only applies to MovieClip instances with mode=INDEPENDENT.
  9340. * <br><br>
  9341. * For example, if you had a character animation with a "body" child MovieClip instance
  9342. * with different costumes on each frame, you could set body.autoReset = false, so that
  9343. * you can manually change the frame it is on, without worrying that it will be reset
  9344. * automatically.
  9345. * @property autoReset
  9346. * @type Boolean
  9347. * @default true
  9348. */
  9349. this.autoReset = true;
  9350. /**
  9351. * An array of bounds for each frame in the MovieClip. This is mainly intended for tool output.
  9352. * @property frameBounds
  9353. * @type Array
  9354. * @default null
  9355. */
  9356. this.frameBounds = this.frameBounds||null; // TODO: Deprecated. This is for backwards support of FlashCC
  9357. /**
  9358. * By default MovieClip instances advance one frame per tick. Specifying a framerate for the MovieClip
  9359. * will cause it to advance based on elapsed time between ticks as appropriate to maintain the target
  9360. * framerate.
  9361. *
  9362. * For example, if a MovieClip with a framerate of 10 is placed on a Stage being updated at 40fps, then the MovieClip will
  9363. * advance roughly one frame every 4 ticks. This will not be exact, because the time between each tick will
  9364. * vary slightly between frames.
  9365. *
  9366. * This feature is dependent on the tick event object (or an object with an appropriate "delta" property) being
  9367. * passed into {{#crossLink "Stage/update"}}{{/crossLink}}.
  9368. * @property framerate
  9369. * @type {Number}
  9370. * @default null
  9371. **/
  9372. this.framerate = null;
  9373. // private properties:
  9374. /**
  9375. * @property _synchOffset
  9376. * @type Number
  9377. * @default 0
  9378. * @private
  9379. */
  9380. this._synchOffset = 0;
  9381. /**
  9382. * @property _prevPos
  9383. * @type Number
  9384. * @default -1
  9385. * @private
  9386. */
  9387. this._prevPos = -1; // TODO: evaluate using a ._reset Boolean prop instead of -1.
  9388. /**
  9389. * @property _prevPosition
  9390. * @type Number
  9391. * @default 0
  9392. * @private
  9393. */
  9394. this._prevPosition = 0;
  9395. /**
  9396. * The time remaining from the previous tick, only applicable when .framerate is set.
  9397. * @property _t
  9398. * @type Number
  9399. * @private
  9400. */
  9401. this._t = 0;
  9402. /**
  9403. * List of display objects that are actively being managed by the MovieClip.
  9404. * @property _managed
  9405. * @type Object
  9406. * @private
  9407. */
  9408. this._managed = {};
  9409. }
  9410. var p = createjs.extend(MovieClip, createjs.Container);
  9411. // constants:
  9412. /**
  9413. * The MovieClip will advance independently of its parent, even if its parent is paused.
  9414. * This is the default mode.
  9415. * @property INDEPENDENT
  9416. * @static
  9417. * @type String
  9418. * @default "independent"
  9419. * @readonly
  9420. **/
  9421. MovieClip.INDEPENDENT = "independent";
  9422. /**
  9423. * The MovieClip will only display a single frame (as determined by the startPosition property).
  9424. * @property SINGLE_FRAME
  9425. * @static
  9426. * @type String
  9427. * @default "single"
  9428. * @readonly
  9429. **/
  9430. MovieClip.SINGLE_FRAME = "single";
  9431. /**
  9432. * The MovieClip will be advanced only when its parent advances and will be synched to the position of
  9433. * the parent MovieClip.
  9434. * @property SYNCHED
  9435. * @static
  9436. * @type String
  9437. * @default "synched"
  9438. * @readonly
  9439. **/
  9440. MovieClip.SYNCHED = "synched";
  9441. // static properties:
  9442. MovieClip.inited = false;
  9443. // static methods:
  9444. MovieClip.init = function() {
  9445. if (MovieClip.inited) { return; }
  9446. // plugins introduce some overhead to Tween, so we only install this if an MC is instantiated.
  9447. MovieClipPlugin.install();
  9448. MovieClip.inited = true;
  9449. };
  9450. // getter / setters:
  9451. /**
  9452. * Use the {{#crossLink "MovieClip/labels:property"}}{{/crossLink}} property instead.
  9453. * @method getLabels
  9454. * @return {Array}
  9455. * @deprecated
  9456. **/
  9457. p.getLabels = function() {
  9458. return this.timeline.getLabels();
  9459. };
  9460. /**
  9461. * Use the {{#crossLink "MovieClip/currentLabel:property"}}{{/crossLink}} property instead.
  9462. * @method getCurrentLabel
  9463. * @return {String}
  9464. * @deprecated
  9465. **/
  9466. p.getCurrentLabel = function() {
  9467. this._updateTimeline();
  9468. return this.timeline.getCurrentLabel();
  9469. };
  9470. /**
  9471. * Use the {{#crossLink "MovieClip/duration:property"}}{{/crossLink}} property instead.
  9472. * @method getDuration
  9473. * @return {Number}
  9474. * @protected
  9475. **/
  9476. p.getDuration = function() {
  9477. return this.timeline.duration;
  9478. };
  9479. /**
  9480. * Returns an array of objects with label and position (aka frame) properties, sorted by position.
  9481. * Shortcut to TweenJS: Timeline.getLabels();
  9482. * @property labels
  9483. * @type {Array}
  9484. * @readonly
  9485. **/
  9486. /**
  9487. * Returns the name of the label on or immediately before the current frame. See TweenJS: Timeline.getCurrentLabel()
  9488. * for more information.
  9489. * @property currentLabel
  9490. * @type {String}
  9491. * @readonly
  9492. **/
  9493. /**
  9494. * Returns the duration of this MovieClip in seconds or ticks. Identical to {{#crossLink "MovieClip/duration:property"}}{{/crossLink}}
  9495. * and provided for Flash API compatibility.
  9496. * @property totalFrames
  9497. * @type {Number}
  9498. * @readonly
  9499. **/
  9500. /**
  9501. * Returns the duration of this MovieClip in seconds or ticks.
  9502. * @property duration
  9503. * @type {Number}
  9504. * @readonly
  9505. **/
  9506. try {
  9507. Object.defineProperties(p, {
  9508. labels: { get: p.getLabels },
  9509. currentLabel: { get: p.getCurrentLabel },
  9510. totalFrames: { get: p.getDuration },
  9511. duration: { get: p.getDuration }
  9512. });
  9513. } catch (e) {}
  9514. // public methods:
  9515. /**
  9516. * Constructor alias for backwards compatibility. This method will be removed in future versions.
  9517. * Subclasses should be updated to use {{#crossLink "Utility Methods/extends"}}{{/crossLink}}.
  9518. * @method initialize
  9519. * @deprecated in favour of `createjs.promote()`
  9520. **/
  9521. p.initialize = MovieClip; // TODO: Deprecated. This is for backwards support of FlashCC
  9522. /**
  9523. * Returns true or false indicating whether the display object would be visible if drawn to a canvas.
  9524. * This does not account for whether it would be visible within the boundaries of the stage.
  9525. * NOTE: This method is mainly for internal use, though it may be useful for advanced uses.
  9526. * @method isVisible
  9527. * @return {Boolean} Boolean indicating whether the display object would be visible if drawn to a canvas
  9528. **/
  9529. p.isVisible = function() {
  9530. // children are placed in draw, so we can't determine if we have content.
  9531. return !!(this.visible && this.alpha > 0 && this.scaleX != 0 && this.scaleY != 0);
  9532. };
  9533. /**
  9534. * Draws the display object into the specified context ignoring its visible, alpha, shadow, and transform.
  9535. * Returns true if the draw was handled (useful for overriding functionality).
  9536. * NOTE: This method is mainly for internal use, though it may be useful for advanced uses.
  9537. * @method draw
  9538. * @param {CanvasRenderingContext2D} ctx The canvas 2D context object to draw into.
  9539. * @param {Boolean} ignoreCache Indicates whether the draw operation should ignore any current cache.
  9540. * For example, used for drawing the cache (to prevent it from simply drawing an existing cache back
  9541. * into itself).
  9542. **/
  9543. p.draw = function(ctx, ignoreCache) {
  9544. // draw to cache first:
  9545. if (this.DisplayObject_draw(ctx, ignoreCache)) { return true; }
  9546. this._updateTimeline();
  9547. this.Container_draw(ctx, ignoreCache);
  9548. return true;
  9549. };
  9550. /**
  9551. * Sets paused to false.
  9552. * @method play
  9553. **/
  9554. p.play = function() {
  9555. this.paused = false;
  9556. };
  9557. /**
  9558. * Sets paused to true.
  9559. * @method stop
  9560. **/
  9561. p.stop = function() {
  9562. this.paused = true;
  9563. };
  9564. /**
  9565. * Advances this movie clip to the specified position or label and sets paused to false.
  9566. * @method gotoAndPlay
  9567. * @param {String|Number} positionOrLabel The animation name or frame number to go to.
  9568. **/
  9569. p.gotoAndPlay = function(positionOrLabel) {
  9570. this.paused = false;
  9571. this._goto(positionOrLabel);
  9572. };
  9573. /**
  9574. * Advances this movie clip to the specified position or label and sets paused to true.
  9575. * @method gotoAndStop
  9576. * @param {String|Number} positionOrLabel The animation or frame name to go to.
  9577. **/
  9578. p.gotoAndStop = function(positionOrLabel) {
  9579. this.paused = true;
  9580. this._goto(positionOrLabel);
  9581. };
  9582. /**
  9583. * Advances the playhead. This occurs automatically each tick by default.
  9584. * @param [time] {Number} The amount of time in ms to advance by. Only applicable if framerate is set.
  9585. * @method advance
  9586. */
  9587. p.advance = function(time) {
  9588. // TODO: should we worry at all about clips who change their own modes via frame scripts?
  9589. var independent = MovieClip.INDEPENDENT;
  9590. if (this.mode != independent) { return; }
  9591. var o=this, fps = o.framerate;
  9592. while ((o = o.parent) && fps == null) {
  9593. if (o.mode == independent) { fps = o._framerate; }
  9594. }
  9595. this._framerate = fps;
  9596. var t = (fps != null && fps != -1 && time != null) ? time/(1000/fps) + this._t : 1;
  9597. var frames = t|0;
  9598. this._t = t-frames; // leftover time
  9599. while (!this.paused && frames--) {
  9600. this._prevPosition = (this._prevPos < 0) ? 0 : this._prevPosition+1;
  9601. this._updateTimeline();
  9602. }
  9603. };
  9604. /**
  9605. * MovieClip instances cannot be cloned.
  9606. * @method clone
  9607. **/
  9608. p.clone = function() {
  9609. // TODO: add support for this? Need to clone the Timeline & retarget tweens - pretty complex.
  9610. throw("MovieClip cannot be cloned.")
  9611. };
  9612. /**
  9613. * Returns a string representation of this object.
  9614. * @method toString
  9615. * @return {String} a string representation of the instance.
  9616. **/
  9617. p.toString = function() {
  9618. return "[MovieClip (name="+ this.name +")]";
  9619. };
  9620. // private methods:
  9621. /**
  9622. * @method _tick
  9623. * @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.
  9624. * function.
  9625. * @protected
  9626. **/
  9627. p._tick = function(evtObj) {
  9628. this.advance(evtObj&&evtObj.delta);
  9629. this.Container__tick(evtObj);
  9630. };
  9631. /**
  9632. * @method _goto
  9633. * @param {String|Number} positionOrLabel The animation name or frame number to go to.
  9634. * @protected
  9635. **/
  9636. p._goto = function(positionOrLabel) {
  9637. var pos = this.timeline.resolve(positionOrLabel);
  9638. if (pos == null) { return; }
  9639. // prevent _updateTimeline from overwriting the new position because of a reset:
  9640. if (this._prevPos == -1) { this._prevPos = NaN; }
  9641. this._prevPosition = pos;
  9642. this._t = 0;
  9643. this._updateTimeline();
  9644. };
  9645. /**
  9646. * @method _reset
  9647. * @private
  9648. **/
  9649. p._reset = function() {
  9650. this._prevPos = -1;
  9651. this._t = this.currentFrame = 0;
  9652. this.paused = false;
  9653. };
  9654. /**
  9655. * @method _updateTimeline
  9656. * @protected
  9657. **/
  9658. p._updateTimeline = function() {
  9659. var tl = this.timeline;
  9660. var synched = this.mode != MovieClip.INDEPENDENT;
  9661. tl.loop = (this.loop==null) ? true : this.loop;
  9662. var pos = synched ? this.startPosition + (this.mode==MovieClip.SINGLE_FRAME?0:this._synchOffset) : (this._prevPos < 0 ? 0 : this._prevPosition);
  9663. var mode = synched || !this.actionsEnabled ? createjs.Tween.NONE : null;
  9664. // pre-assign currentFrame so it is available to frame scripts:
  9665. this.currentFrame = tl._calcPosition(pos);
  9666. // update timeline position, ignoring actions if this is a graphic.
  9667. tl.setPosition(pos, mode);
  9668. this._prevPosition = tl._prevPosition;
  9669. if (this._prevPos == tl._prevPos) { return; }
  9670. this.currentFrame = this._prevPos = tl._prevPos;
  9671. for (var n in this._managed) { this._managed[n] = 1; }
  9672. var tweens = tl._tweens;
  9673. for (var i=0, l=tweens.length; i<l; i++) {
  9674. var tween = tweens[i];
  9675. var target = tween._target;
  9676. if (target == this || tween.passive) { continue; } // TODO: this assumes actions tween has this as the target. Valid?
  9677. var offset = tween._stepPosition;
  9678. if (target instanceof createjs.DisplayObject) {
  9679. // motion tween.
  9680. this._addManagedChild(target, offset);
  9681. } else {
  9682. // state tween.
  9683. this._setState(target.state, offset);
  9684. }
  9685. }
  9686. var kids = this.children;
  9687. for (i=kids.length-1; i>=0; i--) {
  9688. var id = kids[i].id;
  9689. if (this._managed[id] == 1) {
  9690. this.removeChildAt(i);
  9691. delete(this._managed[id]);
  9692. }
  9693. }
  9694. };
  9695. /**
  9696. * @method _setState
  9697. * @param {Array} state
  9698. * @param {Number} offset
  9699. * @protected
  9700. **/
  9701. p._setState = function(state, offset) {
  9702. if (!state) { return; }
  9703. for (var i=state.length-1;i>=0;i--) {
  9704. var o = state[i];
  9705. var target = o.t;
  9706. var props = o.p;
  9707. for (var n in props) { target[n] = props[n]; }
  9708. this._addManagedChild(target, offset);
  9709. }
  9710. };
  9711. /**
  9712. * Adds a child to the timeline, and sets it up as a managed child.
  9713. * @method _addManagedChild
  9714. * @param {MovieClip} child The child MovieClip to manage
  9715. * @param {Number} offset
  9716. * @private
  9717. **/
  9718. p._addManagedChild = function(child, offset) {
  9719. if (child._off) { return; }
  9720. this.addChildAt(child,0);
  9721. if (child instanceof MovieClip) {
  9722. child._synchOffset = offset;
  9723. // 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.
  9724. if (child.mode == MovieClip.INDEPENDENT && child.autoReset && !this._managed[child.id]) { child._reset(); }
  9725. }
  9726. this._managed[child.id] = 2;
  9727. };
  9728. /**
  9729. * @method _getBounds
  9730. * @param {Matrix2D} matrix
  9731. * @param {Boolean} ignoreTransform
  9732. * @return {Rectangle}
  9733. * @protected
  9734. **/
  9735. p._getBounds = function(matrix, ignoreTransform) {
  9736. var bounds = this.DisplayObject_getBounds();
  9737. if (!bounds) {
  9738. this._updateTimeline();
  9739. if (this.frameBounds) { bounds = this._rectangle.copy(this.frameBounds[this.currentFrame]); }
  9740. }
  9741. if (bounds) { return this._transformBounds(bounds, matrix, ignoreTransform); }
  9742. return this.Container__getBounds(matrix, ignoreTransform);
  9743. };
  9744. createjs.MovieClip = createjs.promote(MovieClip, "Container");
  9745. // MovieClipPlugin for TweenJS:
  9746. /**
  9747. * This plugin works with <a href="http://tweenjs.com" target="_blank">TweenJS</a> to prevent the startPosition
  9748. * property from tweening.
  9749. * @private
  9750. * @class MovieClipPlugin
  9751. * @constructor
  9752. **/
  9753. function MovieClipPlugin() {
  9754. throw("MovieClipPlugin cannot be instantiated.")
  9755. }
  9756. /**
  9757. * @method priority
  9758. * @private
  9759. **/
  9760. MovieClipPlugin.priority = 100; // very high priority, should run first
  9761. /**
  9762. * @method install
  9763. * @private
  9764. **/
  9765. MovieClipPlugin.install = function() {
  9766. createjs.Tween.installPlugin(MovieClipPlugin, ["startPosition"]);
  9767. };
  9768. /**
  9769. * @method init
  9770. * @param {Tween} tween
  9771. * @param {String} prop
  9772. * @param {String|Number|Boolean} value
  9773. * @private
  9774. **/
  9775. MovieClipPlugin.init = function(tween, prop, value) {
  9776. return value;
  9777. };
  9778. /**
  9779. * @method step
  9780. * @private
  9781. **/
  9782. MovieClipPlugin.step = function() {
  9783. // unused.
  9784. };
  9785. /**
  9786. * @method tween
  9787. * @param {Tween} tween
  9788. * @param {String} prop
  9789. * @param {String | Number | Boolean} value
  9790. * @param {Array} startValues
  9791. * @param {Array} endValues
  9792. * @param {Number} ratio
  9793. * @param {Object} wait
  9794. * @param {Object} end
  9795. * @return {*}
  9796. */
  9797. MovieClipPlugin.tween = function(tween, prop, value, startValues, endValues, ratio, wait, end) {
  9798. if (!(tween.target instanceof MovieClip)) { return value; }
  9799. return (ratio == 1 ? endValues[prop] : startValues[prop]);
  9800. };
  9801. }());
  9802. //##############################################################################
  9803. // SpriteSheetUtils.js
  9804. //##############################################################################
  9805. this.createjs = this.createjs||{};
  9806. (function() {
  9807. "use strict";
  9808. // constructor:
  9809. /**
  9810. * The SpriteSheetUtils class is a collection of static methods for working with {{#crossLink "SpriteSheet"}}{{/crossLink}}s.
  9811. * A sprite sheet is a series of images (usually animation frames) combined into a single image on a regular grid. For
  9812. * example, an animation consisting of 8 100x100 images could be combined into a 400x200 sprite sheet (4 frames across
  9813. * by 2 high). The SpriteSheetUtils class uses a static interface and should not be instantiated.
  9814. * @class SpriteSheetUtils
  9815. * @static
  9816. **/
  9817. function SpriteSheetUtils() {
  9818. throw "SpriteSheetUtils cannot be instantiated";
  9819. }
  9820. // private static properties:
  9821. /**
  9822. * @property _workingCanvas
  9823. * @static
  9824. * @type HTMLCanvasElement | Object
  9825. * @protected
  9826. */
  9827. /**
  9828. * @property _workingContext
  9829. * @static
  9830. * @type CanvasRenderingContext2D
  9831. * @protected
  9832. */
  9833. var canvas = (createjs.createCanvas?createjs.createCanvas():document.createElement("canvas"));
  9834. if (canvas.getContext) {
  9835. SpriteSheetUtils._workingCanvas = canvas;
  9836. SpriteSheetUtils._workingContext = canvas.getContext("2d");
  9837. canvas.width = canvas.height = 1;
  9838. }
  9839. // public static methods:
  9840. /**
  9841. * <b>This is an experimental method, and may be buggy. Please report issues.</b><br/><br/>
  9842. * Extends the existing sprite sheet by flipping the original frames horizontally, vertically, or both,
  9843. * and adding appropriate animation & frame data. The flipped animations will have a suffix added to their names
  9844. * (_h, _v, _hv as appropriate). Make sure the sprite sheet images are fully loaded before using this method.
  9845. * <br/><br/>
  9846. * For example:<br/>
  9847. * SpriteSheetUtils.addFlippedFrames(mySpriteSheet, true, true);
  9848. * The above would add frames that are flipped horizontally AND frames that are flipped vertically.
  9849. * <br/><br/>
  9850. * Note that you can also flip any display object by setting its scaleX or scaleY to a negative value. On some
  9851. * browsers (especially those without hardware accelerated canvas) this can result in slightly degraded performance,
  9852. * which is why addFlippedFrames is available.
  9853. * @method addFlippedFrames
  9854. * @static
  9855. * @param {SpriteSheet} spriteSheet
  9856. * @param {Boolean} horizontal If true, horizontally flipped frames will be added.
  9857. * @param {Boolean} vertical If true, vertically flipped frames will be added.
  9858. * @param {Boolean} both If true, frames that are flipped both horizontally and vertically will be added.
  9859. * @deprecated Modern browsers perform better when flipping via a transform (ex. scaleX=-1) rendering this obsolete.
  9860. **/
  9861. SpriteSheetUtils.addFlippedFrames = function(spriteSheet, horizontal, vertical, both) {
  9862. if (!horizontal && !vertical && !both) { return; }
  9863. var count = 0;
  9864. if (horizontal) { SpriteSheetUtils._flip(spriteSheet,++count,true,false); }
  9865. if (vertical) { SpriteSheetUtils._flip(spriteSheet,++count,false,true); }
  9866. if (both) { SpriteSheetUtils._flip(spriteSheet,++count,true,true); }
  9867. };
  9868. /**
  9869. * Returns a single frame of the specified sprite sheet as a new PNG image. An example of when this may be useful is
  9870. * to use a spritesheet frame as the source for a bitmap fill.
  9871. *
  9872. * <strong>WARNING:</strong> In almost all cases it is better to display a single frame using a {{#crossLink "Sprite"}}{{/crossLink}}
  9873. * with a {{#crossLink "Sprite/gotoAndStop"}}{{/crossLink}} call than it is to slice out a frame using this
  9874. * method and display it with a Bitmap instance. You can also crop an image using the {{#crossLink "Bitmap/sourceRect"}}{{/crossLink}}
  9875. * property of {{#crossLink "Bitmap"}}{{/crossLink}}.
  9876. *
  9877. * The extractFrame method may cause cross-domain warnings since it accesses pixels directly on the canvas.
  9878. * @method extractFrame
  9879. * @static
  9880. * @param {SpriteSheet} spriteSheet The SpriteSheet instance to extract a frame from.
  9881. * @param {Number|String} frameOrAnimation The frame number or animation name to extract. If an animation
  9882. * name is specified, only the first frame of the animation will be extracted.
  9883. * @return {HTMLImageElement} a single frame of the specified sprite sheet as a new PNG image.
  9884. */
  9885. SpriteSheetUtils.extractFrame = function(spriteSheet, frameOrAnimation) {
  9886. if (isNaN(frameOrAnimation)) {
  9887. frameOrAnimation = spriteSheet.getAnimation(frameOrAnimation).frames[0];
  9888. }
  9889. var data = spriteSheet.getFrame(frameOrAnimation);
  9890. if (!data) { return null; }
  9891. var r = data.rect;
  9892. var canvas = SpriteSheetUtils._workingCanvas;
  9893. canvas.width = r.width;
  9894. canvas.height = r.height;
  9895. SpriteSheetUtils._workingContext.drawImage(data.image, r.x, r.y, r.width, r.height, 0, 0, r.width, r.height);
  9896. var img = document.createElement("img");
  9897. img.src = canvas.toDataURL("image/png");
  9898. return img;
  9899. };
  9900. /**
  9901. * Merges the rgb channels of one image with the alpha channel of another. This can be used to combine a compressed
  9902. * JPEG image containing color data with a PNG32 monochromatic image containing alpha data. With certain types of
  9903. * images (those with detail that lend itself to JPEG compression) this can provide significant file size savings
  9904. * versus a single RGBA PNG32. This method is very fast (generally on the order of 1-2 ms to run).
  9905. * @method mergeAlpha
  9906. * @static
  9907. * @param {HTMLImageElement} rbgImage The image (or canvas) containing the RGB channels to use.
  9908. * @param {HTMLImageElement} alphaImage The image (or canvas) containing the alpha channel to use.
  9909. * @param {HTMLCanvasElement} canvas Optional. If specified, this canvas will be used and returned. If not, a new canvas will be created.
  9910. * @return {HTMLCanvasElement} A canvas with the combined image data. This can be used as a source for Bitmap or SpriteSheet.
  9911. * @deprecated Tools such as ImageAlpha generally provide better results. This will be moved to sandbox in the future.
  9912. */
  9913. SpriteSheetUtils.mergeAlpha = function(rgbImage, alphaImage, canvas) {
  9914. if (!canvas) { canvas = createjs.createCanvas?createjs.createCanvas():document.createElement("canvas"); }
  9915. canvas.width = Math.max(alphaImage.width, rgbImage.width);
  9916. canvas.height = Math.max(alphaImage.height, rgbImage.height);
  9917. var ctx = canvas.getContext("2d");
  9918. ctx.save();
  9919. ctx.drawImage(rgbImage,0,0);
  9920. ctx.globalCompositeOperation = "destination-in";
  9921. ctx.drawImage(alphaImage,0,0);
  9922. ctx.restore();
  9923. return canvas;
  9924. };
  9925. // private static methods:
  9926. SpriteSheetUtils._flip = function(spriteSheet, count, h, v) {
  9927. var imgs = spriteSheet._images;
  9928. var canvas = SpriteSheetUtils._workingCanvas;
  9929. var ctx = SpriteSheetUtils._workingContext;
  9930. var il = imgs.length/count;
  9931. for (var i=0;i<il;i++) {
  9932. var src = imgs[i];
  9933. src.__tmp = i; // a bit hacky, but faster than doing indexOf below.
  9934. ctx.setTransform(1,0,0,1,0,0);
  9935. ctx.clearRect(0,0,canvas.width+1,canvas.height+1);
  9936. canvas.width = src.width;
  9937. canvas.height = src.height;
  9938. ctx.setTransform(h?-1:1, 0, 0, v?-1:1, h?src.width:0, v?src.height:0);
  9939. ctx.drawImage(src,0,0);
  9940. var img = document.createElement("img");
  9941. img.src = canvas.toDataURL("image/png");
  9942. // work around a strange bug in Safari:
  9943. img.width = src.width;
  9944. img.height = src.height;
  9945. imgs.push(img);
  9946. }
  9947. var frames = spriteSheet._frames;
  9948. var fl = frames.length/count;
  9949. for (i=0;i<fl;i++) {
  9950. src = frames[i];
  9951. var rect = src.rect.clone();
  9952. img = imgs[src.image.__tmp+il*count];
  9953. var frame = {image:img,rect:rect,regX:src.regX,regY:src.regY};
  9954. if (h) {
  9955. rect.x = img.width-rect.x-rect.width; // update rect
  9956. frame.regX = rect.width-src.regX; // update registration point
  9957. }
  9958. if (v) {
  9959. rect.y = img.height-rect.y-rect.height; // update rect
  9960. frame.regY = rect.height-src.regY; // update registration point
  9961. }
  9962. frames.push(frame);
  9963. }
  9964. var sfx = "_"+(h?"h":"")+(v?"v":"");
  9965. var names = spriteSheet._animations;
  9966. var data = spriteSheet._data;
  9967. var al = names.length/count;
  9968. for (i=0;i<al;i++) {
  9969. var name = names[i];
  9970. src = data[name];
  9971. var anim = {name:name+sfx,speed:src.speed,next:src.next,frames:[]};
  9972. if (src.next) { anim.next += sfx; }
  9973. frames = src.frames;
  9974. for (var j=0,l=frames.length;j<l;j++) {
  9975. anim.frames.push(frames[j]+fl*count);
  9976. }
  9977. data[anim.name] = anim;
  9978. names.push(anim.name);
  9979. }
  9980. };
  9981. createjs.SpriteSheetUtils = SpriteSheetUtils;
  9982. }());
  9983. //##############################################################################
  9984. // SpriteSheetBuilder.js
  9985. //##############################################################################
  9986. this.createjs = this.createjs||{};
  9987. (function() {
  9988. "use strict";
  9989. // constructor:
  9990. /**
  9991. * The SpriteSheetBuilder allows you to generate {{#crossLink "SpriteSheet"}}{{/crossLink}} instances at run time
  9992. * from any display object. This can allow you to maintain your assets as vector graphics (for low file size), and
  9993. * render them at run time as SpriteSheets for better performance.
  9994. *
  9995. * SpriteSheets can be built either synchronously, or asynchronously, so that large SpriteSheets can be generated
  9996. * without locking the UI.
  9997. *
  9998. * Note that the "images" used in the generated SpriteSheet are actually canvas elements, and that they will be
  9999. * sized to the nearest power of 2 up to the value of {{#crossLink "SpriteSheetBuilder/maxWidth:property"}}{{/crossLink}}
  10000. * or {{#crossLink "SpriteSheetBuilder/maxHeight:property"}}{{/crossLink}}.
  10001. * @class SpriteSheetBuilder
  10002. * @param {Number} [framerate=0] The {{#crossLink "SpriteSheet/framerate:property"}}{{/crossLink}} of
  10003. * {{#crossLink "SpriteSheet"}}{{/crossLink}} instances that are created.
  10004. * @extends EventDispatcher
  10005. * @constructor
  10006. **/
  10007. function SpriteSheetBuilder(framerate) {
  10008. this.EventDispatcher_constructor();
  10009. // public properties:
  10010. /**
  10011. * The maximum width for the images (not individual frames) in the generated SpriteSheet. It is recommended to
  10012. * use a power of 2 for this value (ex. 1024, 2048, 4096). If the frames cannot all fit within the max
  10013. * dimensions, then additional images will be created as needed.
  10014. * @property maxWidth
  10015. * @type Number
  10016. * @default 2048
  10017. */
  10018. this.maxWidth = 2048;
  10019. /**
  10020. * The maximum height for the images (not individual frames) in the generated SpriteSheet. It is recommended to
  10021. * use a power of 2 for this value (ex. 1024, 2048, 4096). If the frames cannot all fit within the max
  10022. * dimensions, then additional images will be created as needed.
  10023. * @property maxHeight
  10024. * @type Number
  10025. * @default 2048
  10026. **/
  10027. this.maxHeight = 2048;
  10028. /**
  10029. * The SpriteSheet that was generated. This will be null before a build is completed successfully.
  10030. * @property spriteSheet
  10031. * @type SpriteSheet
  10032. **/
  10033. this.spriteSheet = null;
  10034. /**
  10035. * The scale to apply when drawing all frames to the SpriteSheet. This is multiplied against any scale specified
  10036. * in the addFrame call. This can be used, for example, to generate a SpriteSheet at run time that is tailored
  10037. * to the a specific device resolution (ex. tablet vs mobile).
  10038. * @property scale
  10039. * @type Number
  10040. * @default 1
  10041. **/
  10042. this.scale = 1;
  10043. /**
  10044. * The padding to use between frames. This is helpful to preserve antialiasing on drawn vector content.
  10045. * @property padding
  10046. * @type Number
  10047. * @default 1
  10048. **/
  10049. this.padding = 1;
  10050. /**
  10051. * A number from 0.01 to 0.99 that indicates what percentage of time the builder can use. This can be
  10052. * thought of as the number of seconds per second the builder will use. For example, with a timeSlice value of 0.3,
  10053. * the builder will run 20 times per second, using approximately 15ms per build (30% of available time, or 0.3s per second).
  10054. * Defaults to 0.3.
  10055. * @property timeSlice
  10056. * @type Number
  10057. * @default 0.3
  10058. **/
  10059. this.timeSlice = 0.3;
  10060. /**
  10061. * A value between 0 and 1 that indicates the progress of a build, or -1 if a build has not
  10062. * been initiated.
  10063. * @property progress
  10064. * @type Number
  10065. * @default -1
  10066. * @readonly
  10067. */
  10068. this.progress = -1;
  10069. /**
  10070. * A {{#crossLink "SpriteSheet/framerate:property"}}{{/crossLink}} value that will be passed to new {{#crossLink "SpriteSheet"}}{{/crossLink}} instances that are
  10071. * created. If no framerate is specified (or it is 0), then SpriteSheets will use the {{#crossLink "Ticker"}}{{/crossLink}}
  10072. * framerate.
  10073. * @property framerate
  10074. * @type Number
  10075. * @default 0
  10076. */
  10077. this.framerate = framerate || 0;
  10078. // private properties:
  10079. /**
  10080. * @property _frames
  10081. * @protected
  10082. * @type Array
  10083. **/
  10084. this._frames = [];
  10085. /**
  10086. * @property _animations
  10087. * @protected
  10088. * @type Array
  10089. **/
  10090. this._animations = {};
  10091. /**
  10092. * @property _data
  10093. * @protected
  10094. * @type Array
  10095. **/
  10096. this._data = null;
  10097. /**
  10098. * @property _nextFrameIndex
  10099. * @protected
  10100. * @type Number
  10101. **/
  10102. this._nextFrameIndex = 0;
  10103. /**
  10104. * @property _index
  10105. * @protected
  10106. * @type Number
  10107. **/
  10108. this._index = 0;
  10109. /**
  10110. * @property _timerID
  10111. * @protected
  10112. * @type Number
  10113. **/
  10114. this._timerID = null;
  10115. /**
  10116. * @property _scale
  10117. * @protected
  10118. * @type Number
  10119. **/
  10120. this._scale = 1;
  10121. }
  10122. var p = createjs.extend(SpriteSheetBuilder, createjs.EventDispatcher);
  10123. /**
  10124. * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`.
  10125. * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}}
  10126. * for details.
  10127. *
  10128. * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance.
  10129. *
  10130. * @method initialize
  10131. * @protected
  10132. * @deprecated
  10133. */
  10134. // p.initialize = function() {}; // searchable for devs wondering where it is.
  10135. // constants:
  10136. SpriteSheetBuilder.ERR_DIMENSIONS = "frame dimensions exceed max spritesheet dimensions";
  10137. SpriteSheetBuilder.ERR_RUNNING = "a build is already running";
  10138. // events:
  10139. /**
  10140. * Dispatched when a build completes.
  10141. * @event complete
  10142. * @param {Object} target The object that dispatched the event.
  10143. * @param {String} type The event type.
  10144. * @since 0.6.0
  10145. */
  10146. /**
  10147. * Dispatched when an asynchronous build has progress.
  10148. * @event progress
  10149. * @param {Object} target The object that dispatched the event.
  10150. * @param {String} type The event type.
  10151. * @param {Number} progress The current progress value (0-1).
  10152. * @since 0.6.0
  10153. */
  10154. // public methods:
  10155. /**
  10156. * Adds a frame to the {{#crossLink "SpriteSheet"}}{{/crossLink}}. Note that the frame will not be drawn until you
  10157. * call {{#crossLink "SpriteSheetBuilder/build"}}{{/crossLink}} method. The optional setup params allow you to have
  10158. * a function run immediately before the draw occurs. For example, this allows you to add a single source multiple
  10159. * times, but manipulate it or its children to change it to generate different frames.
  10160. *
  10161. * Note that the source's transformations (x, y, scale, rotate, alpha) will be ignored, except for regX/Y. To apply
  10162. * transforms to a source object and have them captured in the SpriteSheet, simply place it into a {{#crossLink "Container"}}{{/crossLink}}
  10163. * and pass in the Container as the source.
  10164. * @method addFrame
  10165. * @param {DisplayObject} source The source {{#crossLink "DisplayObject"}}{{/crossLink}} to draw as the frame.
  10166. * @param {Rectangle} [sourceRect] A {{#crossLink "Rectangle"}}{{/crossLink}} defining the portion of the
  10167. * source to draw to the frame. If not specified, it will look for a `getBounds` method, bounds property, or
  10168. * `nominalBounds` property on the source to use. If one is not found, the frame will be skipped.
  10169. * @param {Number} [scale=1] Optional. The scale to draw this frame at. Default is 1.
  10170. * @param {Function} [setupFunction] A function to call immediately before drawing this frame. It will be called with two parameters: the source, and setupData.
  10171. * @param {Object} [setupData] Arbitrary setup data to pass to setupFunction as the second parameter.
  10172. * @return {Number} The index of the frame that was just added, or null if a sourceRect could not be determined.
  10173. **/
  10174. p.addFrame = function(source, sourceRect, scale, setupFunction, setupData) {
  10175. if (this._data) { throw SpriteSheetBuilder.ERR_RUNNING; }
  10176. var rect = sourceRect||source.bounds||source.nominalBounds;
  10177. if (!rect&&source.getBounds) { rect = source.getBounds(); }
  10178. if (!rect) { return null; }
  10179. scale = scale||1;
  10180. return this._frames.push({source:source, sourceRect:rect, scale:scale, funct:setupFunction, data:setupData, index:this._frames.length, height:rect.height*scale})-1;
  10181. };
  10182. /**
  10183. * Adds an animation that will be included in the created {{#crossLink "SpriteSheet"}}{{/crossLink}}.
  10184. * @method addAnimation
  10185. * @param {String} name The name for the animation.
  10186. * @param {Array} frames An array of frame indexes that comprise the animation. Ex. [3,6,5] would describe an animation
  10187. * that played frame indexes 3, 6, and 5 in that order.
  10188. * @param {String} [next] Specifies the name of the animation to continue to after this animation ends. You can
  10189. * also pass false to have the animation stop when it ends. By default it will loop to the start of the same animation.
  10190. * @param {Number} [speed] Specifies a frame advance speed for this animation. For example, a value of 0.5 would
  10191. * cause the animation to advance every second tick. Note that earlier versions used `frequency` instead, which had
  10192. * the opposite effect.
  10193. **/
  10194. p.addAnimation = function(name, frames, next, speed) {
  10195. if (this._data) { throw SpriteSheetBuilder.ERR_RUNNING; }
  10196. this._animations[name] = {frames:frames, next:next, speed:speed};
  10197. };
  10198. /**
  10199. * This will take a {{#crossLink "MovieClip"}}{{/crossLink}} instance, and add its frames and labels to this
  10200. * builder. Labels will be added as an animation running from the label index to the next label. For example, if
  10201. * there is a label named "foo" at frame 0 and a label named "bar" at frame 10, in a MovieClip with 15 frames, it
  10202. * will add an animation named "foo" that runs from frame index 0 to 9, and an animation named "bar" that runs from
  10203. * frame index 10 to 14.
  10204. *
  10205. * Note that this will iterate through the full MovieClip with {{#crossLink "MovieClip/actionsEnabled:property"}}{{/crossLink}}
  10206. * set to `false`, ending on the last frame.
  10207. * @method addMovieClip
  10208. * @param {MovieClip} source The source MovieClip instance to add to the SpriteSheet.
  10209. * @param {Rectangle} [sourceRect] A {{#crossLink "Rectangle"}}{{/crossLink}} defining the portion of the source to
  10210. * draw to the frame. If not specified, it will look for a {{#crossLink "DisplayObject/getBounds"}}{{/crossLink}}
  10211. * method, `frameBounds` Array, `bounds` property, or `nominalBounds` property on the source to use. If one is not
  10212. * found, the MovieClip will be skipped.
  10213. * @param {Number} [scale=1] The scale to draw the movie clip at.
  10214. * @param {Function} [setupFunction] A function to call immediately before drawing each frame. It will be called
  10215. * with three parameters: the source, setupData, and the frame index.
  10216. * @param {Object} [setupData] Arbitrary setup data to pass to setupFunction as the second parameter.
  10217. * @param {Function} [labelFunction] This method will be called for each MovieClip label that is added with four
  10218. * parameters: the label name, the source MovieClip instance, the starting frame index (in the movieclip timeline)
  10219. * and the end index. It must return a new name for the label/animation, or `false` to exclude the label.
  10220. **/
  10221. p.addMovieClip = function(source, sourceRect, scale, setupFunction, setupData, labelFunction) {
  10222. if (this._data) { throw SpriteSheetBuilder.ERR_RUNNING; }
  10223. var rects = source.frameBounds;
  10224. var rect = sourceRect||source.bounds||source.nominalBounds;
  10225. if (!rect&&source.getBounds) { rect = source.getBounds(); }
  10226. if (!rect && !rects) { return; }
  10227. var i, l, baseFrameIndex = this._frames.length;
  10228. var duration = source.timeline.duration;
  10229. for (i=0; i<duration; i++) {
  10230. var r = (rects&&rects[i]) ? rects[i] : rect;
  10231. this.addFrame(source, r, scale, this._setupMovieClipFrame, {i:i, f:setupFunction, d:setupData});
  10232. }
  10233. var labels = source.timeline._labels;
  10234. var lbls = [];
  10235. for (var n in labels) {
  10236. lbls.push({index:labels[n], label:n});
  10237. }
  10238. if (lbls.length) {
  10239. lbls.sort(function(a,b){ return a.index-b.index; });
  10240. for (i=0,l=lbls.length; i<l; i++) {
  10241. var label = lbls[i].label;
  10242. var start = baseFrameIndex+lbls[i].index;
  10243. var end = baseFrameIndex+((i == l-1) ? duration : lbls[i+1].index);
  10244. var frames = [];
  10245. for (var j=start; j<end; j++) { frames.push(j); }
  10246. if (labelFunction) {
  10247. label = labelFunction(label, source, start, end);
  10248. if (!label) { continue; }
  10249. }
  10250. this.addAnimation(label, frames, true); // for now, this loops all animations.
  10251. }
  10252. }
  10253. };
  10254. /**
  10255. * Builds a {{#crossLink "SpriteSheet"}}{{/crossLink}} instance based on the current frames.
  10256. * @method build
  10257. * @return {SpriteSheet} The created SpriteSheet instance, or null if a build is already running or an error
  10258. * occurred.
  10259. **/
  10260. p.build = function() {
  10261. if (this._data) { throw SpriteSheetBuilder.ERR_RUNNING; }
  10262. this._startBuild();
  10263. while (this._drawNext()) {}
  10264. this._endBuild();
  10265. return this.spriteSheet;
  10266. };
  10267. /**
  10268. * Asynchronously builds a {{#crossLink "SpriteSheet"}}{{/crossLink}} instance based on the current frames. It will
  10269. * run 20 times per second, using an amount of time defined by `timeSlice`. When it is complete it will call the
  10270. * specified callback.
  10271. * @method buildAsync
  10272. * @param {Number} [timeSlice] Sets the timeSlice property on this instance.
  10273. **/
  10274. p.buildAsync = function(timeSlice) {
  10275. if (this._data) { throw SpriteSheetBuilder.ERR_RUNNING; }
  10276. this.timeSlice = timeSlice;
  10277. this._startBuild();
  10278. var _this = this;
  10279. this._timerID = setTimeout(function() { _this._run(); }, 50-Math.max(0.01, Math.min(0.99, this.timeSlice||0.3))*50);
  10280. };
  10281. /**
  10282. * Stops the current asynchronous build.
  10283. * @method stopAsync
  10284. **/
  10285. p.stopAsync = function() {
  10286. clearTimeout(this._timerID);
  10287. this._data = null;
  10288. };
  10289. /**
  10290. * SpriteSheetBuilder instances cannot be cloned.
  10291. * @method clone
  10292. **/
  10293. p.clone = function() {
  10294. throw("SpriteSheetBuilder cannot be cloned.");
  10295. };
  10296. /**
  10297. * Returns a string representation of this object.
  10298. * @method toString
  10299. * @return {String} a string representation of the instance.
  10300. **/
  10301. p.toString = function() {
  10302. return "[SpriteSheetBuilder]";
  10303. };
  10304. // private methods:
  10305. /**
  10306. * @method _startBuild
  10307. * @protected
  10308. **/
  10309. p._startBuild = function() {
  10310. var pad = this.padding||0;
  10311. this.progress = 0;
  10312. this.spriteSheet = null;
  10313. this._index = 0;
  10314. this._scale = this.scale;
  10315. var dataFrames = [];
  10316. this._data = {
  10317. images: [],
  10318. frames: dataFrames,
  10319. framerate: this.framerate,
  10320. animations: this._animations // TODO: should we "clone" _animations in case someone adds more animations after a build?
  10321. };
  10322. var frames = this._frames.slice();
  10323. frames.sort(function(a,b) { return (a.height<=b.height) ? -1 : 1; });
  10324. if (frames[frames.length-1].height+pad*2 > this.maxHeight) { throw SpriteSheetBuilder.ERR_DIMENSIONS; }
  10325. var y=0, x=0;
  10326. var img = 0;
  10327. while (frames.length) {
  10328. var o = this._fillRow(frames, y, img, dataFrames, pad);
  10329. if (o.w > x) { x = o.w; }
  10330. y += o.h;
  10331. if (!o.h || !frames.length) {
  10332. var canvas = createjs.createCanvas?createjs.createCanvas():document.createElement("canvas");
  10333. canvas.width = this._getSize(x,this.maxWidth);
  10334. canvas.height = this._getSize(y,this.maxHeight);
  10335. this._data.images[img] = canvas;
  10336. if (!o.h) {
  10337. x=y=0;
  10338. img++;
  10339. }
  10340. }
  10341. }
  10342. };
  10343. /**
  10344. * @method _setupMovieClipFrame
  10345. * @protected
  10346. * @return {Number} The width & height of the row.
  10347. **/
  10348. p._setupMovieClipFrame = function(source, data) {
  10349. var ae = source.actionsEnabled;
  10350. source.actionsEnabled = false;
  10351. source.gotoAndStop(data.i);
  10352. source.actionsEnabled = ae;
  10353. data.f&&data.f(source, data.d, data.i);
  10354. };
  10355. /**
  10356. * @method _getSize
  10357. * @protected
  10358. * @return {Number} The width & height of the row.
  10359. **/
  10360. p._getSize = function(size,max) {
  10361. var pow = 4;
  10362. while (Math.pow(2,++pow) < size){}
  10363. return Math.min(max,Math.pow(2,pow));
  10364. };
  10365. /**
  10366. * @method _fillRow
  10367. * @param {Array} frames
  10368. * @param {Number} y
  10369. * @param {HTMLImageElement} img
  10370. * @param {Object} dataFrames
  10371. * @param {Number} pad
  10372. * @protected
  10373. * @return {Number} The width & height of the row.
  10374. **/
  10375. p._fillRow = function(frames, y, img, dataFrames, pad) {
  10376. var w = this.maxWidth;
  10377. var maxH = this.maxHeight;
  10378. y += pad;
  10379. var h = maxH-y;
  10380. var x = pad;
  10381. var height = 0;
  10382. for (var i=frames.length-1; i>=0; i--) {
  10383. var frame = frames[i];
  10384. var sc = this._scale*frame.scale;
  10385. var rect = frame.sourceRect;
  10386. var source = frame.source;
  10387. var rx = Math.floor(sc*rect.x-pad);
  10388. var ry = Math.floor(sc*rect.y-pad);
  10389. var rh = Math.ceil(sc*rect.height+pad*2);
  10390. var rw = Math.ceil(sc*rect.width+pad*2);
  10391. if (rw > w) { throw SpriteSheetBuilder.ERR_DIMENSIONS; }
  10392. if (rh > h || x+rw > w) { continue; }
  10393. frame.img = img;
  10394. frame.rect = new createjs.Rectangle(x,y,rw,rh);
  10395. height = height || rh;
  10396. frames.splice(i,1);
  10397. dataFrames[frame.index] = [x,y,rw,rh,img,Math.round(-rx+sc*source.regX-pad),Math.round(-ry+sc*source.regY-pad)];
  10398. x += rw;
  10399. }
  10400. return {w:x, h:height};
  10401. };
  10402. /**
  10403. * @method _endBuild
  10404. * @protected
  10405. **/
  10406. p._endBuild = function() {
  10407. this.spriteSheet = new createjs.SpriteSheet(this._data);
  10408. this._data = null;
  10409. this.progress = 1;
  10410. this.dispatchEvent("complete");
  10411. };
  10412. /**
  10413. * @method _run
  10414. * @protected
  10415. **/
  10416. p._run = function() {
  10417. var ts = Math.max(0.01, Math.min(0.99, this.timeSlice||0.3))*50;
  10418. var t = (new Date()).getTime()+ts;
  10419. var complete = false;
  10420. while (t > (new Date()).getTime()) {
  10421. if (!this._drawNext()) { complete = true; break; }
  10422. }
  10423. if (complete) {
  10424. this._endBuild();
  10425. } else {
  10426. var _this = this;
  10427. this._timerID = setTimeout(function() { _this._run(); }, 50-ts);
  10428. }
  10429. var p = this.progress = this._index/this._frames.length;
  10430. if (this.hasEventListener("progress")) {
  10431. var evt = new createjs.Event("progress");
  10432. evt.progress = p;
  10433. this.dispatchEvent(evt);
  10434. }
  10435. };
  10436. /**
  10437. * @method _drawNext
  10438. * @protected
  10439. * @return Boolean Returns false if this is the last draw.
  10440. **/
  10441. p._drawNext = function() {
  10442. var frame = this._frames[this._index];
  10443. var sc = frame.scale*this._scale;
  10444. var rect = frame.rect;
  10445. var sourceRect = frame.sourceRect;
  10446. var canvas = this._data.images[frame.img];
  10447. var ctx = canvas.getContext("2d");
  10448. frame.funct&&frame.funct(frame.source, frame.data);
  10449. ctx.save();
  10450. ctx.beginPath();
  10451. ctx.rect(rect.x, rect.y, rect.width, rect.height);
  10452. ctx.clip();
  10453. ctx.translate(Math.ceil(rect.x-sourceRect.x*sc), Math.ceil(rect.y-sourceRect.y*sc));
  10454. ctx.scale(sc,sc);
  10455. frame.source.draw(ctx); // display object will draw itself.
  10456. ctx.restore();
  10457. return (++this._index) < this._frames.length;
  10458. };
  10459. createjs.SpriteSheetBuilder = createjs.promote(SpriteSheetBuilder, "EventDispatcher");
  10460. }());
  10461. //##############################################################################
  10462. // DOMElement.js
  10463. //##############################################################################
  10464. this.createjs = this.createjs||{};
  10465. (function() {
  10466. "use strict";
  10467. // constructor:
  10468. /**
  10469. * <b>This class is still experimental, and more advanced use is likely to be buggy. Please report bugs.</b>
  10470. *
  10471. * A DOMElement allows you to associate a HTMLElement with the display list. It will be transformed
  10472. * within the DOM as though it is child of the {{#crossLink "Container"}}{{/crossLink}} it is added to. However, it is
  10473. * not rendered to canvas, and as such will retain whatever z-index it has relative to the canvas (ie. it will be
  10474. * drawn in front of or behind the canvas).
  10475. *
  10476. * The position of a DOMElement is relative to their parent node in the DOM. It is recommended that
  10477. * the DOM Object be added to a div that also contains the canvas so that they share the same position
  10478. * on the page.
  10479. *
  10480. * DOMElement is useful for positioning HTML elements over top of canvas content, and for elements
  10481. * that you want to display outside the bounds of the canvas. For example, a tooltip with rich HTML
  10482. * content.
  10483. *
  10484. * <h4>Mouse Interaction</h4>
  10485. *
  10486. * DOMElement instances are not full EaselJS display objects, and do not participate in EaselJS mouse
  10487. * events or support methods like hitTest. To get mouse events from a DOMElement, you must instead add handlers to
  10488. * the htmlElement (note, this does not support EventDispatcher)
  10489. *
  10490. * var domElement = new createjs.DOMElement(htmlElement);
  10491. * domElement.htmlElement.onclick = function() {
  10492. * console.log("clicked");
  10493. * }
  10494. *
  10495. * @class DOMElement
  10496. * @extends DisplayObject
  10497. * @constructor
  10498. * @param {HTMLElement} htmlElement A reference or id for the DOM element to manage.
  10499. */
  10500. function DOMElement(htmlElement) {
  10501. this.DisplayObject_constructor();
  10502. if (typeof(htmlElement)=="string") { htmlElement = document.getElementById(htmlElement); }
  10503. this.mouseEnabled = false;
  10504. var style = htmlElement.style;
  10505. style.position = "absolute";
  10506. style.transformOrigin = style.WebkitTransformOrigin = style.msTransformOrigin = style.MozTransformOrigin = style.OTransformOrigin = "0% 0%";
  10507. // public properties:
  10508. /**
  10509. * The DOM object to manage.
  10510. * @property htmlElement
  10511. * @type HTMLElement
  10512. */
  10513. this.htmlElement = htmlElement;
  10514. // private properties:
  10515. /**
  10516. * @property _oldMtx
  10517. * @type Matrix2D
  10518. * @protected
  10519. */
  10520. this._oldProps = null;
  10521. }
  10522. var p = createjs.extend(DOMElement, createjs.DisplayObject);
  10523. // TODO: deprecated
  10524. // p.initialize = function() {}; // searchable for devs wondering where it is. REMOVED. See docs for details.
  10525. // public methods:
  10526. /**
  10527. * Returns true or false indicating whether the display object would be visible if drawn to a canvas.
  10528. * This does not account for whether it would be visible within the boundaries of the stage.
  10529. * NOTE: This method is mainly for internal use, though it may be useful for advanced uses.
  10530. * @method isVisible
  10531. * @return {Boolean} Boolean indicating whether the display object would be visible if drawn to a canvas
  10532. */
  10533. p.isVisible = function() {
  10534. return this.htmlElement != null;
  10535. };
  10536. /**
  10537. * Draws the display object into the specified context ignoring its visible, alpha, shadow, and transform.
  10538. * Returns true if the draw was handled (useful for overriding functionality).
  10539. * NOTE: This method is mainly for internal use, though it may be useful for advanced uses.
  10540. * @method draw
  10541. * @param {CanvasRenderingContext2D} ctx The canvas 2D context object to draw into.
  10542. * @param {Boolean} ignoreCache Indicates whether the draw operation should ignore any current cache.
  10543. * For example, used for drawing the cache (to prevent it from simply drawing an existing cache back
  10544. * into itself).
  10545. * @return {Boolean}
  10546. */
  10547. p.draw = function(ctx, ignoreCache) {
  10548. // this relies on the _tick method because draw isn't called if the parent is not visible.
  10549. // the actual update happens in _handleDrawEnd
  10550. return true;
  10551. };
  10552. /**
  10553. * Not applicable to DOMElement.
  10554. * @method cache
  10555. */
  10556. p.cache = function() {};
  10557. /**
  10558. * Not applicable to DOMElement.
  10559. * @method uncache
  10560. */
  10561. p.uncache = function() {};
  10562. /**
  10563. * Not applicable to DOMElement.
  10564. * @method updateCache
  10565. */
  10566. p.updateCache = function() {};
  10567. /**
  10568. * Not applicable to DOMElement.
  10569. * @method hitTest
  10570. */
  10571. p.hitTest = function() {};
  10572. /**
  10573. * Not applicable to DOMElement.
  10574. * @method localToGlobal
  10575. */
  10576. p.localToGlobal = function() {};
  10577. /**
  10578. * Not applicable to DOMElement.
  10579. * @method globalToLocal
  10580. */
  10581. p.globalToLocal = function() {};
  10582. /**
  10583. * Not applicable to DOMElement.
  10584. * @method localToLocal
  10585. */
  10586. p.localToLocal = function() {};
  10587. /**
  10588. * DOMElement cannot be cloned. Throws an error.
  10589. * @method clone
  10590. */
  10591. p.clone = function() {
  10592. throw("DOMElement cannot be cloned.")
  10593. };
  10594. /**
  10595. * Returns a string representation of this object.
  10596. * @method toString
  10597. * @return {String} a string representation of the instance.
  10598. */
  10599. p.toString = function() {
  10600. return "[DOMElement (name="+ this.name +")]";
  10601. };
  10602. /**
  10603. * Interaction events should be added to `htmlElement`, and not the DOMElement instance, since DOMElement instances
  10604. * are not full EaselJS display objects and do not participate in EaselJS mouse events.
  10605. * @event click
  10606. */
  10607. /**
  10608. * Interaction events should be added to `htmlElement`, and not the DOMElement instance, since DOMElement instances
  10609. * are not full EaselJS display objects and do not participate in EaselJS mouse events.
  10610. * @event dblClick
  10611. */
  10612. /**
  10613. * Interaction events should be added to `htmlElement`, and not the DOMElement instance, since DOMElement instances
  10614. * are not full EaselJS display objects and do not participate in EaselJS mouse events.
  10615. * @event mousedown
  10616. */
  10617. /**
  10618. * The HTMLElement can listen for the mouseover event, not the DOMElement instance.
  10619. * Since DOMElement instances are not full EaselJS display objects and do not participate in EaselJS mouse events.
  10620. * @event mouseover
  10621. */
  10622. /**
  10623. * Not applicable to DOMElement.
  10624. * @event tick
  10625. */
  10626. // private methods:
  10627. /**
  10628. * @method _tick
  10629. * @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.
  10630. * function.
  10631. * @protected
  10632. */
  10633. p._tick = function(evtObj) {
  10634. var stage = this.getStage();
  10635. stage&&stage.on("drawend", this._handleDrawEnd, this, true);
  10636. this.DisplayObject__tick(evtObj);
  10637. };
  10638. /**
  10639. * @method _handleDrawEnd
  10640. * @param {Event} evt
  10641. * @protected
  10642. */
  10643. p._handleDrawEnd = function(evt) {
  10644. var o = this.htmlElement;
  10645. if (!o) { return; }
  10646. var style = o.style;
  10647. var props = this.getConcatenatedDisplayProps(this._props), mtx = props.matrix;
  10648. var visibility = props.visible ? "visible" : "hidden";
  10649. if (visibility != style.visibility) { style.visibility = visibility; }
  10650. if (!props.visible) { return; }
  10651. var oldProps = this._oldProps, oldMtx = oldProps&&oldProps.matrix;
  10652. var n = 10000; // precision
  10653. if (!oldMtx || !oldMtx.equals(mtx)) {
  10654. 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);
  10655. style.transform = style.WebkitTransform = style.OTransform = style.msTransform = str +","+ (mtx.ty+0.5|0) +")";
  10656. style.MozTransform = str +"px,"+ (mtx.ty+0.5|0) +"px)";
  10657. if (!oldProps) { oldProps = this._oldProps = new createjs.DisplayProps(true, NaN); }
  10658. oldProps.matrix.copy(mtx);
  10659. }
  10660. if (oldProps.alpha != props.alpha) {
  10661. style.opacity = ""+(props.alpha*n|0)/n;
  10662. oldProps.alpha = props.alpha;
  10663. }
  10664. };
  10665. createjs.DOMElement = createjs.promote(DOMElement, "DisplayObject");
  10666. }());
  10667. //##############################################################################
  10668. // Filter.js
  10669. //##############################################################################
  10670. this.createjs = this.createjs||{};
  10671. (function() {
  10672. "use strict";
  10673. // constructor:
  10674. /**
  10675. * Base class that all filters should inherit from. Filters need to be applied to objects that have been cached using
  10676. * the {{#crossLink "DisplayObject/cache"}}{{/crossLink}} method. If an object changes, please cache it again, or use
  10677. * {{#crossLink "DisplayObject/updateCache"}}{{/crossLink}}. Note that the filters must be applied before caching.
  10678. *
  10679. * <h4>Example</h4>
  10680. *
  10681. * myInstance.filters = [
  10682. * new createjs.ColorFilter(0, 0, 0, 1, 255, 0, 0),
  10683. * new createjs.BlurFilter(5, 5, 10)
  10684. * ];
  10685. * myInstance.cache(0,0, 100, 100);
  10686. *
  10687. * Note that each filter can implement a {{#crossLink "Filter/getBounds"}}{{/crossLink}} method, which returns the
  10688. * margins that need to be applied in order to fully display the filter. For example, the {{#crossLink "BlurFilter"}}{{/crossLink}}
  10689. * will cause an object to feather outwards, resulting in a margin around the shape.
  10690. *
  10691. * <h4>EaselJS Filters</h4>
  10692. * EaselJS comes with a number of pre-built filters:
  10693. * <ul><li>{{#crossLink "AlphaMapFilter"}}{{/crossLink}} : Map a greyscale image to the alpha channel of a display object</li>
  10694. * <li>{{#crossLink "AlphaMaskFilter"}}{{/crossLink}}: Map an image's alpha channel to the alpha channel of a display object</li>
  10695. * <li>{{#crossLink "BlurFilter"}}{{/crossLink}}: Apply vertical and horizontal blur to a display object</li>
  10696. * <li>{{#crossLink "ColorFilter"}}{{/crossLink}}: Color transform a display object</li>
  10697. * <li>{{#crossLink "ColorMatrixFilter"}}{{/crossLink}}: Transform an image using a {{#crossLink "ColorMatrix"}}{{/crossLink}}</li>
  10698. * </ul>
  10699. *
  10700. * @class Filter
  10701. * @constructor
  10702. **/
  10703. function Filter() {}
  10704. var p = Filter.prototype;
  10705. /**
  10706. * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`.
  10707. * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}}
  10708. * for details.
  10709. *
  10710. * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance.
  10711. *
  10712. * @method initialize
  10713. * @protected
  10714. * @deprecated
  10715. */
  10716. // p.initialize = function() {}; // searchable for devs wondering where it is.
  10717. // public methods:
  10718. /**
  10719. * Provides padding values for this filter. That is, how much the filter will extend the visual bounds of an object it is applied to.
  10720. * @method getBounds
  10721. * @param {Rectangle} [rect] If specified, the provided Rectangle instance will be expanded by the padding amounts and returned.
  10722. * @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.
  10723. **/
  10724. p.getBounds = function(rect) {
  10725. return rect;
  10726. };
  10727. /**
  10728. * Applies the filter to the specified context.
  10729. * @method applyFilter
  10730. * @param {CanvasRenderingContext2D} ctx The 2D context to use as the source.
  10731. * @param {Number} x The x position to use for the source rect.
  10732. * @param {Number} y The y position to use for the source rect.
  10733. * @param {Number} width The width to use for the source rect.
  10734. * @param {Number} height The height to use for the source rect.
  10735. * @param {CanvasRenderingContext2D} [targetCtx] The 2D context to draw the result to. Defaults to the context passed to ctx.
  10736. * @param {Number} [targetX] The x position to draw the result to. Defaults to the value passed to x.
  10737. * @param {Number} [targetY] The y position to draw the result to. Defaults to the value passed to y.
  10738. * @return {Boolean} If the filter was applied successfully.
  10739. **/
  10740. p.applyFilter = function(ctx, x, y, width, height, targetCtx, targetX, targetY) {
  10741. // this is the default behaviour because most filters access pixel data. It is overridden when not needed.
  10742. targetCtx = targetCtx || ctx;
  10743. if (targetX == null) { targetX = x; }
  10744. if (targetY == null) { targetY = y; }
  10745. try {
  10746. var imageData = ctx.getImageData(x, y, width, height);
  10747. } catch (e) {
  10748. return false;
  10749. }
  10750. if (this._applyFilter(imageData)) {
  10751. targetCtx.putImageData(imageData, targetX, targetY);
  10752. return true;
  10753. }
  10754. return false;
  10755. };
  10756. /**
  10757. * Returns a string representation of this object.
  10758. * @method toString
  10759. * @return {String} a string representation of the instance.
  10760. **/
  10761. p.toString = function() {
  10762. return "[Filter]";
  10763. };
  10764. /**
  10765. * Returns a clone of this Filter instance.
  10766. * @method clone
  10767. * @return {Filter} A clone of the current Filter instance.
  10768. **/
  10769. p.clone = function() {
  10770. return new Filter();
  10771. };
  10772. // private methods:
  10773. /**
  10774. * @method _applyFilter
  10775. * @param {ImageData} imageData Target ImageData instance.
  10776. * @return {Boolean}
  10777. **/
  10778. p._applyFilter = function(imageData) { return true; };
  10779. createjs.Filter = Filter;
  10780. }());
  10781. //##############################################################################
  10782. // BlurFilter.js
  10783. //##############################################################################
  10784. this.createjs = this.createjs||{};
  10785. (function() {
  10786. "use strict";
  10787. // constructor:
  10788. /**
  10789. * Applies a box blur to DisplayObjects. Note that this filter is fairly CPU intensive, particularly if the quality is
  10790. * set higher than 1.
  10791. *
  10792. * <h4>Example</h4>
  10793. * This example creates a red circle, and then applies a 5 pixel blur to it. It uses the {{#crossLink "Filter/getBounds"}}{{/crossLink}}
  10794. * method to account for the spread that the blur causes.
  10795. *
  10796. * var shape = new createjs.Shape().set({x:100,y:100});
  10797. * shape.graphics.beginFill("#ff0000").drawCircle(0,0,50);
  10798. *
  10799. * var blurFilter = new createjs.BlurFilter(5, 5, 1);
  10800. * shape.filters = [blurFilter];
  10801. * var bounds = blurFilter.getBounds();
  10802. *
  10803. * shape.cache(-50+bounds.x, -50+bounds.y, 100+bounds.width, 100+bounds.height);
  10804. *
  10805. * See {{#crossLink "Filter"}}{{/crossLink}} for an more information on applying filters.
  10806. * @class BlurFilter
  10807. * @extends Filter
  10808. * @constructor
  10809. * @param {Number} [blurX=0] The horizontal blur radius in pixels.
  10810. * @param {Number} [blurY=0] The vertical blur radius in pixels.
  10811. * @param {Number} [quality=1] The number of blur iterations.
  10812. **/
  10813. function BlurFilter( blurX, blurY, quality) {
  10814. if ( isNaN(blurX) || blurX < 0 ) blurX = 0;
  10815. if ( isNaN(blurY) || blurY < 0 ) blurY = 0;
  10816. if ( isNaN(quality) || quality < 1 ) quality = 1;
  10817. // public properties:
  10818. /**
  10819. * Horizontal blur radius in pixels
  10820. * @property blurX
  10821. * @default 0
  10822. * @type Number
  10823. **/
  10824. this.blurX = blurX | 0;
  10825. /**
  10826. * Vertical blur radius in pixels
  10827. * @property blurY
  10828. * @default 0
  10829. * @type Number
  10830. **/
  10831. this.blurY = blurY | 0;
  10832. /**
  10833. * Number of blur iterations. For example, a value of 1 will produce a rough blur. A value of 2 will produce a
  10834. * smoother blur, but take twice as long to run.
  10835. * @property quality
  10836. * @default 1
  10837. * @type Number
  10838. **/
  10839. this.quality = quality | 0;
  10840. }
  10841. var p = createjs.extend(BlurFilter, createjs.Filter);
  10842. // TODO: deprecated
  10843. // p.initialize = function() {}; // searchable for devs wondering where it is. REMOVED. See docs for details.
  10844. // constants:
  10845. /**
  10846. * Array of multiply values for blur calculations.
  10847. * @property MUL_TABLE
  10848. * @type Array
  10849. * @protected
  10850. * @static
  10851. **/
  10852. 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];
  10853. /**
  10854. * Array of shift values for blur calculations.
  10855. * @property SHG_TABLE
  10856. * @type Array
  10857. * @protected
  10858. * @static
  10859. **/
  10860. 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];
  10861. // public methods:
  10862. /** docced in super class **/
  10863. p.getBounds = function (rect) {
  10864. var x = this.blurX|0, y = this.blurY| 0;
  10865. if (x <= 0 && y <= 0) { return rect; }
  10866. var q = Math.pow(this.quality, 0.2);
  10867. return (rect || new createjs.Rectangle()).pad(x*q+1,y*q+1,x*q+1,y*q+1);
  10868. };
  10869. /** docced in super class **/
  10870. p.clone = function() {
  10871. return new BlurFilter(this.blurX, this.blurY, this.quality);
  10872. };
  10873. /** docced in super class **/
  10874. p.toString = function() {
  10875. return "[BlurFilter]";
  10876. };
  10877. // private methods:
  10878. /** docced in super class **/
  10879. p._applyFilter = function (imageData) {
  10880. var radiusX = this.blurX >> 1;
  10881. if (isNaN(radiusX) || radiusX < 0) return false;
  10882. var radiusY = this.blurY >> 1;
  10883. if (isNaN(radiusY) || radiusY < 0) return false;
  10884. if (radiusX == 0 && radiusY == 0) return false;
  10885. var iterations = this.quality;
  10886. if (isNaN(iterations) || iterations < 1) iterations = 1;
  10887. iterations |= 0;
  10888. if (iterations > 3) iterations = 3;
  10889. if (iterations < 1) iterations = 1;
  10890. var px = imageData.data;
  10891. 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;
  10892. var divx = (radiusX + radiusX + 1) | 0;
  10893. var divy = (radiusY + radiusY + 1) | 0;
  10894. var w = imageData.width | 0;
  10895. var h = imageData.height | 0;
  10896. var w1 = (w - 1) | 0;
  10897. var h1 = (h - 1) | 0;
  10898. var rxp1 = (radiusX + 1) | 0;
  10899. var ryp1 = (radiusY + 1) | 0;
  10900. var ssx = {r:0,b:0,g:0,a:0};
  10901. var sx = ssx;
  10902. for ( i = 1; i < divx; i++ )
  10903. {
  10904. sx = sx.n = {r:0,b:0,g:0,a:0};
  10905. }
  10906. sx.n = ssx;
  10907. var ssy = {r:0,b:0,g:0,a:0};
  10908. var sy = ssy;
  10909. for ( i = 1; i < divy; i++ )
  10910. {
  10911. sy = sy.n = {r:0,b:0,g:0,a:0};
  10912. }
  10913. sy.n = ssy;
  10914. var si = null;
  10915. var mtx = BlurFilter.MUL_TABLE[radiusX] | 0;
  10916. var stx = BlurFilter.SHG_TABLE[radiusX] | 0;
  10917. var mty = BlurFilter.MUL_TABLE[radiusY] | 0;
  10918. var sty = BlurFilter.SHG_TABLE[radiusY] | 0;
  10919. while (iterations-- > 0) {
  10920. yw = yi = 0;
  10921. var ms = mtx;
  10922. var ss = stx;
  10923. for (y = h; --y > -1;) {
  10924. r = rxp1 * (pr = px[(yi) | 0]);
  10925. g = rxp1 * (pg = px[(yi + 1) | 0]);
  10926. b = rxp1 * (pb = px[(yi + 2) | 0]);
  10927. a = rxp1 * (pa = px[(yi + 3) | 0]);
  10928. sx = ssx;
  10929. for( i = rxp1; --i > -1; )
  10930. {
  10931. sx.r = pr;
  10932. sx.g = pg;
  10933. sx.b = pb;
  10934. sx.a = pa;
  10935. sx = sx.n;
  10936. }
  10937. for( i = 1; i < rxp1; i++ )
  10938. {
  10939. p = (yi + ((w1 < i ? w1 : i) << 2)) | 0;
  10940. r += ( sx.r = px[p]);
  10941. g += ( sx.g = px[p+1]);
  10942. b += ( sx.b = px[p+2]);
  10943. a += ( sx.a = px[p+3]);
  10944. sx = sx.n;
  10945. }
  10946. si = ssx;
  10947. for ( x = 0; x < w; x++ )
  10948. {
  10949. px[yi++] = (r * ms) >>> ss;
  10950. px[yi++] = (g * ms) >>> ss;
  10951. px[yi++] = (b * ms) >>> ss;
  10952. px[yi++] = (a * ms) >>> ss;
  10953. p = ((yw + ((p = x + radiusX + 1) < w1 ? p : w1)) << 2);
  10954. r -= si.r - ( si.r = px[p]);
  10955. g -= si.g - ( si.g = px[p+1]);
  10956. b -= si.b - ( si.b = px[p+2]);
  10957. a -= si.a - ( si.a = px[p+3]);
  10958. si = si.n;
  10959. }
  10960. yw += w;
  10961. }
  10962. ms = mty;
  10963. ss = sty;
  10964. for (x = 0; x < w; x++) {
  10965. yi = (x << 2) | 0;
  10966. r = (ryp1 * (pr = px[yi])) | 0;
  10967. g = (ryp1 * (pg = px[(yi + 1) | 0])) | 0;
  10968. b = (ryp1 * (pb = px[(yi + 2) | 0])) | 0;
  10969. a = (ryp1 * (pa = px[(yi + 3) | 0])) | 0;
  10970. sy = ssy;
  10971. for( i = 0; i < ryp1; i++ )
  10972. {
  10973. sy.r = pr;
  10974. sy.g = pg;
  10975. sy.b = pb;
  10976. sy.a = pa;
  10977. sy = sy.n;
  10978. }
  10979. yp = w;
  10980. for( i = 1; i <= radiusY; i++ )
  10981. {
  10982. yi = ( yp + x ) << 2;
  10983. r += ( sy.r = px[yi]);
  10984. g += ( sy.g = px[yi+1]);
  10985. b += ( sy.b = px[yi+2]);
  10986. a += ( sy.a = px[yi+3]);
  10987. sy = sy.n;
  10988. if( i < h1 )
  10989. {
  10990. yp += w;
  10991. }
  10992. }
  10993. yi = x;
  10994. si = ssy;
  10995. if ( iterations > 0 )
  10996. {
  10997. for ( y = 0; y < h; y++ )
  10998. {
  10999. p = yi << 2;
  11000. px[p+3] = pa =(a * ms) >>> ss;
  11001. if ( pa > 0 )
  11002. {
  11003. px[p] = ((r * ms) >>> ss );
  11004. px[p+1] = ((g * ms) >>> ss );
  11005. px[p+2] = ((b * ms) >>> ss );
  11006. } else {
  11007. px[p] = px[p+1] = px[p+2] = 0
  11008. }
  11009. p = ( x + (( ( p = y + ryp1) < h1 ? p : h1 ) * w )) << 2;
  11010. r -= si.r - ( si.r = px[p]);
  11011. g -= si.g - ( si.g = px[p+1]);
  11012. b -= si.b - ( si.b = px[p+2]);
  11013. a -= si.a - ( si.a = px[p+3]);
  11014. si = si.n;
  11015. yi += w;
  11016. }
  11017. } else {
  11018. for ( y = 0; y < h; y++ )
  11019. {
  11020. p = yi << 2;
  11021. px[p+3] = pa =(a * ms) >>> ss;
  11022. if ( pa > 0 )
  11023. {
  11024. pa = 255 / pa;
  11025. px[p] = ((r * ms) >>> ss ) * pa;
  11026. px[p+1] = ((g * ms) >>> ss ) * pa;
  11027. px[p+2] = ((b * ms) >>> ss ) * pa;
  11028. } else {
  11029. px[p] = px[p+1] = px[p+2] = 0
  11030. }
  11031. p = ( x + (( ( p = y + ryp1) < h1 ? p : h1 ) * w )) << 2;
  11032. r -= si.r - ( si.r = px[p]);
  11033. g -= si.g - ( si.g = px[p+1]);
  11034. b -= si.b - ( si.b = px[p+2]);
  11035. a -= si.a - ( si.a = px[p+3]);
  11036. si = si.n;
  11037. yi += w;
  11038. }
  11039. }
  11040. }
  11041. }
  11042. return true;
  11043. };
  11044. createjs.BlurFilter = createjs.promote(BlurFilter, "Filter");
  11045. }());
  11046. //##############################################################################
  11047. // AlphaMapFilter.js
  11048. //##############################################################################
  11049. this.createjs = this.createjs || {};
  11050. (function () {
  11051. "use strict";
  11052. // constructor:
  11053. /**
  11054. * Applies a greyscale alpha map image (or canvas) to the target, such that the alpha channel of the result will
  11055. * be copied from the red channel of the map, and the RGB channels will be copied from the target.
  11056. *
  11057. * Generally, it is recommended that you use {{#crossLink "AlphaMaskFilter"}}{{/crossLink}}, because it has much
  11058. * better performance.
  11059. *
  11060. * <h4>Example</h4>
  11061. * This example draws a red->blue box, caches it, and then uses the cache canvas as an alpha map on a 100x100 image.
  11062. *
  11063. * var box = new createjs.Shape();
  11064. * box.graphics.beginLinearGradientFill(["#ff0000", "#0000ff"], [0, 1], 0, 0, 0, 100)
  11065. * box.graphics.drawRect(0, 0, 100, 100);
  11066. * box.cache(0, 0, 100, 100);
  11067. *
  11068. * var bmp = new createjs.Bitmap("path/to/image.jpg");
  11069. * bmp.filters = [
  11070. * new createjs.AlphaMapFilter(box.cacheCanvas)
  11071. * ];
  11072. * bmp.cache(0, 0, 100, 100);
  11073. * stage.addChild(bmp);
  11074. *
  11075. * See {{#crossLink "Filter"}}{{/crossLink}} for more information on applying filters.
  11076. * @class AlphaMapFilter
  11077. * @extends Filter
  11078. * @constructor
  11079. * @param {HTMLImageElement|HTMLCanvasElement} alphaMap The greyscale image (or canvas) to use as the alpha value for the
  11080. * result. This should be exactly the same dimensions as the target.
  11081. **/
  11082. function AlphaMapFilter(alphaMap) {
  11083. // public properties:
  11084. /**
  11085. * The greyscale image (or canvas) to use as the alpha value for the result. This should be exactly the same
  11086. * dimensions as the target.
  11087. * @property alphaMap
  11088. * @type HTMLImageElement|HTMLCanvasElement
  11089. **/
  11090. this.alphaMap = alphaMap;
  11091. // private properties:
  11092. /**
  11093. * @property _alphaMap
  11094. * @protected
  11095. * @type HTMLImageElement|HTMLCanvasElement
  11096. **/
  11097. this._alphaMap = null;
  11098. /**
  11099. * @property _mapData
  11100. * @protected
  11101. * @type Uint8ClampedArray
  11102. **/
  11103. this._mapData = null;
  11104. }
  11105. var p = createjs.extend(AlphaMapFilter, createjs.Filter);
  11106. // TODO: deprecated
  11107. // p.initialize = function() {}; // searchable for devs wondering where it is. REMOVED. See docs for details.
  11108. // public methods:
  11109. /** docced in super class **/
  11110. p.clone = function () {
  11111. var o = new AlphaMapFilter(this.alphaMap);
  11112. o._alphaMap = this._alphaMap;
  11113. o._mapData = this._mapData;
  11114. return o;
  11115. };
  11116. /** docced in super class **/
  11117. p.toString = function () {
  11118. return "[AlphaMapFilter]";
  11119. };
  11120. // private methods:
  11121. /** docced in super class **/
  11122. p._applyFilter = function (imageData) {
  11123. if (!this.alphaMap) { return true; }
  11124. if (!this._prepAlphaMap()) { return false; }
  11125. // TODO: update to support scenarios where the target has different dimensions.
  11126. var data = imageData.data;
  11127. var map = this._mapData;
  11128. for(var i=0, l=data.length; i<l; i += 4) { data[i + 3] = map[i] || 0; }
  11129. return true;
  11130. };
  11131. /**
  11132. * @method _prepAlphaMap
  11133. * @protected
  11134. **/
  11135. p._prepAlphaMap = function () {
  11136. if (!this.alphaMap) { return false; }
  11137. if (this.alphaMap == this._alphaMap && this._mapData) { return true; }
  11138. this._mapData = null;
  11139. var map = this._alphaMap = this.alphaMap;
  11140. var canvas = map;
  11141. var ctx;
  11142. if (map instanceof HTMLCanvasElement) {
  11143. ctx = canvas.getContext("2d");
  11144. } else {
  11145. canvas = createjs.createCanvas ? createjs.createCanvas() : document.createElement("canvas");
  11146. canvas.width = map.width;
  11147. canvas.height = map.height;
  11148. ctx = canvas.getContext("2d");
  11149. ctx.drawImage(map, 0, 0);
  11150. }
  11151. try {
  11152. var imgData = ctx.getImageData(0, 0, map.width, map.height);
  11153. } catch (e) {
  11154. //if (!this.suppressCrossDomainErrors) throw new Error("unable to access local image data: " + e);
  11155. return false;
  11156. }
  11157. this._mapData = imgData.data;
  11158. return true;
  11159. };
  11160. createjs.AlphaMapFilter = createjs.promote(AlphaMapFilter, "Filter");
  11161. }());
  11162. //##############################################################################
  11163. // AlphaMaskFilter.js
  11164. //##############################################################################
  11165. this.createjs = this.createjs || {};
  11166. (function () {
  11167. "use strict";
  11168. // constructor:
  11169. /**
  11170. * Applies the alpha from the mask image (or canvas) to the target, such that the alpha channel of the result will
  11171. * be derived from the mask, and the RGB channels will be copied from the target. This can be used, for example, to
  11172. * apply an alpha mask to a display object. This can also be used to combine a JPG compressed RGB image with a PNG32
  11173. * alpha mask, which can result in a much smaller file size than a single PNG32 containing ARGB.
  11174. *
  11175. * <b>IMPORTANT NOTE: This filter currently does not support the targetCtx, or targetX/Y parameters correctly.</b>
  11176. *
  11177. * <h4>Example</h4>
  11178. * This example draws a gradient box, then caches it and uses the "cacheCanvas" as the alpha mask on a 100x100 image.
  11179. *
  11180. * var box = new createjs.Shape();
  11181. * box.graphics.beginLinearGradientFill(["#000000", "rgba(0, 0, 0, 0)"], [0, 1], 0, 0, 100, 100)
  11182. * box.graphics.drawRect(0, 0, 100, 100);
  11183. * box.cache(0, 0, 100, 100);
  11184. *
  11185. * var bmp = new createjs.Bitmap("path/to/image.jpg");
  11186. * bmp.filters = [
  11187. * new createjs.AlphaMaskFilter(box.cacheCanvas)
  11188. * ];
  11189. * bmp.cache(0, 0, 100, 100);
  11190. *
  11191. * See {{#crossLink "Filter"}}{{/crossLink}} for more information on applying filters.
  11192. * @class AlphaMaskFilter
  11193. * @extends Filter
  11194. * @constructor
  11195. * @param {HTMLImageElement|HTMLCanvasElement} mask
  11196. **/
  11197. function AlphaMaskFilter(mask) {
  11198. // public properties:
  11199. /**
  11200. * The image (or canvas) to use as the mask.
  11201. * @property mask
  11202. * @type HTMLImageElement|HTMLCanvasElement
  11203. **/
  11204. this.mask = mask;
  11205. }
  11206. var p = createjs.extend(AlphaMaskFilter, createjs.Filter);
  11207. // TODO: deprecated
  11208. // p.initialize = function() {}; // searchable for devs wondering where it is. REMOVED. See docs for details.
  11209. // public methods:
  11210. /**
  11211. * Applies the filter to the specified context.
  11212. *
  11213. * <strong>IMPORTANT NOTE: This filter currently does not support the targetCtx, or targetX/Y parameters
  11214. * correctly.</strong>
  11215. * @method applyFilter
  11216. * @param {CanvasRenderingContext2D} ctx The 2D context to use as the source.
  11217. * @param {Number} x The x position to use for the source rect.
  11218. * @param {Number} y The y position to use for the source rect.
  11219. * @param {Number} width The width to use for the source rect.
  11220. * @param {Number} height The height to use for the source rect.
  11221. * @param {CanvasRenderingContext2D} [targetCtx] NOT SUPPORTED IN THIS FILTER. The 2D context to draw the result to. Defaults to the context passed to ctx.
  11222. * @param {Number} [targetX] NOT SUPPORTED IN THIS FILTER. The x position to draw the result to. Defaults to the value passed to x.
  11223. * @param {Number} [targetY] NOT SUPPORTED IN THIS FILTER. The y position to draw the result to. Defaults to the value passed to y.
  11224. * @return {Boolean} If the filter was applied successfully.
  11225. **/
  11226. p.applyFilter = function (ctx, x, y, width, height, targetCtx, targetX, targetY) {
  11227. if (!this.mask) { return true; }
  11228. targetCtx = targetCtx || ctx;
  11229. if (targetX == null) { targetX = x; }
  11230. if (targetY == null) { targetY = y; }
  11231. targetCtx.save();
  11232. if (ctx != targetCtx) {
  11233. // TODO: support targetCtx and targetX/Y
  11234. // clearRect, then draw the ctx in?
  11235. return false;
  11236. }
  11237. targetCtx.globalCompositeOperation = "destination-in";
  11238. targetCtx.drawImage(this.mask, targetX, targetY);
  11239. targetCtx.restore();
  11240. return true;
  11241. };
  11242. /** docced in super class **/
  11243. p.clone = function () {
  11244. return new AlphaMaskFilter(this.mask);
  11245. };
  11246. /** docced in super class **/
  11247. p.toString = function () {
  11248. return "[AlphaMaskFilter]";
  11249. };
  11250. createjs.AlphaMaskFilter = createjs.promote(AlphaMaskFilter, "Filter");
  11251. }());
  11252. //##############################################################################
  11253. // ColorFilter.js
  11254. //##############################################################################
  11255. this.createjs = this.createjs||{};
  11256. (function() {
  11257. "use strict";
  11258. // constructor:
  11259. /**
  11260. * Applies a color transform to DisplayObjects.
  11261. *
  11262. * <h4>Example</h4>
  11263. * This example draws a red circle, and then transforms it to Blue. This is accomplished by multiplying all the channels
  11264. * to 0 (except alpha, which is set to 1), and then adding 255 to the blue channel.
  11265. *
  11266. * var shape = new createjs.Shape().set({x:100,y:100});
  11267. * shape.graphics.beginFill("#ff0000").drawCircle(0,0,50);
  11268. *
  11269. * shape.filters = [
  11270. * new createjs.ColorFilter(0,0,0,1, 0,0,255,0)
  11271. * ];
  11272. * shape.cache(-50, -50, 100, 100);
  11273. *
  11274. * See {{#crossLink "Filter"}}{{/crossLink}} for an more information on applying filters.
  11275. * @class ColorFilter
  11276. * @param {Number} [redMultiplier=1] The amount to multiply against the red channel. This is a range between 0 and 1.
  11277. * @param {Number} [greenMultiplier=1] The amount to multiply against the green channel. This is a range between 0 and 1.
  11278. * @param {Number} [blueMultiplier=1] The amount to multiply against the blue channel. This is a range between 0 and 1.
  11279. * @param {Number} [alphaMultiplier=1] The amount to multiply against the alpha channel. This is a range between 0 and 1.
  11280. * @param {Number} [redOffset=0] The amount to add to the red channel after it has been multiplied. This is a range
  11281. * between -255 and 255.
  11282. * @param {Number} [greenOffset=0] The amount to add to the green channel after it has been multiplied. This is a range
  11283. * between -255 and 255.
  11284. * @param {Number} [blueOffset=0] The amount to add to the blue channel after it has been multiplied. This is a range
  11285. * between -255 and 255.
  11286. * @param {Number} [alphaOffset=0] The amount to add to the alpha channel after it has been multiplied. This is a range
  11287. * between -255 and 255.
  11288. * @constructor
  11289. * @extends Filter
  11290. **/
  11291. function ColorFilter(redMultiplier, greenMultiplier, blueMultiplier, alphaMultiplier, redOffset, greenOffset, blueOffset, alphaOffset) {
  11292. // public properties:
  11293. /**
  11294. * Red channel multiplier.
  11295. * @property redMultiplier
  11296. * @type Number
  11297. **/
  11298. this.redMultiplier = redMultiplier != null ? redMultiplier : 1;
  11299. /**
  11300. * Green channel multiplier.
  11301. * @property greenMultiplier
  11302. * @type Number
  11303. **/
  11304. this.greenMultiplier = greenMultiplier != null ? greenMultiplier : 1;
  11305. /**
  11306. * Blue channel multiplier.
  11307. * @property blueMultiplier
  11308. * @type Number
  11309. **/
  11310. this.blueMultiplier = blueMultiplier != null ? blueMultiplier : 1;
  11311. /**
  11312. * Alpha channel multiplier.
  11313. * @property alphaMultiplier
  11314. * @type Number
  11315. **/
  11316. this.alphaMultiplier = alphaMultiplier != null ? alphaMultiplier : 1;
  11317. /**
  11318. * Red channel offset (added to value).
  11319. * @property redOffset
  11320. * @type Number
  11321. **/
  11322. this.redOffset = redOffset || 0;
  11323. /**
  11324. * Green channel offset (added to value).
  11325. * @property greenOffset
  11326. * @type Number
  11327. **/
  11328. this.greenOffset = greenOffset || 0;
  11329. /**
  11330. * Blue channel offset (added to value).
  11331. * @property blueOffset
  11332. * @type Number
  11333. **/
  11334. this.blueOffset = blueOffset || 0;
  11335. /**
  11336. * Alpha channel offset (added to value).
  11337. * @property alphaOffset
  11338. * @type Number
  11339. **/
  11340. this.alphaOffset = alphaOffset || 0;
  11341. }
  11342. var p = createjs.extend(ColorFilter, createjs.Filter);
  11343. // TODO: deprecated
  11344. // p.initialize = function() {}; // searchable for devs wondering where it is. REMOVED. See docs for details.
  11345. // public methods:
  11346. /** docced in super class **/
  11347. p.toString = function() {
  11348. return "[ColorFilter]";
  11349. };
  11350. /** docced in super class **/
  11351. p.clone = function() {
  11352. return new ColorFilter(this.redMultiplier, this.greenMultiplier, this.blueMultiplier, this.alphaMultiplier, this.redOffset, this.greenOffset, this.blueOffset, this.alphaOffset);
  11353. };
  11354. // private methods:
  11355. /** docced in super class **/
  11356. p._applyFilter = function(imageData) {
  11357. var data = imageData.data;
  11358. var l = data.length;
  11359. for (var i=0; i<l; i+=4) {
  11360. data[i] = data[i]*this.redMultiplier+this.redOffset;
  11361. data[i+1] = data[i+1]*this.greenMultiplier+this.greenOffset;
  11362. data[i+2] = data[i+2]*this.blueMultiplier+this.blueOffset;
  11363. data[i+3] = data[i+3]*this.alphaMultiplier+this.alphaOffset;
  11364. }
  11365. return true;
  11366. };
  11367. createjs.ColorFilter = createjs.promote(ColorFilter, "Filter");
  11368. }());
  11369. //##############################################################################
  11370. // ColorMatrix.js
  11371. //##############################################################################
  11372. this.createjs = this.createjs||{};
  11373. (function() {
  11374. "use strict";
  11375. // constructor:
  11376. /**
  11377. * Provides helper functions for assembling a matrix for use with the {{#crossLink "ColorMatrixFilter"}}{{/crossLink}}.
  11378. * Most methods return the instance to facilitate chained calls.
  11379. *
  11380. * <h4>Example</h4>
  11381. *
  11382. * myColorMatrix.adjustHue(20).adjustBrightness(50);
  11383. *
  11384. * See {{#crossLink "Filter"}}{{/crossLink}} for an example of how to apply filters, or {{#crossLink "ColorMatrixFilter"}}{{/crossLink}}
  11385. * for an example of how to use ColorMatrix to change a DisplayObject's color.
  11386. * @class ColorMatrix
  11387. * @param {Number} brightness
  11388. * @param {Number} contrast
  11389. * @param {Number} saturation
  11390. * @param {Number} hue
  11391. * @constructor
  11392. **/
  11393. function ColorMatrix(brightness, contrast, saturation, hue) {
  11394. this.setColor(brightness, contrast, saturation, hue);
  11395. }
  11396. var p = ColorMatrix.prototype;
  11397. /**
  11398. * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`.
  11399. * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}}
  11400. * for details.
  11401. *
  11402. * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance.
  11403. *
  11404. * @method initialize
  11405. * @protected
  11406. * @deprecated
  11407. */
  11408. // p.initialize = function() {}; // searchable for devs wondering where it is.
  11409. // constants:
  11410. /**
  11411. * Array of delta values for contrast calculations.
  11412. * @property DELTA_INDEX
  11413. * @type Array
  11414. * @protected
  11415. * @static
  11416. **/
  11417. ColorMatrix.DELTA_INDEX = [
  11418. 0, 0.01, 0.02, 0.04, 0.05, 0.06, 0.07, 0.08, 0.1, 0.11,
  11419. 0.12, 0.14, 0.15, 0.16, 0.17, 0.18, 0.20, 0.21, 0.22, 0.24,
  11420. 0.25, 0.27, 0.28, 0.30, 0.32, 0.34, 0.36, 0.38, 0.40, 0.42,
  11421. 0.44, 0.46, 0.48, 0.5, 0.53, 0.56, 0.59, 0.62, 0.65, 0.68,
  11422. 0.71, 0.74, 0.77, 0.80, 0.83, 0.86, 0.89, 0.92, 0.95, 0.98,
  11423. 1.0, 1.06, 1.12, 1.18, 1.24, 1.30, 1.36, 1.42, 1.48, 1.54,
  11424. 1.60, 1.66, 1.72, 1.78, 1.84, 1.90, 1.96, 2.0, 2.12, 2.25,
  11425. 2.37, 2.50, 2.62, 2.75, 2.87, 3.0, 3.2, 3.4, 3.6, 3.8,
  11426. 4.0, 4.3, 4.7, 4.9, 5.0, 5.5, 6.0, 6.5, 6.8, 7.0,
  11427. 7.3, 7.5, 7.8, 8.0, 8.4, 8.7, 9.0, 9.4, 9.6, 9.8,
  11428. 10.0
  11429. ];
  11430. /**
  11431. * Identity matrix values.
  11432. * @property IDENTITY_MATRIX
  11433. * @type Array
  11434. * @protected
  11435. * @static
  11436. **/
  11437. ColorMatrix.IDENTITY_MATRIX = [
  11438. 1,0,0,0,0,
  11439. 0,1,0,0,0,
  11440. 0,0,1,0,0,
  11441. 0,0,0,1,0,
  11442. 0,0,0,0,1
  11443. ];
  11444. /**
  11445. * The constant length of a color matrix.
  11446. * @property LENGTH
  11447. * @type Number
  11448. * @protected
  11449. * @static
  11450. **/
  11451. ColorMatrix.LENGTH = ColorMatrix.IDENTITY_MATRIX.length;
  11452. // public methods:
  11453. /**
  11454. * Resets the instance with the specified values.
  11455. * @method setColor
  11456. * @param {Number} brightness
  11457. * @param {Number} contrast
  11458. * @param {Number} saturation
  11459. * @param {Number} hue
  11460. * @return {ColorMatrix} The ColorMatrix instance the method is called on (useful for chaining calls.)
  11461. * @chainable
  11462. */
  11463. p.setColor = function(brightness,contrast,saturation,hue) {
  11464. return this.reset().adjustColor(brightness,contrast,saturation,hue);
  11465. };
  11466. /**
  11467. * Resets the matrix to identity values.
  11468. * @method reset
  11469. * @return {ColorMatrix} The ColorMatrix instance the method is called on (useful for chaining calls.)
  11470. * @chainable
  11471. */
  11472. p.reset = function() {
  11473. return this.copy(ColorMatrix.IDENTITY_MATRIX);
  11474. };
  11475. /**
  11476. * Shortcut method to adjust brightness, contrast, saturation and hue.
  11477. * Equivalent to calling adjustHue(hue), adjustContrast(contrast),
  11478. * adjustBrightness(brightness), adjustSaturation(saturation), in that order.
  11479. * @method adjustColor
  11480. * @param {Number} brightness
  11481. * @param {Number} contrast
  11482. * @param {Number} saturation
  11483. * @param {Number} hue
  11484. * @return {ColorMatrix} The ColorMatrix instance the method is called on (useful for chaining calls.)
  11485. * @chainable
  11486. **/
  11487. p.adjustColor = function(brightness,contrast,saturation,hue) {
  11488. this.adjustHue(hue);
  11489. this.adjustContrast(contrast);
  11490. this.adjustBrightness(brightness);
  11491. return this.adjustSaturation(saturation);
  11492. };
  11493. /**
  11494. * Adjusts the brightness of pixel color by adding the specified value to the red, green and blue channels.
  11495. * Positive values will make the image brighter, negative values will make it darker.
  11496. * @method adjustBrightness
  11497. * @param {Number} value A value between -255 & 255 that will be added to the RGB channels.
  11498. * @return {ColorMatrix} The ColorMatrix instance the method is called on (useful for chaining calls.)
  11499. * @chainable
  11500. **/
  11501. p.adjustBrightness = function(value) {
  11502. if (value == 0 || isNaN(value)) { return this; }
  11503. value = this._cleanValue(value,255);
  11504. this._multiplyMatrix([
  11505. 1,0,0,0,value,
  11506. 0,1,0,0,value,
  11507. 0,0,1,0,value,
  11508. 0,0,0,1,0,
  11509. 0,0,0,0,1
  11510. ]);
  11511. return this;
  11512. };
  11513. /**
  11514. * Adjusts the contrast of pixel color.
  11515. * Positive values will increase contrast, negative values will decrease contrast.
  11516. * @method adjustContrast
  11517. * @param {Number} value A value between -100 & 100.
  11518. * @return {ColorMatrix} The ColorMatrix instance the method is called on (useful for chaining calls.)
  11519. * @chainable
  11520. **/
  11521. p.adjustContrast = function(value) {
  11522. if (value == 0 || isNaN(value)) { return this; }
  11523. value = this._cleanValue(value,100);
  11524. var x;
  11525. if (value<0) {
  11526. x = 127+value/100*127;
  11527. } else {
  11528. x = value%1;
  11529. if (x == 0) {
  11530. x = ColorMatrix.DELTA_INDEX[value];
  11531. } else {
  11532. x = ColorMatrix.DELTA_INDEX[(value<<0)]*(1-x)+ColorMatrix.DELTA_INDEX[(value<<0)+1]*x; // use linear interpolation for more granularity.
  11533. }
  11534. x = x*127+127;
  11535. }
  11536. this._multiplyMatrix([
  11537. x/127,0,0,0,0.5*(127-x),
  11538. 0,x/127,0,0,0.5*(127-x),
  11539. 0,0,x/127,0,0.5*(127-x),
  11540. 0,0,0,1,0,
  11541. 0,0,0,0,1
  11542. ]);
  11543. return this;
  11544. };
  11545. /**
  11546. * Adjusts the color saturation of the pixel.
  11547. * Positive values will increase saturation, negative values will decrease saturation (trend towards greyscale).
  11548. * @method adjustSaturation
  11549. * @param {Number} value A value between -100 & 100.
  11550. * @return {ColorMatrix} The ColorMatrix instance the method is called on (useful for chaining calls.)
  11551. * @chainable
  11552. **/
  11553. p.adjustSaturation = function(value) {
  11554. if (value == 0 || isNaN(value)) { return this; }
  11555. value = this._cleanValue(value,100);
  11556. var x = 1+((value > 0) ? 3*value/100 : value/100);
  11557. var lumR = 0.3086;
  11558. var lumG = 0.6094;
  11559. var lumB = 0.0820;
  11560. this._multiplyMatrix([
  11561. lumR*(1-x)+x,lumG*(1-x),lumB*(1-x),0,0,
  11562. lumR*(1-x),lumG*(1-x)+x,lumB*(1-x),0,0,
  11563. lumR*(1-x),lumG*(1-x),lumB*(1-x)+x,0,0,
  11564. 0,0,0,1,0,
  11565. 0,0,0,0,1
  11566. ]);
  11567. return this;
  11568. };
  11569. /**
  11570. * Adjusts the hue of the pixel color.
  11571. * @method adjustHue
  11572. * @param {Number} value A value between -180 & 180.
  11573. * @return {ColorMatrix} The ColorMatrix instance the method is called on (useful for chaining calls.)
  11574. * @chainable
  11575. **/
  11576. p.adjustHue = function(value) {
  11577. if (value == 0 || isNaN(value)) { return this; }
  11578. value = this._cleanValue(value,180)/180*Math.PI;
  11579. var cosVal = Math.cos(value);
  11580. var sinVal = Math.sin(value);
  11581. var lumR = 0.213;
  11582. var lumG = 0.715;
  11583. var lumB = 0.072;
  11584. this._multiplyMatrix([
  11585. lumR+cosVal*(1-lumR)+sinVal*(-lumR),lumG+cosVal*(-lumG)+sinVal*(-lumG),lumB+cosVal*(-lumB)+sinVal*(1-lumB),0,0,
  11586. lumR+cosVal*(-lumR)+sinVal*(0.143),lumG+cosVal*(1-lumG)+sinVal*(0.140),lumB+cosVal*(-lumB)+sinVal*(-0.283),0,0,
  11587. lumR+cosVal*(-lumR)+sinVal*(-(1-lumR)),lumG+cosVal*(-lumG)+sinVal*(lumG),lumB+cosVal*(1-lumB)+sinVal*(lumB),0,0,
  11588. 0,0,0,1,0,
  11589. 0,0,0,0,1
  11590. ]);
  11591. return this;
  11592. };
  11593. /**
  11594. * Concatenates (multiplies) the specified matrix with this one.
  11595. * @method concat
  11596. * @param {Array} matrix An array or ColorMatrix instance.
  11597. * @return {ColorMatrix} The ColorMatrix instance the method is called on (useful for chaining calls.)
  11598. * @chainable
  11599. **/
  11600. p.concat = function(matrix) {
  11601. matrix = this._fixMatrix(matrix);
  11602. if (matrix.length != ColorMatrix.LENGTH) { return this; }
  11603. this._multiplyMatrix(matrix);
  11604. return this;
  11605. };
  11606. /**
  11607. * Returns a clone of this ColorMatrix.
  11608. * @method clone
  11609. * @return {ColorMatrix} A clone of this ColorMatrix.
  11610. **/
  11611. p.clone = function() {
  11612. return (new ColorMatrix()).copy(this);
  11613. };
  11614. /**
  11615. * Return a length 25 (5x5) array instance containing this matrix's values.
  11616. * @method toArray
  11617. * @return {Array} An array holding this matrix's values.
  11618. **/
  11619. p.toArray = function() {
  11620. var arr = [];
  11621. for (var i= 0, l=ColorMatrix.LENGTH; i<l; i++) {
  11622. arr[i] = this[i];
  11623. }
  11624. return arr;
  11625. };
  11626. /**
  11627. * Copy the specified matrix's values to this matrix.
  11628. * @method copy
  11629. * @param {Array} matrix An array or ColorMatrix instance.
  11630. * @return {ColorMatrix} The ColorMatrix instance the method is called on (useful for chaining calls.)
  11631. * @chainable
  11632. **/
  11633. p.copy = function(matrix) {
  11634. var l = ColorMatrix.LENGTH;
  11635. for (var i=0;i<l;i++) {
  11636. this[i] = matrix[i];
  11637. }
  11638. return this;
  11639. };
  11640. /**
  11641. * Returns a string representation of this object.
  11642. * @method toString
  11643. * @return {String} a string representation of the instance.
  11644. **/
  11645. p.toString = function() {
  11646. return "[ColorMatrix]";
  11647. };
  11648. // private methods:
  11649. /**
  11650. * @method _multiplyMatrix
  11651. * @param {Array} matrix
  11652. * @protected
  11653. **/
  11654. p._multiplyMatrix = function(matrix) {
  11655. var i, j, k, col = [];
  11656. for (i=0;i<5;i++) {
  11657. for (j=0;j<5;j++) {
  11658. col[j] = this[j+i*5];
  11659. }
  11660. for (j=0;j<5;j++) {
  11661. var val=0;
  11662. for (k=0;k<5;k++) {
  11663. val += matrix[j+k*5]*col[k];
  11664. }
  11665. this[j+i*5] = val;
  11666. }
  11667. }
  11668. };
  11669. /**
  11670. * Make sure values are within the specified range, hue has a limit of 180, brightness is 255, others are 100.
  11671. * @method _cleanValue
  11672. * @param {Number} value The raw number
  11673. * @param {Number} limit The maximum that the number can be. The minimum is the limit * -1.
  11674. * @protected
  11675. **/
  11676. p._cleanValue = function(value, limit) {
  11677. return Math.min(limit,Math.max(-limit,value));
  11678. };
  11679. /**
  11680. * Makes sure matrixes are 5x5 (25 long).
  11681. * @method _fixMatrix
  11682. * @param {Array} matrix
  11683. * @protected
  11684. **/
  11685. p._fixMatrix = function(matrix) {
  11686. if (matrix instanceof ColorMatrix) { matrix = matrix.toArray(); }
  11687. if (matrix.length < ColorMatrix.LENGTH) {
  11688. matrix = matrix.slice(0,matrix.length).concat(ColorMatrix.IDENTITY_MATRIX.slice(matrix.length,ColorMatrix.LENGTH));
  11689. } else if (matrix.length > ColorMatrix.LENGTH) {
  11690. matrix = matrix.slice(0,ColorMatrix.LENGTH);
  11691. }
  11692. return matrix;
  11693. };
  11694. createjs.ColorMatrix = ColorMatrix;
  11695. }());
  11696. //##############################################################################
  11697. // ColorMatrixFilter.js
  11698. //##############################################################################
  11699. this.createjs = this.createjs||{};
  11700. (function() {
  11701. "use strict";
  11702. // constructor:
  11703. /**
  11704. * Allows you to carry out complex color operations such as modifying saturation, brightness, or inverting. See the
  11705. * {{#crossLink "ColorMatrix"}}{{/crossLink}} for more information on changing colors. For an easier color transform,
  11706. * consider the {{#crossLink "ColorFilter"}}{{/crossLink}}.
  11707. *
  11708. * <h4>Example</h4>
  11709. * This example creates a red circle, inverts its hue, and then saturates it to brighten it up.
  11710. *
  11711. * var shape = new createjs.Shape().set({x:100,y:100});
  11712. * shape.graphics.beginFill("#ff0000").drawCircle(0,0,50);
  11713. *
  11714. * var matrix = new createjs.ColorMatrix().adjustHue(180).adjustSaturation(100);
  11715. * shape.filters = [
  11716. * new createjs.ColorMatrixFilter(matrix)
  11717. * ];
  11718. *
  11719. * shape.cache(-50, -50, 100, 100);
  11720. *
  11721. * See {{#crossLink "Filter"}}{{/crossLink}} for an more information on applying filters.
  11722. * @class ColorMatrixFilter
  11723. * @constructor
  11724. * @extends Filter
  11725. * @param {Array | ColorMatrix} matrix A 4x5 matrix describing the color operation to perform. See also the {{#crossLink "ColorMatrix"}}{{/crossLink}}
  11726. * class.
  11727. **/
  11728. function ColorMatrixFilter(matrix) {
  11729. // public properties:
  11730. /**
  11731. * A 4x5 matrix describing the color operation to perform. See also the {{#crossLink "ColorMatrix"}}{{/crossLink}}
  11732. * @property matrix
  11733. * @type Array | ColorMatrix
  11734. **/
  11735. this.matrix = matrix;
  11736. }
  11737. var p = createjs.extend(ColorMatrixFilter, createjs.Filter);
  11738. // TODO: deprecated
  11739. // p.initialize = function() {}; // searchable for devs wondering where it is. REMOVED. See docs for details.
  11740. // public methods:
  11741. /** docced in super class **/
  11742. p.toString = function() {
  11743. return "[ColorMatrixFilter]";
  11744. };
  11745. /** docced in super class **/
  11746. p.clone = function() {
  11747. return new ColorMatrixFilter(this.matrix);
  11748. };
  11749. // private methods:
  11750. /** docced in super class **/
  11751. p._applyFilter = function(imageData) {
  11752. var data = imageData.data;
  11753. var l = data.length;
  11754. var r,g,b,a;
  11755. var mtx = this.matrix;
  11756. var m0 = mtx[0], m1 = mtx[1], m2 = mtx[2], m3 = mtx[3], m4 = mtx[4];
  11757. var m5 = mtx[5], m6 = mtx[6], m7 = mtx[7], m8 = mtx[8], m9 = mtx[9];
  11758. var m10 = mtx[10], m11 = mtx[11], m12 = mtx[12], m13 = mtx[13], m14 = mtx[14];
  11759. var m15 = mtx[15], m16 = mtx[16], m17 = mtx[17], m18 = mtx[18], m19 = mtx[19];
  11760. for (var i=0; i<l; i+=4) {
  11761. r = data[i];
  11762. g = data[i+1];
  11763. b = data[i+2];
  11764. a = data[i+3];
  11765. data[i] = r*m0+g*m1+b*m2+a*m3+m4; // red
  11766. data[i+1] = r*m5+g*m6+b*m7+a*m8+m9; // green
  11767. data[i+2] = r*m10+g*m11+b*m12+a*m13+m14; // blue
  11768. data[i+3] = r*m15+g*m16+b*m17+a*m18+m19; // alpha
  11769. }
  11770. return true;
  11771. };
  11772. createjs.ColorMatrixFilter = createjs.promote(ColorMatrixFilter, "Filter");
  11773. }());
  11774. //##############################################################################
  11775. // Touch.js
  11776. //##############################################################################
  11777. this.createjs = this.createjs||{};
  11778. (function() {
  11779. "use strict";
  11780. // constructor:
  11781. /**
  11782. * Global utility for working with multi-touch enabled devices in EaselJS. Currently supports W3C Touch API (iOS and
  11783. * modern Android browser) and the Pointer API (IE), including ms-prefixed events in IE10, and unprefixed in IE11.
  11784. *
  11785. * Ensure that you {{#crossLink "Touch/disable"}}{{/crossLink}} touch when cleaning up your application. You do not have
  11786. * to check if touch is supported to enable it, as it will fail gracefully if it is not supported.
  11787. *
  11788. * <h4>Example</h4>
  11789. *
  11790. * var stage = new createjs.Stage("canvasId");
  11791. * createjs.Touch.enable(stage);
  11792. *
  11793. * <strong>Note:</strong> It is important to disable Touch on a stage that you are no longer using:
  11794. *
  11795. * createjs.Touch.disable(stage);
  11796. *
  11797. * @class Touch
  11798. * @static
  11799. **/
  11800. function Touch() {
  11801. throw "Touch cannot be instantiated";
  11802. }
  11803. // public static methods:
  11804. /**
  11805. * Returns `true` if touch is supported in the current browser.
  11806. * @method isSupported
  11807. * @return {Boolean} Indicates whether touch is supported in the current browser.
  11808. * @static
  11809. **/
  11810. Touch.isSupported = function() {
  11811. return !!(('ontouchstart' in window) // iOS & Android
  11812. || (window.navigator['msPointerEnabled'] && window.navigator['msMaxTouchPoints'] > 0) // IE10
  11813. || (window.navigator['pointerEnabled'] && window.navigator['maxTouchPoints'] > 0)); // IE11+
  11814. };
  11815. /**
  11816. * Enables touch interaction for the specified EaselJS {{#crossLink "Stage"}}{{/crossLink}}. Currently supports iOS
  11817. * (and compatible browsers, such as modern Android browsers), and IE10/11. Supports both single touch and
  11818. * multi-touch modes. Extends the EaselJS {{#crossLink "MouseEvent"}}{{/crossLink}} model, but without support for
  11819. * double click or over/out events. See the MouseEvent {{#crossLink "MouseEvent/pointerId:property"}}{{/crossLink}}
  11820. * for more information.
  11821. * @method enable
  11822. * @param {Stage} stage The {{#crossLink "Stage"}}{{/crossLink}} to enable touch on.
  11823. * @param {Boolean} [singleTouch=false] If `true`, only a single touch will be active at a time.
  11824. * @param {Boolean} [allowDefault=false] If `true`, then default gesture actions (ex. scrolling, zooming) will be
  11825. * allowed when the user is interacting with the target canvas.
  11826. * @return {Boolean} Returns `true` if touch was successfully enabled on the target stage.
  11827. * @static
  11828. **/
  11829. Touch.enable = function(stage, singleTouch, allowDefault) {
  11830. if (!stage || !stage.canvas || !Touch.isSupported()) { return false; }
  11831. if (stage.__touch) { return true; }
  11832. // inject required properties on stage:
  11833. stage.__touch = {pointers:{}, multitouch:!singleTouch, preventDefault:!allowDefault, count:0};
  11834. // note that in the future we may need to disable the standard mouse event model before adding
  11835. // these to prevent duplicate calls. It doesn't seem to be an issue with iOS devices though.
  11836. if ('ontouchstart' in window) { Touch._IOS_enable(stage); }
  11837. else if (window.navigator['msPointerEnabled'] || window.navigator["pointerEnabled"]) { Touch._IE_enable(stage); }
  11838. return true;
  11839. };
  11840. /**
  11841. * Removes all listeners that were set up when calling `Touch.enable()` on a stage.
  11842. * @method disable
  11843. * @param {Stage} stage The {{#crossLink "Stage"}}{{/crossLink}} to disable touch on.
  11844. * @static
  11845. **/
  11846. Touch.disable = function(stage) {
  11847. if (!stage) { return; }
  11848. if ('ontouchstart' in window) { Touch._IOS_disable(stage); }
  11849. else if (window.navigator['msPointerEnabled'] || window.navigator["pointerEnabled"]) { Touch._IE_disable(stage); }
  11850. delete stage.__touch;
  11851. };
  11852. // Private static methods:
  11853. /**
  11854. * @method _IOS_enable
  11855. * @protected
  11856. * @param {Stage} stage
  11857. * @static
  11858. **/
  11859. Touch._IOS_enable = function(stage) {
  11860. var canvas = stage.canvas;
  11861. var f = stage.__touch.f = function(e) { Touch._IOS_handleEvent(stage,e); };
  11862. canvas.addEventListener("touchstart", f, false);
  11863. canvas.addEventListener("touchmove", f, false);
  11864. canvas.addEventListener("touchend", f, false);
  11865. canvas.addEventListener("touchcancel", f, false);
  11866. };
  11867. /**
  11868. * @method _IOS_disable
  11869. * @protected
  11870. * @param {Stage} stage
  11871. * @static
  11872. **/
  11873. Touch._IOS_disable = function(stage) {
  11874. var canvas = stage.canvas;
  11875. if (!canvas) { return; }
  11876. var f = stage.__touch.f;
  11877. canvas.removeEventListener("touchstart", f, false);
  11878. canvas.removeEventListener("touchmove", f, false);
  11879. canvas.removeEventListener("touchend", f, false);
  11880. canvas.removeEventListener("touchcancel", f, false);
  11881. };
  11882. /**
  11883. * @method _IOS_handleEvent
  11884. * @param {Stage} stage
  11885. * @param {Object} e The event to handle
  11886. * @protected
  11887. * @static
  11888. **/
  11889. Touch._IOS_handleEvent = function(stage, e) {
  11890. if (!stage) { return; }
  11891. if (stage.__touch.preventDefault) { e.preventDefault&&e.preventDefault(); }
  11892. var touches = e.changedTouches;
  11893. var type = e.type;
  11894. for (var i= 0,l=touches.length; i<l; i++) {
  11895. var touch = touches[i];
  11896. var id = touch.identifier;
  11897. if (touch.target != stage.canvas) { continue; }
  11898. if (type == "touchstart") {
  11899. this._handleStart(stage, id, e, touch.pageX, touch.pageY);
  11900. } else if (type == "touchmove") {
  11901. this._handleMove(stage, id, e, touch.pageX, touch.pageY);
  11902. } else if (type == "touchend" || type == "touchcancel") {
  11903. this._handleEnd(stage, id, e);
  11904. }
  11905. }
  11906. };
  11907. /**
  11908. * @method _IE_enable
  11909. * @protected
  11910. * @param {Stage} stage
  11911. * @static
  11912. **/
  11913. Touch._IE_enable = function(stage) {
  11914. var canvas = stage.canvas;
  11915. var f = stage.__touch.f = function(e) { Touch._IE_handleEvent(stage,e); };
  11916. if (window.navigator["pointerEnabled"] === undefined) {
  11917. canvas.addEventListener("MSPointerDown", f, false);
  11918. window.addEventListener("MSPointerMove", f, false);
  11919. window.addEventListener("MSPointerUp", f, false);
  11920. window.addEventListener("MSPointerCancel", f, false);
  11921. if (stage.__touch.preventDefault) { canvas.style.msTouchAction = "none"; }
  11922. } else {
  11923. canvas.addEventListener("pointerdown", f, false);
  11924. window.addEventListener("pointermove", f, false);
  11925. window.addEventListener("pointerup", f, false);
  11926. window.addEventListener("pointercancel", f, false);
  11927. if (stage.__touch.preventDefault) { canvas.style.touchAction = "none"; }
  11928. }
  11929. stage.__touch.activeIDs = {};
  11930. };
  11931. /**
  11932. * @method _IE_disable
  11933. * @protected
  11934. * @param {Stage} stage
  11935. * @static
  11936. **/
  11937. Touch._IE_disable = function(stage) {
  11938. var f = stage.__touch.f;
  11939. if (window.navigator["pointerEnabled"] === undefined) {
  11940. window.removeEventListener("MSPointerMove", f, false);
  11941. window.removeEventListener("MSPointerUp", f, false);
  11942. window.removeEventListener("MSPointerCancel", f, false);
  11943. if (stage.canvas) {
  11944. stage.canvas.removeEventListener("MSPointerDown", f, false);
  11945. }
  11946. } else {
  11947. window.removeEventListener("pointermove", f, false);
  11948. window.removeEventListener("pointerup", f, false);
  11949. window.removeEventListener("pointercancel", f, false);
  11950. if (stage.canvas) {
  11951. stage.canvas.removeEventListener("pointerdown", f, false);
  11952. }
  11953. }
  11954. };
  11955. /**
  11956. * @method _IE_handleEvent
  11957. * @param {Stage} stage
  11958. * @param {Object} e The event to handle.
  11959. * @protected
  11960. * @static
  11961. **/
  11962. Touch._IE_handleEvent = function(stage, e) {
  11963. if (!stage) { return; }
  11964. if (stage.__touch.preventDefault) { e.preventDefault && e.preventDefault(); }
  11965. var type = e.type;
  11966. var id = e.pointerId;
  11967. var ids = stage.__touch.activeIDs;
  11968. if (type == "MSPointerDown" || type == "pointerdown") {
  11969. if (e.srcElement != stage.canvas) { return; }
  11970. ids[id] = true;
  11971. this._handleStart(stage, id, e, e.pageX, e.pageY);
  11972. } else if (ids[id]) { // it's an id we're watching
  11973. if (type == "MSPointerMove" || type == "pointermove") {
  11974. this._handleMove(stage, id, e, e.pageX, e.pageY);
  11975. } else if (type == "MSPointerUp" || type == "MSPointerCancel"
  11976. || type == "pointerup" || type == "pointercancel") {
  11977. delete(ids[id]);
  11978. this._handleEnd(stage, id, e);
  11979. }
  11980. }
  11981. };
  11982. /**
  11983. * @method _handleStart
  11984. * @param {Stage} stage
  11985. * @param {String|Number} id
  11986. * @param {Object} e
  11987. * @param {Number} x
  11988. * @param {Number} y
  11989. * @protected
  11990. **/
  11991. Touch._handleStart = function(stage, id, e, x, y) {
  11992. var props = stage.__touch;
  11993. if (!props.multitouch && props.count) { return; }
  11994. var ids = props.pointers;
  11995. if (ids[id]) { return; }
  11996. ids[id] = true;
  11997. props.count++;
  11998. stage._handlePointerDown(id, e, x, y);
  11999. };
  12000. /**
  12001. * @method _handleMove
  12002. * @param {Stage} stage
  12003. * @param {String|Number} id
  12004. * @param {Object} e
  12005. * @param {Number} x
  12006. * @param {Number} y
  12007. * @protected
  12008. **/
  12009. Touch._handleMove = function(stage, id, e, x, y) {
  12010. if (!stage.__touch.pointers[id]) { return; }
  12011. stage._handlePointerMove(id, e, x, y);
  12012. };
  12013. /**
  12014. * @method _handleEnd
  12015. * @param {Stage} stage
  12016. * @param {String|Number} id
  12017. * @param {Object} e
  12018. * @protected
  12019. **/
  12020. Touch._handleEnd = function(stage, id, e) {
  12021. // TODO: cancel should be handled differently for proper UI (ex. an up would trigger a click, a cancel would more closely resemble an out).
  12022. var props = stage.__touch;
  12023. var ids = props.pointers;
  12024. if (!ids[id]) { return; }
  12025. props.count--;
  12026. stage._handlePointerUp(id, e, true);
  12027. delete(ids[id]);
  12028. };
  12029. createjs.Touch = Touch;
  12030. }());
  12031. //##############################################################################
  12032. // version.js
  12033. //##############################################################################
  12034. this.createjs = this.createjs || {};
  12035. (function() {
  12036. "use strict";
  12037. /**
  12038. * Static class holding library specific information such as the version and buildDate of
  12039. * the library.
  12040. * @class EaselJS
  12041. **/
  12042. var s = createjs.EaselJS = createjs.EaselJS || {};
  12043. /**
  12044. * The version string for this release.
  12045. * @property version
  12046. * @type String
  12047. * @static
  12048. **/
  12049. s.version = /*=version*/"0.8.2"; // injected by build process
  12050. /**
  12051. * The build date for this release in UTC format.
  12052. * @property buildDate
  12053. * @type String
  12054. * @static
  12055. **/
  12056. s.buildDate = /*=date*/"Thu, 26 Nov 2015 20:44:34 GMT"; // injected by build process
  12057. })();