playable.js
Version:
A lightweight HTML5 game engine.
1,551 lines (1,527 loc) • 135 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise */
var extendStatics = function(d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
function __extends(d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var Event = /** @class */ (function () {
function Event(type, data) {
if (data === void 0) { data = null; }
this.type = null;
this.data = null;
this.target = null;
this.currentTarget = null;
this.$init(type, data);
}
Event.prototype.$init = function (type, data) {
if (data === void 0) { data = null; }
this.type = type;
this.data = data;
return this;
};
Event.prototype.release = function () {
this.type = null;
this.data = null;
Event.recycle(this);
};
Event.create = function (type, data) {
if (data === void 0) { data = null; }
var pool = this.$pool;
if (pool.length > 0) {
return pool.pop().$init(type, data);
}
else {
return new Event(type, data);
}
};
Event.recycle = function (e) {
this.$pool.push(e);
};
/** @event added */
Event.ADDED = 'added';
/** @event removed */
Event.REMOVED = 'removed';
/** @event addedToStage */
Event.ADDED_TO_STAGE = 'addedToStage';
/** @event removeFromStage */
Event.REMOVED_FROM_STAGE = 'removeFromStage';
/** @event activate */
Event.ACTIVATE = 'activate';
/** @event deactivate */
Event.DEACTIVATE = 'deactivate';
/** @event enterFrame */
Event.ENTER_FRAME = 'enterFrame';
/** @event tick */
Event.TICK = 'tick';
/** @event tickerPause */
Event.TICKER_PAUSE = 'tickerPause';
/** @event tickerResume */
Event.TICKER_RESUME = 'tickerResume';
/** @event viewportResize */
Event.VIEWPORT_RESIZE = 'viewportResize';
/** @event load */
Event.LOAD = 'load';
/** @event abort */
Event.ABORT = 'abort';
/** @event error */
Event.ERROR = 'error';
/** @event progress */
Event.PROGRESS = 'progress';
/** @event complete */
Event.COMPLETE = 'complete';
/** @event ended */
Event.ENDED = 'ended';
/** @event soundComplete */
Event.SOUND_COMPLETE = 'soundComplete';
Event.$pool = [];
return Event;
}());
var Event$1 = /*#__PURE__*/Object.freeze({
__proto__: null,
Event: Event
});
var EventEmitter = /** @class */ (function () {
function EventEmitter() {
this.$events = {};
this.$emittingType = null;
this.$removedListeners = [];
}
EventEmitter.prototype.on = function (type, listener) {
var listeners = this.$events[type] || [];
listeners.push(listener);
this.$events[type] = listeners;
return this;
};
EventEmitter.prototype.off = function (type, listener) {
if (this.$emittingType === type && listener) {
this.$removedListeners.push(listener);
}
else {
var listeners = this.$events[type] || [];
if (listener) {
var index = listeners.indexOf(listener);
if (index >= 0) {
listeners.splice(index, 1);
}
}
else {
listeners.length = 0;
}
}
return this;
};
EventEmitter.prototype.once = function (type, listener) {
var that = this;
var wrapper = function () {
listener.apply(this, arguments);
that.off(type, wrapper);
};
return this.on(type, wrapper);
};
EventEmitter.prototype.emit = function (type) {
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments[_i];
}
var event;
if (type instanceof Event) {
args = [type];
type.target = type.target || this;
type.currentTarget = this;
type = type.type;
}
var listeners = this.$events[type];
var hasListeners = listeners && listeners.length > 0;
var removedListeners = this.$removedListeners;
if (!event && hasListeners && args.length === 0) {
event = Event.create(type);
event.target = this;
event.currentTarget = this;
args.push(event);
}
if (hasListeners) {
this.$emittingType = type;
for (var _a = 0, listeners_1 = listeners; _a < listeners_1.length; _a++) {
var listener = listeners_1[_a];
if (removedListeners.indexOf(listener) < 0) {
listener.apply(this, args);
}
}
this.$emittingType = null;
}
if (event) {
event.release();
}
for (var _b = 0, removedListeners_1 = removedListeners; _b < removedListeners_1.length; _b++) {
var listener = removedListeners_1[_b];
this.off(type, listener);
}
removedListeners.length = 0;
return hasListeners;
};
EventEmitter.prototype.hasEventListener = function (type) {
var listeners = this.$events[type];
return !!listeners && listeners.length > 0;
};
EventEmitter.prototype.removeAllListeners = function () {
this.$events = {};
return this;
};
return EventEmitter;
}());
var EventEmitter$1 = /*#__PURE__*/Object.freeze({
__proto__: null,
EventEmitter: EventEmitter
});
var Ticker = /** @class */ (function (_super) {
__extends(Ticker, _super);
function Ticker(stage) {
var _this = _super.call(this) || this;
_this.$stage = null;
_this.$fps = 0;
_this.$deltaTime = 0;
_this.$paused = true;
_this.$shouldResume = false;
_this.$timerIndex = 0;
_this.$lastTimestamp = 0;
_this.$tickHandle = null;
_this.$stage = stage;
_this.$timers = [];
_this.$boundTick = _this.$tick.bind(_this);
_this.$enterFrameCallbackList = [stage];
_this.$start();
return _this;
}
Object.defineProperty(Ticker.prototype, "fps", {
get: function () {
return this.$fps;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Ticker.prototype, "deltaTime", {
get: function () {
return this.$deltaTime;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Ticker.prototype, "paused", {
get: function () {
return this.$paused;
},
enumerable: false,
configurable: true
});
Ticker.prototype.$start = function () {
var _this = this;
var stage = this.$stage;
var prefixes = ['', 'o', 'ms', 'moz', 'webkit'];
for (var _i = 0, prefixes_1 = prefixes; _i < prefixes_1.length; _i++) {
var prefix = prefixes_1[_i];
var requestKey = prefix ? prefix + 'RequestAnimationFrame' : 'requestAnimationFrame';
var cancelKey = prefix ? prefix + 'CancelAnimationFrame' : 'cancelAnimationFrame';
var cancelRequestKey = prefix ? prefix + 'CancelRequestAnimationFrame' : 'cancelRequestAnimationFrame';
window.requestAnimationFrame = window.requestAnimationFrame || window[requestKey];
window.cancelAnimationFrame = window.cancelAnimationFrame || window[cancelKey] || window[cancelRequestKey];
}
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = function (callback) {
return window.setTimeout(callback, 1000 / 60);
};
window.cancelAnimationFrame = function (handle) {
window.clearTimeout(handle);
};
}
stage.on(Event.ACTIVATE, function () {
if (_this.$shouldResume) {
_this.resume();
_this.$shouldResume = false;
}
});
stage.on(Event.DEACTIVATE, function () {
if (!_this.$paused) {
_this.pause();
_this.$shouldResume = true;
}
});
if (stage.activated) {
this.$paused = false;
this.$tick();
}
else {
this.$shouldResume = true;
}
return this;
};
Ticker.prototype.pause = function () {
if (!this.$paused) {
this.$paused = true;
this.$lastTimestamp = 0;
this.emit(Event.TICKER_PAUSE);
cancelAnimationFrame(this.$tickHandle);
}
return this;
};
Ticker.prototype.resume = function () {
if (this.$paused) {
this.$paused = false;
this.$tick();
this.emit(Event.TICKER_RESUME);
}
return this;
};
Ticker.prototype.setTimeout = function (handler, timeout) {
if (timeout === void 0) { timeout = 0; }
var handle = ++this.$timerIndex;
this.$timers[handle] = { handler: handler, timeout: timeout, resetTime: timeout };
return handle;
};
Ticker.prototype.clearTimeout = function (handle) {
delete this.$timers[handle];
};
Ticker.prototype.setInterval = function (handler, timeout) {
var handle = ++this.$timerIndex;
this.$timers[handle] = { handler: handler, timeout: timeout, resetTime: timeout, interval: true };
return handle;
};
Ticker.prototype.clearInterval = function (handle) {
delete this.$timers[handle];
};
Ticker.prototype.registerEnterFrameCallback = function (layer) {
var list = this.$enterFrameCallbackList;
if (list.indexOf(layer) < 0) {
list.push(layer);
}
return this;
};
Ticker.prototype.unregisterEnterFrameCallback = function (layer) {
var list = this.$enterFrameCallbackList;
var index = list.indexOf(layer);
if (index >= 0) {
list.splice(index, 1);
}
return this;
};
Ticker.prototype.$tick = function () {
var now = Date.now();
var lastTimestamp = this.$lastTimestamp;
var deltaTime = lastTimestamp ? now - this.$lastTimestamp : 1000 / 60;
var enterFrameCallbackList = this.$enterFrameCallbackList;
this.$fps = Math.round(1000 / deltaTime);
this.$deltaTime = deltaTime;
this.$lastTimestamp = now;
this.$tickHandle = window.requestAnimationFrame(this.$boundTick);
this.$checkTimers(deltaTime);
var event = Event.create(Event.ENTER_FRAME, deltaTime);
for (var _i = 0, enterFrameCallbackList_1 = enterFrameCallbackList; _i < enterFrameCallbackList_1.length; _i++) {
var layer = enterFrameCallbackList_1[_i];
layer.emit(event);
}
event.release();
var tickEvent = Event.create(Event.TICK, deltaTime);
this.emit(tickEvent);
tickEvent.release();
};
Ticker.prototype.$checkTimers = function (dt) {
var timers = this.$timers;
for (var key in timers) {
var timer = timers[key];
var restTime = timer.resetTime = timer.resetTime - dt;
if (restTime <= 0) {
timer.handler();
if (timer.interval) {
timer.resetTime += timer.timeout;
}
else {
this.clearTimeout(+key);
}
}
}
};
return Ticker;
}(EventEmitter));
var Ticker$1 = /*#__PURE__*/Object.freeze({
__proto__: null,
Ticker: Ticker
});
var Vector = /** @class */ (function () {
function Vector(x, y) {
this.set(x, y);
}
Object.defineProperty(Vector.prototype, "length", {
get: function () {
return Math.sqrt(this.x * this.x + this.y * this.y);
},
enumerable: false,
configurable: true
});
Object.defineProperty(Vector.prototype, "angle", {
get: function () {
return Math.atan2(this.y, this.x);
},
enumerable: false,
configurable: true
});
Vector.prototype.set = function (x, y) {
this.x = x || 0;
this.y = y || 0;
return this;
};
Vector.prototype.add = function (x, y) {
if (x instanceof Vector) {
this.x += x.x;
this.y += x.y;
}
else {
this.x += x;
this.y += y;
}
return this;
};
Vector.prototype.subtract = function (x, y) {
if (x instanceof Vector) {
this.x -= x.x;
this.y -= x.y;
}
else {
this.x -= x;
this.y -= y;
}
return this;
};
Vector.prototype.dotProduct = function (x, y) {
if (x instanceof Vector) {
return this.x * x.x + this.y * x.y;
}
else {
return this.x * x + this.y * y;
}
};
Vector.prototype.normalize = function () {
var length = this.length;
this.x = this.x / length;
this.y = this.y / length;
return this;
};
Vector.prototype.negate = function () {
this.x *= -1;
this.y *= -1;
return this;
};
Vector.prototype.scale = function (x, y) {
this.x *= x;
this.y *= y === undefined ? x : y;
return this;
};
Vector.prototype.rotate = function (angle) {
var x = this.x;
var y = this.y;
this.x = x * Math.cos(angle) - y * Math.sin(angle);
this.y = x * Math.sin(angle) + y * Math.cos(angle);
return this;
};
Vector.prototype.transform = function (m) {
var x = this.x;
var y = this.y;
this.x = m.a * x + m.c * y + m.tx;
this.y = m.b * x + m.d * y + m.ty;
return this;
};
Vector.prototype.distance = function (v) {
return Math.sqrt((this.x - v.x) * (this.x - v.x) + (this.y - v.y) * (this.y - v.y));
};
Vector.prototype.equal = function (v) {
return this.x === v.x && this.y === v.y;
};
Vector.prototype.release = function () {
Vector.recycle(this);
return this;
};
Vector.create = function (x, y) {
var pool = this.$pool;
if (pool.length > 0) {
return pool.pop().set(x, y);
}
else {
return new Vector(x, y);
}
};
Vector.recycle = function (v) {
this.$pool.push(v);
};
Vector.$pool = [];
return Vector;
}());
var Vector$1 = /*#__PURE__*/Object.freeze({
__proto__: null,
Vector: Vector
});
/**
* ```
* {a b 0}
* (x, y, 1) * {c d 0} = (ax + cy + tx, bx + dy + ty, 1)
* {tx ty 1}
* ```
*/
var Matrix = /** @class */ (function () {
function Matrix(a, b, c, d, tx, ty) {
if (arguments.length > 0) {
this.set(a, b, c, d, tx, ty);
}
else {
this.identity();
}
}
Matrix.prototype.set = function (a, b, c, d, tx, ty) {
this.a = a;
this.b = b;
this.c = c;
this.d = d;
this.tx = tx;
this.ty = ty;
return this;
};
Matrix.prototype.identity = function () {
return this.set(1, 0, 0, 1, 0, 0);
};
Matrix.prototype.invert = function () {
var a = this.a;
var b = this.b;
var c = this.c;
var d = this.d;
var tx = this.tx;
var ty = this.ty;
var n = a * d - c * b;
this.a = d / n;
this.b = -b / n;
this.c = -c / n;
this.d = a / n;
this.tx = (c * ty - d * tx) / n;
this.ty = (b * tx - a * ty) / n;
return this;
};
Matrix.prototype.prepend = function (a, b, c, d, tx, ty) {
if (a instanceof Matrix) {
return this.prepend(a.a, a.b, a.c, a.d, a.tx, a.ty);
}
var a1 = this.a;
var b1 = this.b;
var c1 = this.c;
var d1 = this.d;
var tx1 = this.tx;
var ty1 = this.ty;
this.a = a * a1 + b * c1;
this.b = a * b1 + b * d1;
this.c = c * a1 + d * c1;
this.d = c * b1 + d * d1;
this.tx = tx * a1 + ty * c1 + tx1;
this.ty = tx * b1 + ty * d1 + ty1;
return this;
};
Matrix.prototype.append = function (a, b, c, d, tx, ty) {
if (a instanceof Matrix) {
return this.append(a.a, a.b, a.c, a.d, a.tx, a.ty);
}
var a1 = this.a;
var b1 = this.b;
var c1 = this.c;
var d1 = this.d;
var tx1 = this.tx;
var ty1 = this.ty;
this.a = a * a1 + c * b1;
this.b = b * a1 + d * b1;
this.c = a * c1 + c * d1;
this.d = b * c1 + d * d1;
this.tx = a * tx1 + c * ty1 + tx;
this.ty = b * tx1 + d * ty1 + ty;
return this;
};
Matrix.prototype.scale = function (x, y) {
return this.append(x, 0, 0, y === undefined ? x : y, 0, 0);
};
Matrix.prototype.rotate = function (angle) {
var sin = Math.sin(angle);
var cos = Math.cos(angle);
return this.append(cos, sin, -sin, cos, 0, 0);
};
Matrix.prototype.skew = function (skewX, skewY) {
return this.append(1, Math.tan(skewY), Math.tan(skewX), 1, 0, 0);
};
Matrix.prototype.translate = function (x, y) {
if (x instanceof Vector) {
return this.append(1, 0, 0, 1, x.x, x.y);
}
return this.append(1, 0, 0, 1, x, y);
};
Matrix.prototype.equal = function (m) {
return m instanceof Matrix &&
this.a === m.a && this.b === m.b &&
this.c === m.c && this.d === m.d &&
this.tx === m.tx && this.ty === m.ty;
};
Matrix.prototype.release = function () {
Matrix.recycle(this);
};
Matrix.create = function (a, b, c, d, tx, ty) {
var m;
var pool = this.$pool;
if (pool.length > 0) {
m = pool.pop();
}
else {
m = new Matrix();
}
if (arguments.length) {
m.set(a, b, c, d, tx, ty);
}
else {
m.identity();
}
return m;
};
Matrix.recycle = function (m) {
this.$pool.push(m);
};
Matrix.$pool = [];
return Matrix;
}());
var Matrix$1 = /*#__PURE__*/Object.freeze({
__proto__: null,
Matrix: Matrix
});
var Rectangle = /** @class */ (function () {
function Rectangle(x, y, width, height) {
this.set(x, y, width, height);
}
Object.defineProperty(Rectangle.prototype, "top", {
get: function () {
return this.y;
},
set: function (top) {
this.height += this.y - top;
this.y = top;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Rectangle.prototype, "bottom", {
get: function () {
return this.y + this.height;
},
set: function (bottom) {
this.height = bottom - this.y;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Rectangle.prototype, "left", {
get: function () {
return this.x;
},
set: function (left) {
this.width += this.x - left;
this.x = left;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Rectangle.prototype, "right", {
get: function () {
return this.x + this.width;
},
set: function (right) {
this.width = right - this.x;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Rectangle.prototype, "topLeft", {
get: function () {
return Vector.create(this.left, this.top);
},
set: function (v) {
this.top = v.y;
this.left = v.x;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Rectangle.prototype, "bottomRight", {
get: function () {
return Vector.create(this.right, this.bottom);
},
set: function (v) {
this.bottom = v.y;
this.right = v.x;
},
enumerable: false,
configurable: true
});
Rectangle.prototype.set = function (x, y, width, height) {
this.x = x || 0;
this.y = y || 0;
this.width = width || 0;
this.height = height || 0;
return this;
};
Rectangle.prototype.contains = function (x, y) {
if (x instanceof Vector) {
return this.contains(x.x, x.y);
}
return x >= this.x && x <= this.x + this.width && y >= this.y && y <= this.y + this.height;
};
Rectangle.prototype.equal = function (r) {
return r instanceof Rectangle &&
r.x === this.x && r.y === this.y && r.width === this.width && r.height === this.height;
};
Rectangle.prototype.release = function () {
Rectangle.recycle(this);
};
Rectangle.create = function (x, y, width, height) {
var pool = this.$pool;
if (pool.length > 0) {
return pool.pop().set(x, y, width, height);
}
else {
return new Rectangle(x, y, width, height);
}
};
Rectangle.recycle = function (r) {
this.$pool.push(r);
};
Rectangle.$pool = [];
return Rectangle;
}());
var Rectangle$1 = /*#__PURE__*/Object.freeze({
__proto__: null,
Rectangle: Rectangle
});
var TouchEvent = /** @class */ (function (_super) {
__extends(TouchEvent, _super);
function TouchEvent(type) {
var _this = _super.call(this, type) || this;
_this.$init(type);
return _this;
}
TouchEvent.prototype.$init = function (type) {
this.type = type;
this.targetX = 0;
this.targetY = 0;
this.localX = 0;
this.localY = 0;
this.stageX = 0;
this.stageY = 0;
this.identifier = 0;
this.target = null;
this.currentTarget = null;
this.cancelBubble = false;
return this;
};
TouchEvent.prototype.stopPropagation = function () {
this.cancelBubble = true;
};
TouchEvent.prototype.release = function () {
TouchEvent.recycle(this);
};
TouchEvent.create = function (type) {
var pool = this.$pool;
if (pool.length > 0) {
return pool.pop().$init(type);
}
else {
return new TouchEvent(type);
}
};
TouchEvent.recycle = function (e) {
this.$pool.push(e);
};
/** @event touchStart */
TouchEvent.TOUCH_START = 'touchStart';
/** @event touchMove */
TouchEvent.TOUCH_MOVE = 'touchMove';
/** @event touchEnd */
TouchEvent.TOUCH_END = 'touchEnd';
/** @event touchCancel */
TouchEvent.TOUCH_CANCEL = 'touchCancel';
/** @event touchTap */
TouchEvent.TOUCH_TAP = 'touchTap';
TouchEvent.$pool = [];
return TouchEvent;
}(Event));
var TouchEvent$1 = /*#__PURE__*/Object.freeze({
__proto__: null,
TouchEvent: TouchEvent
});
var Layer = /** @class */ (function (_super) {
__extends(Layer, _super);
function Layer() {
var _this = _super.call(this) || this;
_this.name = '';
_this.tag = '';
_this.touchable = true;
_this.$x = 0;
_this.$y = 0;
_this.$width = 0;
_this.$height = 0;
_this.$anchorX = 0;
_this.$anchorY = 0;
_this.$skewX = 0;
_this.$skewY = 0;
_this.$scaleX = 1;
_this.$scaleY = 1;
_this.$rotation = 0;
_this.$alpha = 1;
_this.$visible = true;
_this.$smoothing = true;
_this.$background = null;
_this.$stage = null;
_this.$parent = null;
_this.$children = [];
_this.$dirty = true;
_this.$shouldEmitTap = true;
_this.$touches = [];
_this.$canvas = document.createElement('canvas');
_this.$context = _this.$canvas.getContext('2d');
return _this;
}
Object.defineProperty(Layer.prototype, "x", {
get: function () {
return this.$x;
},
set: function (x) {
if (this.$x !== x) {
this.$x = x;
this.$markParentDirty();
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(Layer.prototype, "y", {
get: function () {
return this.$y;
},
set: function (y) {
if (this.$y !== y) {
this.$y = y;
this.$markParentDirty();
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(Layer.prototype, "width", {
get: function () {
return this.$width ? this.$width : this.$canvas.width / Layer.pixelRatio;
},
set: function (width) {
if (this.$width !== width) {
this.$width = width;
this.$resizeCanvas();
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(Layer.prototype, "height", {
get: function () {
return this.$height ? this.$height : this.$canvas.height / Layer.pixelRatio;
},
set: function (height) {
if (this.$height !== height) {
this.$height = height;
this.$resizeCanvas();
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(Layer.prototype, "anchorX", {
get: function () {
return this.$anchorX;
},
set: function (anchorX) {
if (this.$anchorX !== anchorX) {
this.$anchorX = anchorX;
this.$resizeCanvas();
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(Layer.prototype, "anchorY", {
get: function () {
return this.$anchorY;
},
set: function (anchorY) {
if (this.$anchorY !== anchorY) {
this.$anchorY = anchorY;
this.$resizeCanvas();
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(Layer.prototype, "skewX", {
get: function () {
return this.$skewX;
},
set: function (skewX) {
if (this.$skewX !== skewX) {
this.$skewX = skewX;
this.$markParentDirty();
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(Layer.prototype, "skewY", {
get: function () {
return this.$skewY;
},
set: function (skewY) {
if (this.$skewY !== skewY) {
this.$skewY = skewY;
this.$markParentDirty();
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(Layer.prototype, "scaleX", {
get: function () {
return this.$scaleX;
},
set: function (scaleX) {
if (this.$scaleX !== scaleX) {
this.$scaleX = scaleX;
this.$markParentDirty();
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(Layer.prototype, "scaleY", {
get: function () {
return this.$scaleY;
},
set: function (scaleY) {
if (this.$scaleY !== scaleY) {
this.$scaleY = scaleY;
this.$markParentDirty();
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(Layer.prototype, "rotation", {
get: function () {
return this.$rotation;
},
set: function (rotation) {
if (this.$rotation !== rotation) {
this.$rotation = rotation;
this.$markParentDirty();
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(Layer.prototype, "alpha", {
get: function () {
return this.$alpha;
},
set: function (alpha) {
if (this.$alpha !== alpha) {
this.$alpha = alpha;
this.$markParentDirty();
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(Layer.prototype, "visible", {
get: function () {
return this.$visible;
},
set: function (visible) {
if (this.$visible !== visible) {
this.$visible = visible;
this.$markParentDirty();
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(Layer.prototype, "smoothing", {
get: function () {
return this.$smoothing;
},
set: function (smoothing) {
this.$smoothing = smoothing;
this.$resizeCanvas();
},
enumerable: false,
configurable: true
});
Object.defineProperty(Layer.prototype, "background", {
get: function () {
return this.$background;
},
set: function (background) {
if (this.$background !== background) {
this.$background = background;
this.$markDirty();
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(Layer.prototype, "stage", {
get: function () {
return this.$stage;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Layer.prototype, "parent", {
get: function () {
return this.$parent;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Layer.prototype, "numChildren", {
get: function () {
return this.$children.length;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Layer.prototype, "ticker", {
get: function () {
return this.$stage ? this.$stage.ticker : null;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Layer.prototype, "canvas", {
get: function () {
return this.$canvas;
},
enumerable: false,
configurable: true
});
Layer.prototype.addChild = function (child) {
return this.addChildAt(child, this.$children.length);
};
Layer.prototype.addChildAt = function (child, index) {
var children = this.$children;
if (child.$parent) {
child.$parent.removeChild(child);
}
if (index < 0 || index > children.length) {
index = children.length;
}
child.$emitAdded(this);
children.splice(index, 0, child);
this.$resizeCanvas();
return this;
};
Layer.prototype.replaceChild = function (oldChild, newChild) {
var index = this.getChildIndex(oldChild);
this.removeChildAt(index);
this.addChildAt(newChild, index);
return this;
};
Layer.prototype.getChildByName = function (name) {
var children = this.$children;
for (var _i = 0, children_1 = children; _i < children_1.length; _i++) {
var child = children_1[_i];
if (child.name === name) {
return child;
}
}
return null;
};
Layer.prototype.getChildrenByTag = function (tag) {
var result = [];
var children = this.$children;
for (var _i = 0, children_2 = children; _i < children_2.length; _i++) {
var child = children_2[_i];
if (child.tag === tag) {
result.push(child);
}
}
return result;
};
Layer.prototype.getChildAt = function (index) {
return this.$children[index] || null;
};
Layer.prototype.getChildIndex = function (child) {
return this.$children.indexOf(child);
};
Layer.prototype.hasChild = function (child) {
return this.getChildIndex(child) >= 0;
};
Layer.prototype.swapChildren = function (child1, child2) {
var index1 = this.getChildIndex(child1);
var index2 = this.getChildIndex(child2);
if (index1 >= 0 && index2 >= 0) {
this.swapChildrenAt(index1, index2);
}
return this;
};
Layer.prototype.swapChildrenAt = function (index1, index2) {
var child1 = this.$children[index1];
var child2 = this.$children[index2];
if (index1 !== index2 && child1 && child2) {
this.$children[index1] = child2;
this.$children[index2] = child1;
this.$markDirty();
}
return this;
};
Layer.prototype.setChildIndex = function (child, index) {
var children = this.$children;
var oldIndex = this.getChildIndex(child);
if (index < 0) {
index = 0;
}
else if (index > children.length) {
index = children.length;
}
if (oldIndex >= 0 && index > oldIndex) {
for (var i = oldIndex + 1; i <= index; ++i) {
children[i - 1] = children[i];
}
children[index] = child;
this.$markDirty();
}
else if (oldIndex >= 0 && index < oldIndex) {
for (var i = oldIndex - 1; i >= index; --i) {
children[i + 1] = children[i];
}
children[index] = child;
this.$markDirty();
}
return this;
};
Layer.prototype.removeChild = function (child) {
var index = this.getChildIndex(child);
return this.removeChildAt(index);
};
Layer.prototype.removeChildAt = function (index) {
var children = this.$children;
var child = children[index];
if (child) {
children.splice(index, 1);
child.$emitRemoved();
this.$resizeCanvas();
}
return this;
};
Layer.prototype.removeChildByName = function (name) {
var children = this.$children;
for (var i = 0, l = children.length; i < l; ++i) {
var child = children[i];
if (child.name === name) {
this.removeChildAt(i);
break;
}
}
return this;
};
Layer.prototype.removeChildrenByTag = function (tag) {
var children = this.$children;
for (var i = children.length - 1; i >= 0; --i) {
var child = children[i];
if (child.tag === tag) {
this.removeChildAt(i);
}
}
return this;
};
Layer.prototype.removeAllChildren = function () {
var children = this.$children;
for (var _i = 0, children_3 = children; _i < children_3.length; _i++) {
var child = children_3[_i];
child.$emitRemoved();
}
this.$children.length = 0;
this.$resizeCanvas();
return this;
};
Layer.prototype.removeSelf = function () {
if (this.$parent) {
this.$parent.removeChild(this);
}
return this;
};
Layer.prototype.$markDirty = function (sizeDirty) {
if (sizeDirty) {
this.$resizeParentCanvas();
}
else if (!this.$dirty) {
this.$markParentDirty();
}
this.$dirty = true;
};
Layer.prototype.$markParentDirty = function () {
if (this.$parent) {
this.$parent.$markDirty();
}
};
Layer.prototype.$resizeCanvas = function () {
var width = this.$width;
var height = this.$height;
var canvas = this.$canvas;
var anchorX = this.$anchorX;
var anchorY = this.$anchorY;
var context = this.$context;
var smoothing = this.$smoothing;
var pixelRatio = Layer.pixelRatio;
if (width && height) {
canvas.width = width * pixelRatio;
canvas.height = height * pixelRatio;
}
else {
var bounds = this.$getContentBounds();
canvas.width = (width || bounds.right + anchorX) * pixelRatio;
canvas.height = (height || bounds.bottom + anchorY) * pixelRatio;
bounds.release();
}
if (context.imageSmoothingEnabled !== smoothing) {
context.imageSmoothingEnabled = smoothing;
}
this.$markDirty(true);
};
Layer.prototype.$resizeParentCanvas = function () {
if (this.$parent) {
this.$parent.$resizeCanvas();
}
};
Layer.prototype.$getTransform = function () {
var degToRad = Math.PI / 180;
var matrix = Matrix.create();
matrix.translate(-this.$anchorX, -this.$anchorY);
matrix.skew(this.skewX * degToRad, this.skewY * degToRad);
matrix.rotate(this.rotation * degToRad);
matrix.scale(this.scaleX, this.scaleY);
matrix.translate(this.x, this.y);
return matrix;
};
Layer.prototype.$getChildTransform = function (child) {
return child.$getTransform();
};
Layer.prototype.$getChildBounds = function (child) {
var width = child.width;
var height = child.height;
var bounds = Rectangle.create();
var matrix = this.$getChildTransform(child);
var topLeft = Vector.create(0, 0).transform(matrix);
var topRight = Vector.create(width, 0).transform(matrix);
var bottomLeft = Vector.create(0, height).transform(matrix);
var bottomRight = Vector.create(width, height).transform(matrix);
var minX = Math.min(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x);
var maxX = Math.max(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x);
var minY = Math.min(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y);
var maxY = Math.max(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y);
bounds.top = minY;
bounds.bottom = maxY;
bounds.left = minX;
bounds.right = maxX;
matrix.release();
topLeft.release();
topRight.release();
bottomLeft.release();
bottomRight.release();
return bounds;
};
Layer.prototype.$getContentBounds = function () {
var bounds;
var children = this.$children;
for (var _i = 0, children_4 = children; _i < children_4.length; _i++) {
var child = children_4[_i];
if (child.$visible) {
var childBounds = this.$getChildBounds(child);
if (bounds) {
bounds.top = Math.min(bounds.top, childBounds.top);
bounds.bottom = Math.max(bounds.bottom, childBounds.bottom);
bounds.left = Math.min(bounds.left, childBounds.left);
bounds.right = Math.max(bounds.right, childBounds.right);
childBounds.release();
}
else {
bounds = childBounds;
}
}
}
bounds = bounds || Rectangle.create();
return bounds;
};
Layer.prototype.$emitTouchEvent = function (event, inside) {
var type = event.type;
var localX = event.localX;
var localY = event.localY;
var touches = this.$touches;
var identifier = event.identifier;
if (type === TouchEvent.TOUCH_START) {
this.$shouldEmitTap = true;
touches[identifier] = true;
}
else if (!touches[identifier]) {
return false;
}
else if (type === TouchEvent.TOUCH_TAP || type === TouchEvent.TOUCH_CANCEL) {
touches[identifier] = false;
}
if (type === TouchEvent.TOUCH_MOVE) {
this.$shouldEmitTap = false;
}
var children = this.$children;
for (var i = children.length - 1; i >= 0; --i) {
var child = children[i];
if (!child.$visible || !child.touchable) {
continue;
}
var matrix = this.$getChildTransform(child);
var localPos = Vector.create(localX, localY).transform(matrix.invert()).subtract(child.$anchorX, child.$anchorY);
var inside_1 = child.$localHitTest(localPos);
localPos.release();
matrix.release();
if (inside_1 || type !== TouchEvent.TOUCH_START) {
event.target = child;
event.localX = event.targetX = localPos.x;
event.localY = event.targetY = localPos.y;
if (child.$emitTouchEvent(event, inside_1)) {
break;
}
}
}
if (type === TouchEvent.TOUCH_TAP && (!inside || !this.$shouldEmitTap)) {
return true;
}
if (!event.cancelBubble) {
event.localX = localX;
event.localY = localY;
this.emit(event);
}
return true;
};
Layer.prototype.$emitAdded = function (parent) {
var stage = parent.$stage;
this.$parent = parent;
this.emit(Event.ADDED);
if (stage) {
this.$emitAddedToStage(stage);
}
};
Layer.prototype.$emitRemoved = function () {
var stage = this.$stage;
this.$parent = null;
this.emit(Event.REMOVED);
if (stage) {
this.$emitRemovedFromStage();
}
};
Layer.prototype.$emitAddedToStage = function (stage) {
var children = this.$children;
this.$stage = stage;
this.emit(Event.ADDED_TO_STAGE);
if (this.hasEventListener(Event.ENTER_FRAME)) {
stage.ticker.registerEnterFrameCallback(this);
}
for (var _i = 0, children_5 = children; _i < children_5.length; _i++) {
var child = children_5[_i];
child.$emitAddedToStage(stage);
}
};
Layer.prototype.$emitRemovedFromStage = function () {
var stage = this.$stage;
var children = this.$children;
this.$stage = null;
this.emit(Event.REMOVED_FROM_STAGE);
if (this.hasEventListener(Event.ENTER_FRAME)) {
stage.ticker.unregisterEnterFrameCallback(this);
}
for (var _i = 0, children_6 = children; _i < children_6.length; _i++) {
var child = children_6[_i];
child.$emitRemovedFromStage();
}
};
Layer.prototype.$localHitTest = function (vector) {
return vector.x >= -this.anchorX && vector.x <= this.width - this.anchorX && vector.y >= -this.anchorY && vector.y <= this.height - this.anchorY;
};
Layer.prototype.$isChildVisible = function (child) {
if (!child.visible || !child.alpha || !child.width || !child.height) {
return false;
}
var minX = -this.$anchorX;
var maxX = this.width + minX;
var minY = -this.$anchorY;
var maxY = this.height + minY;
var bounds = this.$getChildBounds(child);
var inside = bounds.left <= maxX && bounds.right >= minX && bounds.top <= maxY && bounds.bottom >= minY;
bounds.release();
return inside;
};
Layer.prototype.$drawChild = function (child) {
var ctx = this.$context;
var canvas = child.$canvas;
var width = child.width;
var height = child.height;
var pixelRatio = Layer.pixelRatio;
var matrix = this.$getChildTransform(child).scale(pixelRatio);
var drawCalls = child.$render();
var globalAlpha = ctx.globalAlpha;
if (globalAlpha !== child.alpha) {
ctx.globalAlpha = child.alpha;
}
if (matrix.b === 0 && matrix.c === 0) {
var tx = (matrix.tx + 0.5) | 0;
var ty = (matrix.ty + 0.5) | 0;
width = (width * matrix.a) + 0.5 | 0;
height = (height * matrix.d) + 0.5 | 0;
ctx.drawImage(canvas, tx, ty, width, height);
}
else {
ctx.save();
ctx.transform(matrix.a, matrix.b, matrix.c, matrix.d, matrix.tx, matrix.ty);
ctx.drawImage(canvas, 0, 0, width, height);
ctx.restore();
}
if (globalAlpha !== child.alpha) {
ctx.globalAlpha = globalAlpha;
}
matrix.release();
return drawCalls + 1;
};
Layer.prototype.$render = function () {
if (!this.$dirty) {
return 0;
}
var drawCalls = 0;
var ctx = this.$context;
var canvas = this.$canvas;
var children = this.$children;
var canvasWidth = canvas.width;
var canvasHeight = canvas.height;
var anchorX = (this.$anchorX + 0.5) | 0;
var anchorY = (this.$anchorY + 0.5) | 0;
var background = this.$background;
var pixelRatio = Layer.pixelRatio;
ctx.globalAlpha = 1;
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
if (background) {
ctx.fillStyle = background;
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
}
ctx.translate(anchorX * pixelRatio, anchorY * pixelRatio);
for (var _i = 0, children_7 = children; _i < children_7.length; _i++) {
var child = children_7[_i];
if (this.$isChildVisible(child)) {
drawCalls += this.$drawChild(child);
}
}
this.$dirty = false;
return drawCalls;
};
Layer.prototype.on = function (type, listener) {
_super.prototype.on.call(this, type, listener);
if (type === Event.ENTER_FRAME && this.ticker) {
this.ticker.registerEnterFrameCallback(this);
}
else if (type === Event.ADDED && this.$parent) {
var event_1 = Event.create(type);
listener.call(this, event_1);
event_1.release();
}
else if (type === Event.ADDED_TO_STAGE && this.$stage) {
var event_2 = Event.create(type);
listener.call(this, event_2);
event_2.release();
}
return this;
};
Layer.prototype.off = function (type, listener) {
_super.prototype.off.call(this, type, listener);
if (type === Event.ENTER_FRAME && !this.hasEventListener(Event.ENTER_FRAME) && this.ticker) {
this.ticker.unregisterEnterFrameCallback(this);
}
return this;
};
Layer.pixelRatio = typeof window === 'undefined' ? 1 : window.devicePixelRatio || 1;
return Layer;
}(EventEmitter));
var Layer$1 = /*#__PURE__*/Object.freeze({
__proto__: null,
Layer: Layer
});
var Ease = /** @class */ (function () {
function Ease() {
}
Ease.linear = function (t, b, c, d) {
return c * t / d + b;
};
Ease.easeInQuad = function (t, b, c, d) {
return c * (t /= d) * t + b;
};
Ease.easeOutQuad = function (t, b, c, d) {
return -c * (t /= d) * (t - 2) + b;
};
Ease.easeInOutQuad = function (t, b, c, d) {
if ((t /= d / 2) < 1)
return c / 2 * t * t + b;
return -c / 2 * ((--t) * (t - 2) - 1) + b;
};
Ease.easeInCubic = function (t, b, c, d) {
return c * (t /= d) * t * t + b;
};
Ease.easeOutCubic = function (t, b, c, d) {
return c * ((t = t / d - 1) * t * t + 1) + b;
};
Ease.easeInOutCubic = function (t, b, c, d) {
if ((t /= d / 2) < 1)
return c / 2 * t * t * t + b;
return c / 2 * ((t -= 2) * t * t + 2) + b;
};
Ease.easeInQuart = function (t, b, c, d) {
return c * (t /= d) * t * t * t + b;
};
Ease.easeOutQuart = function (t, b, c, d) {
return -c * ((t = t / d - 1) * t * t * t - 1) +