UNPKG

convex-pixel

Version:

The library for creating pseudo 3d interactive scenes based on webgl

1,770 lines (1,662 loc) 2.02 MB
import url, { parse } from 'url'; import { __extends } from 'tslib'; /** * Vector2D * Uses pooling for speed performance */ class Vector2D { constructor(x = 0, y = 0) { this.x = x; this.y = y; } static get poolCount() { return this._pool.length; } static new(x = 0, y = 0) { if (Vector2D._pool.length > 0) { const vect = Vector2D._pool.pop(); if (vect) { return vect.set(x, y); } } return new Vector2D(x, y); } set(x, y) { this.x = x; this.y = y; return this; } /** * @deprecated */ move(x, y) { this.x = x; this.y = y; return this; } from(vector) { this.x = vector.x; this.y = vector.y; return this; } free() { Vector2D._pool.push(this); } valueOf() { return { x: this.x, y: this.y }; } clone() { return Vector2D.new(this.x, this.y); } add(vector, isClone = true) { if (!isClone) { this.x += vector.x; this.y += vector.y; return this; } return Vector2D.new(this.x + vector.x, this.y + vector.y); } deduct(vector, isClone = true) { if (!isClone) { this.x -= vector.x; this.y -= vector.y; return this; } return Vector2D.new(this.x - vector.x, this.y - vector.y); } measureDistance(vector, xAxis = true, yAxis = true) { const a = Math.max(this.x, vector.x) - Math.min(this.x, vector.x); const b = Math.max(this.y, vector.y) - Math.min(this.y, vector.y); if (xAxis && yAxis) return Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2)); else if (xAxis) return a; else if (yAxis) return b; return 0; } comparePoint(vector) { return this.x === vector.x && this.y === vector.y; } empty() { this.x = this.y = 0; } } Vector2D._pool = new Array(); // tslint:disable-next-line: max-classes-per-file class Vector3D { constructor(x = 0, y = 0, z = 0) { this.x = x; this.y = y; this.z = z; } static get poolCount() { return this._pool.length; } static new(x = 0, y = 0, z = 0) { if (Vector3D._pool.length > 0) { const vect = Vector3D._pool.pop(); if (vect) { return vect.set(x, y, z); } } return new Vector3D(x, y, z); } set(x, y, z) { this.x = x; this.y = y; this.z = z; return this; } free() { Vector3D._pool.push(this); } valueOf() { return { x: this.x, y: this.y, z: this.z }; } } Vector3D._pool = new Array(); // tslint:disable-next-line: max-classes-per-file class Vector4D { constructor(x = 0, y = 0, z = 0, t = 0) { this.x = x; this.y = y; this.z = z; this.t = t; } static get poolCount() { return this._pool.length; } static new(x = 0, y = 0, z = 0, t = 0) { if (Vector4D._pool.length > 0) { const vect = Vector4D._pool.pop(); if (vect) { return vect.set(x, y, z, t); } } return new Vector4D(x, y, z, t); } set(x, y, z, t) { this.x = x; this.y = y; this.z = z; this.t = t; return this; } free() { Vector4D._pool.push(this); } valueOf() { return { x: this.x, y: this.y, z: this.z, t: this.t }; } } Vector4D._pool = new Array(); var RatioFitTypes; (function (RatioFitTypes) { RatioFitTypes[RatioFitTypes["NONE"] = 0] = "NONE"; RatioFitTypes[RatioFitTypes["FILL"] = 1] = "FILL"; RatioFitTypes[RatioFitTypes["SHOW_ALL"] = 2] = "SHOW_ALL"; RatioFitTypes[RatioFitTypes["O_FILL"] = 3] = "O_FILL"; RatioFitTypes[RatioFitTypes["O_SHOW_ALL"] = 4] = "O_SHOW_ALL"; })(RatioFitTypes || (RatioFitTypes = {})); const getRatio = (width1, height1, width2, height2, type = RatioFitTypes.NONE) => { let ratioX; let ratioY; switch (type) { case RatioFitTypes.SHOW_ALL: ratioX = width2 / width1; ratioY = height2 / height1; return Math.min(ratioX, ratioY); case RatioFitTypes.FILL: ratioX = width2 / width1; ratioY = height2 / height1; return Math.max(ratioX, ratioY); case RatioFitTypes.O_SHOW_ALL: ratioX = width2 < width1 ? width2 / width1 : width1 / width2; ratioY = height2 < height1 ? height2 / height1 : height1 / height2; return Math.min(ratioX, ratioY); case RatioFitTypes.O_FILL: ratioX = width2 < width1 ? width2 / width1 : width1 / width2; ratioY = height2 < height1 ? height2 / height1 : height1 / height2; return Math.min(ratioX, ratioY); case RatioFitTypes.NONE: default: return 1; } }; const getAbsolutePosition = (object, options, iteration = 0) => { let _to; if (options && options.to) { _to = options.to; } if (!object) { return Vector4D.new(); } const result = Vector4D.new(object.x, object.y, object.scale.x, object.scale.y); if (object.parent) { const isVect = _to && object.parent instanceof _to; // if (!isVect) { const parentPos = getAbsolutePosition(object.parent, options, iteration++); result.x += parentPos.x || 0; result.y += parentPos.y || 0; result.z *= parentPos.z || 1; result.t *= parentPos.t || 1; parentPos.free(); // } } return result; }; var display = /*#__PURE__*/Object.freeze({ get RatioFitTypes () { return RatioFitTypes; }, getRatio: getRatio, getAbsolutePosition: getAbsolutePosition }); const DEFAULT_INTERVAL = 500; var SonarEventTypes; (function (SonarEventTypes) { SonarEventTypes["CHANGE"] = "change"; SonarEventTypes["LOST_CONTEXT"] = "lost-context"; })(SonarEventTypes || (SonarEventTypes = {})); class Sonar { constructor(detectionInterval = DEFAULT_INTERVAL) { this._poolDetectors = new Array(); this._timerId = undefined; this._tickHandler = () => { for (let i = 0, l = this._poolDetectors.length; i < l; i++) { this._poolDetectors[i].detectChanges(); } }; this._interval = detectionInterval; } static create() { if (!Sonar.instance) { Sonar.instance = new Sonar(); } return Sonar.instance; } run() { this._timerId = setInterval(this._tickHandler, this._interval); } stop() { if (this._timerId) { clearInterval(this._timerId); this._timerId = undefined; } } add(detector) { if (this._poolDetectors.indexOf(detector) > -1) return; // throw new Error('The detector is already added to pool'); this._poolDetectors.push(detector); } remove(detector) { const index = this._poolDetectors.indexOf(detector); if (index === -1) return; // throw new Error('The detector is already removed'); this._poolDetectors.splice(index, 1); } removeAll() { while (this._poolDetectors.length > 0) { const detector = this._poolDetectors.pop(); if (detector) { detector.destroy(); } } } destroy() { this.stop(); this.removeAll(); this._poolDetectors.length = 0; } } var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; function unwrapExports (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x.default : x; } function createCommonjsModule(fn, module) { return module = { exports: {} }, fn(module, module.exports), module.exports; } var promise = createCommonjsModule(function (module, exports) { (function(global){ // // Check for native Promise and it has correct interface // var NativePromise = global['Promise']; var nativePromiseSupported = NativePromise && // Some of these methods are missing from // Firefox/Chrome experimental implementations 'resolve' in NativePromise && 'reject' in NativePromise && 'all' in NativePromise && 'race' in NativePromise && // Older version of the spec had a resolver object // as the arg rather than a function (function(){ var resolve; new NativePromise(function(r){ resolve = r; }); return typeof resolve === 'function'; })(); // // export if necessary // if (exports) { // node.js exports.Promise = nativePromiseSupported ? NativePromise : Promise; exports.Polyfill = Promise; } else { // AMD { // in browser add to global if (!nativePromiseSupported) global['Promise'] = Promise; } } // // Polyfill // var PENDING = 'pending'; var SEALED = 'sealed'; var FULFILLED = 'fulfilled'; var REJECTED = 'rejected'; var NOOP = function(){}; function isArray(value) { return Object.prototype.toString.call(value) === '[object Array]'; } // async calls var asyncSetTimer = typeof setImmediate !== 'undefined' ? setImmediate : setTimeout; var asyncQueue = []; var asyncTimer; function asyncFlush(){ // run promise callbacks for (var i = 0; i < asyncQueue.length; i++) asyncQueue[i][0](asyncQueue[i][1]); // reset async asyncQueue asyncQueue = []; asyncTimer = false; } function asyncCall(callback, arg){ asyncQueue.push([callback, arg]); if (!asyncTimer) { asyncTimer = true; asyncSetTimer(asyncFlush, 0); } } function invokeResolver(resolver, promise) { function resolvePromise(value) { resolve(promise, value); } function rejectPromise(reason) { reject(promise, reason); } try { resolver(resolvePromise, rejectPromise); } catch(e) { rejectPromise(e); } } function invokeCallback(subscriber){ var owner = subscriber.owner; var settled = owner.state_; var value = owner.data_; var callback = subscriber[settled]; var promise = subscriber.then; if (typeof callback === 'function') { settled = FULFILLED; try { value = callback(value); } catch(e) { reject(promise, e); } } if (!handleThenable(promise, value)) { if (settled === FULFILLED) resolve(promise, value); if (settled === REJECTED) reject(promise, value); } } function handleThenable(promise, value) { var resolved; try { if (promise === value) throw new TypeError('A promises callback cannot return that same promise.'); if (value && (typeof value === 'function' || typeof value === 'object')) { var then = value.then; // then should be retrived only once if (typeof then === 'function') { then.call(value, function(val){ if (!resolved) { resolved = true; if (value !== val) resolve(promise, val); else fulfill(promise, val); } }, function(reason){ if (!resolved) { resolved = true; reject(promise, reason); } }); return true; } } } catch (e) { if (!resolved) reject(promise, e); return true; } return false; } function resolve(promise, value){ if (promise === value || !handleThenable(promise, value)) fulfill(promise, value); } function fulfill(promise, value){ if (promise.state_ === PENDING) { promise.state_ = SEALED; promise.data_ = value; asyncCall(publishFulfillment, promise); } } function reject(promise, reason){ if (promise.state_ === PENDING) { promise.state_ = SEALED; promise.data_ = reason; asyncCall(publishRejection, promise); } } function publish(promise) { var callbacks = promise.then_; promise.then_ = undefined; for (var i = 0; i < callbacks.length; i++) { invokeCallback(callbacks[i]); } } function publishFulfillment(promise){ promise.state_ = FULFILLED; publish(promise); } function publishRejection(promise){ promise.state_ = REJECTED; publish(promise); } /** * @class */ function Promise(resolver){ if (typeof resolver !== 'function') throw new TypeError('Promise constructor takes a function argument'); if (this instanceof Promise === false) throw new TypeError('Failed to construct \'Promise\': Please use the \'new\' operator, this object constructor cannot be called as a function.'); this.then_ = []; invokeResolver(resolver, this); } Promise.prototype = { constructor: Promise, state_: PENDING, then_: null, data_: undefined, then: function(onFulfillment, onRejection){ var subscriber = { owner: this, then: new this.constructor(NOOP), fulfilled: onFulfillment, rejected: onRejection }; if (this.state_ === FULFILLED || this.state_ === REJECTED) { // already resolved, call callback async asyncCall(invokeCallback, subscriber); } else { // subscribe this.then_.push(subscriber); } return subscriber.then; }, 'catch': function(onRejection) { return this.then(null, onRejection); } }; Promise.all = function(promises){ var Class = this; if (!isArray(promises)) throw new TypeError('You must pass an array to Promise.all().'); return new Class(function(resolve, reject){ var results = []; var remaining = 0; function resolver(index){ remaining++; return function(value){ results[index] = value; if (!--remaining) resolve(results); }; } for (var i = 0, promise; i < promises.length; i++) { promise = promises[i]; if (promise && typeof promise.then === 'function') promise.then(resolver(i), reject); else results[i] = promise; } if (!remaining) resolve(results); }); }; Promise.race = function(promises){ var Class = this; if (!isArray(promises)) throw new TypeError('You must pass an array to Promise.race().'); return new Class(function(resolve, reject) { for (var i = 0, promise; i < promises.length; i++) { promise = promises[i]; if (promise && typeof promise.then === 'function') promise.then(resolve, reject); else resolve(promise); } }); }; Promise.resolve = function(value){ var Class = this; if (value && typeof value === 'object' && value.constructor === Class) return value; return new Class(function(resolve){ resolve(value); }); }; Promise.reject = function(reason){ var Class = this; return new Class(function(resolve, reject){ reject(reason); }); }; })(typeof window != 'undefined' ? window : typeof commonjsGlobal != 'undefined' ? commonjsGlobal : typeof self != 'undefined' ? self : commonjsGlobal); }); var promise_1 = promise.Promise; var promise_2 = promise.Polyfill; /* object-assign (c) Sindre Sorhus @license MIT */ /* eslint-disable no-unused-vars */ var getOwnPropertySymbols = Object.getOwnPropertySymbols; var hasOwnProperty = Object.prototype.hasOwnProperty; var propIsEnumerable = Object.prototype.propertyIsEnumerable; function toObject(val) { if (val === null || val === undefined) { throw new TypeError('Object.assign cannot be called with null or undefined'); } return Object(val); } function shouldUseNative() { try { if (!Object.assign) { return false; } // Detect buggy property enumeration order in older V8 versions. // https://bugs.chromium.org/p/v8/issues/detail?id=4118 var test1 = new String('abc'); // eslint-disable-line no-new-wrappers test1[5] = 'de'; if (Object.getOwnPropertyNames(test1)[0] === '5') { return false; } // https://bugs.chromium.org/p/v8/issues/detail?id=3056 var test2 = {}; for (var i = 0; i < 10; i++) { test2['_' + String.fromCharCode(i)] = i; } var order2 = Object.getOwnPropertyNames(test2).map(function (n) { return test2[n]; }); if (order2.join('') !== '0123456789') { return false; } // https://bugs.chromium.org/p/v8/issues/detail?id=3056 var test3 = {}; 'abcdefghijklmnopqrst'.split('').forEach(function (letter) { test3[letter] = letter; }); if (Object.keys(Object.assign({}, test3)).join('') !== 'abcdefghijklmnopqrst') { return false; } return true; } catch (err) { // We don't expect any of the above to throw, but better to be safe. return false; } } var objectAssign = shouldUseNative() ? Object.assign : function (target, source) { var from; var to = toObject(target); var symbols; for (var s = 1; s < arguments.length; s++) { from = Object(arguments[s]); for (var key in from) { if (hasOwnProperty.call(from, key)) { to[key] = from[key]; } } if (getOwnPropertySymbols) { symbols = getOwnPropertySymbols(from); for (var i = 0; i < symbols.length; i++) { if (propIsEnumerable.call(from, symbols[i])) { to[symbols[i]] = from[symbols[i]]; } } } } return to; }; /*! * @pixi/polyfill - v5.3.3 * Compiled Tue, 04 Aug 2020 16:23:09 UTC * * @pixi/polyfill is licensed under the MIT License. * http://www.opensource.org/licenses/mit-license */ // Support for IE 9 - 11 which does not include Promises if (!window.Promise) { window.Promise = promise_2; } // References: if (!Object.assign) { Object.assign = objectAssign; } // References: // http://paulirish.com/2011/requestanimationframe-for-smart-animating/ // https://gist.github.com/1579671 // http://updates.html5rocks.com/2012/05/requestAnimationFrame-API-now-with-sub-millisecond-precision // https://gist.github.com/timhall/4078614 // https://github.com/Financial-Times/polyfill-service/tree/master/polyfills/requestAnimationFrame // Expected to be used with Browserfiy // Browserify automatically detects the use of `global` and passes the // correct reference of `global`, `self`, and finally `window` var ONE_FRAME_TIME = 16; // Date.now if (!(Date.now && Date.prototype.getTime)) { Date.now = function now() { return new Date().getTime(); }; } // performance.now if (!(window.performance && window.performance.now)) { var startTime_1 = Date.now(); if (!window.performance) { window.performance = {}; } window.performance.now = function () { return Date.now() - startTime_1; }; } // requestAnimationFrame var lastTime = Date.now(); var vendors = ['ms', 'moz', 'webkit', 'o']; for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { var p = vendors[x]; window.requestAnimationFrame = window[p + "RequestAnimationFrame"]; window.cancelAnimationFrame = window[p + "CancelAnimationFrame"] || window[p + "CancelRequestAnimationFrame"]; } if (!window.requestAnimationFrame) { window.requestAnimationFrame = function (callback) { if (typeof callback !== 'function') { throw new TypeError(callback + "is not a function"); } var currentTime = Date.now(); var delay = ONE_FRAME_TIME + lastTime - currentTime; if (delay < 0) { delay = 0; } lastTime = currentTime; return window.setTimeout(function () { lastTime = Date.now(); callback(performance.now()); }, delay); }; } if (!window.cancelAnimationFrame) { window.cancelAnimationFrame = function (id) { return clearTimeout(id); }; } // References: // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign if (!Math.sign) { Math.sign = function mathSign(x) { x = Number(x); if (x === 0 || isNaN(x)) { return x; } return x > 0 ? 1 : -1; }; } // References: // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger if (!Number.isInteger) { Number.isInteger = function numberIsInteger(value) { return typeof value === 'number' && isFinite(value) && Math.floor(value) === value; }; } if (!window.ArrayBuffer) { window.ArrayBuffer = Array; } if (!window.Float32Array) { window.Float32Array = Array; } if (!window.Uint32Array) { window.Uint32Array = Array; } if (!window.Uint16Array) { window.Uint16Array = Array; } if (!window.Uint8Array) { window.Uint8Array = Array; } if (!window.Int32Array) { window.Int32Array = Array; } var appleIphone = /iPhone/i; var appleIpod = /iPod/i; var appleTablet = /iPad/i; var appleUniversal = /\biOS-universal(?:.+)Mac\b/i; var androidPhone = /\bAndroid(?:.+)Mobile\b/i; var androidTablet = /Android/i; var amazonPhone = /(?:SD4930UR|\bSilk(?:.+)Mobile\b)/i; var amazonTablet = /Silk/i; var windowsPhone = /Windows Phone/i; var windowsTablet = /\bWindows(?:.+)ARM\b/i; var otherBlackBerry = /BlackBerry/i; var otherBlackBerry10 = /BB10/i; var otherOpera = /Opera Mini/i; var otherChrome = /\b(CriOS|Chrome)(?:.+)Mobile/i; var otherFirefox = /Mobile(?:.+)Firefox\b/i; var isAppleTabletOnIos13 = function (navigator) { return (typeof navigator !== 'undefined' && navigator.platform === 'MacIntel' && typeof navigator.maxTouchPoints === 'number' && navigator.maxTouchPoints > 1 && typeof MSStream === 'undefined'); }; function createMatch(userAgent) { return function (regex) { return regex.test(userAgent); }; } function isMobile(param) { var nav = { userAgent: '', platform: '', maxTouchPoints: 0 }; if (!param && typeof navigator !== 'undefined') { nav = { userAgent: navigator.userAgent, platform: navigator.platform, maxTouchPoints: navigator.maxTouchPoints || 0 }; } else if (typeof param === 'string') { nav.userAgent = param; } else if (param && param.userAgent) { nav = { userAgent: param.userAgent, platform: param.platform, maxTouchPoints: param.maxTouchPoints || 0 }; } var userAgent = nav.userAgent; var tmp = userAgent.split('[FBAN'); if (typeof tmp[1] !== 'undefined') { userAgent = tmp[0]; } tmp = userAgent.split('Twitter'); if (typeof tmp[1] !== 'undefined') { userAgent = tmp[0]; } var match = createMatch(userAgent); var result = { apple: { phone: match(appleIphone) && !match(windowsPhone), ipod: match(appleIpod), tablet: !match(appleIphone) && (match(appleTablet) || isAppleTabletOnIos13(nav)) && !match(windowsPhone), universal: match(appleUniversal), device: (match(appleIphone) || match(appleIpod) || match(appleTablet) || match(appleUniversal) || isAppleTabletOnIos13(nav)) && !match(windowsPhone) }, amazon: { phone: match(amazonPhone), tablet: !match(amazonPhone) && match(amazonTablet), device: match(amazonPhone) || match(amazonTablet) }, android: { phone: (!match(windowsPhone) && match(amazonPhone)) || (!match(windowsPhone) && match(androidPhone)), tablet: !match(windowsPhone) && !match(amazonPhone) && !match(androidPhone) && (match(amazonTablet) || match(androidTablet)), device: (!match(windowsPhone) && (match(amazonPhone) || match(amazonTablet) || match(androidPhone) || match(androidTablet))) || match(/\bokhttp\b/i) }, windows: { phone: match(windowsPhone), tablet: match(windowsTablet), device: match(windowsPhone) || match(windowsTablet) }, other: { blackberry: match(otherBlackBerry), blackberry10: match(otherBlackBerry10), opera: match(otherOpera), firefox: match(otherFirefox), chrome: match(otherChrome), device: match(otherBlackBerry) || match(otherBlackBerry10) || match(otherOpera) || match(otherFirefox) || match(otherChrome) }, any: false, phone: false, tablet: false }; result.any = result.apple.device || result.android.device || result.windows.device || result.other.device; result.phone = result.apple.phone || result.android.phone || result.windows.phone; result.tablet = result.apple.tablet || result.android.tablet || result.windows.tablet; return result; } /*! * @pixi/settings - v5.3.3 * Compiled Tue, 04 Aug 2020 16:23:09 UTC * * @pixi/settings is licensed under the MIT License. * http://www.opensource.org/licenses/mit-license */ // The ESM/CJS versions of ismobilejs only var isMobile$1 = isMobile(window.navigator); /** * The maximum recommended texture units to use. * In theory the bigger the better, and for desktop we'll use as many as we can. * But some mobile devices slow down if there is to many branches in the shader. * So in practice there seems to be a sweet spot size that varies depending on the device. * * In v4, all mobile devices were limited to 4 texture units because for this. * In v5, we allow all texture units to be used on modern Apple or Android devices. * * @private * @param {number} max * @returns {number} */ function maxRecommendedTextures(max) { var allowMax = true; if (isMobile$1.tablet || isMobile$1.phone) { if (isMobile$1.apple.device) { var match = (navigator.userAgent).match(/OS (\d+)_(\d+)?/); if (match) { var majorVersion = parseInt(match[1], 10); // Limit texture units on devices below iOS 11, which will be older hardware if (majorVersion < 11) { allowMax = false; } } } if (isMobile$1.android.device) { var match = (navigator.userAgent).match(/Android\s([0-9.]*)/); if (match) { var majorVersion = parseInt(match[1], 10); // Limit texture units on devices below Android 7 (Nougat), which will be older hardware if (majorVersion < 7) { allowMax = false; } } } } return allowMax ? max : 4; } /** * Uploading the same buffer multiple times in a single frame can cause performance issues. * Apparent on iOS so only check for that at the moment * This check may become more complex if this issue pops up elsewhere. * * @private * @returns {boolean} */ function canUploadSameBuffer() { return !isMobile$1.apple.device; } /** * User's customizable globals for overriding the default PIXI settings, such * as a renderer's default resolution, framerate, float precision, etc. * @example * // Use the native window resolution as the default resolution * // will support high-density displays when rendering * PIXI.settings.RESOLUTION = window.devicePixelRatio; * * // Disable interpolation when scaling, will make texture be pixelated * PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST; * @namespace PIXI.settings */ var settings = { /** * If set to true WebGL will attempt make textures mimpaped by default. * Mipmapping will only succeed if the base texture uploaded has power of two dimensions. * * @static * @name MIPMAP_TEXTURES * @memberof PIXI.settings * @type {PIXI.MIPMAP_MODES} * @default PIXI.MIPMAP_MODES.POW2 */ MIPMAP_TEXTURES: 1, /** * Default anisotropic filtering level of textures. * Usually from 0 to 16 * * @static * @name ANISOTROPIC_LEVEL * @memberof PIXI.settings * @type {number} * @default 0 */ ANISOTROPIC_LEVEL: 0, /** * Default resolution / device pixel ratio of the renderer. * * @static * @name RESOLUTION * @memberof PIXI.settings * @type {number} * @default 1 */ RESOLUTION: 1, /** * Default filter resolution. * * @static * @name FILTER_RESOLUTION * @memberof PIXI.settings * @type {number} * @default 1 */ FILTER_RESOLUTION: 1, /** * The maximum textures that this device supports. * * @static * @name SPRITE_MAX_TEXTURES * @memberof PIXI.settings * @type {number} * @default 32 */ SPRITE_MAX_TEXTURES: maxRecommendedTextures(32), // TODO: maybe change to SPRITE.BATCH_SIZE: 2000 // TODO: maybe add PARTICLE.BATCH_SIZE: 15000 /** * The default sprite batch size. * * The default aims to balance desktop and mobile devices. * * @static * @name SPRITE_BATCH_SIZE * @memberof PIXI.settings * @type {number} * @default 4096 */ SPRITE_BATCH_SIZE: 4096, /** * The default render options if none are supplied to {@link PIXI.Renderer} * or {@link PIXI.CanvasRenderer}. * * @static * @name RENDER_OPTIONS * @memberof PIXI.settings * @type {object} * @property {HTMLCanvasElement} view=null * @property {number} resolution=1 * @property {boolean} antialias=false * @property {boolean} autoDensity=false * @property {boolean} transparent=false * @property {number} backgroundColor=0x000000 * @property {boolean} clearBeforeRender=true * @property {boolean} preserveDrawingBuffer=false * @property {number} width=800 * @property {number} height=600 * @property {boolean} legacy=false */ RENDER_OPTIONS: { view: null, antialias: false, autoDensity: false, transparent: false, backgroundColor: 0x000000, clearBeforeRender: true, preserveDrawingBuffer: false, width: 800, height: 600, legacy: false, }, /** * Default Garbage Collection mode. * * @static * @name GC_MODE * @memberof PIXI.settings * @type {PIXI.GC_MODES} * @default PIXI.GC_MODES.AUTO */ GC_MODE: 0, /** * Default Garbage Collection max idle. * * @static * @name GC_MAX_IDLE * @memberof PIXI.settings * @type {number} * @default 3600 */ GC_MAX_IDLE: 60 * 60, /** * Default Garbage Collection maximum check count. * * @static * @name GC_MAX_CHECK_COUNT * @memberof PIXI.settings * @type {number} * @default 600 */ GC_MAX_CHECK_COUNT: 60 * 10, /** * Default wrap modes that are supported by pixi. * * @static * @name WRAP_MODE * @memberof PIXI.settings * @type {PIXI.WRAP_MODES} * @default PIXI.WRAP_MODES.CLAMP */ WRAP_MODE: 33071, /** * Default scale mode for textures. * * @static * @name SCALE_MODE * @memberof PIXI.settings * @type {PIXI.SCALE_MODES} * @default PIXI.SCALE_MODES.LINEAR */ SCALE_MODE: 1, /** * Default specify float precision in vertex shader. * * @static * @name PRECISION_VERTEX * @memberof PIXI.settings * @type {PIXI.PRECISION} * @default PIXI.PRECISION.HIGH */ PRECISION_VERTEX: 'highp', /** * Default specify float precision in fragment shader. * iOS is best set at highp due to https://github.com/pixijs/pixi.js/issues/3742 * * @static * @name PRECISION_FRAGMENT * @memberof PIXI.settings * @type {PIXI.PRECISION} * @default PIXI.PRECISION.MEDIUM */ PRECISION_FRAGMENT: isMobile$1.apple.device ? 'highp' : 'mediump', /** * Can we upload the same buffer in a single frame? * * @static * @name CAN_UPLOAD_SAME_BUFFER * @memberof PIXI.settings * @type {boolean} */ CAN_UPLOAD_SAME_BUFFER: canUploadSameBuffer(), /** * Enables bitmap creation before image load. This feature is experimental. * * @static * @name CREATE_IMAGE_BITMAP * @memberof PIXI.settings * @type {boolean} * @default false */ CREATE_IMAGE_BITMAP: false, /** * If true PixiJS will Math.floor() x/y values when rendering, stopping pixel interpolation. * Advantages can include sharper image quality (like text) and faster rendering on canvas. * The main disadvantage is movement of objects may appear less smooth. * * @static * @constant * @memberof PIXI.settings * @type {boolean} * @default false */ ROUND_PIXELS: false, }; /*! * @pixi/math - v5.3.3 * Compiled Tue, 04 Aug 2020 16:23:09 UTC * * @pixi/math is licensed under the MIT License. * http://www.opensource.org/licenses/mit-license */ /** * Two Pi. * * @static * @constant {number} PI_2 * @memberof PIXI */ var PI_2 = Math.PI * 2; /** * Conversion factor for converting radians to degrees. * * @static * @constant {number} RAD_TO_DEG * @memberof PIXI */ var RAD_TO_DEG = 180 / Math.PI; /** * Conversion factor for converting degrees to radians. * * @static * @constant {number} DEG_TO_RAD * @memberof PIXI */ var DEG_TO_RAD = Math.PI / 180; var SHAPES; (function (SHAPES) { SHAPES[SHAPES["POLY"] = 0] = "POLY"; SHAPES[SHAPES["RECT"] = 1] = "RECT"; SHAPES[SHAPES["CIRC"] = 2] = "CIRC"; SHAPES[SHAPES["ELIP"] = 3] = "ELIP"; SHAPES[SHAPES["RREC"] = 4] = "RREC"; })(SHAPES || (SHAPES = {})); /** * Constants that identify shapes, mainly to prevent `instanceof` calls. * * @static * @constant * @name SHAPES * @memberof PIXI * @type {enum} * @property {number} POLY Polygon * @property {number} RECT Rectangle * @property {number} CIRC Circle * @property {number} ELIP Ellipse * @property {number} RREC Rounded Rectangle * @enum {number} */ /** * Size object, contains width and height * * @memberof PIXI * @typedef {object} ISize * @property {number} width - Width component * @property {number} height - Height component */ /** * Rectangle object is an area defined by its position, as indicated by its top-left corner * point (x, y) and by its width and its height. * * @class * @memberof PIXI */ var Rectangle = /** @class */ (function () { /** * @param {number} [x=0] - The X coordinate of the upper-left corner of the rectangle * @param {number} [y=0] - The Y coordinate of the upper-left corner of the rectangle * @param {number} [width=0] - The overall width of this rectangle * @param {number} [height=0] - The overall height of this rectangle */ function Rectangle(x, y, width, height) { if (x === void 0) { x = 0; } if (y === void 0) { y = 0; } if (width === void 0) { width = 0; } if (height === void 0) { height = 0; } /** * @member {number} * @default 0 */ this.x = Number(x); /** * @member {number} * @default 0 */ this.y = Number(y); /** * @member {number} * @default 0 */ this.width = Number(width); /** * @member {number} * @default 0 */ this.height = Number(height); /** * The type of the object, mainly used to avoid `instanceof` checks * * @member {number} * @readOnly * @default PIXI.SHAPES.RECT * @see PIXI.SHAPES */ this.type = SHAPES.RECT; } Object.defineProperty(Rectangle.prototype, "left", { /** * returns the left edge of the rectangle * * @member {number} */ get: function () { return this.x; }, enumerable: false, configurable: true }); Object.defineProperty(Rectangle.prototype, "right", { /** * returns the right edge of the rectangle * * @member {number} */ get: function () { return this.x + this.width; }, enumerable: false, configurable: true }); Object.defineProperty(Rectangle.prototype, "top", { /** * returns the top edge of the rectangle * * @member {number} */ get: function () { return this.y; }, enumerable: false, configurable: true }); Object.defineProperty(Rectangle.prototype, "bottom", { /** * returns the bottom edge of the rectangle * * @member {number} */ get: function () { return this.y + this.height; }, enumerable: false, configurable: true }); Object.defineProperty(Rectangle, "EMPTY", { /** * A constant empty rectangle. * * @static * @constant * @member {PIXI.Rectangle} * @return {PIXI.Rectangle} An empty rectangle */ get: function () { return new Rectangle(0, 0, 0, 0); }, enumerable: false, configurable: true }); /** * Creates a clone of this Rectangle * * @return {PIXI.Rectangle} a copy of the rectangle */ Rectangle.prototype.clone = function () { return new Rectangle(this.x, this.y, this.width, this.height); }; /** * Copies another rectangle to this one. * * @param {PIXI.Rectangle} rectangle - The rectangle to copy from. * @return {PIXI.Rectangle} Returns itself. */ Rectangle.prototype.copyFrom = function (rectangle) { this.x = rectangle.x; this.y = rectangle.y; this.width = rectangle.width; this.height = rectangle.height; return this; }; /** * Copies this rectangle to another one. * * @param {PIXI.Rectangle} rectangle - The rectangle to copy to. * @return {PIXI.Rectangle} Returns given parameter. */ Rectangle.prototype.copyTo = function (rectangle) { rectangle.x = this.x; rectangle.y = this.y; rectangle.width = this.width; rectangle.height = this.height; return rectangle; }; /** * Checks whether the x and y coordinates given are contained within this Rectangle * * @param {number} x - The X coordinate of the point to test * @param {number} y - The Y coordinate of the point to test * @return {boolean} Whether the x/y coordinates are within this Rectangle */ Rectangle.prototype.contains = function (x, y) { if (this.width <= 0 || this.height <= 0) { return false; } if (x >= this.x && x < this.x + this.width) { if (y >= this.y && y < this.y + this.height) { return true; } } return false; }; /** * Pads the rectangle making it grow in all directions. * If paddingY is omitted, both paddingX and paddingY will be set to paddingX. * * @param {number} [paddingX=0] - The horizontal padding amount. * @param {number} [paddingY=0] - The vertical padding amount. * @return {PIXI.Rectangle} Returns itself. */ Rectangle.prototype.pad = function (paddingX, paddingY) { if (paddingX === void 0) { paddingX = 0; } if (paddingY === void 0) { paddingY = paddingX; } this.x -= paddingX; this.y -= paddingY; this.width += paddingX * 2; this.height += paddingY * 2; return this; }; /** * Fits this rectangle around the passed one. * * @param {PIXI.Rectangle} rectangle - The rectangle to fit. * @return {PIXI.Rectangle} Returns itself. */ Rectangle.prototype.fit = function (rectangle) { var x1 = Math.max(this.x, rectangle.x); var x2 = Math.min(this.x + this.width, rectangle.x + rectangle.width); var y1 = Math.max(this.y, rectangle.y); var y2 = Math.min(this.y + this.height, rectangle.y + rectangle.height); this.x = x1; this.width = Math.max(x2 - x1, 0); this.y = y1; this.height = Math.max(y2 - y1, 0); return this; }; /** * Enlarges rectangle that way its corners lie on grid * * @param {number} [resolution=1] resolution * @param {number} [eps=0.001] precision * @return {PIXI.Rectangle} Returns itself. */ Rectangle.prototype.ceil = function (resolution, eps) { if (resolution === void 0) { resolution = 1; } if (eps === void 0) { eps = 0.001; } var x2 = Math.ceil((this.x + this.width - eps) * resolution) / resolution; var y2 = Math.ceil((this.y + this.height - eps) * resolution) / resolution; this.x = Math.floor((this.x + eps) * resolution) / resolution; this.y = Math.floor((this.y + eps) * resolution) / resolution; this.width = x2 - this.x; this.height = y2 - this.y; return this; }; /** * Enlarges this rectangle to include the passed rectangle. * * @param {PIXI.Rectangle} rectangle - The rectangle to include. * @return {PIXI.Rectangle} Returns itself. */ Rectangle.prototype.enlarge = function (rectangle) { var x1 = Math.min(this.x, rectangle.x); var x2 = Math.max(this.x + this.width, rectangle.x + rectangle.width); var y1 = Math.min(this.y, rectangle.y); var y2 = Math.max(this.y + this.height, rectangle.y + rectangle.height); this.x = x1; this.width = x2 - x1; this.y = y1; this.height = y2 - y1; return this; }; return Rectangle; }()); /** * The Circle object is used to help draw graphics and can also be used to specify a hit area for displayObjects. * * @class * @memberof PIXI */ var Circle = /** @class */ (function () { /** * @param {number} [x=0] - The X coordinate of the center of this circle * @param {number} [y=0] - The Y coordinate of the center of this circle * @param {number} [radius=0] - The radius of the circle */ function Circle(x, y, radius) { if (x === void 0) { x = 0; } if (y === void 0) { y = 0; } if (radius === void 0) { radius = 0; } /** * @member {number} * @default 0 */ this.x = x; /** * @member {number} * @default 0 */ this.y = y; /** * @member {number} * @default 0 */ this.radius = radius; /** * The type of the object, mainly used to avoid `instanceof` checks * * @member {number} * @readOnly * @default PIXI.SHAPES.CIRC * @see PIXI.SHAPES */ this.type = SHAPES.CIRC; } /** * Creates a clone of this Circle instance * * @return {PIXI.Circle} a copy of the Circle */ Circle.prototype.clone = function () { return new Circle(this.x, this.y, this.radius); }; /** * Checks whether the x and y coordinates given are contained within this circle * * @param {number} x - The X coordinate of the point to test * @param {number} y - The Y coordinate of the point to test * @return {boolean} Whether the x/y coordinates are within this Circle */ Circle.prototype.contains = function (x, y) { if (this.radius <= 0) { return false; } var r2 = this.radius * this.radius; var dx = (this.x - x); var dy = (this.y - y); dx *= dx; dy *= dy; return (dx + dy <= r2); }; /** * Returns the framing rectangle of the circle as a Rectangle object * * @return {PIXI.Rectangle} the framing rectangle */ Circle.prototype.getBounds = function () { return new Rectangle(this.x - this.radius, this.y - this.radius, this.radius * 2, this.radius * 2); }; return Circle; }()); /** * The Ellipse object is used to help draw graphics and can also be used to specify a hit area for displayObjects. * * @class * @memberof PIXI */ var Ellipse = /** @class */ (function () { /** * @param {number} [x=0] - The X coordinate of the center of this ellipse * @param {number} [y=0] - The Y coordinate of the center of this ellipse * @param {number} [halfWidth=0] - The half width of this ellipse * @param {number} [halfHeight=0] - The half height of this ellipse */ function Ellipse(x, y, halfWidth, halfHeight) { if (x === void 0) { x = 0; } if (y === void 0) { y = 0; } if (halfWidth === void 0) { halfWidth = 0; } if (halfHeight === void 0) { halfHeight = 0; } /** * @member {number} * @default 0 */ this.x = x; /** * @member {number} * @default 0 */ this.y = y; /** * @member {number} * @default 0 */ this.width = halfWidth; /** * @member {number} * @default 0 */ this.height = halfHeight; /** * The type of the object, mainly used to avoid `instanceof` checks * * @member {number} * @readOnly * @default PIXI.SHAPES.ELIP * @see PIXI.SHAPES */ this.type = SHAPES.ELIP; } /** * Creates a clone of this Ellipse instance * * @return {PIXI.Ellipse} a copy of the ellipse */ Ellipse.prototype.clone = function () { return new Ellipse(this.x, this.y, this.width, this.height); }; /** * Checks whether the x and y coordinates given are contained within this ellipse * * @param {number} x - The X coordinate of the point to test * @param {number} y - The Y coordinate of the point to test * @return {boolean} Whether the x/y coords are within this ellipse */ Ellipse.prototype.contains = function (x, y) { if (this.width <= 0 || this.height <= 0) { return false; } // normalize the coords to an ellipse with center 0,0 var normx = ((x - this.x) / this.width); var normy = ((y - this.y) / this.height); normx *= normx; normy *= normy; return (normx + normy <= 1); }; /** * Returns the framing rectangle of the ellipse as a Rectangle object * * @return {PIXI.Rectangle} the framing rectangle */ Ellipse.prototype.getBounds = function () { return new Rectangle(this.x - this.width, this.y - this.height, this.width, this.height); }; return Ellipse; }()); /** * A class to define a shape via user defined co-orinates. * * @class * @memberof PIXI */ var Polygon = /** @class */ (function () { /** * @param {PIXI.IPoint[]|number[]} points - This can be an array of Points * that form the polygon, a flat array of numbers that will be interpreted as [x,y, x,y, ...], or * the arguments passed can be all the points of the polygon e.g. * `new PIXI.Polygon(new PIXI.Point(), new PIXI.Point(), ...)`, or the arguments passed can be flat * x,y values e.g. `new Polygon(x,y, x,y, x,y, ...)` where `x` and `y` are Numbers. */ function Polygon() { var arguments$1 = arguments; var points = []; for (var _i = 0; _i < arguments.length; _i++) { points[_i] = arguments$1[_i]; } var flat = Array.isArray(points[0]) ? points[0] : points; // if this is an array of points, convert it to a flat array of numbers if (typeof flat[0] !== 'number') { var p = []; for (var i = 0, il = flat.length; i < il; i++) { p.push(flat[i].x, flat[i].y); } flat = p; } /** * An array of the points of this polygon * * @member {number[]} */ this.points = flat; /** * The type of the object, mainly used to avoid `instanceof` checks * * @member {number} * @readOnly * @default PIXI.SHAPES.POLY * @see PIXI.SHAPES */ this.type = SHAPES.POLY; /** * `false` after moveTo, `true` after `closePath`. In all other cases it is `true`. * @member {boolean} * @default true */ this.closeStroke = true; } /** * Creates a clone of this polygon * * @return {PIXI.Polygon} a copy of the polygon */ Polygon.prototype.clone = function () { var points = this.points.slice(); var polygon = new Polygon(points); polygon.closeStroke = this.closeStroke; return polygon; }; /** * Checks whether the x and y coordinates passed to this function are contained within this polygon * * @param {number} x - The X coordinate of the point to test * @param {number} y - The Y coordinate of the point to test * @return {boolean} Whether the x/y coordinates are within this polygon */ Polygon.prototype.contains = function (x, y) { var inside = false; // use some raycasting to test hits // https://github.com/substack/point-in-polygon/blob/master/index.js var length = this.points.length / 2; for (var i = 0, j = length