├── .editorconfig ├── .gitattributes ├── .gitignore ├── .npmignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── assets └── icon.png ├── dist ├── core-NEXT.js ├── core-NEXT.js.map ├── core.cjs.js ├── core.cjs.js.map └── core.min.js ├── package.json ├── src ├── events │ ├── Event.js │ └── EventDispatcher.js ├── main.js └── utils │ └── Ticker.js └── tests └── spec ├── events └── Events.js └── utils └── Ticker.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent coding styles between different editors and IDEs 2 | # Docs: http://editorconfig.org 3 | 4 | # For Atom: https://atom.io/packages/editorconfig 5 | # For Sublime: https://github.com/sindresorhus/editorconfig-sublime 6 | # For WebStorm: Natively supported 7 | 8 | root = true 9 | 10 | [*] 11 | indent_style = tab 12 | indent_size = 2 13 | trim_trailing_whitespace = true 14 | insert_final_newline = true 15 | end_of_line = lf 16 | charset = utf-8 17 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Force all line endings to be \n 2 | * text eol=lf 3 | 4 | ############################################################ 5 | # git can corrupt binary files if they're not set to binary. 6 | ############################################################ 7 | 8 | # Image files 9 | *.png binary 10 | *.jpg binary 11 | *.jpeg binary 12 | *.gif binary 13 | *.webp binary 14 | *.ico binary 15 | 16 | # Movie and audio files 17 | *.mov binary 18 | *.mp4 binary 19 | *.mp3 binary 20 | *.flv binary 21 | *.ogg binary 22 | 23 | # Compression formats 24 | *.gz binary 25 | *.bz2 binary 26 | *.7z binary 27 | *.zip binary 28 | 29 | # Web fonts 30 | *.ttf binary 31 | *.eot binary 32 | *.woff binary 33 | *.otf binary 34 | 35 | # Other 36 | *.fla binary 37 | *.swf binary 38 | *.pdf binary 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Packages 2 | node_modules/ 3 | 4 | # JetBrains 5 | .idea/ 6 | 7 | # Sublime Text 8 | *.sublime-project 9 | *.sublime-workspace 10 | 11 | # Atom 12 | .atom/ 13 | 14 | # VSCode 15 | .vscode/ 16 | 17 | # OS 18 | .DS_Store 19 | Thumbs.db 20 | 21 | # Generated 22 | docs/ 23 | tests/coverage/ 24 | 25 | # Other 26 | *.log 27 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # JetBrains 2 | .idea/ 3 | 4 | # Sublime Text 5 | *.sublime-project 6 | *.sublime-workspace 7 | 8 | # Atom 9 | .atom/ 10 | 11 | # VSCode 12 | .vscode/ 13 | 14 | # OS 15 | .DS_Store 16 | Thumbs.db 17 | 18 | # Other 19 | *.log 20 | 21 | # Project 22 | assets/ 23 | docs/ 24 | tests/ 25 | .editorconfig 26 | CHANGELOG.md 27 | CONTRIBUTING.md 28 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ### v2.0.0 4 | 5 | TODO. 6 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | We welcome pull requests on fixes, documentation updates, and even features. Ideally changes are discrete, documented inline with current standards, and don't contain superficial changes like tab formatting an entire file (hard to accept a PR that has 1000 changes). Don't commit updates to the `dist/` folder, as those will be done by the maintainers at our discretion. 4 | 5 | The classes in this repository are used by many of the classes in the CreateJS suite. Ensure that changes are thoroughly tested, and any changes required in the other repositories are committed, referencing the original pull request in this repository. 6 | 7 | ### Pull Requests 8 | 9 | Our continuous integration processes will lint and test all pull requests. To save time, please lint and test your changes locally, prior to committing. 10 | 11 | Please reference any issues that your PR addresses. 12 | 13 | ### Local Development 14 | 15 | ``` 16 | # clone repo 17 | git clone https://github.com:createjs/core.git 18 | cd path/to/core 19 | # install dependencies and create a symlink 20 | npm install 21 | npm link . 22 | # link core to another lib for testing 23 | cd path/to/easeljs 24 | npm link @createjs/core 25 | ``` 26 | 27 | Documentation for compiling and testing the source can be found in the [build repository README](https://github.com/createjs/build/blob/master/README.md). 28 | 29 | Remember to unlink dependencies when local testing is completed. 30 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 gskinner.com, inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # @createjs/core 2 | 3 | Core and shared files for the CreateJS suite of JavaScript libraries. 4 | 5 | View the documentation [here](https://createjs.com/docs). 6 | 7 | ### 2.0 BETA 8 | 9 | **This repo is in beta. Reporting issues is appreciated.** 10 | 11 |

12 | 13 | createjs 14 | 15 |

16 | 17 | Core and shared files for the [CreateJS](https://createjs.com/) suite of JavaScript libraries: 18 | [SoundJS](https://github.com/createjs/soundjs), [PreloadJS](https://github.com/createjs/preloadjs), and [TweenJS](https://github.com/createjs/tweenjs). 19 | 20 | ## Installation 21 | 22 | #### NPM 23 | 24 | `npm install @createjs/core --save` 25 | 26 | ``` 27 | 28 | ## Support and Resources 29 | - Read the [documentation](http://createjs.com/docs). 30 | - Discuss, share projects, and interact with other users on [reddit](http://www.reddit.com/r/createjs/). 31 | - Ask technical questions on [Stack Overflow](http://stackoverflow.com/questions/tagged/createjs). 32 | - File verified bugs or formal feature requests using Issues on [GitHub](https://github.com/createjs/core/issues). 33 | - There is a [Google Group](http://groups.google.com/group/createjs-discussion) for discussions and support. 34 | 35 | It was built by [gskinner.com](http://www.gskinner.com), and is released for free under the MIT license, which means you 36 | can use it for almost any purpose (including commercial projects). We appreciate credit where possible, but it is not a 37 | requirement. 38 | -------------------------------------------------------------------------------- /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreateJS/core/d784daab9821c697ba3bb77f8767e3259483e645/assets/icon.png -------------------------------------------------------------------------------- /dist/core-NEXT.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license Core 3 | * Visit https://createjs.com for documentation, updates and examples. 4 | * 5 | * Copyright (c) 2017 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 | (function (exports) { 30 | 'use strict'; 31 | 32 | var Event = 33 | function () { 34 | function Event(type, bubbles, cancelable) { 35 | if (bubbles === void 0) { 36 | bubbles = false; 37 | } 38 | if (cancelable === void 0) { 39 | cancelable = false; 40 | } 41 | this.type = type; 42 | this.target = null; 43 | this.currentTarget = null; 44 | this.eventPhase = 0; 45 | this.bubbles = bubbles; 46 | this.cancelable = cancelable; 47 | this.timeStamp = new Date().getTime(); 48 | this.defaultPrevented = false; 49 | this.propagationStopped = false; 50 | this.immediatePropagationStopped = false; 51 | this.removed = false; 52 | } 53 | var _proto = Event.prototype; 54 | _proto.preventDefault = function preventDefault() { 55 | this.defaultPrevented = this.cancelable; 56 | return this; 57 | }; 58 | _proto.stopPropagation = function stopPropagation() { 59 | this.propagationStopped = true; 60 | return this; 61 | }; 62 | _proto.stopImmediatePropagation = function stopImmediatePropagation() { 63 | this.immediatePropagationStopped = this.propagationStopped = true; 64 | return this; 65 | }; 66 | _proto.remove = function remove() { 67 | this.removed = true; 68 | return this; 69 | }; 70 | _proto.clone = function clone() { 71 | var event = new Event(this.type, this.bubbles, this.cancelable); 72 | for (var n in this) { 73 | if (this.hasOwnProperty(n)) { 74 | event[n] = this[n]; 75 | } 76 | } 77 | return event; 78 | }; 79 | _proto.set = function set(props) { 80 | for (var n in props) { 81 | this[n] = props[n]; 82 | } 83 | return this; 84 | }; 85 | _proto.toString = function toString() { 86 | return "[" + this.constructor.name + " (type=" + this.type + ")]"; 87 | }; 88 | return Event; 89 | }(); 90 | 91 | var EventDispatcher = 92 | function () { 93 | EventDispatcher.initialize = function initialize(target) { 94 | var p = EventDispatcher.prototype; 95 | target.addEventListener = p.addEventListener; 96 | target.on = p.on; 97 | target.removeEventListener = target.off = p.removeEventListener; 98 | target.removeAllEventListeners = p.removeAllEventListeners; 99 | target.hasEventListener = p.hasEventListener; 100 | target.dispatchEvent = p.dispatchEvent; 101 | target._dispatchEvent = p._dispatchEvent; 102 | target.willTrigger = p.willTrigger; 103 | }; 104 | function EventDispatcher() { 105 | this._listeners = null; 106 | this._captureListeners = null; 107 | } 108 | var _proto = EventDispatcher.prototype; 109 | _proto.addEventListener = function addEventListener(type, listener, useCapture) { 110 | if (useCapture === void 0) { 111 | useCapture = false; 112 | } 113 | var listeners; 114 | if (useCapture) { 115 | listeners = this._captureListeners = this._captureListeners || {}; 116 | } else { 117 | listeners = this._listeners = this._listeners || {}; 118 | } 119 | var arr = listeners[type]; 120 | if (arr) { 121 | this.removeEventListener(type, listener, useCapture); 122 | arr = listeners[type]; 123 | } 124 | if (arr) { 125 | arr.push(listener); 126 | } else { 127 | listeners[type] = [listener]; 128 | } 129 | return listener; 130 | }; 131 | _proto.on = function on(type, listener, scope, once, data, useCapture) { 132 | if (scope === void 0) { 133 | scope = null; 134 | } 135 | if (once === void 0) { 136 | once = false; 137 | } 138 | if (data === void 0) { 139 | data = {}; 140 | } 141 | if (useCapture === void 0) { 142 | useCapture = false; 143 | } 144 | if (listener.handleEvent) { 145 | scope = scope || listener; 146 | listener = listener.handleEvent; 147 | } 148 | scope = scope || this; 149 | return this.addEventListener(type, function (evt) { 150 | listener.call(scope, evt, data); 151 | once && evt.remove(); 152 | }, useCapture); 153 | }; 154 | _proto.removeEventListener = function removeEventListener(type, listener, useCapture) { 155 | if (useCapture === void 0) { 156 | useCapture = false; 157 | } 158 | var listeners = useCapture ? this._captureListeners : this._listeners; 159 | if (!listeners) { 160 | return; 161 | } 162 | var arr = listeners[type]; 163 | if (!arr) { 164 | return; 165 | } 166 | var l = arr.length; 167 | for (var i = 0; i < l; i++) { 168 | if (arr[i] === listener) { 169 | if (l === 1) { 170 | delete listeners[type]; 171 | } 172 | else { 173 | arr.splice(i, 1); 174 | } 175 | break; 176 | } 177 | } 178 | }; 179 | _proto.off = function off(type, listener, useCapture) { 180 | if (useCapture === void 0) { 181 | useCapture = false; 182 | } 183 | this.removeEventListener(type, listener, useCapture); 184 | }; 185 | _proto.removeAllEventListeners = function removeAllEventListeners(type) { 186 | if (type === void 0) { 187 | type = null; 188 | } 189 | if (type) { 190 | if (this._listeners) { 191 | delete this._listeners[type]; 192 | } 193 | if (this._captureListeners) { 194 | delete this._captureListeners[type]; 195 | } 196 | } else { 197 | this._listeners = this._captureListeners = null; 198 | } 199 | }; 200 | _proto.dispatchEvent = function dispatchEvent(eventObj, bubbles, cancelable) { 201 | if (bubbles === void 0) { 202 | bubbles = false; 203 | } 204 | if (cancelable === void 0) { 205 | cancelable = false; 206 | } 207 | if (typeof eventObj === "string") { 208 | var listeners = this._listeners; 209 | if (!bubbles && (!listeners || !listeners[eventObj])) { 210 | return true; 211 | } 212 | eventObj = new Event(eventObj, bubbles, cancelable); 213 | } else if (eventObj.target && eventObj.clone) { 214 | eventObj = eventObj.clone(); 215 | } 216 | try { 217 | eventObj.target = this; 218 | } catch (e) {} 219 | if (!eventObj.bubbles || !this.parent) { 220 | this._dispatchEvent(eventObj, 2); 221 | } else { 222 | var top = this; 223 | var list = [top]; 224 | while (top.parent) { 225 | list.push(top = top.parent); 226 | } 227 | var l = list.length; 228 | var i; 229 | for (i = l - 1; i >= 0 && !eventObj.propagationStopped; i--) { 230 | list[i]._dispatchEvent(eventObj, 1 + (i == 0)); 231 | } 232 | for (i = 1; i < l && !eventObj.propagationStopped; i++) { 233 | list[i]._dispatchEvent(eventObj, 3); 234 | } 235 | } 236 | return !eventObj.defaultPrevented; 237 | }; 238 | _proto.hasEventListener = function hasEventListener(type) { 239 | var listeners = this._listeners, 240 | captureListeners = this._captureListeners; 241 | return !!(listeners && listeners[type] || captureListeners && captureListeners[type]); 242 | }; 243 | _proto.willTrigger = function willTrigger(type) { 244 | var o = this; 245 | while (o) { 246 | if (o.hasEventListener(type)) { 247 | return true; 248 | } 249 | o = o.parent; 250 | } 251 | return false; 252 | }; 253 | _proto.toString = function toString() { 254 | return "[" + (this.constructor.name + this.name ? " " + this.name : "") + "]"; 255 | }; 256 | _proto._dispatchEvent = function _dispatchEvent(eventObj, eventPhase) { 257 | var listeners = eventPhase === 1 ? this._captureListeners : this._listeners; 258 | if (eventObj && listeners) { 259 | var arr = listeners[eventObj.type]; 260 | var l; 261 | if (!arr || (l = arr.length) === 0) { 262 | return; 263 | } 264 | try { 265 | eventObj.currentTarget = this; 266 | } catch (e) {} 267 | try { 268 | eventObj.eventPhase = eventPhase; 269 | } catch (e) {} 270 | eventObj.removed = false; 271 | arr = arr.slice(); 272 | for (var i = 0; i < l && !eventObj.immediatePropagationStopped; i++) { 273 | var o = arr[i]; 274 | if (o.handleEvent) { 275 | o.handleEvent(eventObj); 276 | } else { 277 | o(eventObj); 278 | } 279 | if (eventObj.removed) { 280 | this.off(eventObj.type, o, eventPhase === 1); 281 | eventObj.removed = false; 282 | } 283 | } 284 | } 285 | }; 286 | return EventDispatcher; 287 | }(); 288 | 289 | function _defineProperties(target, props) { 290 | for (var i = 0; i < props.length; i++) { 291 | var descriptor = props[i]; 292 | descriptor.enumerable = descriptor.enumerable || false; 293 | descriptor.configurable = true; 294 | if ("value" in descriptor) descriptor.writable = true; 295 | Object.defineProperty(target, descriptor.key, descriptor); 296 | } 297 | } 298 | 299 | function _createClass(Constructor, protoProps, staticProps) { 300 | if (protoProps) _defineProperties(Constructor.prototype, protoProps); 301 | if (staticProps) _defineProperties(Constructor, staticProps); 302 | return Constructor; 303 | } 304 | 305 | function _inheritsLoose(subClass, superClass) { 306 | subClass.prototype = Object.create(superClass.prototype); 307 | subClass.prototype.constructor = subClass; 308 | subClass.__proto__ = superClass; 309 | } 310 | 311 | var Ticker = 312 | function (_EventDispatcher) { 313 | _inheritsLoose(Ticker, _EventDispatcher); 314 | _createClass(Ticker, null, [{ 315 | key: "RAF_SYNCHED", 316 | get: function get() { 317 | return "synched"; 318 | } 319 | }, { 320 | key: "RAF", 321 | get: function get() { 322 | return "raf"; 323 | } 324 | }, { 325 | key: "TIMEOUT", 326 | get: function get() { 327 | return "timeout"; 328 | } 329 | }]); 330 | function Ticker(name) { 331 | var _this; 332 | _this = _EventDispatcher.call(this) || this; 333 | _this.name = name; 334 | _this.timingMode = Ticker.TIMEOUT; 335 | _this.maxDelta = 0; 336 | _this.paused = false; 337 | _this._inited = false; 338 | _this._startTime = 0; 339 | _this._pausedTime = 0; 340 | _this._ticks = 0; 341 | _this._pausedTicks = 0; 342 | _this._interval = 50; 343 | _this._lastTime = 0; 344 | _this._times = null; 345 | _this._tickTimes = null; 346 | _this._timerId = null; 347 | _this._raf = true; 348 | return _this; 349 | } 350 | var _proto = Ticker.prototype; 351 | _proto.init = function init() { 352 | if (this._inited) { 353 | return; 354 | } 355 | this._inited = true; 356 | this._times = []; 357 | this._tickTimes = []; 358 | this._startTime = this._getTime(); 359 | this._times.push(this._lastTime = 0); 360 | this._setupTick(); 361 | }; 362 | _proto.reset = function reset() { 363 | if (this._raf) { 364 | var f = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.oCancelAnimationFrame || window.msCancelAnimationFrame; 365 | f && f(this._timerId); 366 | } else { 367 | clearTimeout(this._timerId); 368 | } 369 | this.removeAllEventListeners("tick"); 370 | this._timerId = this._times = this._tickTimes = null; 371 | this._startTime = this._lastTime = this._ticks = 0; 372 | this._inited = false; 373 | }; 374 | _proto.addEventListener = function addEventListener(type, listener, useCapture) { 375 | !this._inited && this.init(); 376 | return _EventDispatcher.prototype.addEventListener.call(this, type, listener, useCapture); 377 | }; 378 | _proto.getMeasuredTickTime = function getMeasuredTickTime(ticks) { 379 | if (ticks === void 0) { 380 | ticks = null; 381 | } 382 | var times = this._tickTimes; 383 | if (!times || times.length < 1) { 384 | return -1; 385 | } 386 | ticks = Math.min(times.length, ticks || this.framerate | 0); 387 | return times.reduce(function (a, b) { 388 | return a + b; 389 | }, 0) / ticks; 390 | }; 391 | _proto.getMeasuredFPS = function getMeasuredFPS(ticks) { 392 | if (ticks === void 0) { 393 | ticks = null; 394 | } 395 | var times = this._times; 396 | if (!times || times.length < 2) { 397 | return -1; 398 | } 399 | ticks = Math.min(times.length - 1, ticks || this.framerate | 0); 400 | return 1000 / ((times[0] - times[ticks]) / ticks); 401 | }; 402 | _proto.getTime = function getTime(runTime) { 403 | if (runTime === void 0) { 404 | runTime = false; 405 | } 406 | return this._startTime ? this._getTime() - (runTime ? this._pausedTime : 0) : -1; 407 | }; 408 | _proto.getEventTime = function getEventTime(runTime) { 409 | if (runTime === void 0) { 410 | runTime = false; 411 | } 412 | return this._startTime ? (this._lastTime || this._startTime) - (runTime ? this._pausedTime : 0) : -1; 413 | }; 414 | _proto.getTicks = function getTicks(pauseable) { 415 | if (pauseable === void 0) { 416 | pauseable = false; 417 | } 418 | return this._ticks - (pauseable ? this._pausedTicks : 0); 419 | }; 420 | _proto._handleSynch = function _handleSynch() { 421 | this._timerId = null; 422 | this._setupTick(); 423 | if (this._getTime() - this._lastTime >= (this._interval - 1) * 0.97) { 424 | this._tick(); 425 | } 426 | }; 427 | _proto._handleRAF = function _handleRAF() { 428 | this._timerId = null; 429 | this._setupTick(); 430 | this._tick(); 431 | }; 432 | _proto._handleTimeout = function _handleTimeout() { 433 | this._timerId = null; 434 | this._setupTick(); 435 | this._tick(); 436 | }; 437 | _proto._setupTick = function _setupTick() { 438 | if (this._timerId != null) { 439 | return; 440 | } 441 | var mode = this.timingMode || this._raf && Ticker.RAF; 442 | if (mode === Ticker.RAF_SYNCHED || mode === Ticker.RAF) { 443 | var f = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame; 444 | if (f) { 445 | this._timerId = f(mode === Ticker.RAF ? this._handleRAF.bind(this) : this._handleSynch.bind(this)); 446 | this._raf = true; 447 | return; 448 | } 449 | } 450 | this._raf = false; 451 | this._timerId = setTimeout(this._handleTimeout.bind(this), this._interval); 452 | }; 453 | _proto._tick = function _tick() { 454 | var paused = this.paused, 455 | time = this._getTime(), 456 | elapsedTime = time - this._lastTime; 457 | this._lastTime = time; 458 | this._ticks++; 459 | if (paused) { 460 | this._pausedTicks++; 461 | this._pausedTime += elapsedTime; 462 | } 463 | if (this.hasEventListener("tick")) { 464 | var event = new Event("tick"); 465 | var maxDelta = this.maxDelta; 466 | event.delta = maxDelta && elapsedTime > maxDelta ? maxDelta : elapsedTime; 467 | event.paused = paused; 468 | event.time = time; 469 | event.runTime = time - this._pausedTime; 470 | this.dispatchEvent(event); 471 | } 472 | this._tickTimes.unshift(this._getTime() - time); 473 | while (this._tickTimes.length > 100) { 474 | this._tickTimes.pop(); 475 | } 476 | this._times.unshift(time); 477 | while (this._times.length > 100) { 478 | this._times.pop(); 479 | } 480 | }; 481 | _proto._getTime = function _getTime() { 482 | var now = window.performance && window.performance.now; 483 | return (now && now.call(performance) || new Date().getTime()) - this._startTime; 484 | }; 485 | Ticker.on = function on(type, listener, scope, once, data, useCapture) { 486 | return _instance.on(type, listener, scope, once, data, useCapture); 487 | }; 488 | Ticker.removeEventListener = function removeEventListener(type, listener, useCapture) { 489 | _instance.removeEventListener(type, listener, useCapture); 490 | }; 491 | Ticker.off = function off(type, listener, useCapture) { 492 | _instance.off(type, listener, useCapture); 493 | }; 494 | Ticker.removeAllEventListeners = function removeAllEventListeners(type) { 495 | _instance.removeAllEventListeners(type); 496 | }; 497 | Ticker.dispatchEvent = function dispatchEvent(eventObj, bubbles, cancelable) { 498 | return _instance.dispatchEvent(eventObj, bubbles, cancelable); 499 | }; 500 | Ticker.hasEventListener = function hasEventListener(type) { 501 | return _instance.hasEventListener(type); 502 | }; 503 | Ticker.willTrigger = function willTrigger(type) { 504 | return _instance.willTrigger(type); 505 | }; 506 | Ticker.toString = function toString() { 507 | return _instance.toString(); 508 | }; 509 | Ticker.init = function init() { 510 | _instance.init(); 511 | }; 512 | Ticker.reset = function reset() { 513 | _instance.reset(); 514 | }; 515 | Ticker.addEventListener = function addEventListener(type, listener, useCapture) { 516 | _instance.addEventListener(type, listener, useCapture); 517 | }; 518 | Ticker.getMeasuredTickTime = function getMeasuredTickTime(ticks) { 519 | return _instance.getMeasuredTickTime(ticks); 520 | }; 521 | Ticker.getMeasuredFPS = function getMeasuredFPS(ticks) { 522 | return _instance.getMeasuredFPS(ticks); 523 | }; 524 | Ticker.getTime = function getTime(runTime) { 525 | return _instance.getTime(runTime); 526 | }; 527 | Ticker.getEventTime = function getEventTime(runTime) { 528 | return _instance.getEventTime(runTime); 529 | }; 530 | Ticker.getTicks = function getTicks(pauseable) { 531 | return _instance.getTicks(pauseable); 532 | }; 533 | _createClass(Ticker, [{ 534 | key: "interval", 535 | get: function get() { 536 | return this._interval; 537 | }, 538 | set: function set(interval) { 539 | this._interval = interval; 540 | if (!this._inited) { 541 | return; 542 | } 543 | this._setupTick(); 544 | } 545 | }, { 546 | key: "framerate", 547 | get: function get() { 548 | return 1000 / this._interval; 549 | }, 550 | set: function set(framerate) { 551 | this.interval = 1000 / framerate; 552 | } 553 | }], [{ 554 | key: "interval", 555 | get: function get() { 556 | return _instance.interval; 557 | }, 558 | set: function set(interval) { 559 | _instance.interval = interval; 560 | } 561 | }, { 562 | key: "framerate", 563 | get: function get() { 564 | return _instance.framerate; 565 | }, 566 | set: function set(framerate) { 567 | _instance.framerate = framerate; 568 | } 569 | }, { 570 | key: "name", 571 | get: function get() { 572 | return _instance.name; 573 | }, 574 | set: function set(name) { 575 | _instance.name = name; 576 | } 577 | }, { 578 | key: "timingMode", 579 | get: function get() { 580 | return _instance.timingMode; 581 | }, 582 | set: function set(timingMode) { 583 | _instance.timingMode = timingMode; 584 | } 585 | }, { 586 | key: "maxDelta", 587 | get: function get() { 588 | return _instance.maxDelta; 589 | }, 590 | set: function set(maxDelta) { 591 | _instance.maxDelta = maxDelta; 592 | } 593 | }, { 594 | key: "paused", 595 | get: function get() { 596 | return _instance.paused; 597 | }, 598 | set: function set(paused) { 599 | _instance.paused = paused; 600 | } 601 | }]); 602 | return Ticker; 603 | }(EventDispatcher); 604 | var _instance = new Ticker("createjs.global"); 605 | 606 | exports.Event = Event; 607 | exports.EventDispatcher = EventDispatcher; 608 | exports.Ticker = Ticker; 609 | 610 | var v = exports.versions = exports.versions || {}; 611 | v.core = "NEXT"; 612 | 613 | }((this.createjs = this.createjs || {}))); 614 | //# sourceMappingURL=core-NEXT.js.map 615 | -------------------------------------------------------------------------------- /dist/core-NEXT.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"core-NEXT.js","sources":["../src/events/Event.js","../src/events/EventDispatcher.js","../src/utils/Ticker.js"],"sourcesContent":["/**\n * @license Event\n * Visit http://createjs.com/ for documentation, updates and examples.\n *\n * Copyright (c) 2017 gskinner.com, inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n/**\n * Contains properties and methods shared by all events for use with {@link core.EventDispatcher}.\n * Note that Event objects are often reused, so you should never\n * rely on an event object's state outside of the call stack it was received in.\n *\n * @memberof core\n * @example\n * const evt = new Event(\"myEvent\");\n * const dispatcher = new EventDispatcher();\n * dispatcher.on(\"myEvent\", event => console.log(event.type));\n * dispatcher.dispatchEvent(evt); // logs \"myEvent\"\n *\n * @param {string} type The event type.\n * @param {boolean} [bubbles=false] Indicates whether the event will bubble through the display list.\n * @param {boolean} [cancelable=false] Indicates whether the default behaviour of this event can be cancelled.\n */\nclass Event {\n\n\tconstructor (type, bubbles = false, cancelable = false) {\n\t\t/**\n\t\t * The type of event.\n\t\t * @type string\n\t\t */\n\t\tthis.type = type;\n\n\t\t/**\n\t\t * The object that generated an event.\n\t\t *\n\t\t * @type Object\n\t\t * @default null\n\t\t * @readonly\n\t\t */\n\t\tthis.target = null;\n\n\t\t/**\n\t\t * The current target that a bubbling event is being dispatched from. For non-bubbling events, this will\n\t\t * always be the same as target. For example, if childObj.parent = parentObj, and a bubbling event\n\t\t * is generated from childObj, then a listener on parentObj would receive the event with\n\t\t * target=childObj (the original target) and currentTarget=parentObj (where the listener was added).\n\t\t *\n\t\t * @type Object\n\t\t * @default null\n\t\t * @readonly\n\t\t */\n\t\tthis.currentTarget = null;\n\n\t\t/**\n\t\t * For bubbling events, this indicates the current event phase:\n\t\t *
    \n\t\t * \t
  1. capture phase: starting from the top parent to the target
  2. \n\t\t * \t
  3. at target phase: currently being dispatched from the target
  4. \n\t\t * \t
  5. bubbling phase: from the target to the top parent
  6. \n\t\t *
\n\t\t *\n\t\t * @type number\n\t\t * @default 0\n\t\t * @readonly\n\t\t */\n\t\tthis.eventPhase = 0;\n\n\t\t/**\n\t\t * Indicates whether the event will bubble through the display list.\n\t\t *\n\t\t * @type boolean\n\t\t * @readonly\n\t\t */\n\t\tthis.bubbles = bubbles;\n\n\t\t/**\n\t\t * Indicates whether the default behaviour of this event can be cancelled via {@link core.Event#preventDefault}.\n\t\t *\n\t\t * @type boolean\n\t\t * @readonly\n\t\t */\n\t\tthis.cancelable = cancelable;\n\n\t\t/**\n\t\t * The epoch time at which this event was created.\n\t\t *\n\t\t * @type number\n\t\t * @readonly\n\t\t */\n\t\tthis.timeStamp = new Date().getTime();\n\n\t\t/**\n\t\t * Indicates if {@link core.Event#preventDefault} has been called on this event.\n\t\t *\n\t\t * @type boolean\n\t\t * @default false\n\t\t * @readonly\n\t\t */\n\t\tthis.defaultPrevented = false;\n\n\t\t/**\n\t\t * Indicates if {@link core.Event#stopPropagation} or {@link core.Event#stopImmediatePropagation} has been called on this event.\n\t\t *\n\t\t * @type boolean\n\t\t * @default false\n\t\t * @readonly\n\t\t */\n\t\tthis.propagationStopped = false;\n\n\t\t/**\n\t\t * Indicates if {@link core.Event#stopImmediatePropagation} has been called on this event.\n\t\t *\n\t\t * @type boolean\n\t\t * @default false\n\t\t * @readonly\n\t\t */\n\t\tthis.immediatePropagationStopped = false;\n\n\t\t/**\n\t\t * Indicates if {@link core.Event#remove} has been called on this event.\n\t\t *\n\t\t * @type boolean\n\t\t * @default false\n\t\t * @readonly\n\t\t */\n\t\tthis.removed = false;\n\t}\n\n\t/**\n\t * Sets {@link core.Event#defaultPrevented} to true if the event is cancelable.\n\t * Mirrors the DOM level 2 event standard. In general, cancelable events that have `preventDefault()` called will\n\t * cancel the default behaviour associated with the event.\n\t * @return {core.Event} this, chainable\n\t */\n\tpreventDefault () {\n\t\tthis.defaultPrevented = this.cancelable;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets {@link core.Event#propagationStopped} to true.\n\t * Mirrors the DOM event standard.\n\t * @return {core.Event} this, chainable\n\t */\n\tstopPropagation () {\n\t\tthis.propagationStopped = true;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets {@link core.Event#propagationStopped} and {@link core.Event#immediatePropagationStopped} to true.\n\t * Mirrors the DOM event standard.\n\t * @return {core.Event} this, chainable\n\t */\n\tstopImmediatePropagation () {\n\t\tthis.immediatePropagationStopped = this.propagationStopped = true;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Causes the active listener to be removed via removeEventListener();\n\t *\n\t * @example\n\t * myBtn.addEventListener(\"click\", event => {\n\t * event.remove(); // removes this listener.\n\t * });\n\t *\n\t * @return {core.Event} this, chainable\n\t */\n\tremove () {\n\t\tthis.removed = true;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Returns a clone of the Event instance.\n\t *\n\t * @return {core.Event} a clone of the Event instance.\n\t */\n\tclone () {\n\t\tconst event = new Event(this.type, this.bubbles, this.cancelable);\n\t\tfor (let n in this) {\n\t\t\tif (this.hasOwnProperty(n)) {\n\t\t\t\tevent[n] = this[n];\n\t\t\t}\n\t\t}\n\t\treturn event;\n\t}\n\n\t/**\n\t * Provides a return {core.Event} this, chainable shortcut method for setting a number of properties on the instance.\n\t *\n\t * @param {Object} props A generic object containing properties to copy to the instance.\n\t * @return {core.Event} this, chainable\n\t */\n\tset (props) {\n\t\tfor (let n in props) { this[n] = props[n]; }\n\t\treturn this;\n\t}\n\n\t/**\n\t * Returns a string representation of this object.\n\t *\n\t * @return {string} A string representation of the instance.\n\t */\n\ttoString () {\n\t\treturn `[${this.constructor.name} (type=${this.type})]`;\n\t}\n\n}\n\nexport default Event;\n","/**\n * @license EventDispatcher\n * Visit http://createjs.com/ for documentation, updates and examples.\n *\n * Copyright (c) 2017 gskinner.com, inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\nimport Event from \"./Event\";\n\n/**\n * EventDispatcher provides methods for managing queues of event listeners and dispatching events.\n *\n * You can either extend EventDispatcher or mix its methods into an existing prototype or instance by using the\n * EventDispatcher {@link core.EventDispatcher.initialize} method.\n *\n * Together with the CreateJS Event class, EventDispatcher provides an extended event model that is based on the\n * DOM Level 2 event model, including addEventListener, removeEventListener, and dispatchEvent. It supports\n * bubbling / capture, preventDefault, stopPropagation, stopImmediatePropagation, and handleEvent.\n *\n * EventDispatcher also exposes a {@link core.EventDispatcher#on} method, which makes it easier\n * to create scoped listeners, listeners that only run once, and listeners with associated arbitrary data. The\n * {@link core.EventDispatcher#off} method is merely an alias to {@link core.EventDispatcher#removeEventListener}.\n *\n * Another addition to the DOM Level 2 model is the {@link core.EventDispatcher#removeAllEventListeners}\n * method, which can be used to listeners for all events, or listeners for a specific event. The Event object also\n * includes a {@link core.Event#remove} method which removes the active listener.\n *\n * @memberof core\n * @example\n * // add EventDispatcher capabilities to the \"MyClass\" class.\n * EventDispatcher.initialize(MyClass.prototype);\n *\n * // Add an event.\n * instance.addEventListener(\"eventName\", event => console.log(event.target + \" was clicked.\"));\n *\n * // scope (\"this\") can be be a challenge with events.\n * // using the {@link core.EventDispatcher#on} method to subscribe to events simplifies this.\n * instance.addEventListener(\"click\", event => console.log(instance === this)); // false, scope is ambiguous.\n * instance.on(\"click\", event => console.log(instance === this)); // true, `on` uses dispatcher scope by default.\n */\nclass EventDispatcher {\n\n\t/**\n\t * Static initializer to mix EventDispatcher methods into a target object or prototype.\n\t *\n\t * @static\n\t * @example\n\t * EventDispatcher.initialize(MyClass.prototype); // add to the prototype of the class\n\t * EventDispatcher.initialize(myInstance); // add to a specific instance\n\t *\n\t * @param {Object} target The target object to inject EventDispatcher methods into.\n\t */\n\tstatic initialize (target) {\n\t\tconst p = EventDispatcher.prototype;\n\t\ttarget.addEventListener = p.addEventListener;\n\t\ttarget.on = p.on;\n\t\ttarget.removeEventListener = target.off = p.removeEventListener;\n\t\ttarget.removeAllEventListeners = p.removeAllEventListeners;\n\t\ttarget.hasEventListener = p.hasEventListener;\n\t\ttarget.dispatchEvent = p.dispatchEvent;\n\t\ttarget._dispatchEvent = p._dispatchEvent;\n\t\ttarget.willTrigger = p.willTrigger;\n\t}\n\n\tconstructor () {\n\t\t/**\n\t\t * @private\n\t\t * @default null\n\t\t * @type Object\n\t\t */\n\t\tthis._listeners = null;\n\n\t\t/**\n\t\t * @private\n\t\t * @default null\n\t\t * @type Object\n\t\t */\n\t\tthis._captureListeners = null;\n\t}\n\n\t/**\n\t * Adds the specified event listener. Note that adding multiple listeners to the same function will result in\n\t * multiple callbacks getting fired.\n\t *\n\t * @example\n\t * displayObject.addEventListener(\"click\", event => console.log('clicked', event));\n\t *\n\t * @param {string} type The string type of the event.\n\t * @param {Function|Object} listener An object with a handleEvent method, or a function that will be called when the event is dispatched.\n\t * @param {boolean} [useCapture=false] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase.\n\t * @return {Function|Object} Returns the listener for chaining or assignment.\n\t */\n\taddEventListener (type, listener, useCapture = false) {\n\t\tlet listeners;\n\t\tif (useCapture) {\n\t\t\tlisteners = this._captureListeners = this._captureListeners || {};\n\t\t} else {\n\t\t\tlisteners = this._listeners = this._listeners || {};\n\t\t}\n\t\tlet arr = listeners[type];\n\t\tif (arr) {\n\t\t\tthis.removeEventListener(type, listener, useCapture);\n\t\t\tarr = listeners[type]; // remove may have deleted the array\n\t\t}\n\t\tif (arr) { arr.push(listener); }\n\t\telse { listeners[type] = [listener]; }\n\t\treturn listener;\n\t}\n\n\t/**\n\t * A shortcut method for using addEventListener that makes it easier to specify an execution scope, have a listener\n\t * only run once, associate arbitrary data with the listener, and remove the listener.\n\t *\n\t * This method works by creating an anonymous wrapper function and subscribing it with `addEventListener`.\n\t * The wrapper function is returned for use with `removeEventListener` (or `off`).\n\t *\n\t * To remove a listener added with `on`, you must pass in the returned wrapper function as the listener, or use\n\t * {@link core.Event#remove}. Likewise, each time you call `on` a NEW wrapper function is subscribed, so multiple calls\n\t * to `on` with the same params will create multiple listeners.\n\t *\n\t * @example\n\t * const listener = myBtn.on(\"click\", handleClick, null, false, { count: 3 });\n\t * function handleClick (evt, data) {\n\t * data.count -= 1;\n\t * console.log(this == myBtn); // true - scope defaults to the dispatcher\n\t * if (data.count == 0) {\n\t * alert(\"clicked 3 times!\");\n\t * myBtn.off(\"click\", listener);\n\t * // alternately: evt.remove();\n\t * }\n\t * }\n\t *\n\t * @param {string} type The string type of the event.\n\t * @param {Function|Object} listener An object with a handleEvent method, or a function that will be called when the event is dispatched.\n\t * @param {Object} [scope=null] 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).\n\t * @param {boolean} [once=false] If true, the listener will remove itself after the first time it is triggered.\n\t * @param {*} [data={}] Arbitrary data that will be included as the second parameter when the listener is called.\n\t * @param {boolean} [useCapture=false] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase.\n\t * @return {Function} Returns the anonymous function that was created and assigned as the listener. This is needed to remove the listener later using .removeEventListener.\n\t */\n\ton (type, listener, scope = null, once = false, data = {}, useCapture = false) {\n\t\tif (listener.handleEvent) {\n\t\t\tscope = scope || listener;\n\t\t\tlistener = listener.handleEvent;\n\t\t}\n\t\tscope = scope || this;\n\t\treturn this.addEventListener(type, evt => {\n\t\t\tlistener.call(scope, evt, data);\n\t\t\tonce && evt.remove();\n\t\t}, useCapture);\n\t}\n\n\t/**\n\t * Removes the specified event listener.\n\t *\n\t * You must pass the exact function reference used when the event was added. If a proxy\n\t * function, or function closure is used as the callback, the proxy/closure reference must be used - a new proxy or\n\t * closure will not work.\n\t *\n\t * @example\n\t * displayObject.removeEventListener(\"click\", handleClick);\n\t *\n\t * @param {string} type The string type of the event.\n\t * @param {Function|Object} listener The listener function or object.\n\t * @param {boolean} [useCapture=false] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase.\n\t */\n\tremoveEventListener (type, listener, useCapture = false) {\n\t\tconst listeners = useCapture ? this._captureListeners : this._listeners;\n\t\tif (!listeners) { return; }\n\t\tconst arr = listeners[type];\n\t\tif (!arr) { return; }\n\t\tconst l = arr.length;\n\t\tfor (let i = 0; i < l; i++) {\n\t\t\tif (arr[i] === listener) {\n\t\t\t\tif (l === 1) { delete(listeners[type]); } // allows for faster checks.\n\t\t\t\telse { arr.splice(i, 1); }\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * A shortcut to the removeEventListener method, with the same parameters and return value. This is a companion to the\n\t * `on` method.\n\t *\n\t * To remove a listener added with `on`, you must pass in the returned wrapper function as the listener. See\n\t * {@link core.EventDispatcher#on} for an example.\n\t *\n\t * @param {string} type The string type of the event.\n\t * @param {Function|Object} listener The listener function or object.\n\t * @param {boolean} [useCapture=false] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase.\n\t */\n\toff (type, listener, useCapture = false) {\n\t\tthis.removeEventListener(type, listener, useCapture);\n\t}\n\n\t/**\n\t * Removes all listeners for the specified type, or all listeners of all types.\n\t *\n\t * @example\n\t * // remove all listeners\n\t * displayObject.removeAllEventListeners();\n\t *\n\t * // remove all click listeners\n\t * displayObject.removeAllEventListeners(\"click\");\n\t *\n\t * @param {string} [type=null] The string type of the event. If omitted, all listeners for all types will be removed.\n\t */\n\tremoveAllEventListeners (type = null) {\n\t\tif (type) {\n\t\t\tif (this._listeners) { delete(this._listeners[type]); }\n\t\t\tif (this._captureListeners) { delete(this._captureListeners[type]); }\n\t\t} else {\n\t\t\tthis._listeners = this._captureListeners = null;\n\t\t}\n\t}\n\n\t/**\n\t * Dispatches the specified event to all listeners.\n\t *\n\t * @example\n\t * // use a string event\n\t * this.dispatchEvent(\"complete\")\n\t *\n\t * // use an Event instance\n\t * const event = new createjs.Event(\"progress\");\n\t * this.dispatchEvent(event);\n\t *\n\t * @param {Object|Event|string} eventObj An object with a \"type\" property, or a string type.\n\t * While a generic object will work, it is recommended to use a CreateJS Event instance. If a string is used,\n\t * dispatchEvent will construct an Event instance if necessary with the specified type. This latter approach can\n\t * be used to avoid event object instantiation for non-bubbling events that may not have any listeners.\n\t * @param {boolean} [bubbles=false] Specifies the `bubbles` value when a string was passed to eventObj.\n\t * @param {boolean} [cancelable=false] Specifies the `cancelable` value when a string was passed to eventObj.\n\t * @return {boolean} Returns false if `preventDefault()` was called on a cancelable event, true otherwise.\n\t */\n\tdispatchEvent (eventObj, bubbles = false, cancelable = false) {\n\t\tif (typeof eventObj === \"string\") {\n\t\t\t// skip everything if there's no listeners and it doesn't bubble:\n\t\t\tconst listeners = this._listeners;\n\t\t\tif (!bubbles && (!listeners || !listeners[eventObj])) { return true; }\n\t\t\teventObj = new Event(eventObj, bubbles, cancelable);\n\t\t} else if (eventObj.target && eventObj.clone) {\n\t\t\t// redispatching an active event object, so clone it:\n\t\t\teventObj = eventObj.clone();\n\t\t}\n\n\t\t// TODO: it would be nice to eliminate this. Maybe in favour of evtObj instanceof Event? Or !!evtObj.createEvent\n\t\ttry { eventObj.target = this; } catch (e) {} // try/catch allows redispatching of native events\n\n\t\tif (!eventObj.bubbles || !this.parent) {\n\t\t\tthis._dispatchEvent(eventObj, 2);\n\t\t} else {\n\t\t\tlet top = this;\n\t\t\tconst list = [top];\n\t\t\twhile (top.parent) { list.push(top = top.parent); }\n\t\t\tconst l = list.length;\n\t\t\tlet i;\n\n\t\t\t// capture & atTarget\n\t\t\tfor (i = l - 1; i >= 0 && !eventObj.propagationStopped; i--) {\n\t\t\t\tlist[i]._dispatchEvent(eventObj, 1+(i==0));\n\t\t\t}\n\t\t\t// bubbling\n\t\t\tfor (i = 1; i < l && !eventObj.propagationStopped; i++) {\n\t\t\t\tlist[i]._dispatchEvent(eventObj, 3);\n\t\t\t}\n\t\t}\n\t\treturn !eventObj.defaultPrevented;\n\t}\n\n\t/**\n\t * Indicates whether there is at least one listener for the specified event type.\n\t *\n\t * @param {string} type The string type of the event.\n\t * @return {boolean} Returns true if there is at least one listener for the specified event.\n\t */\n\thasEventListener (type) {\n\t\tconst listeners = this._listeners, captureListeners = this._captureListeners;\n\t\treturn !!((listeners && listeners[type]) || (captureListeners && captureListeners[type]));\n\t}\n\n\t/**\n\t * Indicates whether there is at least one listener for the specified event type on this object or any of its\n\t * ancestors (parent, parent's parent, etc). A return value of true indicates that if a bubbling event of the\n\t * specified type is dispatched from this object, it will trigger at least one listener.\n\t *\n\t * This is similar to {@link core.EventDispatcher#hasEventListener}, but it searches the entire\n\t * event flow for a listener, not just this object.\n\t *\n\t * @param {string} type The string type of the event.\n\t * @return {boolean} Returns `true` if there is at least one listener for the specified event.\n\t */\n\twillTrigger (type) {\n\t\tlet o = this;\n\t\twhile (o) {\n\t\t\tif (o.hasEventListener(type)) { return true; }\n\t\t\to = o.parent;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * @return {String} a string representation of the instance.\n\t */\n\ttoString () {\n\t\treturn `[${this.constructor.name + this.name ? ` ${this.name}` : \"\"}]`;\n\t}\n\n\t/**\n\t * @private\n\t * @param {Object|Event|string} eventObj\n\t * @param {Object} eventPhase\n\t */\n\t_dispatchEvent (eventObj, eventPhase) {\n\t\tconst listeners = eventPhase === 1 ? this._captureListeners : this._listeners;\n\t\tif (eventObj && listeners) {\n\t\t\tlet arr = listeners[eventObj.type];\n\t\t\tlet l;\n\t\t\tif (!arr || (l = arr.length) === 0) { return; }\n\t\t\ttry { eventObj.currentTarget = this; } catch (e) {}\n\t\t\ttry { eventObj.eventPhase = eventPhase; } catch (e) {}\n\t\t\teventObj.removed = false;\n\n\t\t\tarr = arr.slice(); // to avoid issues with items being removed or added during the dispatch\n\t\t\tfor (let i = 0; i < l && !eventObj.immediatePropagationStopped; i++) {\n\t\t\t\tlet o = arr[i];\n\t\t\t\tif (o.handleEvent) { o.handleEvent(eventObj); }\n\t\t\t\telse { o(eventObj); }\n\t\t\t\tif (eventObj.removed) {\n\t\t\t\t\tthis.off(eventObj.type, o, eventPhase === 1);\n\t\t\t\t\teventObj.removed = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n}\n\nexport default EventDispatcher;\n","/**\n * @license Ticker\n * Visit http://createjs.com/ for documentation, updates and examples.\n *\n * Copyright (c) 2017 gskinner.com, inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\nimport EventDispatcher from \"../events/EventDispatcher\";\nimport Event from \"../events/Event\";\n\n/**\n * The Ticker provides a centralized tick or heartbeat broadcast at a set interval. Listeners can subscribe to the tick\n * event to be notified when a set time interval has elapsed.\n *\n * Note that the interval that the tick event is called is a target interval, and may be broadcast at a slower interval\n * when under high CPU load. The Ticker class uses a static interface (ex. `Ticker.framerate = 30;`) and\n * can not be instantiated.\n *\n * @todo Pass timingMode, maxDelta, paused values as instantiation arguments?\n *\n * @memberof core\n * @example\n * Ticker.addEventListener(\"tick\", event => {\n * // Actions carried out each tick (aka frame)\n * if (!event.paused) {\n * // Actions carried out when the Ticker is not paused.\n * }\n * });\n * @example\n * // Ticker export explanation\n * import Ticker, { Ticker as TickerClass, getTicker } from \"@createjs/core\";\n * Ticker.name, Ticker.RAF // -> createjs.global, undefined\n * TickerClass.RAF // -> raf\n * Ticker === getTicker(\"createjs.global\") // -> true\n *\n * @extends core.EventDispatcher\n * @param {string} name The name assigned to this instance.\n */\nclass Ticker extends EventDispatcher {\n\n\t/**\n\t * In this mode, Ticker uses the requestAnimationFrame API, but attempts to synch the ticks to target framerate. It\n\t * uses a simple heuristic that compares the time of the RAF return to the target time for the current frame and\n\t * dispatches the tick when the time is within a certain threshold.\n\t *\n\t * This mode has a higher variance for time between frames than {{#crossLink \"Ticker/TIMEOUT:property\"}}{{/crossLink}},\n\t * but does not require that content be time based as with {{#crossLink \"Ticker/RAF:property\"}}{{/crossLink}} while\n\t * gaining the benefits of that API (screen synch, background throttling).\n\t *\n\t * Variance is usually lowest for framerates that are a divisor of the RAF frequency. This is usually 60, so\n\t * framerates of 10, 12, 15, 20, and 30 work well.\n\t *\n\t * Falls back to {{#crossLink \"Ticker/TIMEOUT:property\"}}{{/crossLink}} if the requestAnimationFrame API is not\n\t * supported.\n\t *\n\t * @static\n\t * @type {string}\n\t * @default \"synched\"\n\t * @readonly\n\t */\n\tstatic get RAF_SYNCHED () { return \"synched\"; }\n\n\t/**\n\t * In this mode, Ticker passes through the requestAnimationFrame heartbeat, ignoring the target framerate completely.\n\t * Because requestAnimationFrame frequency is not deterministic, any content using this mode should be time based.\n\t * You can leverage {@link core.Ticker#getTime} and the {@link core.Ticker#event:tick}\n\t * event object's \"delta\" properties to make this easier.\n\t *\n\t * Falls back on {@link core.Ticker.TIMEOUT} if the requestAnimationFrame API is not supported.\n\t *\n\t * @static\n\t * @type {string}\n\t * @default \"raf\"\n\t * @readonly\n\t */\n\tstatic get RAF () { return \"raf\"; }\n\n\t/**\n\t * In this mode, Ticker uses the setTimeout API. This provides predictable, adaptive frame timing, but does not\n\t * provide the benefits of requestAnimationFrame (screen synch, background throttling).\n\t *\n\t * @static\n\t * @type {string}\n\t * @default \"timeout\"\n\t * @readonly\n\t */\n\tstatic get TIMEOUT () { return \"timeout\"; }\n\n\tconstructor (name) {\n\t\tsuper();\n\n\t\t/**\n\t\t * The name of this instance.\n\t\t * @type {string}\n\t\t */\n\t\tthis.name = name;\n\n\t\t/**\n\t\t * Specifies the timing api (setTimeout or requestAnimationFrame) and mode to use.\n\t\t *\n\t\t * @see {@link core.Ticker.TIMEOUT}\n\t\t * @see {@link core.Ticker.RAF}\n\t\t * @see {@link core.Ticker.RAF_SYNCHED}\n\t\t *\n\t\t * @type {string}\n\t\t * @default Ticker.TIMEOUT\n\t\t */\n\t\tthis.timingMode = Ticker.TIMEOUT;\n\n\t\t/**\n\t\t * Specifies a maximum value for the delta property in the tick event object. This is useful when building time\n\t\t * based animations and systems to prevent issues caused by large time gaps caused by background tabs, system sleep,\n\t\t * alert dialogs, or other blocking routines. Double the expected frame duration is often an effective value\n\t\t * (ex. maxDelta=50 when running at 40fps).\n\t\t *\n\t\t * This does not impact any other values (ex. time, runTime, etc), so you may experience issues if you enable maxDelta\n\t\t * when using both delta and other values.\n\t\t *\n\t\t * If 0, there is no maximum.\n\t\t *\n\t\t * @type {number}\n\t\t * @default 0\n\t\t */\n\t\tthis.maxDelta = 0;\n\n\t\t/**\n\t\t * When the ticker is paused, all listeners will still receive a tick event, but the `paused` property\n\t\t * of the event will be `true`. Also, while paused the `runTime` will not increase.\n\t\t *\n\t\t * @example\n\t\t * Ticker.addEventListener(\"tick\", event => console.log(event.paused, Ticker.getTime(false), Ticker.getTime(true)));\n\t\t * Ticker.paused = true;\n\t\t *\n\t\t * @see {@link core.Ticker#event:tick}\n\t\t * @see {@link core.Ticker#getTime}\n\t\t * @see {@link core.Ticker#getEventTime}\n\t\t *\n\t\t * @type {boolean}\n\t\t * @default false\n\t\t */\n\t\tthis.paused = false;\n\n\t\t/**\n\t\t * @private\n\t\t * @type {boolean}\n\t\t * @default false\n\t\t */\n\t\tthis._inited = false;\n\n\t\t/**\n\t\t * @private\n\t\t * @type {number}\n\t\t * @default 0\n\t\t */\n\t\tthis._startTime = 0;\n\n\t\t/**\n\t\t * @private\n\t\t * @type {number}\n\t\t * @default 0\n\t\t */\n\t\tthis._pausedTime = 0;\n\n\t\t/**\n\t\t * The number of ticks that have passed.\n\t\t *\n\t\t * @private\n\t\t * @type {number}\n\t\t * @default 0\n\t\t */\n\t\tthis._ticks = 0;\n\n\t\t/**\n\t\t * The number of ticks that have passed while Ticker has been paused.\n\t\t *\n\t\t * @private\n\t\t * @type {number}\n\t\t * @default\n\t\t */\n\t\tthis._pausedTicks = 0;\n\n\t\t/**\n\t\t * @private\n\t\t * @type {number}\n\t\t * @default\n\t\t */\n\t\tthis._interval = 50;\n\n\t\t/**\n\t\t * @private\n\t\t * @type {number}\n\t\t * @default\n\t\t */\n\t\tthis._lastTime = 0;\n\n\t\t/**\n\t\t * @private\n\t\t * @type {Array}\n\t\t * @default null\n\t\t */\n\t\tthis._times = null;\n\n\t\t/**\n\t\t * @private\n\t\t * @type {Array}\n\t\t * @default null\n\t\t */\n\t\tthis._tickTimes = null;\n\n\t\t/**\n\t\t * Stores the timeout or requestAnimationFrame id.\n\t\t *\n\t\t * @private\n\t\t * @type {number}\n\t\t * @default null\n\t\t */\n\t\tthis._timerId = null;\n\n\t\t/**\n\t\t * True if currently using requestAnimationFrame, false if using setTimeout. This may be different than timingMode\n\t\t * if that property changed and a tick hasn't fired.\n\t\t *\n\t\t * @private\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t */\n\t\tthis._raf = true;\n\t}\n\n\t/**\n\t * Indicates the target time (in milliseconds) between ticks. Default is 50 (20 FPS).\n\t * Note that actual time between ticks may be more than specified depending on CPU load.\n\t * This property is ignored if the ticker is using the `RAF` timing mode.\n\t *\n\t * @type {number}\n\t */\n\tget interval () { return this._interval; }\n\tset interval (interval) {\n\t\tthis._interval = interval;\n\t\tif (!this._inited) { return; }\n\t\tthis._setupTick();\n\t}\n\n\t/**\n\t * Indicates the target frame rate in frames per second (FPS). Effectively just a shortcut to `interval`, where\n\t * `framerate == 1000/interval`.\n\t *\n\t * @type {number}\n\t */\n\tget framerate () { return 1000 / this._interval; }\n\tset framerate (framerate) { this.interval = 1000 / framerate; }\n\n\t/**\n\t * Starts the tick. This is called automatically when the first listener is added.\n\t */\n\tinit () {\n\t\tif (this._inited) { return; }\n\t\tthis._inited = true;\n\t\tthis._times = [];\n\t\tthis._tickTimes = [];\n\t\tthis._startTime = this._getTime();\n\t\tthis._times.push(this._lastTime = 0);\n\t\tthis._setupTick();\n\t}\n\n\t/**\n\t * Stops the Ticker and removes all listeners. Use init() to restart the Ticker.\n\t */\n\treset () {\n\t\tif (this._raf) {\n\t\t\tlet f = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.oCancelAnimationFrame || window.msCancelAnimationFrame;\n\t\t\tf && f(this._timerId);\n\t\t} else {\n\t\t\tclearTimeout(this._timerId);\n\t\t}\n\t\tthis.removeAllEventListeners(\"tick\");\n\t\tthis._timerId = this._times = this._tickTimes = null;\n\t\tthis._startTime = this._lastTime = this._ticks = 0;\n\t\tthis._inited = false;\n\t}\n\n\t/**\n\t * Init the Ticker instance if it hasn't been already.\n\t */\n\taddEventListener (type, listener, useCapture) {\n\t\t!this._inited && this.init();\n\t\treturn super.addEventListener(type, listener, useCapture);\n\t}\n\n\t/**\n\t * Returns the average time spent within a tick. This can vary significantly from the value provided by getMeasuredFPS\n\t * because it only measures the time spent within the tick execution stack.\n\t *\n\t * Example 1: With a target FPS of 20, getMeasuredFPS() returns 20fps, which indicates an average of 50ms between\n\t * the end of one tick and the end of the next. However, getMeasuredTickTime() returns 15ms. This indicates that\n\t * there may be up to 35ms of \"idle\" time between the end of one tick and the start of the next.\n\t *\n\t * Example 2: With a target FPS of 30, getFPS() returns 10fps, which indicates an average of 100ms between the end of\n\t * one tick and the end of the next. However, getMeasuredTickTime() returns 20ms. This would indicate that something\n\t * other than the tick is using ~80ms (another script, DOM rendering, etc).\n\t *\n\t * @param {number} [ticks=null] The number of previous ticks over which to measure the average time spent in a tick.\n\t * Defaults to the number of ticks per second. To get only the last tick's time, pass in 1.\n\t * @return {number} The average time spent in a tick in milliseconds.\n\t */\n\tgetMeasuredTickTime (ticks = null) {\n\t\tconst times = this._tickTimes;\n\t\tif (!times || times.length < 1) { return -1; }\n\t\t// by default, calculate average for the past ~1 second:\n\t\tticks = Math.min(times.length, ticks || (this.framerate | 0));\n\t\treturn times.reduce((a, b) => a + b, 0) / ticks;\n\t}\n\n\t/**\n\t * Returns the actual frames / ticks per second.\n\t *\n\t * @param {number} [ticks=null] The number of previous ticks over which to measure the actual frames / ticks per second.\n\t * Defaults to the number of ticks per second.\n\t * @return {number} The actual frames / ticks per second. Depending on performance, this may differ\n\t * from the target frames per second.\n\t */\n\tgetMeasuredFPS (ticks = null) {\n\t\tconst times = this._times;\n\t\tif (!times || times.length < 2) { return -1; }\n\t\t// by default, calculate fps for the past ~1 second:\n\t\tticks = Math.min(times.length - 1, ticks || (this.framerate | 0));\n\t\treturn 1000 / ((times[0] - times[ticks]) / ticks);\n\t}\n\n\t/**\n\t * Returns the number of milliseconds that have elapsed since Ticker was initialized via {@link core.Ticker#init}.\n\t * Returns -1 if Ticker has not been initialized. For example, you could use\n\t * this in a time synchronized animation to determine the exact amount of time that has elapsed.\n\t *\n\t * @param {boolean} [runTime=false] If true only time elapsed while Ticker was not paused will be returned.\n\t * If false, the value returned will be total time elapsed since the first tick event listener was added.\n\t * @return {number} Number of milliseconds that have elapsed since Ticker was initialized or -1.\n\t */\n\tgetTime (runTime = false) {\n\t\treturn this._startTime ? this._getTime() - (runTime ? this._pausedTime : 0) : -1;\n\t}\n\n\t/**\n\t * Similar to {@link core.Ticker#getTime}, but returns the time on the most recent {@link core.Ticker#event:tick}\n\t * event object.\n\t *\n\t * @param {boolean} [runTime=false] If true, the runTime property will be returned instead of time.\n\t * @returns {number} The time or runTime property from the most recent tick event or -1.\n\t */\n\tgetEventTime (runTime = false) {\n\t\treturn this._startTime ? (this._lastTime || this._startTime) - (runTime ? this._pausedTime : 0) : -1;\n\t}\n\n\t/**\n\t * Returns the number of ticks that have been broadcast by Ticker.\n\t *\n\t * @param {boolean} [pauseable=false] Indicates whether to include ticks that would have been broadcast\n\t * while Ticker was paused. If true only tick events broadcast while Ticker is not paused will be returned.\n\t * If false, tick events that would have been broadcast while Ticker was paused will be included in the return\n\t * value.\n\t * @return {number} of ticks that have been broadcast.\n\t */\n\tgetTicks (pauseable = false) {\n\t\treturn this._ticks - (pauseable ? this._pausedTicks : 0);\n\t}\n\n\t/**\n\t * @private\n\t */\n\t_handleSynch () {\n\t\tthis._timerId = null;\n\t\tthis._setupTick();\n\n\t\t// run if enough time has elapsed, with a little bit of flexibility to be early:\n\t\tif (this._getTime() - this._lastTime >= (this._interval - 1) * 0.97) {\n\t\t\tthis._tick();\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t */\n\t_handleRAF () {\n\t\tthis._timerId = null;\n\t\tthis._setupTick();\n\t\tthis._tick();\n\t}\n\n\t/**\n\t * @private\n\t */\n\t_handleTimeout () {\n\t\tthis._timerId = null;\n\t\tthis._setupTick();\n\t\tthis._tick();\n\t}\n\n\t/**\n\t * @private\n\t */\n\t_setupTick () {\n\t\tif (this._timerId != null) { return; } // avoid duplicates\n\t\tconst mode = this.timingMode || (this._raf && Ticker.RAF);\n\t\tif (mode === Ticker.RAF_SYNCHED || mode === Ticker.RAF) {\n\t\t\tconst f = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame;\n\t\t\tif (f) {\n\t\t\t\tthis._timerId = f(mode === Ticker.RAF ? this._handleRAF.bind(this) : this._handleSynch.bind(this));\n\t\t\t\tthis._raf = true;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tthis._raf = false;\n\t\tthis._timerId = setTimeout(this._handleTimeout.bind(this), this._interval);\n\t}\n\n\t/**\n\t * @private\n\t * @emits core.Ticker#event:tick\n\t */\n\t_tick () {\n\t\tconst paused = this.paused, time = this._getTime(), elapsedTime = time - this._lastTime;\n\t\tthis._lastTime = time;\n\t\tthis._ticks++;\n\n\t\tif (paused) {\n\t\t\tthis._pausedTicks++;\n\t\t\tthis._pausedTime += elapsedTime;\n\t\t}\n\n\t\tif (this.hasEventListener(\"tick\")) {\n\t\t\tconst event = new Event(\"tick\");\n\t\t\tconst maxDelta = this.maxDelta;\n\t\t\tevent.delta = (maxDelta && elapsedTime > maxDelta) ? maxDelta : elapsedTime;\n\t\t\tevent.paused = paused;\n\t\t\tevent.time = time;\n\t\t\tevent.runTime = time - this._pausedTime;\n\t\t\tthis.dispatchEvent(event);\n\t\t}\n\n\t\tthis._tickTimes.unshift(this._getTime() - time);\n\t\twhile (this._tickTimes.length > 100) { this._tickTimes.pop(); }\n\n\t\tthis._times.unshift(time);\n\t\twhile (this._times.length > 100) { this._times.pop(); }\n\t}\n\n\t/**\n\t * @private\n\t */\n\t_getTime () {\n\t\tconst now = window.performance && window.performance.now;\n\t\treturn ((now && now.call(performance)) || (new Date().getTime())) - this._startTime;\n\t}\n\n\tstatic on (type, listener, scope, once, data, useCapture) { return _instance.on(type, listener, scope, once, data, useCapture); }\n\tstatic removeEventListener (type, listener, useCapture) { _instance.removeEventListener(type, listener, useCapture); }\n\tstatic off (type, listener, useCapture) { _instance.off(type, listener, useCapture); }\n\tstatic removeAllEventListeners (type) { _instance.removeAllEventListeners(type); }\n\tstatic dispatchEvent (eventObj, bubbles, cancelable) { return _instance.dispatchEvent(eventObj, bubbles, cancelable); }\n\tstatic hasEventListener (type) { return _instance.hasEventListener(type); }\n\tstatic willTrigger (type) { return _instance.willTrigger(type); }\n\tstatic toString () { return _instance.toString(); }\n\tstatic init () { _instance.init(); }\n\tstatic reset () { _instance.reset(); }\n\tstatic addEventListener (type, listener, useCapture) { _instance.addEventListener(type, listener, useCapture); }\n\tstatic getMeasuredTickTime (ticks) { return _instance.getMeasuredTickTime(ticks); }\n\tstatic getMeasuredFPS (ticks) { return _instance.getMeasuredFPS(ticks); }\n\tstatic getTime (runTime) { return _instance.getTime(runTime); }\n\tstatic getEventTime (runTime) { return _instance.getEventTime(runTime); }\n\tstatic getTicks (pauseable) { return _instance.getTicks(pauseable); }\n\n\tstatic get interval () { return _instance.interval; }\n\tstatic set interval (interval) { _instance.interval = interval; }\n\tstatic get framerate () { return _instance.framerate; }\n\tstatic set framerate (framerate) { _instance.framerate = framerate; }\n\tstatic get name () { return _instance.name; }\n\tstatic set name (name) { _instance.name = name; }\n\tstatic get timingMode () { return _instance.timingMode; }\n\tstatic set timingMode (timingMode) { _instance.timingMode = timingMode; }\n\tstatic get maxDelta () { return _instance.maxDelta; }\n\tstatic set maxDelta (maxDelta) { _instance.maxDelta = maxDelta; }\n\tstatic get paused () { return _instance.paused; }\n\tstatic set paused (paused) { _instance.paused = paused; }\n\n}\n\n/**\n * Dispatched each tick. The event will be dispatched to each listener even when the Ticker has been paused.\n *\n * @example\n * Ticker.addEventListener(\"tick\", event => console.log(\"Paused:\", event.paused, event.delta));\n *\n * @event core.Ticker#tick\n * @type {Object}\n * @property {Object} target The object that dispatched the event.\n * @property {string} type The event type.\n * @property {boolean} paused Indicates whether the ticker is currently paused.\n * @property {number} delta The time elapsed in ms since the last tick.\n * @property {number} time The total time in ms since Ticker was initialized.\n * @property {number} runTime The total time in ms that Ticker was not paused since it was initialized. For example,\n * you could determine the amount of time that the Ticker has been paused since initialization with `time-runTime`.\n * @since 0.6.0\n */\n\nexport default Ticker;\n\n// the default Ticker instance\nconst _instance = new Ticker(\"createjs.global\");\n"],"names":["Event","type","bubbles","cancelable","target","currentTarget","eventPhase","timeStamp","Date","getTime","defaultPrevented","propagationStopped","immediatePropagationStopped","removed","preventDefault","stopPropagation","stopImmediatePropagation","remove","clone","event","n","hasOwnProperty","set","props","toString","constructor","name","EventDispatcher","initialize","p","prototype","addEventListener","on","removeEventListener","off","removeAllEventListeners","hasEventListener","dispatchEvent","_dispatchEvent","willTrigger","_listeners","_captureListeners","listener","useCapture","listeners","arr","push","scope","once","data","handleEvent","evt","call","l","length","i","splice","eventObj","e","parent","top","list","captureListeners","o","slice","Ticker","timingMode","TIMEOUT","maxDelta","paused","_inited","_startTime","_pausedTime","_ticks","_pausedTicks","_interval","_lastTime","_times","_tickTimes","_timerId","_raf","init","_getTime","_setupTick","reset","f","window","cancelAnimationFrame","webkitCancelAnimationFrame","mozCancelAnimationFrame","oCancelAnimationFrame","msCancelAnimationFrame","clearTimeout","getMeasuredTickTime","ticks","times","Math","min","framerate","reduce","a","b","getMeasuredFPS","runTime","getEventTime","getTicks","pauseable","_handleSynch","_tick","_handleRAF","_handleTimeout","mode","RAF","RAF_SYNCHED","requestAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","oRequestAnimationFrame","msRequestAnimationFrame","bind","setTimeout","time","elapsedTime","delta","unshift","pop","now","performance","_instance","interval"],"mappings":"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"} -------------------------------------------------------------------------------- /dist/core.cjs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license Core 3 | * Visit https://createjs.com for documentation, updates and examples. 4 | * 5 | * Copyright (c) 2017 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 | 'use strict'; 30 | 31 | Object.defineProperty(exports, '__esModule', { value: true }); 32 | 33 | var Event = 34 | function () { 35 | function Event(type, bubbles, cancelable) { 36 | if (bubbles === void 0) { 37 | bubbles = false; 38 | } 39 | if (cancelable === void 0) { 40 | cancelable = false; 41 | } 42 | this.type = type; 43 | this.target = null; 44 | this.currentTarget = null; 45 | this.eventPhase = 0; 46 | this.bubbles = bubbles; 47 | this.cancelable = cancelable; 48 | this.timeStamp = new Date().getTime(); 49 | this.defaultPrevented = false; 50 | this.propagationStopped = false; 51 | this.immediatePropagationStopped = false; 52 | this.removed = false; 53 | } 54 | var _proto = Event.prototype; 55 | _proto.preventDefault = function preventDefault() { 56 | this.defaultPrevented = this.cancelable; 57 | return this; 58 | }; 59 | _proto.stopPropagation = function stopPropagation() { 60 | this.propagationStopped = true; 61 | return this; 62 | }; 63 | _proto.stopImmediatePropagation = function stopImmediatePropagation() { 64 | this.immediatePropagationStopped = this.propagationStopped = true; 65 | return this; 66 | }; 67 | _proto.remove = function remove() { 68 | this.removed = true; 69 | return this; 70 | }; 71 | _proto.clone = function clone() { 72 | var event = new Event(this.type, this.bubbles, this.cancelable); 73 | for (var n in this) { 74 | if (this.hasOwnProperty(n)) { 75 | event[n] = this[n]; 76 | } 77 | } 78 | return event; 79 | }; 80 | _proto.set = function set(props) { 81 | for (var n in props) { 82 | this[n] = props[n]; 83 | } 84 | return this; 85 | }; 86 | _proto.toString = function toString() { 87 | return "[" + this.constructor.name + " (type=" + this.type + ")]"; 88 | }; 89 | return Event; 90 | }(); 91 | 92 | var EventDispatcher = 93 | function () { 94 | EventDispatcher.initialize = function initialize(target) { 95 | var p = EventDispatcher.prototype; 96 | target.addEventListener = p.addEventListener; 97 | target.on = p.on; 98 | target.removeEventListener = target.off = p.removeEventListener; 99 | target.removeAllEventListeners = p.removeAllEventListeners; 100 | target.hasEventListener = p.hasEventListener; 101 | target.dispatchEvent = p.dispatchEvent; 102 | target._dispatchEvent = p._dispatchEvent; 103 | target.willTrigger = p.willTrigger; 104 | }; 105 | function EventDispatcher() { 106 | this._listeners = null; 107 | this._captureListeners = null; 108 | } 109 | var _proto = EventDispatcher.prototype; 110 | _proto.addEventListener = function addEventListener(type, listener, useCapture) { 111 | if (useCapture === void 0) { 112 | useCapture = false; 113 | } 114 | var listeners; 115 | if (useCapture) { 116 | listeners = this._captureListeners = this._captureListeners || {}; 117 | } else { 118 | listeners = this._listeners = this._listeners || {}; 119 | } 120 | var arr = listeners[type]; 121 | if (arr) { 122 | this.removeEventListener(type, listener, useCapture); 123 | arr = listeners[type]; 124 | } 125 | if (arr) { 126 | arr.push(listener); 127 | } else { 128 | listeners[type] = [listener]; 129 | } 130 | return listener; 131 | }; 132 | _proto.on = function on(type, listener, scope, once, data, useCapture) { 133 | if (scope === void 0) { 134 | scope = null; 135 | } 136 | if (once === void 0) { 137 | once = false; 138 | } 139 | if (data === void 0) { 140 | data = {}; 141 | } 142 | if (useCapture === void 0) { 143 | useCapture = false; 144 | } 145 | if (listener.handleEvent) { 146 | scope = scope || listener; 147 | listener = listener.handleEvent; 148 | } 149 | scope = scope || this; 150 | return this.addEventListener(type, function (evt) { 151 | listener.call(scope, evt, data); 152 | once && evt.remove(); 153 | }, useCapture); 154 | }; 155 | _proto.removeEventListener = function removeEventListener(type, listener, useCapture) { 156 | if (useCapture === void 0) { 157 | useCapture = false; 158 | } 159 | var listeners = useCapture ? this._captureListeners : this._listeners; 160 | if (!listeners) { 161 | return; 162 | } 163 | var arr = listeners[type]; 164 | if (!arr) { 165 | return; 166 | } 167 | var l = arr.length; 168 | for (var i = 0; i < l; i++) { 169 | if (arr[i] === listener) { 170 | if (l === 1) { 171 | delete listeners[type]; 172 | } 173 | else { 174 | arr.splice(i, 1); 175 | } 176 | break; 177 | } 178 | } 179 | }; 180 | _proto.off = function off(type, listener, useCapture) { 181 | if (useCapture === void 0) { 182 | useCapture = false; 183 | } 184 | this.removeEventListener(type, listener, useCapture); 185 | }; 186 | _proto.removeAllEventListeners = function removeAllEventListeners(type) { 187 | if (type === void 0) { 188 | type = null; 189 | } 190 | if (type) { 191 | if (this._listeners) { 192 | delete this._listeners[type]; 193 | } 194 | if (this._captureListeners) { 195 | delete this._captureListeners[type]; 196 | } 197 | } else { 198 | this._listeners = this._captureListeners = null; 199 | } 200 | }; 201 | _proto.dispatchEvent = function dispatchEvent(eventObj, bubbles, cancelable) { 202 | if (bubbles === void 0) { 203 | bubbles = false; 204 | } 205 | if (cancelable === void 0) { 206 | cancelable = false; 207 | } 208 | if (typeof eventObj === "string") { 209 | var listeners = this._listeners; 210 | if (!bubbles && (!listeners || !listeners[eventObj])) { 211 | return true; 212 | } 213 | eventObj = new Event(eventObj, bubbles, cancelable); 214 | } else if (eventObj.target && eventObj.clone) { 215 | eventObj = eventObj.clone(); 216 | } 217 | try { 218 | eventObj.target = this; 219 | } catch (e) {} 220 | if (!eventObj.bubbles || !this.parent) { 221 | this._dispatchEvent(eventObj, 2); 222 | } else { 223 | var top = this; 224 | var list = [top]; 225 | while (top.parent) { 226 | list.push(top = top.parent); 227 | } 228 | var l = list.length; 229 | var i; 230 | for (i = l - 1; i >= 0 && !eventObj.propagationStopped; i--) { 231 | list[i]._dispatchEvent(eventObj, 1 + (i == 0)); 232 | } 233 | for (i = 1; i < l && !eventObj.propagationStopped; i++) { 234 | list[i]._dispatchEvent(eventObj, 3); 235 | } 236 | } 237 | return !eventObj.defaultPrevented; 238 | }; 239 | _proto.hasEventListener = function hasEventListener(type) { 240 | var listeners = this._listeners, 241 | captureListeners = this._captureListeners; 242 | return !!(listeners && listeners[type] || captureListeners && captureListeners[type]); 243 | }; 244 | _proto.willTrigger = function willTrigger(type) { 245 | var o = this; 246 | while (o) { 247 | if (o.hasEventListener(type)) { 248 | return true; 249 | } 250 | o = o.parent; 251 | } 252 | return false; 253 | }; 254 | _proto.toString = function toString() { 255 | return "[" + (this.constructor.name + this.name ? " " + this.name : "") + "]"; 256 | }; 257 | _proto._dispatchEvent = function _dispatchEvent(eventObj, eventPhase) { 258 | var listeners = eventPhase === 1 ? this._captureListeners : this._listeners; 259 | if (eventObj && listeners) { 260 | var arr = listeners[eventObj.type]; 261 | var l; 262 | if (!arr || (l = arr.length) === 0) { 263 | return; 264 | } 265 | try { 266 | eventObj.currentTarget = this; 267 | } catch (e) {} 268 | try { 269 | eventObj.eventPhase = eventPhase; 270 | } catch (e) {} 271 | eventObj.removed = false; 272 | arr = arr.slice(); 273 | for (var i = 0; i < l && !eventObj.immediatePropagationStopped; i++) { 274 | var o = arr[i]; 275 | if (o.handleEvent) { 276 | o.handleEvent(eventObj); 277 | } else { 278 | o(eventObj); 279 | } 280 | if (eventObj.removed) { 281 | this.off(eventObj.type, o, eventPhase === 1); 282 | eventObj.removed = false; 283 | } 284 | } 285 | } 286 | }; 287 | return EventDispatcher; 288 | }(); 289 | 290 | function _defineProperties(target, props) { 291 | for (var i = 0; i < props.length; i++) { 292 | var descriptor = props[i]; 293 | descriptor.enumerable = descriptor.enumerable || false; 294 | descriptor.configurable = true; 295 | if ("value" in descriptor) descriptor.writable = true; 296 | Object.defineProperty(target, descriptor.key, descriptor); 297 | } 298 | } 299 | 300 | function _createClass(Constructor, protoProps, staticProps) { 301 | if (protoProps) _defineProperties(Constructor.prototype, protoProps); 302 | if (staticProps) _defineProperties(Constructor, staticProps); 303 | return Constructor; 304 | } 305 | 306 | function _inheritsLoose(subClass, superClass) { 307 | subClass.prototype = Object.create(superClass.prototype); 308 | subClass.prototype.constructor = subClass; 309 | subClass.__proto__ = superClass; 310 | } 311 | 312 | var Ticker = 313 | function (_EventDispatcher) { 314 | _inheritsLoose(Ticker, _EventDispatcher); 315 | _createClass(Ticker, null, [{ 316 | key: "RAF_SYNCHED", 317 | get: function get() { 318 | return "synched"; 319 | } 320 | }, { 321 | key: "RAF", 322 | get: function get() { 323 | return "raf"; 324 | } 325 | }, { 326 | key: "TIMEOUT", 327 | get: function get() { 328 | return "timeout"; 329 | } 330 | }]); 331 | function Ticker(name) { 332 | var _this; 333 | _this = _EventDispatcher.call(this) || this; 334 | _this.name = name; 335 | _this.timingMode = Ticker.TIMEOUT; 336 | _this.maxDelta = 0; 337 | _this.paused = false; 338 | _this._inited = false; 339 | _this._startTime = 0; 340 | _this._pausedTime = 0; 341 | _this._ticks = 0; 342 | _this._pausedTicks = 0; 343 | _this._interval = 50; 344 | _this._lastTime = 0; 345 | _this._times = null; 346 | _this._tickTimes = null; 347 | _this._timerId = null; 348 | _this._raf = true; 349 | return _this; 350 | } 351 | var _proto = Ticker.prototype; 352 | _proto.init = function init() { 353 | if (this._inited) { 354 | return; 355 | } 356 | this._inited = true; 357 | this._times = []; 358 | this._tickTimes = []; 359 | this._startTime = this._getTime(); 360 | this._times.push(this._lastTime = 0); 361 | this._setupTick(); 362 | }; 363 | _proto.reset = function reset() { 364 | if (this._raf) { 365 | var f = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.oCancelAnimationFrame || window.msCancelAnimationFrame; 366 | f && f(this._timerId); 367 | } else { 368 | clearTimeout(this._timerId); 369 | } 370 | this.removeAllEventListeners("tick"); 371 | this._timerId = this._times = this._tickTimes = null; 372 | this._startTime = this._lastTime = this._ticks = 0; 373 | this._inited = false; 374 | }; 375 | _proto.addEventListener = function addEventListener(type, listener, useCapture) { 376 | !this._inited && this.init(); 377 | return _EventDispatcher.prototype.addEventListener.call(this, type, listener, useCapture); 378 | }; 379 | _proto.getMeasuredTickTime = function getMeasuredTickTime(ticks) { 380 | if (ticks === void 0) { 381 | ticks = null; 382 | } 383 | var times = this._tickTimes; 384 | if (!times || times.length < 1) { 385 | return -1; 386 | } 387 | ticks = Math.min(times.length, ticks || this.framerate | 0); 388 | return times.reduce(function (a, b) { 389 | return a + b; 390 | }, 0) / ticks; 391 | }; 392 | _proto.getMeasuredFPS = function getMeasuredFPS(ticks) { 393 | if (ticks === void 0) { 394 | ticks = null; 395 | } 396 | var times = this._times; 397 | if (!times || times.length < 2) { 398 | return -1; 399 | } 400 | ticks = Math.min(times.length - 1, ticks || this.framerate | 0); 401 | return 1000 / ((times[0] - times[ticks]) / ticks); 402 | }; 403 | _proto.getTime = function getTime(runTime) { 404 | if (runTime === void 0) { 405 | runTime = false; 406 | } 407 | return this._startTime ? this._getTime() - (runTime ? this._pausedTime : 0) : -1; 408 | }; 409 | _proto.getEventTime = function getEventTime(runTime) { 410 | if (runTime === void 0) { 411 | runTime = false; 412 | } 413 | return this._startTime ? (this._lastTime || this._startTime) - (runTime ? this._pausedTime : 0) : -1; 414 | }; 415 | _proto.getTicks = function getTicks(pauseable) { 416 | if (pauseable === void 0) { 417 | pauseable = false; 418 | } 419 | return this._ticks - (pauseable ? this._pausedTicks : 0); 420 | }; 421 | _proto._handleSynch = function _handleSynch() { 422 | this._timerId = null; 423 | this._setupTick(); 424 | if (this._getTime() - this._lastTime >= (this._interval - 1) * 0.97) { 425 | this._tick(); 426 | } 427 | }; 428 | _proto._handleRAF = function _handleRAF() { 429 | this._timerId = null; 430 | this._setupTick(); 431 | this._tick(); 432 | }; 433 | _proto._handleTimeout = function _handleTimeout() { 434 | this._timerId = null; 435 | this._setupTick(); 436 | this._tick(); 437 | }; 438 | _proto._setupTick = function _setupTick() { 439 | if (this._timerId != null) { 440 | return; 441 | } 442 | var mode = this.timingMode || this._raf && Ticker.RAF; 443 | if (mode === Ticker.RAF_SYNCHED || mode === Ticker.RAF) { 444 | var f = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame; 445 | if (f) { 446 | this._timerId = f(mode === Ticker.RAF ? this._handleRAF.bind(this) : this._handleSynch.bind(this)); 447 | this._raf = true; 448 | return; 449 | } 450 | } 451 | this._raf = false; 452 | this._timerId = setTimeout(this._handleTimeout.bind(this), this._interval); 453 | }; 454 | _proto._tick = function _tick() { 455 | var paused = this.paused, 456 | time = this._getTime(), 457 | elapsedTime = time - this._lastTime; 458 | this._lastTime = time; 459 | this._ticks++; 460 | if (paused) { 461 | this._pausedTicks++; 462 | this._pausedTime += elapsedTime; 463 | } 464 | if (this.hasEventListener("tick")) { 465 | var event = new Event("tick"); 466 | var maxDelta = this.maxDelta; 467 | event.delta = maxDelta && elapsedTime > maxDelta ? maxDelta : elapsedTime; 468 | event.paused = paused; 469 | event.time = time; 470 | event.runTime = time - this._pausedTime; 471 | this.dispatchEvent(event); 472 | } 473 | this._tickTimes.unshift(this._getTime() - time); 474 | while (this._tickTimes.length > 100) { 475 | this._tickTimes.pop(); 476 | } 477 | this._times.unshift(time); 478 | while (this._times.length > 100) { 479 | this._times.pop(); 480 | } 481 | }; 482 | _proto._getTime = function _getTime() { 483 | var now = window.performance && window.performance.now; 484 | return (now && now.call(performance) || new Date().getTime()) - this._startTime; 485 | }; 486 | Ticker.on = function on(type, listener, scope, once, data, useCapture) { 487 | return _instance.on(type, listener, scope, once, data, useCapture); 488 | }; 489 | Ticker.removeEventListener = function removeEventListener(type, listener, useCapture) { 490 | _instance.removeEventListener(type, listener, useCapture); 491 | }; 492 | Ticker.off = function off(type, listener, useCapture) { 493 | _instance.off(type, listener, useCapture); 494 | }; 495 | Ticker.removeAllEventListeners = function removeAllEventListeners(type) { 496 | _instance.removeAllEventListeners(type); 497 | }; 498 | Ticker.dispatchEvent = function dispatchEvent(eventObj, bubbles, cancelable) { 499 | return _instance.dispatchEvent(eventObj, bubbles, cancelable); 500 | }; 501 | Ticker.hasEventListener = function hasEventListener(type) { 502 | return _instance.hasEventListener(type); 503 | }; 504 | Ticker.willTrigger = function willTrigger(type) { 505 | return _instance.willTrigger(type); 506 | }; 507 | Ticker.toString = function toString() { 508 | return _instance.toString(); 509 | }; 510 | Ticker.init = function init() { 511 | _instance.init(); 512 | }; 513 | Ticker.reset = function reset() { 514 | _instance.reset(); 515 | }; 516 | Ticker.addEventListener = function addEventListener(type, listener, useCapture) { 517 | _instance.addEventListener(type, listener, useCapture); 518 | }; 519 | Ticker.getMeasuredTickTime = function getMeasuredTickTime(ticks) { 520 | return _instance.getMeasuredTickTime(ticks); 521 | }; 522 | Ticker.getMeasuredFPS = function getMeasuredFPS(ticks) { 523 | return _instance.getMeasuredFPS(ticks); 524 | }; 525 | Ticker.getTime = function getTime(runTime) { 526 | return _instance.getTime(runTime); 527 | }; 528 | Ticker.getEventTime = function getEventTime(runTime) { 529 | return _instance.getEventTime(runTime); 530 | }; 531 | Ticker.getTicks = function getTicks(pauseable) { 532 | return _instance.getTicks(pauseable); 533 | }; 534 | _createClass(Ticker, [{ 535 | key: "interval", 536 | get: function get() { 537 | return this._interval; 538 | }, 539 | set: function set(interval) { 540 | this._interval = interval; 541 | if (!this._inited) { 542 | return; 543 | } 544 | this._setupTick(); 545 | } 546 | }, { 547 | key: "framerate", 548 | get: function get() { 549 | return 1000 / this._interval; 550 | }, 551 | set: function set(framerate) { 552 | this.interval = 1000 / framerate; 553 | } 554 | }], [{ 555 | key: "interval", 556 | get: function get() { 557 | return _instance.interval; 558 | }, 559 | set: function set(interval) { 560 | _instance.interval = interval; 561 | } 562 | }, { 563 | key: "framerate", 564 | get: function get() { 565 | return _instance.framerate; 566 | }, 567 | set: function set(framerate) { 568 | _instance.framerate = framerate; 569 | } 570 | }, { 571 | key: "name", 572 | get: function get() { 573 | return _instance.name; 574 | }, 575 | set: function set(name) { 576 | _instance.name = name; 577 | } 578 | }, { 579 | key: "timingMode", 580 | get: function get() { 581 | return _instance.timingMode; 582 | }, 583 | set: function set(timingMode) { 584 | _instance.timingMode = timingMode; 585 | } 586 | }, { 587 | key: "maxDelta", 588 | get: function get() { 589 | return _instance.maxDelta; 590 | }, 591 | set: function set(maxDelta) { 592 | _instance.maxDelta = maxDelta; 593 | } 594 | }, { 595 | key: "paused", 596 | get: function get() { 597 | return _instance.paused; 598 | }, 599 | set: function set(paused) { 600 | _instance.paused = paused; 601 | } 602 | }]); 603 | return Ticker; 604 | }(EventDispatcher); 605 | var _instance = new Ticker("createjs.global"); 606 | 607 | exports.Event = Event; 608 | exports.EventDispatcher = EventDispatcher; 609 | exports.Ticker = Ticker; 610 | 611 | 612 | var cjs = window.createjs = window.createjs || {}; 613 | var v = cjs.v = cjs.v || {}; 614 | 615 | v.core = "NEXT"; 616 | //# sourceMappingURL=core.cjs.js.map 617 | -------------------------------------------------------------------------------- /dist/core.cjs.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"core.cjs.js","sources":["../src/events/Event.js","../src/events/EventDispatcher.js","../src/utils/Ticker.js"],"sourcesContent":["/**\n * @license Event\n * Visit http://createjs.com/ for documentation, updates and examples.\n *\n * Copyright (c) 2017 gskinner.com, inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n/**\n * Contains properties and methods shared by all events for use with {@link core.EventDispatcher}.\n * Note that Event objects are often reused, so you should never\n * rely on an event object's state outside of the call stack it was received in.\n *\n * @memberof core\n * @example\n * const evt = new Event(\"myEvent\");\n * const dispatcher = new EventDispatcher();\n * dispatcher.on(\"myEvent\", event => console.log(event.type));\n * dispatcher.dispatchEvent(evt); // logs \"myEvent\"\n *\n * @param {string} type The event type.\n * @param {boolean} [bubbles=false] Indicates whether the event will bubble through the display list.\n * @param {boolean} [cancelable=false] Indicates whether the default behaviour of this event can be cancelled.\n */\nclass Event {\n\n\tconstructor (type, bubbles = false, cancelable = false) {\n\t\t/**\n\t\t * The type of event.\n\t\t * @type string\n\t\t */\n\t\tthis.type = type;\n\n\t\t/**\n\t\t * The object that generated an event.\n\t\t *\n\t\t * @type Object\n\t\t * @default null\n\t\t * @readonly\n\t\t */\n\t\tthis.target = null;\n\n\t\t/**\n\t\t * The current target that a bubbling event is being dispatched from. For non-bubbling events, this will\n\t\t * always be the same as target. For example, if childObj.parent = parentObj, and a bubbling event\n\t\t * is generated from childObj, then a listener on parentObj would receive the event with\n\t\t * target=childObj (the original target) and currentTarget=parentObj (where the listener was added).\n\t\t *\n\t\t * @type Object\n\t\t * @default null\n\t\t * @readonly\n\t\t */\n\t\tthis.currentTarget = null;\n\n\t\t/**\n\t\t * For bubbling events, this indicates the current event phase:\n\t\t *
    \n\t\t * \t
  1. capture phase: starting from the top parent to the target
  2. \n\t\t * \t
  3. at target phase: currently being dispatched from the target
  4. \n\t\t * \t
  5. bubbling phase: from the target to the top parent
  6. \n\t\t *
\n\t\t *\n\t\t * @type number\n\t\t * @default 0\n\t\t * @readonly\n\t\t */\n\t\tthis.eventPhase = 0;\n\n\t\t/**\n\t\t * Indicates whether the event will bubble through the display list.\n\t\t *\n\t\t * @type boolean\n\t\t * @readonly\n\t\t */\n\t\tthis.bubbles = bubbles;\n\n\t\t/**\n\t\t * Indicates whether the default behaviour of this event can be cancelled via {@link core.Event#preventDefault}.\n\t\t *\n\t\t * @type boolean\n\t\t * @readonly\n\t\t */\n\t\tthis.cancelable = cancelable;\n\n\t\t/**\n\t\t * The epoch time at which this event was created.\n\t\t *\n\t\t * @type number\n\t\t * @readonly\n\t\t */\n\t\tthis.timeStamp = new Date().getTime();\n\n\t\t/**\n\t\t * Indicates if {@link core.Event#preventDefault} has been called on this event.\n\t\t *\n\t\t * @type boolean\n\t\t * @default false\n\t\t * @readonly\n\t\t */\n\t\tthis.defaultPrevented = false;\n\n\t\t/**\n\t\t * Indicates if {@link core.Event#stopPropagation} or {@link core.Event#stopImmediatePropagation} has been called on this event.\n\t\t *\n\t\t * @type boolean\n\t\t * @default false\n\t\t * @readonly\n\t\t */\n\t\tthis.propagationStopped = false;\n\n\t\t/**\n\t\t * Indicates if {@link core.Event#stopImmediatePropagation} has been called on this event.\n\t\t *\n\t\t * @type boolean\n\t\t * @default false\n\t\t * @readonly\n\t\t */\n\t\tthis.immediatePropagationStopped = false;\n\n\t\t/**\n\t\t * Indicates if {@link core.Event#remove} has been called on this event.\n\t\t *\n\t\t * @type boolean\n\t\t * @default false\n\t\t * @readonly\n\t\t */\n\t\tthis.removed = false;\n\t}\n\n\t/**\n\t * Sets {@link core.Event#defaultPrevented} to true if the event is cancelable.\n\t * Mirrors the DOM level 2 event standard. In general, cancelable events that have `preventDefault()` called will\n\t * cancel the default behaviour associated with the event.\n\t * @return {core.Event} this, chainable\n\t */\n\tpreventDefault () {\n\t\tthis.defaultPrevented = this.cancelable;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets {@link core.Event#propagationStopped} to true.\n\t * Mirrors the DOM event standard.\n\t * @return {core.Event} this, chainable\n\t */\n\tstopPropagation () {\n\t\tthis.propagationStopped = true;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets {@link core.Event#propagationStopped} and {@link core.Event#immediatePropagationStopped} to true.\n\t * Mirrors the DOM event standard.\n\t * @return {core.Event} this, chainable\n\t */\n\tstopImmediatePropagation () {\n\t\tthis.immediatePropagationStopped = this.propagationStopped = true;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Causes the active listener to be removed via removeEventListener();\n\t *\n\t * @example\n\t * myBtn.addEventListener(\"click\", event => {\n\t * event.remove(); // removes this listener.\n\t * });\n\t *\n\t * @return {core.Event} this, chainable\n\t */\n\tremove () {\n\t\tthis.removed = true;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Returns a clone of the Event instance.\n\t *\n\t * @return {core.Event} a clone of the Event instance.\n\t */\n\tclone () {\n\t\tconst event = new Event(this.type, this.bubbles, this.cancelable);\n\t\tfor (let n in this) {\n\t\t\tif (this.hasOwnProperty(n)) {\n\t\t\t\tevent[n] = this[n];\n\t\t\t}\n\t\t}\n\t\treturn event;\n\t}\n\n\t/**\n\t * Provides a return {core.Event} this, chainable shortcut method for setting a number of properties on the instance.\n\t *\n\t * @param {Object} props A generic object containing properties to copy to the instance.\n\t * @return {core.Event} this, chainable\n\t */\n\tset (props) {\n\t\tfor (let n in props) { this[n] = props[n]; }\n\t\treturn this;\n\t}\n\n\t/**\n\t * Returns a string representation of this object.\n\t *\n\t * @return {string} A string representation of the instance.\n\t */\n\ttoString () {\n\t\treturn `[${this.constructor.name} (type=${this.type})]`;\n\t}\n\n}\n\nexport default Event;\n","/**\n * @license EventDispatcher\n * Visit http://createjs.com/ for documentation, updates and examples.\n *\n * Copyright (c) 2017 gskinner.com, inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\nimport Event from \"./Event\";\n\n/**\n * EventDispatcher provides methods for managing queues of event listeners and dispatching events.\n *\n * You can either extend EventDispatcher or mix its methods into an existing prototype or instance by using the\n * EventDispatcher {@link core.EventDispatcher.initialize} method.\n *\n * Together with the CreateJS Event class, EventDispatcher provides an extended event model that is based on the\n * DOM Level 2 event model, including addEventListener, removeEventListener, and dispatchEvent. It supports\n * bubbling / capture, preventDefault, stopPropagation, stopImmediatePropagation, and handleEvent.\n *\n * EventDispatcher also exposes a {@link core.EventDispatcher#on} method, which makes it easier\n * to create scoped listeners, listeners that only run once, and listeners with associated arbitrary data. The\n * {@link core.EventDispatcher#off} method is merely an alias to {@link core.EventDispatcher#removeEventListener}.\n *\n * Another addition to the DOM Level 2 model is the {@link core.EventDispatcher#removeAllEventListeners}\n * method, which can be used to listeners for all events, or listeners for a specific event. The Event object also\n * includes a {@link core.Event#remove} method which removes the active listener.\n *\n * @memberof core\n * @example\n * // add EventDispatcher capabilities to the \"MyClass\" class.\n * EventDispatcher.initialize(MyClass.prototype);\n *\n * // Add an event.\n * instance.addEventListener(\"eventName\", event => console.log(event.target + \" was clicked.\"));\n *\n * // scope (\"this\") can be be a challenge with events.\n * // using the {@link core.EventDispatcher#on} method to subscribe to events simplifies this.\n * instance.addEventListener(\"click\", event => console.log(instance === this)); // false, scope is ambiguous.\n * instance.on(\"click\", event => console.log(instance === this)); // true, `on` uses dispatcher scope by default.\n */\nclass EventDispatcher {\n\n\t/**\n\t * Static initializer to mix EventDispatcher methods into a target object or prototype.\n\t *\n\t * @static\n\t * @example\n\t * EventDispatcher.initialize(MyClass.prototype); // add to the prototype of the class\n\t * EventDispatcher.initialize(myInstance); // add to a specific instance\n\t *\n\t * @param {Object} target The target object to inject EventDispatcher methods into.\n\t */\n\tstatic initialize (target) {\n\t\tconst p = EventDispatcher.prototype;\n\t\ttarget.addEventListener = p.addEventListener;\n\t\ttarget.on = p.on;\n\t\ttarget.removeEventListener = target.off = p.removeEventListener;\n\t\ttarget.removeAllEventListeners = p.removeAllEventListeners;\n\t\ttarget.hasEventListener = p.hasEventListener;\n\t\ttarget.dispatchEvent = p.dispatchEvent;\n\t\ttarget._dispatchEvent = p._dispatchEvent;\n\t\ttarget.willTrigger = p.willTrigger;\n\t}\n\n\tconstructor () {\n\t\t/**\n\t\t * @private\n\t\t * @default null\n\t\t * @type Object\n\t\t */\n\t\tthis._listeners = null;\n\n\t\t/**\n\t\t * @private\n\t\t * @default null\n\t\t * @type Object\n\t\t */\n\t\tthis._captureListeners = null;\n\t}\n\n\t/**\n\t * Adds the specified event listener. Note that adding multiple listeners to the same function will result in\n\t * multiple callbacks getting fired.\n\t *\n\t * @example\n\t * displayObject.addEventListener(\"click\", event => console.log('clicked', event));\n\t *\n\t * @param {string} type The string type of the event.\n\t * @param {Function|Object} listener An object with a handleEvent method, or a function that will be called when the event is dispatched.\n\t * @param {boolean} [useCapture=false] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase.\n\t * @return {Function|Object} Returns the listener for chaining or assignment.\n\t */\n\taddEventListener (type, listener, useCapture = false) {\n\t\tlet listeners;\n\t\tif (useCapture) {\n\t\t\tlisteners = this._captureListeners = this._captureListeners || {};\n\t\t} else {\n\t\t\tlisteners = this._listeners = this._listeners || {};\n\t\t}\n\t\tlet arr = listeners[type];\n\t\tif (arr) {\n\t\t\tthis.removeEventListener(type, listener, useCapture);\n\t\t\tarr = listeners[type]; // remove may have deleted the array\n\t\t}\n\t\tif (arr) { arr.push(listener); }\n\t\telse { listeners[type] = [listener]; }\n\t\treturn listener;\n\t}\n\n\t/**\n\t * A shortcut method for using addEventListener that makes it easier to specify an execution scope, have a listener\n\t * only run once, associate arbitrary data with the listener, and remove the listener.\n\t *\n\t * This method works by creating an anonymous wrapper function and subscribing it with `addEventListener`.\n\t * The wrapper function is returned for use with `removeEventListener` (or `off`).\n\t *\n\t * To remove a listener added with `on`, you must pass in the returned wrapper function as the listener, or use\n\t * {@link core.Event#remove}. Likewise, each time you call `on` a NEW wrapper function is subscribed, so multiple calls\n\t * to `on` with the same params will create multiple listeners.\n\t *\n\t * @example\n\t * const listener = myBtn.on(\"click\", handleClick, null, false, { count: 3 });\n\t * function handleClick (evt, data) {\n\t * data.count -= 1;\n\t * console.log(this == myBtn); // true - scope defaults to the dispatcher\n\t * if (data.count == 0) {\n\t * alert(\"clicked 3 times!\");\n\t * myBtn.off(\"click\", listener);\n\t * // alternately: evt.remove();\n\t * }\n\t * }\n\t *\n\t * @param {string} type The string type of the event.\n\t * @param {Function|Object} listener An object with a handleEvent method, or a function that will be called when the event is dispatched.\n\t * @param {Object} [scope=null] 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).\n\t * @param {boolean} [once=false] If true, the listener will remove itself after the first time it is triggered.\n\t * @param {*} [data={}] Arbitrary data that will be included as the second parameter when the listener is called.\n\t * @param {boolean} [useCapture=false] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase.\n\t * @return {Function} Returns the anonymous function that was created and assigned as the listener. This is needed to remove the listener later using .removeEventListener.\n\t */\n\ton (type, listener, scope = null, once = false, data = {}, useCapture = false) {\n\t\tif (listener.handleEvent) {\n\t\t\tscope = scope || listener;\n\t\t\tlistener = listener.handleEvent;\n\t\t}\n\t\tscope = scope || this;\n\t\treturn this.addEventListener(type, evt => {\n\t\t\tlistener.call(scope, evt, data);\n\t\t\tonce && evt.remove();\n\t\t}, useCapture);\n\t}\n\n\t/**\n\t * Removes the specified event listener.\n\t *\n\t * You must pass the exact function reference used when the event was added. If a proxy\n\t * function, or function closure is used as the callback, the proxy/closure reference must be used - a new proxy or\n\t * closure will not work.\n\t *\n\t * @example\n\t * displayObject.removeEventListener(\"click\", handleClick);\n\t *\n\t * @param {string} type The string type of the event.\n\t * @param {Function|Object} listener The listener function or object.\n\t * @param {boolean} [useCapture=false] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase.\n\t */\n\tremoveEventListener (type, listener, useCapture = false) {\n\t\tconst listeners = useCapture ? this._captureListeners : this._listeners;\n\t\tif (!listeners) { return; }\n\t\tconst arr = listeners[type];\n\t\tif (!arr) { return; }\n\t\tconst l = arr.length;\n\t\tfor (let i = 0; i < l; i++) {\n\t\t\tif (arr[i] === listener) {\n\t\t\t\tif (l === 1) { delete(listeners[type]); } // allows for faster checks.\n\t\t\t\telse { arr.splice(i, 1); }\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * A shortcut to the removeEventListener method, with the same parameters and return value. This is a companion to the\n\t * `on` method.\n\t *\n\t * To remove a listener added with `on`, you must pass in the returned wrapper function as the listener. See\n\t * {@link core.EventDispatcher#on} for an example.\n\t *\n\t * @param {string} type The string type of the event.\n\t * @param {Function|Object} listener The listener function or object.\n\t * @param {boolean} [useCapture=false] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase.\n\t */\n\toff (type, listener, useCapture = false) {\n\t\tthis.removeEventListener(type, listener, useCapture);\n\t}\n\n\t/**\n\t * Removes all listeners for the specified type, or all listeners of all types.\n\t *\n\t * @example\n\t * // remove all listeners\n\t * displayObject.removeAllEventListeners();\n\t *\n\t * // remove all click listeners\n\t * displayObject.removeAllEventListeners(\"click\");\n\t *\n\t * @param {string} [type=null] The string type of the event. If omitted, all listeners for all types will be removed.\n\t */\n\tremoveAllEventListeners (type = null) {\n\t\tif (type) {\n\t\t\tif (this._listeners) { delete(this._listeners[type]); }\n\t\t\tif (this._captureListeners) { delete(this._captureListeners[type]); }\n\t\t} else {\n\t\t\tthis._listeners = this._captureListeners = null;\n\t\t}\n\t}\n\n\t/**\n\t * Dispatches the specified event to all listeners.\n\t *\n\t * @example\n\t * // use a string event\n\t * this.dispatchEvent(\"complete\")\n\t *\n\t * // use an Event instance\n\t * const event = new createjs.Event(\"progress\");\n\t * this.dispatchEvent(event);\n\t *\n\t * @param {Object|Event|string} eventObj An object with a \"type\" property, or a string type.\n\t * While a generic object will work, it is recommended to use a CreateJS Event instance. If a string is used,\n\t * dispatchEvent will construct an Event instance if necessary with the specified type. This latter approach can\n\t * be used to avoid event object instantiation for non-bubbling events that may not have any listeners.\n\t * @param {boolean} [bubbles=false] Specifies the `bubbles` value when a string was passed to eventObj.\n\t * @param {boolean} [cancelable=false] Specifies the `cancelable` value when a string was passed to eventObj.\n\t * @return {boolean} Returns false if `preventDefault()` was called on a cancelable event, true otherwise.\n\t */\n\tdispatchEvent (eventObj, bubbles = false, cancelable = false) {\n\t\tif (typeof eventObj === \"string\") {\n\t\t\t// skip everything if there's no listeners and it doesn't bubble:\n\t\t\tconst listeners = this._listeners;\n\t\t\tif (!bubbles && (!listeners || !listeners[eventObj])) { return true; }\n\t\t\teventObj = new Event(eventObj, bubbles, cancelable);\n\t\t} else if (eventObj.target && eventObj.clone) {\n\t\t\t// redispatching an active event object, so clone it:\n\t\t\teventObj = eventObj.clone();\n\t\t}\n\n\t\t// TODO: it would be nice to eliminate this. Maybe in favour of evtObj instanceof Event? Or !!evtObj.createEvent\n\t\ttry { eventObj.target = this; } catch (e) {} // try/catch allows redispatching of native events\n\n\t\tif (!eventObj.bubbles || !this.parent) {\n\t\t\tthis._dispatchEvent(eventObj, 2);\n\t\t} else {\n\t\t\tlet top = this;\n\t\t\tconst list = [top];\n\t\t\twhile (top.parent) { list.push(top = top.parent); }\n\t\t\tconst l = list.length;\n\t\t\tlet i;\n\n\t\t\t// capture & atTarget\n\t\t\tfor (i = l - 1; i >= 0 && !eventObj.propagationStopped; i--) {\n\t\t\t\tlist[i]._dispatchEvent(eventObj, 1+(i==0));\n\t\t\t}\n\t\t\t// bubbling\n\t\t\tfor (i = 1; i < l && !eventObj.propagationStopped; i++) {\n\t\t\t\tlist[i]._dispatchEvent(eventObj, 3);\n\t\t\t}\n\t\t}\n\t\treturn !eventObj.defaultPrevented;\n\t}\n\n\t/**\n\t * Indicates whether there is at least one listener for the specified event type.\n\t *\n\t * @param {string} type The string type of the event.\n\t * @return {boolean} Returns true if there is at least one listener for the specified event.\n\t */\n\thasEventListener (type) {\n\t\tconst listeners = this._listeners, captureListeners = this._captureListeners;\n\t\treturn !!((listeners && listeners[type]) || (captureListeners && captureListeners[type]));\n\t}\n\n\t/**\n\t * Indicates whether there is at least one listener for the specified event type on this object or any of its\n\t * ancestors (parent, parent's parent, etc). A return value of true indicates that if a bubbling event of the\n\t * specified type is dispatched from this object, it will trigger at least one listener.\n\t *\n\t * This is similar to {@link core.EventDispatcher#hasEventListener}, but it searches the entire\n\t * event flow for a listener, not just this object.\n\t *\n\t * @param {string} type The string type of the event.\n\t * @return {boolean} Returns `true` if there is at least one listener for the specified event.\n\t */\n\twillTrigger (type) {\n\t\tlet o = this;\n\t\twhile (o) {\n\t\t\tif (o.hasEventListener(type)) { return true; }\n\t\t\to = o.parent;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * @return {String} a string representation of the instance.\n\t */\n\ttoString () {\n\t\treturn `[${this.constructor.name + this.name ? ` ${this.name}` : \"\"}]`;\n\t}\n\n\t/**\n\t * @private\n\t * @param {Object|Event|string} eventObj\n\t * @param {Object} eventPhase\n\t */\n\t_dispatchEvent (eventObj, eventPhase) {\n\t\tconst listeners = eventPhase === 1 ? this._captureListeners : this._listeners;\n\t\tif (eventObj && listeners) {\n\t\t\tlet arr = listeners[eventObj.type];\n\t\t\tlet l;\n\t\t\tif (!arr || (l = arr.length) === 0) { return; }\n\t\t\ttry { eventObj.currentTarget = this; } catch (e) {}\n\t\t\ttry { eventObj.eventPhase = eventPhase; } catch (e) {}\n\t\t\teventObj.removed = false;\n\n\t\t\tarr = arr.slice(); // to avoid issues with items being removed or added during the dispatch\n\t\t\tfor (let i = 0; i < l && !eventObj.immediatePropagationStopped; i++) {\n\t\t\t\tlet o = arr[i];\n\t\t\t\tif (o.handleEvent) { o.handleEvent(eventObj); }\n\t\t\t\telse { o(eventObj); }\n\t\t\t\tif (eventObj.removed) {\n\t\t\t\t\tthis.off(eventObj.type, o, eventPhase === 1);\n\t\t\t\t\teventObj.removed = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n}\n\nexport default EventDispatcher;\n","/**\n * @license Ticker\n * Visit http://createjs.com/ for documentation, updates and examples.\n *\n * Copyright (c) 2017 gskinner.com, inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\nimport EventDispatcher from \"../events/EventDispatcher\";\nimport Event from \"../events/Event\";\n\n/**\n * The Ticker provides a centralized tick or heartbeat broadcast at a set interval. Listeners can subscribe to the tick\n * event to be notified when a set time interval has elapsed.\n *\n * Note that the interval that the tick event is called is a target interval, and may be broadcast at a slower interval\n * when under high CPU load. The Ticker class uses a static interface (ex. `Ticker.framerate = 30;`) and\n * can not be instantiated.\n *\n * @todo Pass timingMode, maxDelta, paused values as instantiation arguments?\n *\n * @memberof core\n * @example\n * Ticker.addEventListener(\"tick\", event => {\n * // Actions carried out each tick (aka frame)\n * if (!event.paused) {\n * // Actions carried out when the Ticker is not paused.\n * }\n * });\n * @example\n * // Ticker export explanation\n * import Ticker, { Ticker as TickerClass, getTicker } from \"@createjs/core\";\n * Ticker.name, Ticker.RAF // -> createjs.global, undefined\n * TickerClass.RAF // -> raf\n * Ticker === getTicker(\"createjs.global\") // -> true\n *\n * @extends core.EventDispatcher\n * @param {string} name The name assigned to this instance.\n */\nclass Ticker extends EventDispatcher {\n\n\t/**\n\t * In this mode, Ticker uses the requestAnimationFrame API, but attempts to synch the ticks to target framerate. It\n\t * uses a simple heuristic that compares the time of the RAF return to the target time for the current frame and\n\t * dispatches the tick when the time is within a certain threshold.\n\t *\n\t * This mode has a higher variance for time between frames than {{#crossLink \"Ticker/TIMEOUT:property\"}}{{/crossLink}},\n\t * but does not require that content be time based as with {{#crossLink \"Ticker/RAF:property\"}}{{/crossLink}} while\n\t * gaining the benefits of that API (screen synch, background throttling).\n\t *\n\t * Variance is usually lowest for framerates that are a divisor of the RAF frequency. This is usually 60, so\n\t * framerates of 10, 12, 15, 20, and 30 work well.\n\t *\n\t * Falls back to {{#crossLink \"Ticker/TIMEOUT:property\"}}{{/crossLink}} if the requestAnimationFrame API is not\n\t * supported.\n\t *\n\t * @static\n\t * @type {string}\n\t * @default \"synched\"\n\t * @readonly\n\t */\n\tstatic get RAF_SYNCHED () { return \"synched\"; }\n\n\t/**\n\t * In this mode, Ticker passes through the requestAnimationFrame heartbeat, ignoring the target framerate completely.\n\t * Because requestAnimationFrame frequency is not deterministic, any content using this mode should be time based.\n\t * You can leverage {@link core.Ticker#getTime} and the {@link core.Ticker#event:tick}\n\t * event object's \"delta\" properties to make this easier.\n\t *\n\t * Falls back on {@link core.Ticker.TIMEOUT} if the requestAnimationFrame API is not supported.\n\t *\n\t * @static\n\t * @type {string}\n\t * @default \"raf\"\n\t * @readonly\n\t */\n\tstatic get RAF () { return \"raf\"; }\n\n\t/**\n\t * In this mode, Ticker uses the setTimeout API. This provides predictable, adaptive frame timing, but does not\n\t * provide the benefits of requestAnimationFrame (screen synch, background throttling).\n\t *\n\t * @static\n\t * @type {string}\n\t * @default \"timeout\"\n\t * @readonly\n\t */\n\tstatic get TIMEOUT () { return \"timeout\"; }\n\n\tconstructor (name) {\n\t\tsuper();\n\n\t\t/**\n\t\t * The name of this instance.\n\t\t * @type {string}\n\t\t */\n\t\tthis.name = name;\n\n\t\t/**\n\t\t * Specifies the timing api (setTimeout or requestAnimationFrame) and mode to use.\n\t\t *\n\t\t * @see {@link core.Ticker.TIMEOUT}\n\t\t * @see {@link core.Ticker.RAF}\n\t\t * @see {@link core.Ticker.RAF_SYNCHED}\n\t\t *\n\t\t * @type {string}\n\t\t * @default Ticker.TIMEOUT\n\t\t */\n\t\tthis.timingMode = Ticker.TIMEOUT;\n\n\t\t/**\n\t\t * Specifies a maximum value for the delta property in the tick event object. This is useful when building time\n\t\t * based animations and systems to prevent issues caused by large time gaps caused by background tabs, system sleep,\n\t\t * alert dialogs, or other blocking routines. Double the expected frame duration is often an effective value\n\t\t * (ex. maxDelta=50 when running at 40fps).\n\t\t *\n\t\t * This does not impact any other values (ex. time, runTime, etc), so you may experience issues if you enable maxDelta\n\t\t * when using both delta and other values.\n\t\t *\n\t\t * If 0, there is no maximum.\n\t\t *\n\t\t * @type {number}\n\t\t * @default 0\n\t\t */\n\t\tthis.maxDelta = 0;\n\n\t\t/**\n\t\t * When the ticker is paused, all listeners will still receive a tick event, but the `paused` property\n\t\t * of the event will be `true`. Also, while paused the `runTime` will not increase.\n\t\t *\n\t\t * @example\n\t\t * Ticker.addEventListener(\"tick\", event => console.log(event.paused, Ticker.getTime(false), Ticker.getTime(true)));\n\t\t * Ticker.paused = true;\n\t\t *\n\t\t * @see {@link core.Ticker#event:tick}\n\t\t * @see {@link core.Ticker#getTime}\n\t\t * @see {@link core.Ticker#getEventTime}\n\t\t *\n\t\t * @type {boolean}\n\t\t * @default false\n\t\t */\n\t\tthis.paused = false;\n\n\t\t/**\n\t\t * @private\n\t\t * @type {boolean}\n\t\t * @default false\n\t\t */\n\t\tthis._inited = false;\n\n\t\t/**\n\t\t * @private\n\t\t * @type {number}\n\t\t * @default 0\n\t\t */\n\t\tthis._startTime = 0;\n\n\t\t/**\n\t\t * @private\n\t\t * @type {number}\n\t\t * @default 0\n\t\t */\n\t\tthis._pausedTime = 0;\n\n\t\t/**\n\t\t * The number of ticks that have passed.\n\t\t *\n\t\t * @private\n\t\t * @type {number}\n\t\t * @default 0\n\t\t */\n\t\tthis._ticks = 0;\n\n\t\t/**\n\t\t * The number of ticks that have passed while Ticker has been paused.\n\t\t *\n\t\t * @private\n\t\t * @type {number}\n\t\t * @default\n\t\t */\n\t\tthis._pausedTicks = 0;\n\n\t\t/**\n\t\t * @private\n\t\t * @type {number}\n\t\t * @default\n\t\t */\n\t\tthis._interval = 50;\n\n\t\t/**\n\t\t * @private\n\t\t * @type {number}\n\t\t * @default\n\t\t */\n\t\tthis._lastTime = 0;\n\n\t\t/**\n\t\t * @private\n\t\t * @type {Array}\n\t\t * @default null\n\t\t */\n\t\tthis._times = null;\n\n\t\t/**\n\t\t * @private\n\t\t * @type {Array}\n\t\t * @default null\n\t\t */\n\t\tthis._tickTimes = null;\n\n\t\t/**\n\t\t * Stores the timeout or requestAnimationFrame id.\n\t\t *\n\t\t * @private\n\t\t * @type {number}\n\t\t * @default null\n\t\t */\n\t\tthis._timerId = null;\n\n\t\t/**\n\t\t * True if currently using requestAnimationFrame, false if using setTimeout. This may be different than timingMode\n\t\t * if that property changed and a tick hasn't fired.\n\t\t *\n\t\t * @private\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t */\n\t\tthis._raf = true;\n\t}\n\n\t/**\n\t * Indicates the target time (in milliseconds) between ticks. Default is 50 (20 FPS).\n\t * Note that actual time between ticks may be more than specified depending on CPU load.\n\t * This property is ignored if the ticker is using the `RAF` timing mode.\n\t *\n\t * @type {number}\n\t */\n\tget interval () { return this._interval; }\n\tset interval (interval) {\n\t\tthis._interval = interval;\n\t\tif (!this._inited) { return; }\n\t\tthis._setupTick();\n\t}\n\n\t/**\n\t * Indicates the target frame rate in frames per second (FPS). Effectively just a shortcut to `interval`, where\n\t * `framerate == 1000/interval`.\n\t *\n\t * @type {number}\n\t */\n\tget framerate () { return 1000 / this._interval; }\n\tset framerate (framerate) { this.interval = 1000 / framerate; }\n\n\t/**\n\t * Starts the tick. This is called automatically when the first listener is added.\n\t */\n\tinit () {\n\t\tif (this._inited) { return; }\n\t\tthis._inited = true;\n\t\tthis._times = [];\n\t\tthis._tickTimes = [];\n\t\tthis._startTime = this._getTime();\n\t\tthis._times.push(this._lastTime = 0);\n\t\tthis._setupTick();\n\t}\n\n\t/**\n\t * Stops the Ticker and removes all listeners. Use init() to restart the Ticker.\n\t */\n\treset () {\n\t\tif (this._raf) {\n\t\t\tlet f = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.oCancelAnimationFrame || window.msCancelAnimationFrame;\n\t\t\tf && f(this._timerId);\n\t\t} else {\n\t\t\tclearTimeout(this._timerId);\n\t\t}\n\t\tthis.removeAllEventListeners(\"tick\");\n\t\tthis._timerId = this._times = this._tickTimes = null;\n\t\tthis._startTime = this._lastTime = this._ticks = 0;\n\t\tthis._inited = false;\n\t}\n\n\t/**\n\t * Init the Ticker instance if it hasn't been already.\n\t */\n\taddEventListener (type, listener, useCapture) {\n\t\t!this._inited && this.init();\n\t\treturn super.addEventListener(type, listener, useCapture);\n\t}\n\n\t/**\n\t * Returns the average time spent within a tick. This can vary significantly from the value provided by getMeasuredFPS\n\t * because it only measures the time spent within the tick execution stack.\n\t *\n\t * Example 1: With a target FPS of 20, getMeasuredFPS() returns 20fps, which indicates an average of 50ms between\n\t * the end of one tick and the end of the next. However, getMeasuredTickTime() returns 15ms. This indicates that\n\t * there may be up to 35ms of \"idle\" time between the end of one tick and the start of the next.\n\t *\n\t * Example 2: With a target FPS of 30, getFPS() returns 10fps, which indicates an average of 100ms between the end of\n\t * one tick and the end of the next. However, getMeasuredTickTime() returns 20ms. This would indicate that something\n\t * other than the tick is using ~80ms (another script, DOM rendering, etc).\n\t *\n\t * @param {number} [ticks=null] The number of previous ticks over which to measure the average time spent in a tick.\n\t * Defaults to the number of ticks per second. To get only the last tick's time, pass in 1.\n\t * @return {number} The average time spent in a tick in milliseconds.\n\t */\n\tgetMeasuredTickTime (ticks = null) {\n\t\tconst times = this._tickTimes;\n\t\tif (!times || times.length < 1) { return -1; }\n\t\t// by default, calculate average for the past ~1 second:\n\t\tticks = Math.min(times.length, ticks || (this.framerate | 0));\n\t\treturn times.reduce((a, b) => a + b, 0) / ticks;\n\t}\n\n\t/**\n\t * Returns the actual frames / ticks per second.\n\t *\n\t * @param {number} [ticks=null] The number of previous ticks over which to measure the actual frames / ticks per second.\n\t * Defaults to the number of ticks per second.\n\t * @return {number} The actual frames / ticks per second. Depending on performance, this may differ\n\t * from the target frames per second.\n\t */\n\tgetMeasuredFPS (ticks = null) {\n\t\tconst times = this._times;\n\t\tif (!times || times.length < 2) { return -1; }\n\t\t// by default, calculate fps for the past ~1 second:\n\t\tticks = Math.min(times.length - 1, ticks || (this.framerate | 0));\n\t\treturn 1000 / ((times[0] - times[ticks]) / ticks);\n\t}\n\n\t/**\n\t * Returns the number of milliseconds that have elapsed since Ticker was initialized via {@link core.Ticker#init}.\n\t * Returns -1 if Ticker has not been initialized. For example, you could use\n\t * this in a time synchronized animation to determine the exact amount of time that has elapsed.\n\t *\n\t * @param {boolean} [runTime=false] If true only time elapsed while Ticker was not paused will be returned.\n\t * If false, the value returned will be total time elapsed since the first tick event listener was added.\n\t * @return {number} Number of milliseconds that have elapsed since Ticker was initialized or -1.\n\t */\n\tgetTime (runTime = false) {\n\t\treturn this._startTime ? this._getTime() - (runTime ? this._pausedTime : 0) : -1;\n\t}\n\n\t/**\n\t * Similar to {@link core.Ticker#getTime}, but returns the time on the most recent {@link core.Ticker#event:tick}\n\t * event object.\n\t *\n\t * @param {boolean} [runTime=false] If true, the runTime property will be returned instead of time.\n\t * @returns {number} The time or runTime property from the most recent tick event or -1.\n\t */\n\tgetEventTime (runTime = false) {\n\t\treturn this._startTime ? (this._lastTime || this._startTime) - (runTime ? this._pausedTime : 0) : -1;\n\t}\n\n\t/**\n\t * Returns the number of ticks that have been broadcast by Ticker.\n\t *\n\t * @param {boolean} [pauseable=false] Indicates whether to include ticks that would have been broadcast\n\t * while Ticker was paused. If true only tick events broadcast while Ticker is not paused will be returned.\n\t * If false, tick events that would have been broadcast while Ticker was paused will be included in the return\n\t * value.\n\t * @return {number} of ticks that have been broadcast.\n\t */\n\tgetTicks (pauseable = false) {\n\t\treturn this._ticks - (pauseable ? this._pausedTicks : 0);\n\t}\n\n\t/**\n\t * @private\n\t */\n\t_handleSynch () {\n\t\tthis._timerId = null;\n\t\tthis._setupTick();\n\n\t\t// run if enough time has elapsed, with a little bit of flexibility to be early:\n\t\tif (this._getTime() - this._lastTime >= (this._interval - 1) * 0.97) {\n\t\t\tthis._tick();\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t */\n\t_handleRAF () {\n\t\tthis._timerId = null;\n\t\tthis._setupTick();\n\t\tthis._tick();\n\t}\n\n\t/**\n\t * @private\n\t */\n\t_handleTimeout () {\n\t\tthis._timerId = null;\n\t\tthis._setupTick();\n\t\tthis._tick();\n\t}\n\n\t/**\n\t * @private\n\t */\n\t_setupTick () {\n\t\tif (this._timerId != null) { return; } // avoid duplicates\n\t\tconst mode = this.timingMode || (this._raf && Ticker.RAF);\n\t\tif (mode === Ticker.RAF_SYNCHED || mode === Ticker.RAF) {\n\t\t\tconst f = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame;\n\t\t\tif (f) {\n\t\t\t\tthis._timerId = f(mode === Ticker.RAF ? this._handleRAF.bind(this) : this._handleSynch.bind(this));\n\t\t\t\tthis._raf = true;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tthis._raf = false;\n\t\tthis._timerId = setTimeout(this._handleTimeout.bind(this), this._interval);\n\t}\n\n\t/**\n\t * @private\n\t * @emits core.Ticker#event:tick\n\t */\n\t_tick () {\n\t\tconst paused = this.paused, time = this._getTime(), elapsedTime = time - this._lastTime;\n\t\tthis._lastTime = time;\n\t\tthis._ticks++;\n\n\t\tif (paused) {\n\t\t\tthis._pausedTicks++;\n\t\t\tthis._pausedTime += elapsedTime;\n\t\t}\n\n\t\tif (this.hasEventListener(\"tick\")) {\n\t\t\tconst event = new Event(\"tick\");\n\t\t\tconst maxDelta = this.maxDelta;\n\t\t\tevent.delta = (maxDelta && elapsedTime > maxDelta) ? maxDelta : elapsedTime;\n\t\t\tevent.paused = paused;\n\t\t\tevent.time = time;\n\t\t\tevent.runTime = time - this._pausedTime;\n\t\t\tthis.dispatchEvent(event);\n\t\t}\n\n\t\tthis._tickTimes.unshift(this._getTime() - time);\n\t\twhile (this._tickTimes.length > 100) { this._tickTimes.pop(); }\n\n\t\tthis._times.unshift(time);\n\t\twhile (this._times.length > 100) { this._times.pop(); }\n\t}\n\n\t/**\n\t * @private\n\t */\n\t_getTime () {\n\t\tconst now = window.performance && window.performance.now;\n\t\treturn ((now && now.call(performance)) || (new Date().getTime())) - this._startTime;\n\t}\n\n\tstatic on (type, listener, scope, once, data, useCapture) { return _instance.on(type, listener, scope, once, data, useCapture); }\n\tstatic removeEventListener (type, listener, useCapture) { _instance.removeEventListener(type, listener, useCapture); }\n\tstatic off (type, listener, useCapture) { _instance.off(type, listener, useCapture); }\n\tstatic removeAllEventListeners (type) { _instance.removeAllEventListeners(type); }\n\tstatic dispatchEvent (eventObj, bubbles, cancelable) { return _instance.dispatchEvent(eventObj, bubbles, cancelable); }\n\tstatic hasEventListener (type) { return _instance.hasEventListener(type); }\n\tstatic willTrigger (type) { return _instance.willTrigger(type); }\n\tstatic toString () { return _instance.toString(); }\n\tstatic init () { _instance.init(); }\n\tstatic reset () { _instance.reset(); }\n\tstatic addEventListener (type, listener, useCapture) { _instance.addEventListener(type, listener, useCapture); }\n\tstatic getMeasuredTickTime (ticks) { return _instance.getMeasuredTickTime(ticks); }\n\tstatic getMeasuredFPS (ticks) { return _instance.getMeasuredFPS(ticks); }\n\tstatic getTime (runTime) { return _instance.getTime(runTime); }\n\tstatic getEventTime (runTime) { return _instance.getEventTime(runTime); }\n\tstatic getTicks (pauseable) { return _instance.getTicks(pauseable); }\n\n\tstatic get interval () { return _instance.interval; }\n\tstatic set interval (interval) { _instance.interval = interval; }\n\tstatic get framerate () { return _instance.framerate; }\n\tstatic set framerate (framerate) { _instance.framerate = framerate; }\n\tstatic get name () { return _instance.name; }\n\tstatic set name (name) { _instance.name = name; }\n\tstatic get timingMode () { return _instance.timingMode; }\n\tstatic set timingMode (timingMode) { _instance.timingMode = timingMode; }\n\tstatic get maxDelta () { return _instance.maxDelta; }\n\tstatic set maxDelta (maxDelta) { _instance.maxDelta = maxDelta; }\n\tstatic get paused () { return _instance.paused; }\n\tstatic set paused (paused) { _instance.paused = paused; }\n\n}\n\n/**\n * Dispatched each tick. The event will be dispatched to each listener even when the Ticker has been paused.\n *\n * @example\n * Ticker.addEventListener(\"tick\", event => console.log(\"Paused:\", event.paused, event.delta));\n *\n * @event core.Ticker#tick\n * @type {Object}\n * @property {Object} target The object that dispatched the event.\n * @property {string} type The event type.\n * @property {boolean} paused Indicates whether the ticker is currently paused.\n * @property {number} delta The time elapsed in ms since the last tick.\n * @property {number} time The total time in ms since Ticker was initialized.\n * @property {number} runTime The total time in ms that Ticker was not paused since it was initialized. For example,\n * you could determine the amount of time that the Ticker has been paused since initialization with `time-runTime`.\n * @since 0.6.0\n */\n\nexport default Ticker;\n\n// the default Ticker instance\nconst _instance = new Ticker(\"createjs.global\");\n"],"names":["Event","type","bubbles","cancelable","target","currentTarget","eventPhase","timeStamp","Date","getTime","defaultPrevented","propagationStopped","immediatePropagationStopped","removed","preventDefault","stopPropagation","stopImmediatePropagation","remove","clone","event","n","hasOwnProperty","set","props","toString","constructor","name","EventDispatcher","initialize","p","prototype","addEventListener","on","removeEventListener","off","removeAllEventListeners","hasEventListener","dispatchEvent","_dispatchEvent","willTrigger","_listeners","_captureListeners","listener","useCapture","listeners","arr","push","scope","once","data","handleEvent","evt","call","l","length","i","splice","eventObj","e","parent","top","list","captureListeners","o","slice","Ticker","timingMode","TIMEOUT","maxDelta","paused","_inited","_startTime","_pausedTime","_ticks","_pausedTicks","_interval","_lastTime","_times","_tickTimes","_timerId","_raf","init","_getTime","_setupTick","reset","f","window","cancelAnimationFrame","webkitCancelAnimationFrame","mozCancelAnimationFrame","oCancelAnimationFrame","msCancelAnimationFrame","clearTimeout","getMeasuredTickTime","ticks","times","Math","min","framerate","reduce","a","b","getMeasuredFPS","runTime","getEventTime","getTicks","pauseable","_handleSynch","_tick","_handleRAF","_handleTimeout","mode","RAF","RAF_SYNCHED","requestAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","oRequestAnimationFrame","msRequestAnimationFrame","bind","setTimeout","time","elapsedTime","delta","unshift","pop","now","performance","_instance","interval"],"mappings":"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"} -------------------------------------------------------------------------------- /dist/core.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license Core 3 | * Visit https://createjs.com for documentation, updates and examples. 4 | * 5 | * Copyright (c) 2017 gskinner.com, inc. 6 | * 7 | * Distributed under the terms of the MIT license. 8 | * http://www.opensource.org/licenses/mit-license.html 9 | * 10 | * This notice shall be included in all copies or substantial portions of the Software. 11 | */ 12 | !function(t){"use strict";var u=function(){function i(t,e,i){void 0===e&&(e=!1),void 0===i&&(i=!1),this.type=t,this.target=null,this.currentTarget=null,this.eventPhase=0,this.bubbles=e,this.cancelable=i,this.timeStamp=(new Date).getTime(),this.defaultPrevented=!1,this.propagationStopped=!1,this.immediatePropagationStopped=!1,this.removed=!1}var t=i.prototype;return t.preventDefault=function(){return this.defaultPrevented=this.cancelable,this},t.stopPropagation=function(){return this.propagationStopped=!0,this},t.stopImmediatePropagation=function(){return this.immediatePropagationStopped=this.propagationStopped=!0,this},t.remove=function(){return this.removed=!0,this},t.clone=function(){var t=new i(this.type,this.bubbles,this.cancelable);for(var e in this)this.hasOwnProperty(e)&&(t[e]=this[e]);return t},t.set=function(t){for(var e in t)this[e]=t[e];return this},t.toString=function(){return"["+this.constructor.name+" (type="+this.type+")]"},i}(),e=function(){function i(){this._listeners=null,this._captureListeners=null}i.initialize=function(t){var e=i.prototype;t.addEventListener=e.addEventListener,t.on=e.on,t.removeEventListener=t.off=e.removeEventListener,t.removeAllEventListeners=e.removeAllEventListeners,t.hasEventListener=e.hasEventListener,t.dispatchEvent=e.dispatchEvent,t._dispatchEvent=e._dispatchEvent,t.willTrigger=e.willTrigger};var t=i.prototype;return t.addEventListener=function(t,e,i){var n;void 0===i&&(i=!1);var r=(n=i?this._captureListeners=this._captureListeners||{}:this._listeners=this._listeners||{})[t];return r&&(this.removeEventListener(t,e,i),r=n[t]),r?r.push(e):n[t]=[e],e},t.on=function(t,e,i,n,r,s){return void 0===i&&(i=null),void 0===n&&(n=!1),void 0===r&&(r={}),void 0===s&&(s=!1),e.handleEvent&&(i=i||e,e=e.handleEvent),i=i||this,this.addEventListener(t,function(t){e.call(i,t,r),n&&t.remove()},s)},t.removeEventListener=function(t,e,i){void 0===i&&(i=!1);var n=i?this._captureListeners:this._listeners;if(n){var r=n[t];if(r)for(var s=r.length,a=0;a=.97*(this._interval-1)&&this._tick()},r._handleRAF=function(){this._timerId=null,this._setupTick(),this._tick()},r._handleTimeout=function(){this._timerId=null,this._setupTick(),this._tick()},r._setupTick=function(){if(null==this._timerId){var t=this.timingMode||this._raf&&i.RAF;if(t===i.RAF_SYNCHED||t===i.RAF){var e=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame;if(e)return this._timerId=e(t===i.RAF?this._handleRAF.bind(this):this._handleSynch.bind(this)),void(this._raf=!0)}this._raf=!1,this._timerId=setTimeout(this._handleTimeout.bind(this),this._interval)}},r._tick=function(){var t=this.paused,e=this._getTime(),i=e-this._lastTime;if(this._lastTime=e,this._ticks++,t&&(this._pausedTicks++,this._pausedTime+=i),this.hasEventListener("tick")){var n=new u("tick"),r=this.maxDelta;n.delta=r&&r (https://github.com/gskinner)", 22 | "Lanny McNie (https://github.com/lannymcnie)", 23 | "Wes Gorgichuk (https://github.com/wdamien)", 24 | "Patrick McGuckin (https://github.com/tehvgg)" 25 | ], 26 | "main": "dist/core.cjs.js", 27 | "module": "src/main.js", 28 | "logo": "assets/icon.png", 29 | "repository": { 30 | "type": "git", 31 | "url": "https://github.com/createjs/core.git" 32 | }, 33 | "scripts": { 34 | "test": "cd node_modules/@createjs/build && npm test", 35 | "dev": "cd node_modules/@createjs/build && gulp dev --format=iife", 36 | "build": "cd node_modules/@createjs/build && gulp build", 37 | "docs": "cd node_modules/@createjs/docs && npm run gen" 38 | }, 39 | "devDependencies": { 40 | "@createjs/build": "2.0.0-beta.4", 41 | "@createjs/easeljs": "2.0.0-beta.4" 42 | }, 43 | "engine": "node >= 8.9.0", 44 | "npmName": "createjs-core", 45 | "npmFileMap": [ 46 | { 47 | "basePath": "dist", 48 | "files": [ 49 | "**/*" 50 | ] 51 | } 52 | ], 53 | "directories": { 54 | "doc": "docs", 55 | "lib": "dist", 56 | "test": "tests" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/events/Event.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license Event 3 | * Visit http://createjs.com/ for documentation, updates and examples. 4 | * 5 | * Copyright (c) 2017 gskinner.com, inc. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | /** 30 | * Contains properties and methods shared by all events for use with {@link core.EventDispatcher}. 31 | * Note that Event objects are often reused, so you should never 32 | * rely on an event object's state outside of the call stack it was received in. 33 | * 34 | * @memberof core 35 | * @example 36 | * const evt = new Event("myEvent"); 37 | * const dispatcher = new EventDispatcher(); 38 | * dispatcher.on("myEvent", event => console.log(event.type)); 39 | * dispatcher.dispatchEvent(evt); // logs "myEvent" 40 | * 41 | * @param {string} type The event type. 42 | * @param {boolean} [bubbles=false] Indicates whether the event will bubble through the display list. 43 | * @param {boolean} [cancelable=false] Indicates whether the default behaviour of this event can be cancelled. 44 | */ 45 | class Event { 46 | 47 | constructor (type, bubbles = false, cancelable = false) { 48 | /** 49 | * The type of event. 50 | * @type string 51 | */ 52 | this.type = type; 53 | 54 | /** 55 | * The object that generated an event. 56 | * 57 | * @type Object 58 | * @default null 59 | * @readonly 60 | */ 61 | this.target = null; 62 | 63 | /** 64 | * The current target that a bubbling event is being dispatched from. For non-bubbling events, this will 65 | * always be the same as target. For example, if childObj.parent = parentObj, and a bubbling event 66 | * is generated from childObj, then a listener on parentObj would receive the event with 67 | * target=childObj (the original target) and currentTarget=parentObj (where the listener was added). 68 | * 69 | * @type Object 70 | * @default null 71 | * @readonly 72 | */ 73 | this.currentTarget = null; 74 | 75 | /** 76 | * For bubbling events, this indicates the current event phase: 77 | *
    78 | *
  1. capture phase: starting from the top parent to the target
  2. 79 | *
  3. at target phase: currently being dispatched from the target
  4. 80 | *
  5. bubbling phase: from the target to the top parent
  6. 81 | *
82 | * 83 | * @type number 84 | * @default 0 85 | * @readonly 86 | */ 87 | this.eventPhase = 0; 88 | 89 | /** 90 | * Indicates whether the event will bubble through the display list. 91 | * 92 | * @type boolean 93 | * @readonly 94 | */ 95 | this.bubbles = bubbles; 96 | 97 | /** 98 | * Indicates whether the default behaviour of this event can be cancelled via {@link core.Event#preventDefault}. 99 | * 100 | * @type boolean 101 | * @readonly 102 | */ 103 | this.cancelable = cancelable; 104 | 105 | /** 106 | * The epoch time at which this event was created. 107 | * 108 | * @type number 109 | * @readonly 110 | */ 111 | this.timeStamp = new Date().getTime(); 112 | 113 | /** 114 | * Indicates if {@link core.Event#preventDefault} has been called on this event. 115 | * 116 | * @type boolean 117 | * @default false 118 | * @readonly 119 | */ 120 | this.defaultPrevented = false; 121 | 122 | /** 123 | * Indicates if {@link core.Event#stopPropagation} or {@link core.Event#stopImmediatePropagation} has been called on this event. 124 | * 125 | * @type boolean 126 | * @default false 127 | * @readonly 128 | */ 129 | this.propagationStopped = false; 130 | 131 | /** 132 | * Indicates if {@link core.Event#stopImmediatePropagation} has been called on this event. 133 | * 134 | * @type boolean 135 | * @default false 136 | * @readonly 137 | */ 138 | this.immediatePropagationStopped = false; 139 | 140 | /** 141 | * Indicates if {@link core.Event#remove} has been called on this event. 142 | * 143 | * @type boolean 144 | * @default false 145 | * @readonly 146 | */ 147 | this.removed = false; 148 | } 149 | 150 | /** 151 | * Sets {@link core.Event#defaultPrevented} to true if the event is cancelable. 152 | * Mirrors the DOM level 2 event standard. In general, cancelable events that have `preventDefault()` called will 153 | * cancel the default behaviour associated with the event. 154 | * @return {core.Event} this, chainable 155 | */ 156 | preventDefault () { 157 | this.defaultPrevented = this.cancelable; 158 | return this; 159 | } 160 | 161 | /** 162 | * Sets {@link core.Event#propagationStopped} to true. 163 | * Mirrors the DOM event standard. 164 | * @return {core.Event} this, chainable 165 | */ 166 | stopPropagation () { 167 | this.propagationStopped = true; 168 | return this; 169 | } 170 | 171 | /** 172 | * Sets {@link core.Event#propagationStopped} and {@link core.Event#immediatePropagationStopped} to true. 173 | * Mirrors the DOM event standard. 174 | * @return {core.Event} this, chainable 175 | */ 176 | stopImmediatePropagation () { 177 | this.immediatePropagationStopped = this.propagationStopped = true; 178 | return this; 179 | } 180 | 181 | /** 182 | * Causes the active listener to be removed via removeEventListener(); 183 | * 184 | * @example 185 | * myBtn.addEventListener("click", event => { 186 | * event.remove(); // removes this listener. 187 | * }); 188 | * 189 | * @return {core.Event} this, chainable 190 | */ 191 | remove () { 192 | this.removed = true; 193 | return this; 194 | } 195 | 196 | /** 197 | * Returns a clone of the Event instance. 198 | * 199 | * @return {core.Event} a clone of the Event instance. 200 | */ 201 | clone () { 202 | const event = new Event(this.type, this.bubbles, this.cancelable); 203 | for (let n in this) { 204 | if (this.hasOwnProperty(n)) { 205 | event[n] = this[n]; 206 | } 207 | } 208 | return event; 209 | } 210 | 211 | /** 212 | * Provides a return {core.Event} this, chainable shortcut method for setting a number of properties on the instance. 213 | * 214 | * @param {Object} props A generic object containing properties to copy to the instance. 215 | * @return {core.Event} this, chainable 216 | */ 217 | set (props) { 218 | for (let n in props) { this[n] = props[n]; } 219 | return this; 220 | } 221 | 222 | /** 223 | * Returns a string representation of this object. 224 | * 225 | * @return {string} A string representation of the instance. 226 | */ 227 | toString () { 228 | return `[${this.constructor.name} (type=${this.type})]`; 229 | } 230 | 231 | } 232 | 233 | export default Event; 234 | -------------------------------------------------------------------------------- /src/events/EventDispatcher.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license EventDispatcher 3 | * Visit http://createjs.com/ for documentation, updates and examples. 4 | * 5 | * Copyright (c) 2017 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 | import Event from "./Event"; 30 | 31 | /** 32 | * EventDispatcher provides methods for managing queues of event listeners and dispatching events. 33 | * 34 | * You can either extend EventDispatcher or mix its methods into an existing prototype or instance by using the 35 | * EventDispatcher {@link core.EventDispatcher.initialize} method. 36 | * 37 | * Together with the CreateJS Event class, EventDispatcher provides an extended event model that is based on the 38 | * DOM Level 2 event model, including addEventListener, removeEventListener, and dispatchEvent. It supports 39 | * bubbling / capture, preventDefault, stopPropagation, stopImmediatePropagation, and handleEvent. 40 | * 41 | * EventDispatcher also exposes a {@link core.EventDispatcher#on} method, which makes it easier 42 | * to create scoped listeners, listeners that only run once, and listeners with associated arbitrary data. The 43 | * {@link core.EventDispatcher#off} method is merely an alias to {@link core.EventDispatcher#removeEventListener}. 44 | * 45 | * Another addition to the DOM Level 2 model is the {@link core.EventDispatcher#removeAllEventListeners} 46 | * method, which can be used to listeners for all events, or listeners for a specific event. The Event object also 47 | * includes a {@link core.Event#remove} method which removes the active listener. 48 | * 49 | * @memberof core 50 | * @example 51 | * // add EventDispatcher capabilities to the "MyClass" class. 52 | * EventDispatcher.initialize(MyClass.prototype); 53 | * 54 | * // Add an event. 55 | * instance.addEventListener("eventName", event => console.log(event.target + " was clicked.")); 56 | * 57 | * // scope ("this") can be be a challenge with events. 58 | * // using the {@link core.EventDispatcher#on} method to subscribe to events simplifies this. 59 | * instance.addEventListener("click", event => console.log(instance === this)); // false, scope is ambiguous. 60 | * instance.on("click", event => console.log(instance === this)); // true, `on` uses dispatcher scope by default. 61 | */ 62 | class EventDispatcher { 63 | 64 | /** 65 | * Static initializer to mix EventDispatcher methods into a target object or prototype. 66 | * 67 | * @static 68 | * @example 69 | * EventDispatcher.initialize(MyClass.prototype); // add to the prototype of the class 70 | * EventDispatcher.initialize(myInstance); // add to a specific instance 71 | * 72 | * @param {Object} target The target object to inject EventDispatcher methods into. 73 | */ 74 | static initialize (target) { 75 | const p = EventDispatcher.prototype; 76 | target.addEventListener = p.addEventListener; 77 | target.on = p.on; 78 | target.removeEventListener = target.off = p.removeEventListener; 79 | target.removeAllEventListeners = p.removeAllEventListeners; 80 | target.hasEventListener = p.hasEventListener; 81 | target.dispatchEvent = p.dispatchEvent; 82 | target._dispatchEvent = p._dispatchEvent; 83 | target.willTrigger = p.willTrigger; 84 | } 85 | 86 | constructor () { 87 | /** 88 | * @private 89 | * @default null 90 | * @type Object 91 | */ 92 | this._listeners = null; 93 | 94 | /** 95 | * @private 96 | * @default null 97 | * @type Object 98 | */ 99 | this._captureListeners = null; 100 | } 101 | 102 | /** 103 | * Adds the specified event listener. Note that adding multiple listeners to the same function will result in 104 | * multiple callbacks getting fired. 105 | * 106 | * @example 107 | * displayObject.addEventListener("click", event => console.log('clicked', event)); 108 | * 109 | * @param {string} type The string type of the event. 110 | * @param {Function|Object} listener An object with a handleEvent method, or a function that will be called when the event is dispatched. 111 | * @param {boolean} [useCapture=false] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase. 112 | * @return {Function|Object} Returns the listener for chaining or assignment. 113 | */ 114 | addEventListener (type, listener, useCapture = false) { 115 | let listeners; 116 | if (useCapture) { 117 | listeners = this._captureListeners = this._captureListeners || {}; 118 | } else { 119 | listeners = this._listeners = this._listeners || {}; 120 | } 121 | let arr = listeners[type]; 122 | if (arr) { 123 | this.removeEventListener(type, listener, useCapture); 124 | arr = listeners[type]; // remove may have deleted the array 125 | } 126 | if (arr) { arr.push(listener); } 127 | else { listeners[type] = [listener]; } 128 | return listener; 129 | } 130 | 131 | /** 132 | * A shortcut method for using addEventListener that makes it easier to specify an execution scope, have a listener 133 | * only run once, associate arbitrary data with the listener, and remove the listener. 134 | * 135 | * This method works by creating an anonymous wrapper function and subscribing it with `addEventListener`. 136 | * The wrapper function is returned for use with `removeEventListener` (or `off`). 137 | * 138 | * To remove a listener added with `on`, you must pass in the returned wrapper function as the listener, or use 139 | * {@link core.Event#remove}. Likewise, each time you call `on` a NEW wrapper function is subscribed, so multiple calls 140 | * to `on` with the same params will create multiple listeners. 141 | * 142 | * @example 143 | * const listener = myBtn.on("click", handleClick, null, false, { count: 3 }); 144 | * function handleClick (evt, data) { 145 | * data.count -= 1; 146 | * console.log(this == myBtn); // true - scope defaults to the dispatcher 147 | * if (data.count == 0) { 148 | * alert("clicked 3 times!"); 149 | * myBtn.off("click", listener); 150 | * // alternately: evt.remove(); 151 | * } 152 | * } 153 | * 154 | * @param {string} type The string type of the event. 155 | * @param {Function|Object} listener An object with a handleEvent method, or a function that will be called when the event is dispatched. 156 | * @param {Object} [scope=null] 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). 157 | * @param {boolean} [once=false] If true, the listener will remove itself after the first time it is triggered. 158 | * @param {*} [data={}] Arbitrary data that will be included as the second parameter when the listener is called. 159 | * @param {boolean} [useCapture=false] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase. 160 | * @return {Function} Returns the anonymous function that was created and assigned as the listener. This is needed to remove the listener later using .removeEventListener. 161 | */ 162 | on (type, listener, scope = null, once = false, data = {}, useCapture = false) { 163 | if (listener.handleEvent) { 164 | scope = scope || listener; 165 | listener = listener.handleEvent; 166 | } 167 | scope = scope || this; 168 | return this.addEventListener(type, evt => { 169 | listener.call(scope, evt, data); 170 | once && evt.remove(); 171 | }, useCapture); 172 | } 173 | 174 | /** 175 | * Removes the specified event listener. 176 | * 177 | * You must pass the exact function reference used when the event was added. If a proxy 178 | * function, or function closure is used as the callback, the proxy/closure reference must be used - a new proxy or 179 | * closure will not work. 180 | * 181 | * @example 182 | * displayObject.removeEventListener("click", handleClick); 183 | * 184 | * @param {string} type The string type of the event. 185 | * @param {Function|Object} listener The listener function or object. 186 | * @param {boolean} [useCapture=false] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase. 187 | */ 188 | removeEventListener (type, listener, useCapture = false) { 189 | const listeners = useCapture ? this._captureListeners : this._listeners; 190 | if (!listeners) { return; } 191 | const arr = listeners[type]; 192 | if (!arr) { return; } 193 | const l = arr.length; 194 | for (let i = 0; i < l; i++) { 195 | if (arr[i] === listener) { 196 | if (l === 1) { delete(listeners[type]); } // allows for faster checks. 197 | else { arr.splice(i, 1); } 198 | break; 199 | } 200 | } 201 | } 202 | 203 | /** 204 | * A shortcut to the removeEventListener method, with the same parameters and return value. This is a companion to the 205 | * `on` method. 206 | * 207 | * To remove a listener added with `on`, you must pass in the returned wrapper function as the listener. See 208 | * {@link core.EventDispatcher#on} for an example. 209 | * 210 | * @param {string} type The string type of the event. 211 | * @param {Function|Object} listener The listener function or object. 212 | * @param {boolean} [useCapture=false] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase. 213 | */ 214 | off (type, listener, useCapture = false) { 215 | this.removeEventListener(type, listener, useCapture); 216 | } 217 | 218 | /** 219 | * Removes all listeners for the specified type, or all listeners of all types. 220 | * 221 | * @example 222 | * // remove all listeners 223 | * displayObject.removeAllEventListeners(); 224 | * 225 | * // remove all click listeners 226 | * displayObject.removeAllEventListeners("click"); 227 | * 228 | * @param {string} [type=null] The string type of the event. If omitted, all listeners for all types will be removed. 229 | */ 230 | removeAllEventListeners (type = null) { 231 | if (type) { 232 | if (this._listeners) { delete(this._listeners[type]); } 233 | if (this._captureListeners) { delete(this._captureListeners[type]); } 234 | } else { 235 | this._listeners = this._captureListeners = null; 236 | } 237 | } 238 | 239 | /** 240 | * Dispatches the specified event to all listeners. 241 | * 242 | * @example 243 | * // use a string event 244 | * this.dispatchEvent("complete") 245 | * 246 | * // use an Event instance 247 | * const event = new createjs.Event("progress"); 248 | * this.dispatchEvent(event); 249 | * 250 | * @param {Object|Event|string} eventObj An object with a "type" property, or a string type. 251 | * While a generic object will work, it is recommended to use a CreateJS Event instance. If a string is used, 252 | * dispatchEvent will construct an Event instance if necessary with the specified type. This latter approach can 253 | * be used to avoid event object instantiation for non-bubbling events that may not have any listeners. 254 | * @param {boolean} [bubbles=false] Specifies the `bubbles` value when a string was passed to eventObj. 255 | * @param {boolean} [cancelable=false] Specifies the `cancelable` value when a string was passed to eventObj. 256 | * @return {boolean} Returns false if `preventDefault()` was called on a cancelable event, true otherwise. 257 | */ 258 | dispatchEvent (eventObj, bubbles = false, cancelable = false) { 259 | if (typeof eventObj === "string") { 260 | // skip everything if there's no listeners and it doesn't bubble: 261 | const listeners = this._listeners; 262 | if (!bubbles && (!listeners || !listeners[eventObj])) { return true; } 263 | eventObj = new Event(eventObj, bubbles, cancelable); 264 | } else if (eventObj.target && eventObj.clone) { 265 | // redispatching an active event object, so clone it: 266 | eventObj = eventObj.clone(); 267 | } 268 | 269 | // TODO: it would be nice to eliminate this. Maybe in favour of evtObj instanceof Event? Or !!evtObj.createEvent 270 | try { eventObj.target = this; } catch (e) {} // try/catch allows redispatching of native events 271 | 272 | if (!eventObj.bubbles || !this.parent) { 273 | this._dispatchEvent(eventObj, 2); 274 | } else { 275 | let top = this; 276 | const list = [top]; 277 | while (top.parent) { list.push(top = top.parent); } 278 | const l = list.length; 279 | let i; 280 | 281 | // capture & atTarget 282 | for (i = l - 1; i >= 0 && !eventObj.propagationStopped; i--) { 283 | list[i]._dispatchEvent(eventObj, 1+(i==0)); 284 | } 285 | // bubbling 286 | for (i = 1; i < l && !eventObj.propagationStopped; i++) { 287 | list[i]._dispatchEvent(eventObj, 3); 288 | } 289 | } 290 | return !eventObj.defaultPrevented; 291 | } 292 | 293 | /** 294 | * Indicates whether there is at least one listener for the specified event type. 295 | * 296 | * @param {string} type The string type of the event. 297 | * @return {boolean} Returns true if there is at least one listener for the specified event. 298 | */ 299 | hasEventListener (type) { 300 | const listeners = this._listeners, captureListeners = this._captureListeners; 301 | return !!((listeners && listeners[type]) || (captureListeners && captureListeners[type])); 302 | } 303 | 304 | /** 305 | * Indicates whether there is at least one listener for the specified event type on this object or any of its 306 | * ancestors (parent, parent's parent, etc). A return value of true indicates that if a bubbling event of the 307 | * specified type is dispatched from this object, it will trigger at least one listener. 308 | * 309 | * This is similar to {@link core.EventDispatcher#hasEventListener}, but it searches the entire 310 | * event flow for a listener, not just this object. 311 | * 312 | * @param {string} type The string type of the event. 313 | * @return {boolean} Returns `true` if there is at least one listener for the specified event. 314 | */ 315 | willTrigger (type) { 316 | let o = this; 317 | while (o) { 318 | if (o.hasEventListener(type)) { return true; } 319 | o = o.parent; 320 | } 321 | return false; 322 | } 323 | 324 | /** 325 | * @return {String} a string representation of the instance. 326 | */ 327 | toString () { 328 | return `[${this.constructor.name + this.name ? ` ${this.name}` : ""}]`; 329 | } 330 | 331 | /** 332 | * @private 333 | * @param {Object|Event|string} eventObj 334 | * @param {Object} eventPhase 335 | */ 336 | _dispatchEvent (eventObj, eventPhase) { 337 | const listeners = eventPhase === 1 ? this._captureListeners : this._listeners; 338 | if (eventObj && listeners) { 339 | let arr = listeners[eventObj.type]; 340 | let l; 341 | if (!arr || (l = arr.length) === 0) { return; } 342 | try { eventObj.currentTarget = this; } catch (e) {} 343 | try { eventObj.eventPhase = eventPhase; } catch (e) {} 344 | eventObj.removed = false; 345 | 346 | arr = arr.slice(); // to avoid issues with items being removed or added during the dispatch 347 | for (let i = 0; i < l && !eventObj.immediatePropagationStopped; i++) { 348 | let o = arr[i]; 349 | if (o.handleEvent) { o.handleEvent(eventObj); } 350 | else { o(eventObj); } 351 | if (eventObj.removed) { 352 | this.off(eventObj.type, o, eventPhase === 1); 353 | eventObj.removed = false; 354 | } 355 | } 356 | } 357 | } 358 | 359 | } 360 | 361 | export default EventDispatcher; 362 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * The core classes of CreateJS. 3 | * @namespace core 4 | * 5 | * @example 6 | * import { EventDispatcher, Event } from "@createjs/core"; 7 | * const dispatcher = new EventDispatcher(); 8 | * dispatcher.on("myEvent", foo); 9 | * dispatcher.dispatchEvent(new Event("myEvent")); 10 | * // foo() is called. 11 | */ 12 | 13 | // events 14 | export { default as Event } from "./events/Event"; 15 | export { default as EventDispatcher } from "./events/EventDispatcher"; 16 | // utils 17 | export { default as Ticker } from "./utils/Ticker"; 18 | -------------------------------------------------------------------------------- /src/utils/Ticker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license Ticker 3 | * Visit http://createjs.com/ for documentation, updates and examples. 4 | * 5 | * Copyright (c) 2017 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 | import EventDispatcher from "../events/EventDispatcher"; 30 | import Event from "../events/Event"; 31 | 32 | /** 33 | * The Ticker provides a centralized tick or heartbeat broadcast at a set interval. Listeners can subscribe to the tick 34 | * event to be notified when a set time interval has elapsed. 35 | * 36 | * Note that the interval that the tick event is called is a target interval, and may be broadcast at a slower interval 37 | * when under high CPU load. The Ticker class uses a static interface (ex. `Ticker.framerate = 30;`) and 38 | * can not be instantiated. 39 | * 40 | * @todo Pass timingMode, maxDelta, paused values as instantiation arguments? 41 | * 42 | * @memberof core 43 | * @example 44 | * Ticker.addEventListener("tick", event => { 45 | * // Actions carried out each tick (aka frame) 46 | * if (!event.paused) { 47 | * // Actions carried out when the Ticker is not paused. 48 | * } 49 | * }); 50 | * @example 51 | * // Ticker export explanation 52 | * import Ticker, { Ticker as TickerClass, getTicker } from "@createjs/core"; 53 | * Ticker.name, Ticker.RAF // -> createjs.global, undefined 54 | * TickerClass.RAF // -> raf 55 | * Ticker === getTicker("createjs.global") // -> true 56 | * 57 | * @extends core.EventDispatcher 58 | * @param {string} name The name assigned to this instance. 59 | */ 60 | class Ticker extends EventDispatcher { 61 | 62 | /** 63 | * In this mode, Ticker uses the requestAnimationFrame API, but attempts to synch the ticks to target framerate. It 64 | * uses a simple heuristic that compares the time of the RAF return to the target time for the current frame and 65 | * dispatches the tick when the time is within a certain threshold. 66 | * 67 | * This mode has a higher variance for time between frames than {{#crossLink "Ticker/TIMEOUT:property"}}{{/crossLink}}, 68 | * but does not require that content be time based as with {{#crossLink "Ticker/RAF:property"}}{{/crossLink}} while 69 | * gaining the benefits of that API (screen synch, background throttling). 70 | * 71 | * Variance is usually lowest for framerates that are a divisor of the RAF frequency. This is usually 60, so 72 | * framerates of 10, 12, 15, 20, and 30 work well. 73 | * 74 | * Falls back to {{#crossLink "Ticker/TIMEOUT:property"}}{{/crossLink}} if the requestAnimationFrame API is not 75 | * supported. 76 | * 77 | * @static 78 | * @type {string} 79 | * @default "synched" 80 | * @readonly 81 | */ 82 | static get RAF_SYNCHED () { return "synched"; } 83 | 84 | /** 85 | * In this mode, Ticker passes through the requestAnimationFrame heartbeat, ignoring the target framerate completely. 86 | * Because requestAnimationFrame frequency is not deterministic, any content using this mode should be time based. 87 | * You can leverage {@link core.Ticker#getTime} and the {@link core.Ticker#event:tick} 88 | * event object's "delta" properties to make this easier. 89 | * 90 | * Falls back on {@link core.Ticker.TIMEOUT} if the requestAnimationFrame API is not supported. 91 | * 92 | * @static 93 | * @type {string} 94 | * @default "raf" 95 | * @readonly 96 | */ 97 | static get RAF () { return "raf"; } 98 | 99 | /** 100 | * In this mode, Ticker uses the setTimeout API. This provides predictable, adaptive frame timing, but does not 101 | * provide the benefits of requestAnimationFrame (screen synch, background throttling). 102 | * 103 | * @static 104 | * @type {string} 105 | * @default "timeout" 106 | * @readonly 107 | */ 108 | static get TIMEOUT () { return "timeout"; } 109 | 110 | constructor (name) { 111 | super(); 112 | 113 | /** 114 | * The name of this instance. 115 | * @type {string} 116 | */ 117 | this.name = name; 118 | 119 | /** 120 | * Specifies the timing api (setTimeout or requestAnimationFrame) and mode to use. 121 | * 122 | * @see {@link core.Ticker.TIMEOUT} 123 | * @see {@link core.Ticker.RAF} 124 | * @see {@link core.Ticker.RAF_SYNCHED} 125 | * 126 | * @type {string} 127 | * @default Ticker.TIMEOUT 128 | */ 129 | this.timingMode = Ticker.TIMEOUT; 130 | 131 | /** 132 | * Specifies a maximum value for the delta property in the tick event object. This is useful when building time 133 | * based animations and systems to prevent issues caused by large time gaps caused by background tabs, system sleep, 134 | * alert dialogs, or other blocking routines. Double the expected frame duration is often an effective value 135 | * (ex. maxDelta=50 when running at 40fps). 136 | * 137 | * This does not impact any other values (ex. time, runTime, etc), so you may experience issues if you enable maxDelta 138 | * when using both delta and other values. 139 | * 140 | * If 0, there is no maximum. 141 | * 142 | * @type {number} 143 | * @default 0 144 | */ 145 | this.maxDelta = 0; 146 | 147 | /** 148 | * When the ticker is paused, all listeners will still receive a tick event, but the `paused` property 149 | * of the event will be `true`. Also, while paused the `runTime` will not increase. 150 | * 151 | * @example 152 | * Ticker.addEventListener("tick", event => console.log(event.paused, Ticker.getTime(false), Ticker.getTime(true))); 153 | * Ticker.paused = true; 154 | * 155 | * @see {@link core.Ticker#event:tick} 156 | * @see {@link core.Ticker#getTime} 157 | * @see {@link core.Ticker#getEventTime} 158 | * 159 | * @type {boolean} 160 | * @default false 161 | */ 162 | this.paused = false; 163 | 164 | /** 165 | * @private 166 | * @type {boolean} 167 | * @default false 168 | */ 169 | this._inited = false; 170 | 171 | /** 172 | * @private 173 | * @type {number} 174 | * @default 0 175 | */ 176 | this._startTime = 0; 177 | 178 | /** 179 | * @private 180 | * @type {number} 181 | * @default 0 182 | */ 183 | this._pausedTime = 0; 184 | 185 | /** 186 | * The number of ticks that have passed. 187 | * 188 | * @private 189 | * @type {number} 190 | * @default 0 191 | */ 192 | this._ticks = 0; 193 | 194 | /** 195 | * The number of ticks that have passed while Ticker has been paused. 196 | * 197 | * @private 198 | * @type {number} 199 | * @default 200 | */ 201 | this._pausedTicks = 0; 202 | 203 | /** 204 | * @private 205 | * @type {number} 206 | * @default 207 | */ 208 | this._interval = 50; 209 | 210 | /** 211 | * @private 212 | * @type {number} 213 | * @default 214 | */ 215 | this._lastTime = 0; 216 | 217 | /** 218 | * @private 219 | * @type {Array} 220 | * @default null 221 | */ 222 | this._times = null; 223 | 224 | /** 225 | * @private 226 | * @type {Array} 227 | * @default null 228 | */ 229 | this._tickTimes = null; 230 | 231 | /** 232 | * Stores the timeout or requestAnimationFrame id. 233 | * 234 | * @private 235 | * @type {number} 236 | * @default null 237 | */ 238 | this._timerId = null; 239 | 240 | /** 241 | * True if currently using requestAnimationFrame, false if using setTimeout. This may be different than timingMode 242 | * if that property changed and a tick hasn't fired. 243 | * 244 | * @private 245 | * @type {boolean} 246 | * @default true 247 | */ 248 | this._raf = true; 249 | } 250 | 251 | /** 252 | * Indicates the target time (in milliseconds) between ticks. Default is 50 (20 FPS). 253 | * Note that actual time between ticks may be more than specified depending on CPU load. 254 | * This property is ignored if the ticker is using the `RAF` timing mode. 255 | * 256 | * @type {number} 257 | */ 258 | get interval () { return this._interval; } 259 | set interval (interval) { 260 | this._interval = interval; 261 | if (!this._inited) { return; } 262 | this._setupTick(); 263 | } 264 | 265 | /** 266 | * Indicates the target frame rate in frames per second (FPS). Effectively just a shortcut to `interval`, where 267 | * `framerate == 1000/interval`. 268 | * 269 | * @type {number} 270 | */ 271 | get framerate () { return 1000 / this._interval; } 272 | set framerate (framerate) { this.interval = 1000 / framerate; } 273 | 274 | /** 275 | * Starts the tick. This is called automatically when the first listener is added. 276 | */ 277 | init () { 278 | if (this._inited) { return; } 279 | this._inited = true; 280 | this._times = []; 281 | this._tickTimes = []; 282 | this._startTime = this._getTime(); 283 | this._times.push(this._lastTime = 0); 284 | this._setupTick(); 285 | } 286 | 287 | /** 288 | * Stops the Ticker and removes all listeners. Use init() to restart the Ticker. 289 | */ 290 | reset () { 291 | if (this._raf) { 292 | let f = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.oCancelAnimationFrame || window.msCancelAnimationFrame; 293 | f && f(this._timerId); 294 | } else { 295 | clearTimeout(this._timerId); 296 | } 297 | this.removeAllEventListeners("tick"); 298 | this._timerId = this._times = this._tickTimes = null; 299 | this._startTime = this._lastTime = this._ticks = 0; 300 | this._inited = false; 301 | } 302 | 303 | /** 304 | * Init the Ticker instance if it hasn't been already. 305 | */ 306 | addEventListener (type, listener, useCapture) { 307 | !this._inited && this.init(); 308 | return super.addEventListener(type, listener, useCapture); 309 | } 310 | 311 | /** 312 | * Returns the average time spent within a tick. This can vary significantly from the value provided by getMeasuredFPS 313 | * because it only measures the time spent within the tick execution stack. 314 | * 315 | * Example 1: With a target FPS of 20, getMeasuredFPS() returns 20fps, which indicates an average of 50ms between 316 | * the end of one tick and the end of the next. However, getMeasuredTickTime() returns 15ms. This indicates that 317 | * there may be up to 35ms of "idle" time between the end of one tick and the start of the next. 318 | * 319 | * Example 2: With a target FPS of 30, getFPS() returns 10fps, which indicates an average of 100ms between the end of 320 | * one tick and the end of the next. However, getMeasuredTickTime() returns 20ms. This would indicate that something 321 | * other than the tick is using ~80ms (another script, DOM rendering, etc). 322 | * 323 | * @param {number} [ticks=null] The number of previous ticks over which to measure the average time spent in a tick. 324 | * Defaults to the number of ticks per second. To get only the last tick's time, pass in 1. 325 | * @return {number} The average time spent in a tick in milliseconds. 326 | */ 327 | getMeasuredTickTime (ticks = null) { 328 | const times = this._tickTimes; 329 | if (!times || times.length < 1) { return -1; } 330 | // by default, calculate average for the past ~1 second: 331 | ticks = Math.min(times.length, ticks || (this.framerate | 0)); 332 | return times.reduce((a, b) => a + b, 0) / ticks; 333 | } 334 | 335 | /** 336 | * Returns the actual frames / ticks per second. 337 | * 338 | * @param {number} [ticks=null] The number of previous ticks over which to measure the actual frames / ticks per second. 339 | * Defaults to the number of ticks per second. 340 | * @return {number} The actual frames / ticks per second. Depending on performance, this may differ 341 | * from the target frames per second. 342 | */ 343 | getMeasuredFPS (ticks = null) { 344 | const times = this._times; 345 | if (!times || times.length < 2) { return -1; } 346 | // by default, calculate fps for the past ~1 second: 347 | ticks = Math.min(times.length - 1, ticks || (this.framerate | 0)); 348 | return 1000 / ((times[0] - times[ticks]) / ticks); 349 | } 350 | 351 | /** 352 | * Returns the number of milliseconds that have elapsed since Ticker was initialized via {@link core.Ticker#init}. 353 | * Returns -1 if Ticker has not been initialized. For example, you could use 354 | * this in a time synchronized animation to determine the exact amount of time that has elapsed. 355 | * 356 | * @param {boolean} [runTime=false] If true only time elapsed while Ticker was not paused will be returned. 357 | * If false, the value returned will be total time elapsed since the first tick event listener was added. 358 | * @return {number} Number of milliseconds that have elapsed since Ticker was initialized or -1. 359 | */ 360 | getTime (runTime = false) { 361 | return this._startTime ? this._getTime() - (runTime ? this._pausedTime : 0) : -1; 362 | } 363 | 364 | /** 365 | * Similar to {@link core.Ticker#getTime}, but returns the time on the most recent {@link core.Ticker#event:tick} 366 | * event object. 367 | * 368 | * @param {boolean} [runTime=false] If true, the runTime property will be returned instead of time. 369 | * @returns {number} The time or runTime property from the most recent tick event or -1. 370 | */ 371 | getEventTime (runTime = false) { 372 | return this._startTime ? (this._lastTime || this._startTime) - (runTime ? this._pausedTime : 0) : -1; 373 | } 374 | 375 | /** 376 | * Returns the number of ticks that have been broadcast by Ticker. 377 | * 378 | * @param {boolean} [pauseable=false] Indicates whether to include ticks that would have been broadcast 379 | * while Ticker was paused. If true only tick events broadcast while Ticker is not paused will be returned. 380 | * If false, tick events that would have been broadcast while Ticker was paused will be included in the return 381 | * value. 382 | * @return {number} of ticks that have been broadcast. 383 | */ 384 | getTicks (pauseable = false) { 385 | return this._ticks - (pauseable ? this._pausedTicks : 0); 386 | } 387 | 388 | /** 389 | * @private 390 | */ 391 | _handleSynch () { 392 | this._timerId = null; 393 | this._setupTick(); 394 | 395 | // run if enough time has elapsed, with a little bit of flexibility to be early: 396 | if (this._getTime() - this._lastTime >= (this._interval - 1) * 0.97) { 397 | this._tick(); 398 | } 399 | } 400 | 401 | /** 402 | * @private 403 | */ 404 | _handleRAF () { 405 | this._timerId = null; 406 | this._setupTick(); 407 | this._tick(); 408 | } 409 | 410 | /** 411 | * @private 412 | */ 413 | _handleTimeout () { 414 | this._timerId = null; 415 | this._setupTick(); 416 | this._tick(); 417 | } 418 | 419 | /** 420 | * @private 421 | */ 422 | _setupTick () { 423 | if (this._timerId != null) { return; } // avoid duplicates 424 | const mode = this.timingMode || (this._raf && Ticker.RAF); 425 | if (mode === Ticker.RAF_SYNCHED || mode === Ticker.RAF) { 426 | const f = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame; 427 | if (f) { 428 | this._timerId = f(mode === Ticker.RAF ? this._handleRAF.bind(this) : this._handleSynch.bind(this)); 429 | this._raf = true; 430 | return; 431 | } 432 | } 433 | this._raf = false; 434 | this._timerId = setTimeout(this._handleTimeout.bind(this), this._interval); 435 | } 436 | 437 | /** 438 | * @private 439 | * @emits core.Ticker#event:tick 440 | */ 441 | _tick () { 442 | const paused = this.paused, time = this._getTime(), elapsedTime = time - this._lastTime; 443 | this._lastTime = time; 444 | this._ticks++; 445 | 446 | if (paused) { 447 | this._pausedTicks++; 448 | this._pausedTime += elapsedTime; 449 | } 450 | 451 | if (this.hasEventListener("tick")) { 452 | const event = new Event("tick"); 453 | const maxDelta = this.maxDelta; 454 | event.delta = (maxDelta && elapsedTime > maxDelta) ? maxDelta : elapsedTime; 455 | event.paused = paused; 456 | event.time = time; 457 | event.runTime = time - this._pausedTime; 458 | this.dispatchEvent(event); 459 | } 460 | 461 | this._tickTimes.unshift(this._getTime() - time); 462 | while (this._tickTimes.length > 100) { this._tickTimes.pop(); } 463 | 464 | this._times.unshift(time); 465 | while (this._times.length > 100) { this._times.pop(); } 466 | } 467 | 468 | /** 469 | * @private 470 | */ 471 | _getTime () { 472 | const now = window.performance && window.performance.now; 473 | return ((now && now.call(performance)) || (new Date().getTime())) - this._startTime; 474 | } 475 | 476 | static on (type, listener, scope, once, data, useCapture) { return _instance.on(type, listener, scope, once, data, useCapture); } 477 | static removeEventListener (type, listener, useCapture) { _instance.removeEventListener(type, listener, useCapture); } 478 | static off (type, listener, useCapture) { _instance.off(type, listener, useCapture); } 479 | static removeAllEventListeners (type) { _instance.removeAllEventListeners(type); } 480 | static dispatchEvent (eventObj, bubbles, cancelable) { return _instance.dispatchEvent(eventObj, bubbles, cancelable); } 481 | static hasEventListener (type) { return _instance.hasEventListener(type); } 482 | static willTrigger (type) { return _instance.willTrigger(type); } 483 | static toString () { return _instance.toString(); } 484 | static init () { _instance.init(); } 485 | static reset () { _instance.reset(); } 486 | static addEventListener (type, listener, useCapture) { _instance.addEventListener(type, listener, useCapture); } 487 | static getMeasuredTickTime (ticks) { return _instance.getMeasuredTickTime(ticks); } 488 | static getMeasuredFPS (ticks) { return _instance.getMeasuredFPS(ticks); } 489 | static getTime (runTime) { return _instance.getTime(runTime); } 490 | static getEventTime (runTime) { return _instance.getEventTime(runTime); } 491 | static getTicks (pauseable) { return _instance.getTicks(pauseable); } 492 | 493 | static get interval () { return _instance.interval; } 494 | static set interval (interval) { _instance.interval = interval; } 495 | static get framerate () { return _instance.framerate; } 496 | static set framerate (framerate) { _instance.framerate = framerate; } 497 | static get name () { return _instance.name; } 498 | static set name (name) { _instance.name = name; } 499 | static get timingMode () { return _instance.timingMode; } 500 | static set timingMode (timingMode) { _instance.timingMode = timingMode; } 501 | static get maxDelta () { return _instance.maxDelta; } 502 | static set maxDelta (maxDelta) { _instance.maxDelta = maxDelta; } 503 | static get paused () { return _instance.paused; } 504 | static set paused (paused) { _instance.paused = paused; } 505 | 506 | } 507 | 508 | /** 509 | * Dispatched each tick. The event will be dispatched to each listener even when the Ticker has been paused. 510 | * 511 | * @example 512 | * Ticker.addEventListener("tick", event => console.log("Paused:", event.paused, event.delta)); 513 | * 514 | * @event core.Ticker#tick 515 | * @type {Object} 516 | * @property {Object} target The object that dispatched the event. 517 | * @property {string} type The event type. 518 | * @property {boolean} paused Indicates whether the ticker is currently paused. 519 | * @property {number} delta The time elapsed in ms since the last tick. 520 | * @property {number} time The total time in ms since Ticker was initialized. 521 | * @property {number} runTime The total time in ms that Ticker was not paused since it was initialized. For example, 522 | * you could determine the amount of time that the Ticker has been paused since initialization with `time-runTime`. 523 | * @since 0.6.0 524 | */ 525 | 526 | export default Ticker; 527 | 528 | // the default Ticker instance 529 | const _instance = new Ticker("createjs.global"); 530 | -------------------------------------------------------------------------------- /tests/spec/events/Events.js: -------------------------------------------------------------------------------- 1 | import Event from "../../../src/events/Event"; 2 | import EventDispatcher from "../../../src/events/EventDispatcher"; 3 | import { Container } from "@createjs/easeljs"; 4 | 5 | describe("Events", function() { 6 | var eventDispatcher; 7 | 8 | beforeEach(function() { 9 | jest.useFakeTimers(); 10 | eventDispatcher = new EventDispatcher(); 11 | }); 12 | 13 | afterEach(function() { 14 | eventDispatcher.removeAllEventListeners(); 15 | }); 16 | 17 | test("dispatchEvent() and addEventListener() should work", function() { 18 | eventDispatcher.addEventListener("test", function(data) { 19 | expect(data.data).toBe("bar"); 20 | }); 21 | eventDispatcher.dispatchEvent({ 22 | type: "test", 23 | target: this, 24 | data: "bar", 25 | }); 26 | }); 27 | 28 | test("dispatchEvent() and on() should work", function() { 29 | eventDispatcher.on("test", function(data) { 30 | expect(data.data).toBe("bar"); 31 | }); 32 | eventDispatcher.dispatchEvent({ 33 | type: "test", 34 | target: this, 35 | data: "bar", 36 | }); 37 | }); 38 | 39 | test("hasEventlistener() should be true.", function() { 40 | eventDispatcher.addEventListener("test", function() {}); 41 | expect(eventDispatcher.hasEventListener("test")).toBe(true); 42 | }); 43 | 44 | test("removeEventListener() should work", function() { 45 | var foo = function() {}; 46 | eventDispatcher.addEventListener("test", foo); 47 | eventDispatcher.removeEventListener("test", foo); 48 | expect(eventDispatcher.hasEventListener("test")).toBe(false); 49 | }); 50 | 51 | test("off() should work", function() { 52 | var foo = function() {}; 53 | eventDispatcher.addEventListener("test", foo); 54 | eventDispatcher.off("test", foo); 55 | expect(eventDispatcher.hasEventListener("test")).toBe(false); 56 | }); 57 | 58 | test("removeAllEventListeners() should work", function() { 59 | eventDispatcher.addEventListener("test", function() {}); 60 | eventDispatcher.addEventListener("test2", function() {}); 61 | eventDispatcher.addEventListener("test3", function() {}); 62 | 63 | eventDispatcher.removeAllEventListeners(); 64 | 65 | expect(eventDispatcher.hasEventListener("test")).toBe(false); 66 | expect(eventDispatcher.hasEventListener("test2")).toBe(false); 67 | expect(eventDispatcher.hasEventListener("test3")).toBe(false); 68 | }); 69 | 70 | test("willTrigger() should work", function() { 71 | var foo = new Container(); 72 | var bar = new Container(); 73 | 74 | foo.addChild(bar); 75 | 76 | foo.addEventListener("test", function() {}); 77 | expect(bar.willTrigger("test")).toBe(true); 78 | }); 79 | 80 | test("enableMouseOver() should work", function() { 81 | this.stage.enableMouseOver(true); 82 | 83 | expect(this.stage._mouseOverIntervalID).not.toBe(null); 84 | }); 85 | 86 | test("Events should bubble.", function(done) { 87 | var a = new Container(); 88 | var b = new Container(); 89 | var c = new Container(); 90 | 91 | var timeout = setTimeout(function() { 92 | expect(true).toBe(false); 93 | done(); 94 | }, 10); 95 | 96 | a.addEventListener("foo", function() { 97 | clearTimeout(timeout); 98 | expect(true).toBe(true); 99 | done(); 100 | }); 101 | 102 | a.addChild(b); 103 | b.addChild(c); 104 | 105 | c.dispatchEvent(new Event("foo", true)); 106 | }); 107 | 108 | test("Events should not bubble.", function(done) { 109 | var a = new Container(); 110 | var b = new Container(); 111 | var c = new Container(); 112 | 113 | var timeout = setTimeout(function() { 114 | expect(true).toBe(true); 115 | done(); 116 | }, 10); 117 | 118 | a.addEventListener("foo", function() { 119 | clearTimeout(timeout); 120 | expect(true).toBe(false); 121 | done(); 122 | }); 123 | 124 | a.addChild(b); 125 | b.addChild(c); 126 | 127 | c.dispatchEvent(new Event("foo", false)); 128 | }); 129 | 130 | test("event.useCapture should work.", function(done) { 131 | var a = new Container(); 132 | var b = new Container(); 133 | var c = new Container(); 134 | 135 | // Fail condition 136 | var timeout = setTimeout(function() { 137 | expect(true).toBe(false); 138 | done(); 139 | }, 10); 140 | 141 | // Success 142 | a.addEventListener( 143 | "foo", 144 | function(evt) { 145 | clearTimeout(timeout); 146 | expect(evt.eventPhase).toBe(1); 147 | done(); 148 | }, 149 | true, 150 | ); 151 | 152 | a.addChild(b); 153 | b.addChild(c); 154 | c.dispatchEvent(new Event("foo", true)); 155 | }); 156 | 157 | test("event.stopPropagation() should work.", function(done) { 158 | var a = new Container(); 159 | var b = new Container(); 160 | var c = new Container(); 161 | var d = new Container(); 162 | 163 | // Success 164 | var timeout = setTimeout(function() { 165 | expect(true).toBe(true); 166 | done(); 167 | }, 10); 168 | 169 | // Should not get called 170 | c.addEventListener( 171 | "foo", 172 | function(evt) { 173 | clearTimeout(timeout); 174 | expect(true).toBe(false); 175 | done(); 176 | }, 177 | false, 178 | ); 179 | 180 | a.addChild(b); 181 | 182 | a.addEventListener( 183 | "foo", 184 | function(evt) { 185 | evt.stopPropagation(); 186 | }, 187 | true, 188 | ); 189 | b.addChild(c); 190 | 191 | c.addChild(d); 192 | 193 | d.dispatchEvent(new Event("foo", true)); 194 | }); 195 | 196 | test("event.stopImmediatePropagation() should work.", function(done) { 197 | var a = new Container(); 198 | var b = new Container(); 199 | var c = new Container(); 200 | var d = new Container(); 201 | 202 | // Success 203 | var timeout = setTimeout(function() { 204 | expect(true).toBe(true); 205 | done(); 206 | }, 10); 207 | 208 | // Should not get called 209 | c.addEventListener( 210 | "foo", 211 | function(evt) { 212 | clearTimeout(timeout); 213 | expect(true).toBe(false); 214 | done(); 215 | }, 216 | true, 217 | ); 218 | 219 | a.addChild(b); 220 | 221 | b.addEventListener( 222 | "foo", 223 | function(evt) { 224 | evt.stopImmediatePropagation(); 225 | }, 226 | true, 227 | ); 228 | b.addChild(c); 229 | 230 | c.addChild(d); 231 | 232 | d.dispatchEvent(new Event("foo", true)); 233 | }); 234 | 235 | test("event.preventDefault() should work.", function(done) { 236 | var a = new Container(); 237 | var b = new Container(); 238 | var c = new Container(); 239 | 240 | var timeout = setTimeout(function() { 241 | expect(true).toBe(true); 242 | done(); 243 | }, 10); 244 | 245 | a.addEventListener("foo", function(evt) { 246 | clearTimeout(timeout); 247 | expect(evt.defaultPrevented).toBe(true); 248 | done(); 249 | }); 250 | 251 | a.addChild(b); 252 | 253 | b.addEventListener("foo", function(evt) { 254 | evt.preventDefault(); 255 | }); 256 | b.addChild(c); 257 | 258 | c.dispatchEvent(new Event("foo", true, true)); 259 | }); 260 | }); 261 | -------------------------------------------------------------------------------- /tests/spec/utils/Ticker.js: -------------------------------------------------------------------------------- 1 | import Ticker from "../../../src/utils/Ticker"; 2 | 3 | describe("Ticker", () => { 4 | 5 | beforeEach(() => { 6 | jest.useFakeTimers(); 7 | Ticker.reset(); 8 | Ticker.init(); 9 | }); 10 | 11 | test("addEventListener() => evt.time", () => { 12 | Ticker.addEventListener("tick", evt => { 13 | expect(evt.time).toBeInRange(Ticker.getTime(), 2); 14 | }); 15 | }); 16 | 17 | test("addEventListener() => evt.delta", () => { 18 | Ticker.addEventListener("tick", evt => { 19 | expect(evt.delta).toBeInRange(Ticker.interval, 5); 20 | }); 21 | }); 22 | 23 | test("addEventListener() => evt.runTime", () => { 24 | Ticker.addEventListener("tick", evt => { 25 | expect(evt.runTime).toBeInRange(Ticker.getTime() | 0, 1); 26 | }); 27 | }); 28 | 29 | test("addEventListener() => evt.paused", () => { 30 | Ticker.paused = true; 31 | 32 | Ticker.addEventListener("tick", evt => { 33 | expect(evt.paused).toBeTruthy(); 34 | }); 35 | }); 36 | 37 | test("get framerate", () => { 38 | Ticker.interval = 40; 39 | expect(Ticker.framerate).toBe(25); 40 | }); 41 | 42 | test("set framerate", () => { 43 | Ticker.framerate = 40; 44 | setTimeout(() => expect(Ticker.getTime() | 0).toBeInRange(40 * 2, 3), 40 * 2); 45 | }); 46 | 47 | test("getMeasuredFPS()", () => { 48 | Ticker.addEventListener("tick", evt => { 49 | expect(Ticker.getMeasuredFPS()).toBeInRange(Ticker.framerate, 5); 50 | }); 51 | }); 52 | 53 | test("getMeasuredTickTime()", () => { 54 | expect(Ticker.getMeasuredTickTime() | 0).not.toBeNull(); 55 | }); 56 | 57 | test("getTicks()", () => { 58 | Ticker.addEventListener("tick", evt => { 59 | expect(Ticker.getTicks()).toBeInRange(Ticker.framerate, 5); 60 | }); 61 | }); 62 | 63 | test("getTime()", () => { 64 | Ticker.addEventListener("tick", evt => { 65 | expect(Ticker.getTime()).toBeInRange(1000, 5); 66 | }); 67 | }); 68 | 69 | test("getEventTime()", () => { 70 | Ticker.addEventListener("tick", evt => { 71 | expect(Ticker.getEventTime() | 0).toBeInRange( 72 | (Ticker.interval * Ticker.framerate) - Ticker.interval, 73 | 40 74 | ); 75 | }); 76 | }); 77 | 78 | }); 79 | --------------------------------------------------------------------------------