UNPKG

canvas2djs

Version:

HTML5 canvas based game engine

1,494 lines (1,447 loc) 177 kB
/** * canvas2djs v2.6.3 * Copyright (c) 2013-present Todd Fon <tilfon@live.com> * All rights reserved. */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define('canvas2djs', ['exports'], factory) : (factory((global.canvas2d = global.canvas2d || {}))); }(this, (function (exports) { 'use strict'; var Keys = { MOUSE_LEFT: 1, MOUSE_MID: 2, MOUSE_RIGHT: 3, BACKSPACE: 8, TAB: 9, NUM_CENTER: 12, ENTER: 13, RETURN: 13, SHIFT: 16, CTRL: 17, ALT: 18, PAUSE: 19, CAPS_LOCK: 20, ESC: 27, ESCAPE: 27, SPACE: 32, PAGE_UP: 33, PAGE_DOWN: 34, END: 35, HOME: 36, LEFT: 37, UP: 38, RIGHT: 39, DOWN: 40, PRINT_SCREEN: 44, INSERT: 45, DELETE: 46, ZERO: 48, ONE: 49, TWO: 50, THREE: 51, FOUR: 52, FIVE: 53, SIX: 54, SEVEN: 55, EIGHT: 56, NINE: 57, A: 65, B: 66, C: 67, D: 68, E: 69, F: 70, G: 71, H: 72, I: 73, J: 74, K: 75, L: 76, M: 77, N: 78, O: 79, P: 80, Q: 81, R: 82, S: 83, T: 84, U: 85, V: 86, W: 87, X: 88, Y: 89, Z: 90, CONTEXT_MENU: 93, NUM0: 96, NUM1: 97, NUM2: 98, NUM3: 99, NUM4: 100, NUM5: 101, NUM6: 102, NUM7: 103, NUM8: 104, NUM9: 105, NUM_MULTIPLY: 106, NUM_PLUS: 107, NUM_MINUS: 109, NUM_PERIOD: 110, NUM_DIVISION: 111, F1: 112, F2: 113, F3: 114, F4: 115, F5: 116, F6: 117, F7: 118, F8: 119, F9: 120, F10: 121, F11: 122, F12: 123 }; var Tween = { easeInQuad: function (pos) { return Math.pow(pos, 2); }, easeOutQuad: function (pos) { return -(Math.pow((pos - 1), 2) - 1); }, easeInOutQuad: function (pos) { if ((pos /= 0.5) < 1) { return 0.5 * Math.pow(pos, 2); } return -0.5 * ((pos -= 2) * pos - 2); }, easeInCubic: function (pos) { return Math.pow(pos, 3); }, easeOutCubic: function (pos) { return (Math.pow((pos - 1), 3) + 1); }, easeInOutCubic: function (pos) { if ((pos /= 0.5) < 1) { return 0.5 * Math.pow(pos, 3); } return 0.5 * (Math.pow((pos - 2), 3) + 2); }, easeInQuart: function (pos) { return Math.pow(pos, 4); }, easeOutQuart: function (pos) { return -(Math.pow((pos - 1), 4) - 1); }, easeInOutQuart: function (pos) { if ((pos /= 0.5) < 1) return 0.5 * Math.pow(pos, 4); return -0.5 * ((pos -= 2) * Math.pow(pos, 3) - 2); }, easeInQuint: function (pos) { return Math.pow(pos, 5); }, easeOutQuint: function (pos) { return (Math.pow((pos - 1), 5) + 1); }, easeInOutQuint: function (pos) { if ((pos /= 0.5) < 1) { return 0.5 * Math.pow(pos, 5); } return 0.5 * (Math.pow((pos - 2), 5) + 2); }, easeInSine: function (pos) { return -Math.cos(pos * (Math.PI / 2)) + 1; }, easeOutSine: function (pos) { return Math.sin(pos * (Math.PI / 2)); }, easeInOutSine: function (pos) { return (-.5 * (Math.cos(Math.PI * pos) - 1)); }, easeInExpo: function (pos) { return (pos == 0) ? 0 : Math.pow(2, 10 * (pos - 1)); }, easeOutExpo: function (pos) { return (pos == 1) ? 1 : -Math.pow(2, -10 * pos) + 1; }, easeInOutExpo: function (pos) { if (pos == 0) return 0; if (pos == 1) return 1; if ((pos /= 0.5) < 1) return 0.5 * Math.pow(2, 10 * (pos - 1)); return 0.5 * (-Math.pow(2, -10 * --pos) + 2); }, easeInCirc: function (pos) { return -(Math.sqrt(1 - (pos * pos)) - 1); }, easeOutCirc: function (pos) { return Math.sqrt(1 - Math.pow((pos - 1), 2)); }, easeInOutCirc: function (pos) { if ((pos /= 0.5) < 1) return -0.5 * (Math.sqrt(1 - pos * pos) - 1); return 0.5 * (Math.sqrt(1 - (pos -= 2) * pos) + 1); }, easeOutBounce: function (pos) { if ((pos) < (1 / 2.75)) { return (7.5625 * pos * pos); } else if (pos < (2 / 2.75)) { return (7.5625 * (pos -= (1.5 / 2.75)) * pos + .75); } else if (pos < (2.5 / 2.75)) { return (7.5625 * (pos -= (2.25 / 2.75)) * pos + .9375); } else { return (7.5625 * (pos -= (2.625 / 2.75)) * pos + .984375); } }, easeInBack: function (pos) { var s = 1.70158; return (pos) * pos * ((s + 1) * pos - s); }, easeOutBack: function (pos) { var s = 1.70158; return (pos = pos - 1) * pos * ((s + 1) * pos + s) + 1; }, easeInOutBack: function (pos) { var s = 1.70158; if ((pos /= 0.5) < 1) return 0.5 * (pos * pos * (((s *= (1.525)) + 1) * pos - s)); return 0.5 * ((pos -= 2) * pos * (((s *= (1.525)) + 1) * pos + s) + 2); }, elastic: function (pos) { return -1 * Math.pow(4, -8 * pos) * Math.sin((pos * 6 - 1) * (2 * Math.PI) / 2) + 1; }, swingFromTo: function (pos) { var s = 1.70158; return ((pos /= 0.5) < 1) ? 0.5 * (pos * pos * (((s *= (1.525)) + 1) * pos - s)) : 0.5 * ((pos -= 2) * pos * (((s *= (1.525)) + 1) * pos + s) + 2); }, swingFrom: function (pos) { var s = 1.70158; return pos * pos * ((s + 1) * pos - s); }, swingTo: function (pos) { var s = 1.70158; return (pos -= 1) * pos * ((s + 1) * pos + s) + 1; }, bounce: function (pos) { if (pos < (1 / 2.75)) { return (7.5625 * pos * pos); } else if (pos < (2 / 2.75)) { return (7.5625 * (pos -= (1.5 / 2.75)) * pos + .75); } else if (pos < (2.5 / 2.75)) { return (7.5625 * (pos -= (2.25 / 2.75)) * pos + .9375); } else { return (7.5625 * (pos -= (2.625 / 2.75)) * pos + .984375); } }, bouncePast: function (pos) { if (pos < (1 / 2.75)) { return (7.5625 * pos * pos); } else if (pos < (2 / 2.75)) { return 2 - (7.5625 * (pos -= (1.5 / 2.75)) * pos + .75); } else if (pos < (2.5 / 2.75)) { return 2 - (7.5625 * (pos -= (2.25 / 2.75)) * pos + .9375); } else { return 2 - (7.5625 * (pos -= (2.625 / 2.75)) * pos + .984375); } }, easeFromTo: function (pos) { if ((pos /= 0.5) < 1) return 0.5 * Math.pow(pos, 4); return -0.5 * ((pos -= 2) * Math.pow(pos, 3) - 2); }, easeFrom: function (pos) { return Math.pow(pos, 4); }, easeTo: function (pos) { return Math.pow(pos, 0.25); }, linear: function (pos) { return pos; }, sinusoidal: function (pos) { return (-Math.cos(pos * Math.PI) / 2) + 0.5; }, reverse: function (pos) { return 1 - pos; }, mirror: function (pos, transition) { transition = transition || this.sinusoidal; if (pos < 0.5) return transition(pos * 2); else return transition(1 - (pos - 0.5) * 2); }, flicker: function (pos) { var pos = pos + (Math.random() - 0.5) / 5; return this.sinusoidal(pos < 0 ? 0 : pos > 1 ? 1 : pos); }, wobble: function (pos) { return (-Math.cos(pos * Math.PI * (9 * pos)) / 2) + 0.5; }, pulse: function (pos, pulses) { return (-Math.cos((pos * ((pulses || 5) - .5) * 2) * Math.PI) / 2) + .5; }, blink: function (pos, blinks) { return Math.round(pos * (blinks || 5)) % 2; }, spring: function (pos) { return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6)); }, none: function (pos) { return 0; }, full: function (pos) { return 1; } }; var CanvasSource = (function () { function CanvasSource() { this.isIdle = false; this.canvas = document.createElement('canvas'); this.context = this.canvas.getContext('2d'); this.width = this.canvas.width; this.height = this.canvas.height; } CanvasSource.create = function () { var instance; var instanceList = this.instanceList; for (var i = 0; instance = instanceList[i]; i++) { if (instance.isIdle) { instance.isIdle = false; this.activeCount += 1; return instance; } } if (!instance) { instance = new CanvasSource(); instanceList.push(instance); } this.activeCount += 1; return instance; }; CanvasSource.prototype.setSize = function (width, height) { this.canvas.width = this.width = width; this.canvas.height = this.height = height; }; CanvasSource.prototype.clear = function () { this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); }; CanvasSource.prototype.recycle = function () { CanvasSource.activeCount -= 1; this.setSize(0, 0); this.isIdle = true; }; return CanvasSource; }()); CanvasSource.instanceList = []; CanvasSource.activeCount = 0; /** * Sprite texture */ var Texture = (function () { function Texture(source, sourceRect, textureRect) { this._readyCallbacks = []; this._gridSourceCache = {}; this._gridSourceCount = 0; /** * Texture resource loading state */ this.ready = false; this.width = 0; this.height = 0; var name = getCacheKey(source, sourceRect, textureRect); if (Texture.textureCache[name]) { return Texture.textureCache[name]; } if (typeof source === 'string') { this._createByPath(source, sourceRect, textureRect, Texture.retryTimes); } else if ((source instanceof HTMLImageElement) || (source instanceof HTMLCanvasElement)) { this._createByImage(source, sourceRect, textureRect); } else { throw new Error("Invalid texture source"); } if (name) { this.name = name; Texture.textureCache[name] = this; } } Texture.create = function (source, sourceRect, textureRect) { var name = getCacheKey(source, sourceRect, textureRect); if (name && this.textureCache[name]) { return this.textureCache[name]; } return new Texture(source, sourceRect, textureRect); }; Texture.getByName = function (name) { return this.textureCache[name]; }; /** * 缓存Texture实例 */ Texture.cacheAs = function (name, texture) { this.textureCache[name] = texture; }; /** * 清除缓存 */ Texture.clearCache = function (name) { if (name != null) { var texture = this.textureCache[name]; if (texture) { texture.clearCacheGridSources(); } delete this.textureCache[name]; } else { this.textureCache = {}; } }; Texture.prototype.onReady = function (callback) { if (this.ready) { callback({ width: this.width, height: this.height }); } else { this._readyCallbacks.push(callback); } }; Texture.prototype.createGridSource = function (w, h, sx, sy, sw, sh, grid) { w = Math.ceil(w); h = Math.ceil(h); var cacheKey = [w, h, sx, sy, sw, sh, grid].join(':'); if (this._gridSourceCache[cacheKey]) { return this._gridSourceCache[cacheKey].canvas; } var top = grid[0], right = grid[1], bottom = grid[2], left = grid[3], repeat = grid[4]; var grids = [ { x: 0, y: 0, w: left, h: top, sx: sx, sy: sy, sw: left, sh: top }, { x: w - right, y: 0, w: right, h: top, sx: sx + sw - right, sy: sy, sw: right, sh: top }, { x: 0, y: h - bottom, w: left, h: bottom, sx: sx, sy: sy + sh - bottom, sw: left, sh: bottom }, { x: w - right, y: h - bottom, w: right, h: bottom, sx: sx + sw - right, sy: sh - bottom + sy, sw: right, sh: bottom }, { x: left, y: 0, w: w - left - right, h: top, sx: sx + left, sy: sy, sw: sw - left - right, sh: top }, { x: left, y: h - bottom, w: w - left - right, h: bottom, sx: sx + left, sy: sh - bottom + sy, sw: sw - left - right, sh: bottom }, { x: 0, y: top, w: left, h: h - top - bottom, sx: sx, sy: top, sw: left, sh: sh - top - bottom }, { x: w - right, y: top, w: right, h: h - top - bottom, sx: sx + sw - right, sy: top, sw: right, sh: sh - top - bottom }, ]; var centerGrid = { x: left, y: top, w: w - left - right, h: h - top - bottom, sx: sx + left, sy: top, sw: sw - left - right, sh: sh - top - bottom }; var source = CanvasSource.create(); var canvas = source.canvas; var context = source.context; source.setSize(w, h); for (var i = 0, l = grids.length; i < l; i++) { var g = grids[i]; if (g.w && g.h) { context.drawImage(this.source, g.sx, g.sy, g.sw, g.sh, Math.ceil(g.x), Math.ceil(g.y), Math.ceil(g.w), Math.ceil(g.h)); } } if (repeat) { var cvs_1 = getRepeatPatternSource(this.source, { x: centerGrid.sx, y: centerGrid.sy, width: centerGrid.sw, height: centerGrid.sh, }, centerGrid.sw, centerGrid.sh); var pattern = context.createPattern(cvs_1, "repeat"); context.fillStyle = pattern; context.fillRect(Math.ceil(centerGrid.x), Math.ceil(centerGrid.y), Math.ceil(centerGrid.w), Math.ceil(centerGrid.h)); } else if (centerGrid.w && centerGrid.h) { context.drawImage(this.source, centerGrid.sx, centerGrid.sy, centerGrid.sw, centerGrid.sh, Math.ceil(centerGrid.x), Math.ceil(centerGrid.y), Math.ceil(centerGrid.w), Math.ceil(centerGrid.h)); } this._gridSourceCache[cacheKey] = source; this._gridSourceCount += 1; return canvas; }; Texture.prototype.clearCacheGridSources = function () { for (var k in this._gridSourceCache) { this._gridSourceCache[k].recycle(); } this._gridSourceCache = {}; this._gridSourceCount = 0; }; Texture.prototype.destroy = function () { if (this.canvasSource) { this.canvasSource.recycle(); } this.clearCacheGridSources(); this._readyCallbacks.length = 0; this.source = this.canvasSource = null; }; Texture.prototype._createByPath = function (path, sourceRect, textureRect, retryTimes) { var _this = this; if (Texture.loadedImages[path]) { return this._onImageLoaded(img, path, sourceRect, textureRect); } var img = Texture.loadingImages[path] || new Image(); var onLoad = function () { _this._onImageLoaded(img, path, sourceRect, textureRect); img.removeEventListener("load", onLoad); img.removeEventListener("error", onError); }; var onError = function () { img.removeEventListener("load", onLoad); img.removeEventListener("error", onError); delete Texture.loadingImages[path]; img = null; if (retryTimes) { _this._createByPath(path, sourceRect, textureRect, --retryTimes); } else { _this._readyCallbacks.length = 0; if (_this.name != null) { delete Texture.textureCache[_this.name]; } } console.warn("canvas2d: Texture creating fail, error loading source \"" + path + "\"."); }; img.addEventListener('load', onLoad); img.addEventListener('error', onError); var src = Texture.version != null ? path + '?v=' + Texture.version : path; if (!Texture.loadingImages[path]) { img.crossOrigin = 'anonymous'; Texture.loadingImages[path] = img; img.src = src; } }; Texture.prototype._onImageLoaded = function (img, path, sourceRect, textureRect) { this._createByImage(img, sourceRect, textureRect); Texture.loadedImages[path] = img; delete Texture.loadingImages[path]; if (this._readyCallbacks.length) { var size = { width: this.width, height: this.height }; for (var i = 0, callback = void 0; callback = this._readyCallbacks[i]; i++) { callback(size); } this._readyCallbacks.length = 0; } img = null; }; Texture.prototype._createByImage = function (image, sourceRect, textureRect) { var source; if (!sourceRect && !textureRect) { source = image; } else { if (!sourceRect) { sourceRect = { x: 0, y: 0, width: image.width, height: image.height }; } if (!textureRect) { textureRect = { x: 0, y: 0, width: sourceRect.width, height: sourceRect.height, }; } // source = createCanvas(image, sourceRect, textureRect); var canvasSource = this.canvasSource = CanvasSource.create(); canvasSource.setSize(textureRect.width, textureRect.height); canvasSource.context.drawImage(image, sourceRect.x, sourceRect.y, sourceRect.width, sourceRect.height, textureRect.x, textureRect.y, sourceRect.width, sourceRect.height); source = canvasSource.canvas; } this.width = source.width; this.height = source.height; this.source = source; this.ready = true; }; return Texture; }()); Texture.textureCache = {}; Texture.loadingImages = {}; Texture.loadedImages = {}; Texture.retryTimes = 2; function getCacheKey(source, sourceRect, textureRect) { var isStr = typeof source === 'string'; if (!isStr && !source.src) { return null; } var src = isStr ? source : source.src; var sourceRectStr = sourceRect ? [sourceRect.x, sourceRect.y, sourceRect.width, sourceRect.height].join(',') : ''; var textureRectStr = textureRect ? [textureRect.x, textureRect.y, textureRect.width, textureRect.height].join(',') : ''; return src + sourceRectStr + textureRectStr; } // function createCanvas(image: any, sourceRect: Rect, textureRect: Rect): HTMLCanvasElement { // var canvas: HTMLCanvasElement = document.createElement("canvas"); // var context: CanvasRenderingContext2D = canvas.getContext('2d'); // canvas.width = textureRect.width; // canvas.height = textureRect.height; // context.drawImage( // image, sourceRect.x, sourceRect.y, sourceRect.width, sourceRect.height, // textureRect.x, textureRect.y, sourceRect.width, sourceRect.height); // return canvas; // } var cvs; var ctx; function getRepeatPatternSource(source, sourceRect, canvasWidth, canvasHeight) { if (!cvs) { cvs = document.createElement("canvas"); ctx = cvs.getContext("2d"); } cvs.width = canvasWidth; cvs.height = canvasHeight; ctx.drawImage(source, sourceRect.x, sourceRect.y, sourceRect.width, sourceRect.height, 0, 0, sourceRect.width, sourceRect.height); return cvs; } /*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ /* global Reflect, Promise */ var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; function __extends(d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } var __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; }; function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) t[p[i]] = s[p[i]]; return t; } function __values(o) { var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; if (m) return m.call(o); return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; } function __read(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } function __asyncValues(o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); } var BaseAction = (function () { function BaseAction() { this.immediate = false; this.done = false; } return BaseAction; }()); var Delay = (function (_super) { __extends(Delay, _super); function Delay(duration) { var _this = _super.call(this) || this; _this.elapsed = 0; _this.duration = duration; return _this; } Delay.prototype.step = function (deltaTime) { this.elapsed += deltaTime; if (this.elapsed >= this.duration) { this.done = true; } }; Delay.prototype.end = function () { }; Delay.prototype.reset = function () { this.elapsed = 0; this.done = false; }; Delay.prototype.reverse = function () { this.done = false; this.elapsed = 0; }; Delay.prototype.destroy = function () { }; return Delay; }(BaseAction)); var Callback = (function (_super) { __extends(Callback, _super); function Callback(func) { var _this = _super.call(this) || this; _this.immediate = true; _this.func = func; return _this; } Callback.prototype.step = function () { this.func.call(null); this.end(); }; Callback.prototype.end = function () { this.func = null; this.done = true; }; Callback.prototype.reset = function () { this.done = false; }; Callback.prototype.reverse = function () { this.done = false; }; Callback.prototype.destroy = function () { this.func = null; }; return Callback; }(BaseAction)); var Animation = (function (_super) { __extends(Animation, _super); function Animation(frameList, frameRate, repetitions) { var _this = _super.call(this) || this; _this.elapsed = 0; _this.count = 0; _this.frameIndex = 0; _this.frameList = frameList; _this.repetitions = repetitions; _this.interval = 1 / frameRate; return _this; } Animation.prototype.step = function (deltaTime, target) { this.elapsed += deltaTime; if (this.elapsed >= this.interval) { target.texture = this.frameList[this.frameIndex++]; if (this.frameIndex === this.frameList.length) { if (this.repetitions == null || ++this.count < this.repetitions) { this.frameIndex = 0; } else { this.end(); } } this.elapsed = 0; } }; Animation.prototype.end = function () { this.done = true; }; Animation.prototype.reset = function () { this.done = false; this.frameIndex = 0; this.elapsed = 0; this.count = 0; }; Animation.prototype.reverse = function () { this.done = false; this.frameIndex = 0; this.elapsed = 0; this.count = 0; this.frameList = this.frameList.slice().reverse(); }; Animation.prototype.destroy = function () { this.frameList = null; }; return Animation; }(BaseAction)); var Key = 'canvas2d.uid'; var counter = 0; var cachedColor = {}; function uid(target) { if (typeof target[Key] === 'undefined') { Object.defineProperty(target, Key, { value: counter++ }); } return target[Key]; } function addArrayItem(array, item) { if (array.indexOf(item) === -1) { array.push(item); } } function removeArrayItem(array, item) { var index = array.indexOf(item); if (index > -1) { array.splice(index, 1); } } function convertColor(color) { if (typeof color === 'string') { return color; } if (cachedColor[color]) { return cachedColor[color]; } if (typeof color === 'number') { var result = color.toString(16); if (result.length < 3) { while (result.length < 3) { result = '0' + result; } } else if (result.length > 3 && result.length < 6) { while (result.length < 6) { result = '0' + result; } } if (result.length !== 3 && result.length !== 6) { throw new Error("canvas2d: Invalid hex color \"0x" + result + "\"."); } result = cachedColor[color] = '#' + result; return result; } } function hexToRgb(hex) { // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; hex = hex.replace(shorthandRegex, function (m, r, g, b) { return r + r + g + g + b + b; }); var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); return result ? { r: parseInt(result[1], 16), g: parseInt(result[2], 16), b: parseInt(result[3], 16) } : null; } function rgbToHex(r, g, b) { return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); } var ActionListener = (function () { function ActionListener(actions) { this._resolved = false; this._callbacks = {}; this._actions = actions; } ActionListener.prototype.all = function (callback) { if (this._resolved) { callback(); } else { if (!this._callbacks.all) { this._callbacks.all = []; } addArrayItem(this._callbacks.all, callback); } return this; }; ActionListener.prototype.any = function (callback) { if (this._resolved) { callback(); } else { if (!this._callbacks.any) { this._callbacks.any = []; } addArrayItem(this._callbacks.any, callback); } return this; }; ActionListener.prototype._step = function () { var allDone = true; var anyDone = false; for (var i = 0, action = void 0; action = this._actions[i]; i++) { if (action.isDone()) { anyDone = true; } else { allDone = false; } } if (anyDone && this._callbacks.any) { for (var i = 0, callback = void 0; callback = this._callbacks.any[i]; i++) { callback(); } this._callbacks.any = null; } if (allDone && this._callbacks.all) { for (var i = 0, callback = void 0; callback = this._callbacks.all[i]; i++) { callback(); } Action.removeListener(this); this._resolved = true; } }; return ActionListener; }()); var Transition = (function (_super) { __extends(Transition, _super); function Transition(options, duration, isTransitionBy) { var _this = _super.call(this) || this; _this.elapsed = 0; _this.options = []; _this.deltaValue = {}; _this.duration = duration; _this.isTransitionBy = isTransitionBy; if (isTransitionBy) { _this._initAsTransitionBy(options); } else { _this._initAsTransitionTo(options); } return _this; } Transition.setDefaultEasingFunc = function (func) { this.defaultEasingFunc = func; }; Transition.prototype._initAsTransitionTo = function (options) { for (var name in options) { var info = options[name]; var easing = void 0; var dest = void 0; if (typeof info === 'number') { dest = info; } else { easing = info.easing; dest = info.dest; } this.options.push({ name: name, dest: dest, easing: easing }); } }; Transition.prototype._initAsTransitionBy = function (options) { var deltaValue = this.deltaValue; for (var name in options) { var info = options[name]; var easing = void 0; var dest = void 0; if (typeof info === 'number') { deltaValue[name] = info; } else { easing = info.easing; deltaValue[name] = info.value; } this.options.push({ name: name, dest: dest, easing: easing }); } }; Transition.prototype._initBeginValue = function (target) { var beginValue = this.beginValue = {}; var deltaValue = this.deltaValue; if (this.isTransitionBy) { for (var i = 0, option = void 0; option = this.options[i]; i++) { beginValue[option.name] = target[option.name]; option.dest = target[option.name] + deltaValue[option.name]; } } else { for (var i = 0, option = void 0; option = this.options[i]; i++) { beginValue[option.name] = target[option.name]; deltaValue[option.name] = option.dest - target[option.name]; } } }; Transition.prototype.step = function (deltaTime, target) { this.elapsed += deltaTime; if (this.beginValue == null) { this._initBeginValue(target); } if (this.elapsed >= this.duration) { return this.end(target); } var percent = this.elapsed / this.duration; var beginValue = this.beginValue; var deltaValue = this.deltaValue; for (var i = 0, option = void 0; option = this.options[i]; i++) { var name = option.name, dest = option.dest, easing = option.easing; easing = easing || Transition.defaultEasingFunc; target[name] = beginValue[name] + (easing(percent) * deltaValue[name]); } }; Transition.prototype.end = function (target) { for (var i = 0, option = void 0; option = this.options[i]; i++) { target[option.name] = option.dest; } this.done = true; }; Transition.prototype.destroy = function () { this.beginValue = null; this.deltaValue = null; this.options = null; }; Transition.prototype.reset = function () { this.done = false; this.elapsed = 0; }; Transition.prototype.reverse = function () { this.done = false; this.elapsed = 0; var _a = this, options = _a.options, beginValue = _a.beginValue, deltaValue = _a.deltaValue; for (var i = 0, option = void 0; option = options[i]; i++) { var dest = beginValue[option.name]; beginValue[option.name] = option.dest; deltaValue[option.name] = -deltaValue[option.name]; option.dest = dest; } }; return Transition; }(BaseAction)); Transition.defaultEasingFunc = Tween.easeInOutQuad; (function (ActionType) { ActionType[ActionType["TO"] = 0] = "TO"; ActionType[ActionType["BY"] = 1] = "BY"; ActionType[ActionType["ANIM"] = 2] = "ANIM"; ActionType[ActionType["WAIT"] = 3] = "WAIT"; ActionType[ActionType["CALLBACK"] = 4] = "CALLBACK"; })(exports.ActionType || (exports.ActionType = {})); (function (ActionRepeatMode) { ActionRepeatMode[ActionRepeatMode["NONE"] = 0] = "NONE"; ActionRepeatMode[ActionRepeatMode["REPEAT"] = 1] = "REPEAT"; ActionRepeatMode[ActionRepeatMode["REVERSE_REPEAT"] = 2] = "REVERSE_REPEAT"; })(exports.ActionRepeatMode || (exports.ActionRepeatMode = {})); var Action = (function () { function Action(target, tag) { this._queue = []; this._currentIndex = 0; this._done = false; this._repeatMode = exports.ActionRepeatMode.NONE; /** * Action running state */ this.isRunning = false; this.target = target; this.tag = tag; } Object.defineProperty(Action, "scheduleCostTime", { get: function () { return this._scheduleCostTime; }, enumerable: true, configurable: true }); /** * Stop action by target */ Action.stop = function (target, tag) { var list = Action._actionList.slice(); for (var i = 0, action = void 0; action = list[i]; i++) { if (action.target === target) { if (tag == null || action.tag == tag) { action.stop(); } } } }; /** * Listen a action list, when all actions are done then publish to listener */ Action.listen = function (actions) { var listener = new ActionListener(actions); Action._listenerList.push(listener); return listener; }; Action.removeListener = function (listener) { removeArrayItem(this._listenerList, this); }; Action.schedule = function (deltaTime) { var startTime = Date.now(); var actionList = Action._actionList.slice(); var listenerList = Action._listenerList.slice(); for (var i = 0, action = void 0; action = actionList[i]; i++) { action._step(deltaTime); if (action._done) { removeArrayItem(Action._actionList, action); } } for (var i = 0, listener = void 0; listener = listenerList[i]; i++) { listener._step(); } Action._scheduleCostTime = Date.now() - startTime; }; Action.prototype.isDone = function () { return this._done; }; Action.prototype.setRepeatMode = function (mode) { this._repeatMode = mode; return this; }; Object.defineProperty(Action.prototype, "repeatMode", { get: function () { return this._repeatMode; }, set: function (mode) { this._repeatMode = mode; }, enumerable: true, configurable: true }); Action.prototype.queue = function (actions) { for (var i = 0, action = void 0; action = actions[i]; i++) { switch (action.type) { case exports.ActionType.ANIM: this.animate(action.frameList, action.frameRate, action.repetitions); break; case exports.ActionType.BY: this.by(action.options, action.duration); break; case exports.ActionType.TO: this.to(action.options, action.duration); break; case exports.ActionType.WAIT: this.wait(action.duration); break; case exports.ActionType.CALLBACK: this.then(action.callback); break; } } return this; }; /** * Add a callback, it will exec after previous action is done. */ Action.prototype.then = function (callback) { this._queue.push(new Callback(callback)); return this; }; /** * Add a delay action. */ Action.prototype.wait = function (time) { this._queue.push(new Delay(time)); return this; }; /** * Add a animation action */ Action.prototype.animate = function (frameList, frameRate, repetitions) { var anim = new Animation(frameList, frameRate, repetitions); this._queue.push(anim); anim.step(anim.interval, this.target); return this; }; /** * TransitionTo action */ Action.prototype.to = function (attrs, duration) { this._queue.push(new Transition(attrs, duration)); return this; }; /** * TransitionBy action */ Action.prototype.by = function (attrs, duration) { this._queue.push(new Transition(attrs, duration, true)); return this; }; /** * Start the action */ Action.prototype.start = function () { if (!this.isRunning) { addArrayItem(Action._actionList, this); this.isRunning = true; } return this; }; /** * Stop the action */ Action.prototype.stop = function () { for (var i = 0, action = void 0; action = this._queue[i]; i++) { action.destroy(); } this._done = true; this.isRunning = false; this._queue.length = 0; removeArrayItem(Action._actionList, this); }; Action.prototype.clear = function () { for (var i = 0, action = void 0; action = this._queue[i]; i++) { action.destroy(); } this._done = false; this.isRunning = false; this._queue.length = 0; this._currentIndex = 0; this._repeatMode = exports.ActionRepeatMode.NONE; removeArrayItem(Action._actionList, this); }; Action.prototype._step = function (deltaTime) { if (!this._queue.length || this._currentIndex >= this._queue.length) { return; } var action = this._queue[this._currentIndex]; action.step(deltaTime, this.target); if (action.done) { this._currentIndex += 1; if (this._currentIndex >= this._queue.length) { this._onAllActionDone(); } else if (action.immediate) { this._step(deltaTime); } } }; Action.prototype._onAllActionDone = function () { switch (this._repeatMode) { case exports.ActionRepeatMode.REPEAT: for (var i = 0, action = void 0; action = this._queue[i]; i++) { action.reset(); } this._currentIndex = 0; break; case exports.ActionRepeatMode.REVERSE_REPEAT: for (var i = 0, action = void 0; action = this._queue[i]; i++) { action.reverse(); } this._currentIndex = 0; break; default: this._done = true; this.isRunning = false; this.target = null; for (var i = 0, action = void 0; action = this._queue[i]; i++) { action.destroy(); } this._queue.length = 0; break; } }; return Action; }()); Action._actionList = []; Action._listenerList = []; Action._scheduleCostTime = 0; var EventEmitter = (function () { function EventEmitter() { } EventEmitter.prototype.addListener = function (type, listener) { if (typeof listener !== 'function') { return this; } var id = uid(this); if (!EventEmitter._eventCache[id]) { EventEmitter._eventCache[id] = {}; } if (!EventEmitter._eventCache[id][type]) { EventEmitter._eventCache[id][type] = []; } var events = EventEmitter._eventCache[id][type]; for (var i = 0, ev = void 0; ev = events[i]; i++) { if (ev.listener === listener && !ev.once) { return this; } } events.push({ listener: listener }); return this; }; EventEmitter.prototype.on = function (type, listener) { return this.addListener(type, listener); }; EventEmitter.prototype.once = function (type, listener) { if (typeof listener !== 'function') { return this; } var id = uid(this); if (!EventEmitter._eventCache[id]) { EventEmitter._eventCache[id] = {}; } if (!EventEmitter._eventCache[id][type]) { EventEmitter._eventCache[id][type] = []; } var events = EventEmitter._eventCache[id][type]; for (var i = 0, ev = void 0; ev = events[i]; i++) { if (ev.listener === listener && ev.once) { return this; } } events.push({ listener: listener, once: true }); return this; }; EventEmitter.prototype.removeListener = function (type, listener) { var cache = EventEmitter._eventCache[uid(this)]; if (cache && cache[type]) { var events = cache[type]; var temp = events.slice(); for (var i = 0, l = temp.length; i < l; i++) { var ev = temp[i]; if (ev.listener === listener) { removeArrayItem(events, ev); } } if (!events.length) { delete cache[type]; } } return this; }; EventEmitter.prototype.removeAllListeners = function (type) { var id = uid(this); var cache = EventEmitter._eventCache[id]; if (cache) { if (type == null) { EventEmitter._eventCache[id] = null; } else { delete cache[type]; } } return this; }; EventEmitter.prototype.hasListener = function (type) { var id = uid(this); var eventCache = EventEmitter._eventCache; if (!eventCache[id] || !eventCache[id][type] || !eventCache[id][type].length) { return false; } return true; }; EventEmitter.prototype.emit = function (type) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } var id = uid(this); var cache = EventEmitter._eventCache[id]; if (cache && cache[type]) { var events = cache[type]; var temp = events.slice(); for (var i = 0, l = temp.length; i < l; i++) { var ev = temp[i]; if (ev) { if (typeof ev.listener === 'function') { ev.listener.apply(this, args); } if (ev.once) { removeArrayItem(events, ev); } } } } return this; }; return EventEmitter; }()); EventEmitter._eventCache = {}; var instance; var ReleasePool = (function () { function ReleasePool() { this._objs = []; } ReleasePool.prototype.add = function (obj) { var _this = this; this._objs.push(obj); if (this._timerId != null) { return; } this._timerId = setTimeout(function () { return _this._release(); }, 0); }; ReleasePool.prototype._release = function () { for (var i = 0, obj = void 0; obj = this._objs[i]; i++) { for (var key in obj) { delete obj[key]; } } this._timerId = null; this._objs.length = 0; }; Object.defineProperty(ReleasePool, "instance", { get: function () { if (!instance) { instance = new ReleasePool(); } return instance; }, enumerable: true, configurable: true }); return ReleasePool; }()); // import { CanvasFrameBuffer } from '../framebuffer/CanvasFrameBuffer'; var RAD_PER_DEG = Math.PI / 180; (function (AlignType) { AlignType[AlignType["TOP"] = 0] = "TOP"; AlignType[AlignType["RIGHT"] = 1] = "RIGHT"; AlignType[AlignType["BOTTOM"] = 2] = "BOTTOM"; AlignType[AlignType["LEFT"] = 3] = "LEFT"; AlignType[AlignType["CENTER"] = 4] = "CENTER"; })(exports.AlignType || (exports.AlignType = {})); (function (BlendMode) { BlendMode[BlendMode["SOURCE_IN"] = 0] = "SOURCE_IN"; BlendMode[BlendMode["SOURCE_OVER"] = 1] = "SOURCE_OVER"; BlendMode[BlendMode["SOURCE_ATOP"] = 2] = "SOURCE_ATOP"; BlendMode[BlendMode["SOURCE_OUT"] = 3] = "SOURCE_OUT"; BlendMode[BlendMode["DESTINATION_OVER"] = 4] = "DESTINATION_OVER"; BlendMode[BlendMode["DESTINATION_IN"] = 5] = "DESTINATION_IN"; BlendMode[BlendMode["DESTINATION_OUT"] = 6] = "DESTINATION_OUT"; BlendMode[BlendMode["DESTINATION_ATOP"] = 7] = "DESTINATION_ATOP"; BlendMode[BlendMode["LIGHTER"] = 8] = "LIGHTER"; BlendMode[BlendMode["COPY"] = 9] = "COPY"; BlendMode[BlendMode["XOR"] = 10] = "XOR"; })(exports.BlendMode || (exports.BlendMode = {})); var BlendModeStrings = (_a = {}, _a[exports.BlendMode.SOURCE_IN] = "source-in", _a[exports.BlendMode.SOURCE_OVER] = "source-over", _a[exports.BlendMode.SOURCE_ATOP] = "source-atop", _a[exports.BlendMode.SOURCE_OUT] = "source-out", _a[exports.BlendMode.DESTINATION_OVER] = "destination-over", _a[exports.BlendMode.DESTINATION_IN] = "destination-in", _a[exports.BlendMode.DESTINATION_OUT] = "destination-out", _a[exports.BlendMode.DESTINATION_ATOP] = "destination-atop", _a[exports.BlendMode.LIGHTER] = "lighter", _a[exports.BlendMode.COPY] = "copy", _a[exports.BlendMode.XOR] = "xor", _a); var Sprite = (function (_super) { __extends(Sprite, _super); function Sprite(props) { var _this = _super.call(this) || this; _this._width = 0; _this._height = 0; _this._originX = 0.5; _this._originY = 0.5; _this._rotation = 0; _this._rotationInRadians = 0; _this._originPixelX = 0; _this._originPixelY = 0; _this.x = 0; _this.y = 0; _this.scaleX = 1; _this.scaleY = 1; _this.radius = 0; _this.opacity = 1; _this.sourceX = 0; _this.sourceY = 0; _this.autoResize = true; _this.flippedX = false; _this.flippedY = false; _this.visible = true; _this.clipOverflow = false; _this.touchEnabled = true; _this.mouseEnabled = true; _this.id = uid(_this); // this._canvasFrameBuffer = CanvasFrameBuffer.create(this.