1/*! 2 * pixi.js-legacy - v5.0.0-rc.3 3 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 4 * 5 * pixi.js-legacy is licensed under the MIT License. 6 * http://www.opensource.org/licenses/mit-license 7 */ 8var PIXI = (function (exports) { 9 'use strict'; 10 11 var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; 12 13 function commonjsRequire () { 14 throw new Error('Dynamic requires are not currently supported by rollup-plugin-commonjs'); 15 } 16 17 function unwrapExports (x) { 18 return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x.default : x; 19 } 20 21 function createCommonjsModule(fn, module) { 22 return module = { exports: {} }, fn(module, module.exports), module.exports; 23 } 24 25 function getCjsExportFromNamespace (n) { 26 return n && n.default || n; 27 } 28 29 var promise = createCommonjsModule(function (module, exports) { 30 (function(global){ 31 32 // 33 // Check for native Promise and it has correct interface 34 // 35 36 var NativePromise = global['Promise']; 37 var nativePromiseSupported = 38 NativePromise && 39 // Some of these methods are missing from 40 // Firefox/Chrome experimental implementations 41 'resolve' in NativePromise && 42 'reject' in NativePromise && 43 'all' in NativePromise && 44 'race' in NativePromise && 45 // Older version of the spec had a resolver object 46 // as the arg rather than a function 47 (function(){ 48 var resolve; 49 new NativePromise(function(r){ resolve = r; }); 50 return typeof resolve === 'function'; 51 })(); 52 53 54 // 55 // export if necessary 56 // 57 58 if ('object' !== 'undefined' && exports) 59 { 60 // node.js 61 exports.Promise = nativePromiseSupported ? NativePromise : Promise; 62 exports.Polyfill = Promise; 63 } 64 else 65 { 66 // AMD 67 if (typeof undefined == 'function' && undefined.amd) 68 { 69 undefined(function(){ 70 return nativePromiseSupported ? NativePromise : Promise; 71 }); 72 } 73 else 74 { 75 // in browser add to global 76 if (!nativePromiseSupported) 77 { global['Promise'] = Promise; } 78 } 79 } 80 81 82 // 83 // Polyfill 84 // 85 86 var PENDING = 'pending'; 87 var SEALED = 'sealed'; 88 var FULFILLED = 'fulfilled'; 89 var REJECTED = 'rejected'; 90 var NOOP = function(){}; 91 92 function isArray(value) { 93 return Object.prototype.toString.call(value) === '[object Array]'; 94 } 95 96 // async calls 97 var asyncSetTimer = typeof setImmediate !== 'undefined' ? setImmediate : setTimeout; 98 var asyncQueue = []; 99 var asyncTimer; 100 101 function asyncFlush(){ 102 // run promise callbacks 103 for (var i = 0; i < asyncQueue.length; i++) 104 { asyncQueue[i][0](asyncQueue[i][1]); } 105 106 // reset async asyncQueue 107 asyncQueue = []; 108 asyncTimer = false; 109 } 110 111 function asyncCall(callback, arg){ 112 asyncQueue.push([callback, arg]); 113 114 if (!asyncTimer) 115 { 116 asyncTimer = true; 117 asyncSetTimer(asyncFlush, 0); 118 } 119 } 120 121 122 function invokeResolver(resolver, promise) { 123 function resolvePromise(value) { 124 resolve(promise, value); 125 } 126 127 function rejectPromise(reason) { 128 reject(promise, reason); 129 } 130 131 try { 132 resolver(resolvePromise, rejectPromise); 133 } catch(e) { 134 rejectPromise(e); 135 } 136 } 137 138 function invokeCallback(subscriber){ 139 var owner = subscriber.owner; 140 var settled = owner.state_; 141 var value = owner.data_; 142 var callback = subscriber[settled]; 143 var promise = subscriber.then; 144 145 if (typeof callback === 'function') 146 { 147 settled = FULFILLED; 148 try { 149 value = callback(value); 150 } catch(e) { 151 reject(promise, e); 152 } 153 } 154 155 if (!handleThenable(promise, value)) 156 { 157 if (settled === FULFILLED) 158 { resolve(promise, value); } 159 160 if (settled === REJECTED) 161 { reject(promise, value); } 162 } 163 } 164 165 function handleThenable(promise, value) { 166 var resolved; 167 168 try { 169 if (promise === value) 170 { throw new TypeError('A promises callback cannot return that same promise.'); } 171 172 if (value && (typeof value === 'function' || typeof value === 'object')) 173 { 174 var then = value.then; // then should be retrived only once 175 176 if (typeof then === 'function') 177 { 178 then.call(value, function(val){ 179 if (!resolved) 180 { 181 resolved = true; 182 183 if (value !== val) 184 { resolve(promise, val); } 185 else 186 { fulfill(promise, val); } 187 } 188 }, function(reason){ 189 if (!resolved) 190 { 191 resolved = true; 192 193 reject(promise, reason); 194 } 195 }); 196 197 return true; 198 } 199 } 200 } catch (e) { 201 if (!resolved) 202 { reject(promise, e); } 203 204 return true; 205 } 206 207 return false;
208 } 209 210 function resolve(promise, value){ 211 if (promise === value || !handleThenable(promise, value)) 212 { fulfill(promise, value); } 213 } 214 215 function fulfill(promise, value){ 216 if (promise.state_ === PENDING) 217 { 218 promise.state_ = SEALED; 219 promise.data_ = value; 220 221 asyncCall(publishFulfillment, promise); 222 } 223 } 224 225 function reject(promise, reason){ 226 if (promise.state_ === PENDING) 227 { 228 promise.state_ = SEALED; 229 promise.data_ = reason; 230 231 asyncCall(publishRejection, promise); 232 } 233 } 234 235 function publish(promise) { 236 var callbacks = promise.then_; 237 promise.then_ = undefined; 238 239 for (var i = 0; i < callbacks.length; i++) { 240 invokeCallback(callbacks[i]); 241 } 242 } 243 244 function publishFulfillment(promise){ 245 promise.state_ = FULFILLED; 246 publish(promise); 247 } 248 249 function publishRejection(promise){ 250 promise.state_ = REJECTED; 251 publish(promise); 252 } 253 254 /** 255 * @class 256 */ 257 function Promise(resolver){ 258 if (typeof resolver !== 'function') 259 { throw new TypeError('Promise constructor takes a function argument'); } 260 261 if (this instanceof Promise === false) 262 { throw new TypeError('Failed to construct \'Promise\': Please use the \'new\' operator, this object c
262onstructor cannot be called as a function.'); } 263 264 this.then_ = []; 265 266 invokeResolver(resolver, this); 267 } 268 269 Promise.prototype = { 270 constructor: Promise, 271 272 state_: PENDING, 273 then_: null, 274 data_: undefined, 275 276 then: function(onFulfillment, onRejection){ 277 var subscriber = { 278 owner: this, 279 then: new this.constructor(NOOP), 280 fulfilled: onFulfillment, 281 rejected: onRejection 282 }; 283 284 if (this.state_ === FULFILLED || this.state_ === REJECTED) 285 { 286 // already resolved, call callback async 287 asyncCall(invokeCallback, subscriber); 288 } 289 else 290 { 291 // subscribe 292 this.then_.push(subscriber); 293 } 294 295 return subscriber.then; 296 }, 297 298 'catch': function(onRejection) { 299 return this.then(null, onRejection); 300 } 301 }; 302 303 Promise.all = function(promises){ 304 var Class = this; 305 306 if (!isArray(promises)) 307 { throw new TypeError('You must pass an array to Promise.all().'); } 308 309 return new Class(function(resolve, reject){ 310 var results = []; 311 var remaining = 0; 312 313 function resolver(index){ 314 remaining++; 315 return function(value){ 316 results[index] = value; 317 if (!--remaining) 318 { resolve(results); } 319 }; 320 } 321 322 for (var i = 0, promise; i < promises.length; i++) 323 { 324 promise = promises[i]; 325 326 if (promise && typeof promise.then === 'function') 327 { promise.then(resolver(i), reject); } 328 else 329 { results[i] = promise; } 330 } 331 332 if (!remaining) 333 { resolve(results); } 334 }); 335 }; 336 337 Promise.race = function(promises){ 338 var Class = this; 339 340 if (!isArray(promises)) 341 { throw new TypeError('You must pass an array to Promise.race().'); } 342 343 return new Class(function(resolve, reject) { 344 for (var i = 0, promise; i < promises.length; i++) 345 { 346 promise = promises[i]; 347 348 if (promise && typeof promise.then === 'function') 349 { promise.then(resolve, reject); } 350 else 351 { resolve(promise); } 352 } 353 }); 354 }; 355 356 Promise.resolve = function(value){ 357 var Class = this; 358 359 if (value && typeof value === 'object' && value.constructor === Class) 360 { return value; } 361 362 return new Class(function(resolve){ 363 resolve(value); 364 }); 365 }; 366 367 Promise.reject = function(reason){ 368 var Class = this; 369 370 return new Class(function(resolve, reject){ 371 reject(reason); 372 }); 373 }; 374 375 })(typeof window != 'undefined' ? window : typeof commonjsGlobal != 'undefined' ? commonjsGlobal : typeof self != 'undefined' ? self : commonjsGlobal); 376 }); 377 var promise_1 = promise.Promise; 378 var promise_2 = promise.Polyfill; 379 380 /* 381 object-assign 382 (c) Sindre Sorhus 383 @license MIT 384 */ 385 386 'use strict'; 387 /* eslint-disable no-unused-vars */ 388 var getOwnPropertySymbols = Object.getOwnPropertySymbols; 389 var hasOwnProperty = Object.prototype.hasOwnProperty; 390 var propIsEnumerable = Object.prototype.propertyIsEnumerable; 391 392 function toObject(val) { 393 if (val === null || val === undefined) { 394 throw new TypeError('Object.assign cannot be called with null or undefined'); 395 } 396 397 return Object(val); 398 } 399 400 function shouldUseNative() { 401 try { 402 if (!Object.assign) { 403 return false; 404 } 405 406 // Detect buggy property enumeration order in older V8 versions. 407 408 // https://bugs.chromium.org/p/v8/issues/detail?id=4118 409 var test1 = new String('abc'); // eslint-disable-line no-new-wrappers 410 test1[5] = 'de'; 411 if (Object.getOwnPropertyNames(test1)[0] === '5') { 412 return false; 413 } 414 415 // https://bugs.chromium.org/p/v8/issues/detail?id=3056 416 var test2 = {}; 417 for (var i = 0; i < 10; i++) { 418 test2['_' + String.fromCharCode(i)] = i; 419 } 420 var order2 = Object.getOwnPropertyNames(test2).map(function (n) { 421 return test2[n]; 422 }); 423 if (order2.join('') !== '0123456789') { 424 return false; 425 } 426 427 // https://bugs.chromium.org/p/v8/issues/detail?id=3056 428 var test3 = {}; 429 'abcdefghijklmnopqrst'.split('').forEach(function (letter) { 430 test3[letter] = letter; 431 }); 432 if (Object.keys(Object.assign({}, test3)).join('') !== 433 'abcdefghijklmnopqrst') { 434 return false; 435 } 436 437 return true; 438 } catch (err) { 439 // We don't expect any of the above to throw, but better to be safe. 440 return false;
441 } 442 } 443 444 var objectAssign = shouldUseNative() ? Object.assign : function (target, source) { 445 var arguments$1 = arguments; 446 447 var from; 448 var to = toObject(target); 449 var symbols; 450 451 for (var s = 1; s < arguments.length; s++) { 452 from = Object(arguments$1[s]); 453 454 for (var key in from) { 455 if (hasOwnProperty.call(from, key)) { 456 to[key] = from[key]; 457 } 458 } 459 460 if (getOwnPropertySymbols) { 461 symbols = getOwnPropertySymbols(from); 462 for (var i = 0; i < symbols.length; i++) { 463 if (propIsEnumerable.call(from, symbols[i])) { 464 to[symbols[i]] = from[symbols[i]]; 465 } 466 } 467 } 468 } 469 470 return to; 471 }; 472 473 /*! 474 * @pixi/polyfill - v5.0.0-rc.3 475 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 476 * 477 * @pixi/polyfill is licensed under the MIT License. 478 * http://www.opensource.org/licenses/mit-license 479 */ 480 481 // Support for IE 9 - 11 which does not include Promises 482 if (!window.Promise) 483 { 484 window.Promise = promise_2; 485 } 486 487 // References: 488 489 if (!Object.assign) 490 { 491 Object.assign = objectAssign; 492 } 493 494 var commonjsGlobal$1 = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; 495 496 // References: 497 // http://paulirish.com/2011/requestanimationframe-for-smart-animating/ 498 // https://gist.github.com/1579671 499 // http://updates.html5rocks.com/2012/05/requestAnimationFrame-API-now-with-sub-millisecond-precision 500 // https://gist.github.com/timhall/4078614 501 // https://github.com/Financial-Times/polyfill-service/tree/master/polyfills/requestAnimationFrame 502 503 // Expected to be used with Browserfiy 504 // Browserify automatically detects the use of `global` and passes the 505 // correct reference of `global`, `self`, and finally `window` 506 507 var ONE_FRAME_TIME = 16; 508 509 // Date.now 510 if (!(Date.now && Date.prototype.getTime)) 511 { 512 Date.now = function now() 513 { 514 return new Date().getTime(); 515 }; 516 } 517 518 // performance.now 519 if (!(commonjsGlobal$1.performance && commonjsGlobal$1.performance.now)) 520 { 521 var startTime = Date.now(); 522 523 if (!commonjsGlobal$1.performance) 524 { 525 commonjsGlobal$1.performance = {}; 526 } 527 528 commonjsGlobal$1.performance.now = function () { return Date.now() - startTime; }; 529 } 530 531 // requestAnimationFrame 532 var lastTime = Date.now(); 533 var vendors = ['ms', 'moz', 'webkit', 'o']; 534 535 for (var x = 0; x < vendors.length && !commonjsGlobal$1.requestAnimationFrame; ++x) 536 { 537 var p = vendors[x]; 538 539 commonjsGlobal$1.requestAnimationFrame = commonjsGlobal$1[(p + "RequestAnimationFrame")]; 540 commonjsGlobal$1.cancelAnimationFrame = commonjsGlobal$1[(p + "CancelAnimationFrame")] || commonjsGlobal$1[(p + "CancelRequestAnimationFrame")]; 541 } 542 543 if (!commonjsGlobal$1.requestAnimationFrame) 544 { 545 commonjsGlobal$1.requestAnimationFrame = function (callback) { 546 if (typeof callback !== 'function') 547 { 548 throw new TypeError((callback + "is not a function")); 549 } 550 551 var currentTime = Date.now(); 552 var delay = ONE_FRAME_TIME + lastTime - currentTime; 553 554 if (delay < 0) 555 { 556 delay = 0; 557 } 558 559 lastTime = currentTime; 560 561 return setTimeout(function () { 562 lastTime = Date.now(); 563 callback(performance.now()); 564 }, delay); 565 }; 566 } 567 568 if (!commonjsGlobal$1.cancelAnimationFrame) 569 { 570 commonjsGlobal$1.cancelAnimationFrame = function (id) { return clearTimeout(id); }; 571 } 572 573 // References: 574 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign 575 576 if (!Math.sign) 577 { 578 Math.sign = function mathSign(x) 579 { 580 x = Number(x); 581 582 if (x === 0 || isNaN(x)) 583 { 584 return x; 585 } 586 587 return x > 0 ? 1 : -1; 588 }; 589 } 590 591 // References: 592 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger 593 594 if (!Number.isInteger) 595 { 596 Number.isInteger = function numberIsInteger(value) 597 { 598 return typeof value === 'number' && isFinite(value) && Math.floor(value) === value; 599 }; 600 } 601 602 if (!window.ArrayBuffer) 603 { 604 window.ArrayBuffer = Array; 605 } 606 607 if (!window.Float32Array) 608 { 609 window.Float32Array = Array; 610 } 611 612 if (!window.Uint32Array) 613 { 614 window.Uint32Array = Array; 615 } 616 617 if (!window.Uint16Array) 618 { 619 window.Uint16Array = Array; 620 } 621 622 if (!window.Uint8Array) 623 { 624 window.Uint8Array = Array; 625 } 626 627 if (!window.Int32Array) 628 { 629 window.Int32Array = Array; 630 } 631 632 var isMobile_min = createCommonjsModule(function (module) { 633 !function(e){var n=/iPhone/i,t=/iPod/i,r=/iPad/i,a=/\bAndroid(?:.+)Mobile\b/i,p=/Android/i,l=/\bAndroid(?:.+)SD4930UR\b/i,b=/\bAndroid(?:.+)(?:KF[A-Z]{2,4})\b/i,f=/Windows Phone/i,u=/\bWindows(?:.+)ARM\b/i,c=/BlackBerry/i,s=/BB10/i,v=/Opera Mini/i,h=/\b(CriOS|Chrome)(?:.+)Mobile/i,w=/\Mobile(?:.+)Firefox\b/i;function m(e,i){return e.test(i)}function i(e){var i=e||("undefined"!=typeof navigator?navigator.userAgent:""),o=i.split("[FBAN");void 0!==o[1]&&(i=o[0]),void 0!==(o=i.split("Twitter"))[1]&&(i=o[0]);var d={apple:{phone:m(n,i)&&!m(f,i),ipod:m(t,i),tablet:!m(n,i)&&m(r,i)&&!m(f,i),device:(m(n,i)||m(t,i)||m(r,i))&&!m(f,i)},amazon:{phone:m(l,i),tablet:!m(l,i)&&m(b,i),device:m(l,i)||m(b,i)},android:{phone:!m(f,i)&&m(l,i)||!m(f,i)&&m(a,i),tablet:!m(f,i)&&!m(l,i)&&!m(a,i)&&(m(b,i)||m(p,i)),device:!m(f,i)&&(m(l,i)||m(b,i)||m(a,i)||m(p,i))}
633,windows:{phone:m(f,i),tablet:m(u,i),device:m(f,i)||m(u,i)},other:{blackberry:m(c,i),blackberry10:m(s,i),opera:m(v,i),firefox:m(w,i),chrome:m(h,i),device:m(c,i)||m(s,i)||m(v,i)||m(w,i)||m(h,i)}};return d.any=d.apple.device||d.android.device||d.windows.device||d.other.device,d.phone=d.apple.phone||d.android.phone||d.windows.phone,d.tablet=d.apple.tablet||d.android.tablet||d.windows.tablet,d}"undefined"!='object'&&module.exports&&"undefined"==typeof window?module.exports=i:"undefined"!='object'&&module.exports&&"undefined"!=typeof window?module.exports=i():"function"==typeof undefined&&undefined.amd?undefined([],e.isMobile=i()):e.isMobile=i();}(commonjsGlobal); 634 }); 635 636 /*! 637 * @pixi/settings - v5.0.0-rc.3 638 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 639 * 640 * @pixi/settings is licensed under the MIT License. 641 * http://www.opensource.org/licenses/mit-license 642 */ 643 644 /** 645 * The maximum recommended texture units to use. 646 * In theory the bigger the better, and for desktop we'll use as many as we can. 647 * But some mobile devices slow down if there is to many branches in the shader. 648 * So in practice there seems to be a sweet spot size that varies depen
648ding on the device. 649 * 650 * In v4, all mobile devices were limited to 4 texture units because for this. 651 * In v5, we allow all texture units to be used on modern Apple or Android devices. 652 * 653 * @private 654 * @param {number} max 655 * @returns {number} 656 */ 657 function maxRecommendedTextures(max) 658 { 659 var allowMax = true; 660 661 if (isMobile_min.tablet || isMobile_min.phone) 662 { 663 allowMax = false; 664 665 if (isMobile_min.apple.device) 666 { 667 var match = (navigator.userAgent).match(/OS (\d+)_(\d+)?/); 668 669 if (match) 670 { 671 var majorVersion = parseInt(match[1], 10); 672 673 // All texture units can be used on devices that support ios 11 or above 674 if (majorVersion >= 11) 675 { 676 allowMax = true; 677 } 678 } 679 } 680 if (isMobile_min.android.device) 681 { 682 var match$1 = (navigator.userAgent).match(/Android\s([0-9.]*)/); 683 684 if (match$1) 685 { 686 var majorVersion$1 = parseInt(match$1[1], 10); 687 688 // All texture units can be used on devices that support Android 7 (Nougat) or above 689 if (majorVersion$1 >= 7) 690 { 691 allowMax = true; 692 } 693 } 694 } 695 } 696 697 return allowMax ? max : 4; 698 } 699 700 /** 701 * Uploading the same buffer multiple times in a single frame can cause performance issues. 702 * Apparent on iOS so only check for that at the moment 703 * This check may become more complex if this issue pops up elsewhere. 704 * 705 * @private 706 * @returns {boolean} 707 */ 708 function canUploadSameBuffer() 709 { 710 return !isMobile_min.apple.device; 711 } 712 713 /** 714 * User's customizable globals for overriding the default PIXI settings, such 715 * as a renderer's default resolution, framerate, float precision, etc. 716 * @example 717 * // Use the native window resolution as the default resolution 718 * // will support high-density displays when rendering 719 * PIXI.settings.RESOLUTION = window.devicePixelRatio. 720 * 721 * // Disable interpolation when scaling, will make texture be pixelated 722 * PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST; 723 * @namespace PIXI.settings 724 */ 725 var settings = { 726 727 /** 728 * If set to true WebGL will attempt make textures mimpaped by default. 729 * Mipmapping will only succeed if the base texture uploaded has power of two dimensions. 730 * 731 * @static 732 * @name MIPMAP_TEXTURES 733 * @memberof PIXI.settings 734 * @type {PIXI.MIPMAP_MODES} 735 * @default PIXI.MIPMAP_MODES.POW2 736 */ 737 MIPMAP_TEXTURES: 1, 738 739 /** 740 * Default resolution / device pixel ratio of the renderer. 741 * 742 * @static 743 * @name RESOLUTION 744 * @memberof PIXI.settings 745 * @type {number} 746 * @default 1 747 */ 748 RESOLUTION: 1, 749 750 /** 751 * Default filter resolution. 752 * 753 * @static 754 * @name FILTER_RESOLUTION 755 * @memberof PIXI.settings 756 * @type {number} 757 * @default 1 758 */ 759 FILTER_RESOLUTION: 1, 760 761 /** 762 * The maximum textures that this device supports. 763 * 764 * @static 765 * @name SPRITE_MAX_TEXTURES 766 * @memberof PIXI.settings 767 * @type {number} 768 * @default 32 769 */ 770 SPRITE_MAX_TEXTURES: maxRecommendedTextures(32), 771 772 // TODO: maybe change to SPRITE.BATCH_SIZE: 2000 773 // TODO: maybe add PARTICLE.BATCH_SIZE: 15000 774 775 /** 776 * The default sprite batch size. 777 * 778 * The default aims to balance desktop and mobile devices. 779 * 780 * @static 781 * @name SPRITE_BATCH_SIZE 782 * @memberof PIXI.settings 783 * @type {number} 784 * @default 4096 785 */ 786 SPRITE_BATCH_SIZE: 4096, 787 788 /** 789 * The default render options if none are supplied to {@link PIXI.Renderer} 790 * or {@link PIXI.CanvasRenderer}. 791 * 792 * @static 793 * @name RENDER_OPTIONS 794 * @memberof PIXI.settings 795 * @type {object} 796 * @property {HTMLCanvasElement} view=null 797 * @property {number} resolution=1 798 * @property {boolean} antialias=false 799 * @property {boolean} forceFXAA=false 800 * @property {boolean} autoResize=false 801 * @property {boolean} transparent=false 802 * @property {number} backgroundColor=0x000000 803 * @property {boolean} clearBeforeRender=true 804 * @property {boolean} preserveDrawingBuffer=false 805 * @property {number} width=800 806 * @property {number} height=600 807 * @property {boolean} legacy=false 808 */ 809 RENDER_OPTIONS: { 810 view: null, 811 antialias: false, 812 forceFXAA: false, 813 autoResize: false, 814 transparent: false, 815 backgroundColor: 0x000000, 816 clearBeforeRender: true, 817 preserveDrawingBuffer: false, 818 width: 800, 819 height: 600,
820 legacy: false, 821 }, 822 823 /** 824 * Default Garbage Collection mode. 825 * 826 * @static 827 * @name GC_MODE 828 * @memberof PIXI.settings 829 * @type {PIXI.GC_MODES} 830 * @default PIXI.GC_MODES.AUTO 831 */ 832 GC_MODE: 0, 833 834 /** 835 * Default Garbage Collection max idle. 836 * 837 * @static 838 * @name GC_MAX_IDLE 839 * @memberof PIXI.settings 840 * @type {number} 841 * @default 3600 842 */ 843 GC_MAX_IDLE: 60 * 60, 844 845 /** 846 * Default Garbage Collection maximum check count. 847 * 848 * @static 849 * @name GC_MAX_CHECK_COUNT 850 * @memberof PIXI.settings 851 * @type {number} 852 * @default 600 853 */ 854 GC_MAX_CHECK_COUNT: 60 * 10, 855 856 /** 857 * Default wrap modes that are supported by pixi. 858 * 859 * @static 860 * @name WRAP_MODE 861 * @memberof PIXI.settings 862 * @type {PIXI.WRAP_MODES} 863 * @default PIXI.WRAP_MODES.CLAMP 864 */ 865 WRAP_MODE: 33071, 866 867 /** 868 * Default scale mode for textures. 869 * 870 * @static 871 * @name SCALE_MODE 872 * @memberof PIXI.settings 873 * @type {PIXI.SCALE_MODES} 874 * @default PIXI.SCALE_MODES.LINEAR 875 */ 876 SCALE_MODE: 1, 877 878 /** 879 * Default specify float precision in vertex shader. 880 * 881 * @static 882 * @name PRECISION_VERTEX 883 * @memberof PIXI.settings 884 * @type {PIXI.PRECISION} 885 * @default PIXI.PRECISION.HIGH 886 */ 887 PRECISION_VERTEX: 'highp', 888 889 /** 890 * Default specify float precision in fragment shader. 891 * 892 * @static 893 * @name PRECISION_FRAGMENT 894 * @memberof PIXI.settings 895 * @type {PIXI.PRECISION} 896 * @default PIXI.PRECISION.MEDIUM 897 */ 898 PRECISION_FRAGMENT: isMobile_min.apple.device ? 'highp' : 'mediump', 899 900 /** 901 * Can we upload the same buffer in a single frame? 902 * 903 * @static 904 * @name CAN_UPLOAD_SAME_BUFFER 905 * @memberof PIXI.settings 906 * @type {boolean} 907 */ 908 CAN_UPLOAD_SAME_BUFFER: canUploadSameBuffer(), 909 910 /** 911 * Enables bitmap creation before image load 912 * 913 * @static 914 * @name CREATE_IMAGE_BITMAP 915 * @memberof PIXI.settings 916 * @type {boolean} 917 * @default true 918 */ 919 CREATE_IMAGE_BITMAP: true, 920 921 /** 922 * If true PixiJS will Math.floor() x/y values when rendering, stopping pixel interpolation. 923 * Advantages can include sharper image quality (like text) and faster rendering on canvas. 924 * The main disadvantage is movement of objects may appear less smooth. 925 * 926 * @static 927 * @constant 928 * @memberof PIXI.settings 929 * @type {boolean} 930 * @default false 931 */ 932 ROUND_PIXELS: false, 933 }; 934 935 var eventemitter3 = createCommonjsModule(function (module) { 936 'use strict'; 937 938 var has = Object.prototype.hasOwnProperty 939 , prefix = '~'; 940 941 /** 942 * Constructor to create a storage for our `EE` objects. 943 * An `Events` instance is a plain object whose properties are event names. 944 * 945 * @constructor 946 * @private 947 */ 948 function Events() {} 949 950 // 951 // We try to not inherit from `Object.prototype`. In some engines creating an 952 // instance in this way is faster than calling `Object.create(null)` directly. 953 // If `Object.create(null)` is not supported we prefix the event names with a 954 // character to make sure that the built-in object properties are not 955 // overridden or used as an attack vector. 956 // 957 if (Object.create) { 958 Events.prototype = Object.create(null); 959 960 // 961 // This hack is needed because the `__proto__` property is still inherited in 962 // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5. 963 // 964 if (!new Events().__proto__) { prefix = false; } 965 } 966 967 /** 968 * Representation of a single event listener. 969 * 970 * @param {Function} fn The listener function. 971 * @param {*} context The context to invoke the listener with. 972 * @param {Boolean} [once=false] Specify if the listener is a one-time listener. 973 * @constructor 974 * @private 975 */ 976 function EE(fn, context, once) { 977 this.fn = fn; 978 this.context = context; 979 this.once = once || false; 980 } 981 982 /** 983 * Add a listener for a given event. 984 * 985 * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. 986 * @param {(String|Symbol)} event The event name. 987 * @param {Function} fn The listener function. 988 * @param {*} context The context to invoke the listener with. 989 * @param {Boolean} once Specify if the listener is a one-time listener. 990 * @returns {EventEmitter} 991 * @private 992 */ 993 function addListener(emitter, event, fn, context, once) { 994 if (typeof fn !== 'function') { 995 throw new TypeError('The listener must be a function'); 996 } 997 998 var listener = new EE(fn, context || emitter, once) 999 , evt = prefix ? prefix + event : event; 1000 1001 if (!emitter._events[evt]) { emitter._events[evt] = listener, emitter._eventsCount++; } 1002 else if (!emitter._events[evt].fn) { emitter._events[evt].push(listener); } 1003 else { emitter._events[evt] = [emitter._events[evt], listener]; } 1004 1005 return emitter; 1006 } 1007 1008 /** 1009 * Clear event by name. 1010 * 1011 * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. 1012 * @param {(String|Symbol)} evt The Event name. 1013 * @private 1014 */ 1015 function clearEvent(emitter, evt) { 1016 if (--emitter._eventsCount === 0) { emitter._events = new Events(); } 1017 else { delete emitter._events[evt]; } 1018 } 1019
1020 /** 1021 * Minimal `EventEmitter` interface that is molded against the Node.js 1022 * `EventEmitter` interface. 1023 * 1024 * @constructor 1025 * @public 1026 */ 1027 function EventEmitter() { 1028 this._events = new Events(); 1029 this._eventsCount = 0; 1030 } 1031 1032 /** 1033 * Return an array listing the events for which the emitter has registered 1034 * listeners. 1035 * 1036 * @returns {Array} 1037 * @public 1038 */ 1039 EventEmitter.prototype.eventNames = function eventNames() { 1040 var names = [] 1041 , events 1042 , name; 1043 1044 if (this._eventsCount === 0) { return names; } 1045 1046 for (name in (events = this._events)) { 1047 if (has.call(events, name)) { names.push(prefix ? name.slice(1) : name); } 1048 } 1049 1050 if (Object.getOwnPropertySymbols) { 1051 return names.concat(Object.getOwnPropertySymbols(events)); 1052 } 1053 1054 return names; 1055 }; 1056 1057 /** 1058 * Return the listeners registered for a given event. 1059 * 1060 * @param {(String|Symbol)} event The event name. 1061 * @returns {Array} The registered listeners. 1062 * @public 1063 */ 1064 EventEmitter.prototype.listeners = function listeners(event) { 1065 var evt = prefix ? prefix + event : event 1066 , handlers = this._events[evt]; 1067 1068 if (!handlers) { return []; } 1069 if (handlers.fn) { return [handlers.fn]; } 1070 1071 for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) { 1072 ee[i] = handlers[i].fn; 1073 } 1074 1075 return ee; 1076 }; 1077 1078 /** 1079 * Return the number of listeners listening to a given event. 1080 * 1081 * @param {(String|Symbol)} event The event name. 1082 * @returns {Number} The number of listeners. 1083 * @public 1084 */ 1085 EventEmitter.prototype.listenerCount = function listenerCount(event) { 1086 var evt = prefix ? prefix + event : event 1087 , listeners = this._events[evt]; 1088 1089 if (!listeners) { return 0; } 1090 if (listeners.fn) { return 1; } 1091 return listeners.length; 1092 }; 1093 1094 /** 1095 * Calls each of the listeners registered for a given event. 1096 * 1097 * @param {(String|Symbol)} event The event name. 1098 * @returns {Boolean} `true` if the event had listeners, else `false`. 1099 * @public 1100 */ 1101 EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) { 1102 var arguments$1 = arguments; 1103 1104 var evt = prefix ? prefix + event : event; 1105 1106 if (!this._events[evt]) { return false; } 1107 1108 var listeners = this._events[evt] 1109 , len = arguments.length 1110 , args 1111 , i; 1112 1113 if (listeners.fn) { 1114 if (listeners.once) { this.removeListener(event, listeners.fn, undefined, true); } 1115 1116 switch (len) { 1117 case 1: return listeners.fn.call(listeners.context), true; 1118 case 2: return listeners.fn.call(listeners.context, a1), true; 1119 case 3: return listeners.fn.call(listeners.context, a1, a2), true; 1120 case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true; 1121 case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true; 1122 case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true; 1123 } 1124 1125 for (i = 1, args = new Array(len -1); i < len; i++) { 1126 args[i - 1] = arguments$1[i]; 1127 } 1128 1129 listeners.fn.apply(listeners.context, args); 1130 } else { 1131 var length = listeners.length 1132 , j; 1133 1134 for (i = 0; i < length; i++) { 1135 if (listeners[i].once) { this.removeListener(event, listeners[i].fn, undefined, true); } 1136 1137 switch (len) { 1138 case 1: listeners[i].fn.call(listeners[i].context); break; 1139 case 2: listeners[i].fn.call(listeners[i].context, a1); break; 1140 case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break; 1141 case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break; 1142 default: 1143 if (!args) { for (j = 1, args = new Array(len -1); j < len; j++) { 1144 args[j - 1] = arguments$1[j]; 1145 } } 1146 1147 listeners[i].fn.apply(listeners[i].context, args); 1148 } 1149 } 1150 } 1151 1152 return true; 1153 }; 1154 1155 /** 1156 * Add a listener for a given event. 1157 * 1158 * @param {(String|Symbol)} event The event name. 1159 * @param {Function} fn The listener function. 1160 * @param {*} [context=this] The context to invoke the listener with. 1161 * @returns {EventEmitter} `this`. 1162 * @public 1163 */ 1164 EventEmitter.prototype.on = function on(event, fn, context) { 1165 return addListener(this, event, fn, context, false); 1166 }; 1167 1168 /** 1169 * Add a one-time listener for a given event. 1170 * 1171 * @param {(String|Symbol)} event The event name. 1172 * @param {Function} fn The listener function. 1173 * @param {*} [context=this] The context to invoke the listener with. 1174 * @returns {EventEmitter} `this`. 1175 * @public 1176 */ 1177 EventEmitter.prototype.once = function once(event, fn, context) { 1178 return addListener(this, event, fn, context, true); 1179 }; 1180 1181 /** 1182 * Remove the listeners of a given event. 1183 * 1184 * @param {(String|Symbol)} event The event name. 1185 * @param {Function} fn Only remove the listeners that match this function. 1186 * @param {*} context Only remove the listeners that have this context. 1187 * @param {Boolean} once Only remove one-time listeners. 1188 * @returns {EventEmitter} `this`. 1189 * @public 1190 */ 1191 EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) { 1192 var evt = prefix ? prefix + event : event; 1193 1194 if (!this._events[evt]) { return this; } 1195 if (!fn) { 1196 clearEvent(this, evt); 1197 return this; 1198 } 1199 1200 var listeners = this._events[evt]; 1201 1202 if (listeners.fn) { 1203 if ( 1204 listeners.fn === fn && 1205 (!once || listeners.once) && 1206 (!context || listeners.context === context) 1207 ) { 1208 clearEvent(this, evt); 1209 } 1210 } else { 1211 for (var i = 0, events = [], length = listeners.length; i < length; i++) { 1212 if ( 1213 listeners[i].fn !== fn || 1214 (once && !listeners[i].once) || 1215 (context && listeners[i].context !== context) 1216 ) { 1217 events.push(listeners[i]); 1218 } 1219 } 1220 1221 // 1222 // Reset the array, or remove it completely if we have no more listeners. 1223 // 1224 if (events.length) { this._events[evt] = events.length === 1 ? events[0] : events; } 1225 else { clearEvent(this, evt); } 1226 } 1227 1228 return this; 1229 }; 1230 1231 /** 1232 * Remove all listeners, or those of the specified event. 1233 * 1234 * @param {(String|Symbol)} [event] The event name. 1235 * @returns {EventEmitter} `this`. 1236 * @public 1237 */ 1238 EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) { 1239 var evt; 1240 1241 if (event) { 1242 evt = prefix ? prefix + event : event; 1243 if (this._events[evt]) { clearEvent(this, evt); } 1244 } else { 1245 this._events = new Events(); 1246 this._eventsCount = 0; 1247 } 1248 1249 return this; 1250 }; 1251 1252 // 1253 // Alias methods names because people roll like that. 1254 // 1255 EventEmitter.prototype.off = EventEmitter.prototype.removeListener; 1256 EventEmitter.prototype.addListener = EventEmitter.prototype.on; 1257 1258 // 1259 // Expose the prefix. 1260 // 1261 EventEmitter.prefixed = prefix; 1262 1263 // 1264 // Allow `EventEmitter` to be imported as module namespace. 1265 // 1266 EventEmitter.EventEmitter = EventEmitter; 1267 1268 // 1269 // Expose the module. 1270 // 1271 if ('undefined' !== 'object') { 1272 module.exports = EventEmitter; 1273 } 1274 }); 1275 1276 'use strict'; 1277 1278 var earcut_1 = earcut; 1279 var default_1 = earcut; 1280 1281 function earcut(data, holeIndices, dim) { 1282 1283 dim = dim || 2; 1284 1285 var hasHoles = holeIndices && holeIndices.length, 1286 outerLen = hasHoles ? holeIndices[0] * dim : data.length, 1287 outerNode = linkedList(data, 0, outerLen, dim, true), 1288 triangles = []; 1289 1290 if (!outerNode || outerNode.next === outerNode.prev) { return triangles; } 1291 1292 var minX, minY, maxX, maxY, x, y, invSize; 1293 1294 if (hasHoles) { outerNode = eliminateHoles(data, holeIndices, outerNode, dim); } 1295 1296 // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox 1297 if (data.length > 80 * dim) { 1298 minX = maxX = data[0]; 1299 minY = maxY = data[1]; 1300 1301 for (var i = dim; i < outerLen; i += dim) { 1302 x = data[i]; 1303 y = data[i + 1]; 1304 if (x < minX) { minX = x; } 1305 if (y < minY) { minY = y; } 1306 if (x > maxX) { maxX = x; } 1307 if (y > maxY) { maxY = y; } 1308 } 1309 1310 // minX, minY and invSize are later used to transform coords into integers for z-order calculation 1311 invSize = Math.max(maxX - minX, maxY - minY); 1312 invSize = invSize !== 0 ? 1 / invSize : 0; 1313 } 1314 1315 earcutLinked(outerNode, triangles, dim, minX, minY, invSize); 1316 1317 return triangles; 1318 } 1319 1320 // create a circular doubly linked list from polygon points in the specified winding order 1321 function linkedList(data, start, end, dim, clockwise) { 1322 var i, last; 1323 1324 if (clockwise === (signedArea(data, start, end, dim) > 0)) { 1325 for (i = start; i < end;
vendor: 18,084 bytes, lines 1325-1927
1325 i += dim) { last = insertNode(i, data[i], data[i + 1], last); } 1326 } else { 1327 for (i = end - dim; i >= start; i -= dim) { last = insertNode(i, data[i], data[i + 1], last); } 1328 } 1329 1330 if (last && equals(last, last.next)) { 1331 removeNode(last); 1332 last = last.next; 1333 } 1334 1335 return last; 1336 } 1337 1338 // eliminate colinear or duplicate points 1339 function filterPoints(start, end) { 1340 if (!start) { return start; } 1341 if (!end) { end = start; } 1342 1343 var p = start, 1344 again; 1345 do { 1346 again = false; 1347 1348 if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) { 1349 removeNode(p); 1350 p = end = p.prev; 1351 if (p === p.next) { break; } 1352 again = true; 1353 1354 } else { 1355 p = p.next; 1356 } 1357 } while (again || p !== end); 1358 1359 return end; 1360 } 1361 1362 // main ear slicing loop which triangulates a polygon (given as a linked list) 1363 function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) { 1364 if (!ear) { return; } 1365 1366 // interlink polygon nodes in z-order 1367 if (!pass && invSize) { indexCurve(ear, minX, minY, invSize); } 1368 1369 var stop = ear, 1370 prev, next; 1371 1372 // iterate through ears, slicing them one by one 1373 while (ear.prev !== ear.next) { 1374 prev = ear.prev; 1375 next = ear.next; 1376 1377 if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) { 1378 // cut off the triangle 1379 triangles.push(prev.i / dim); 1380 triangles.push(ear.i / dim); 1381 triangles.push(next.i / dim); 1382 1383 removeNode(ear); 1384 1385 // skipping the next vertex leads to less sliver triangles 1386 ear = next.next; 1387 stop = next.next; 1388 1389 continue; 1390 } 1391 1392 ear = next; 1393 1394 // if we looped through the whole remaining polygon and can't find any more ears 1395 if (ear === stop) { 1396 // try filtering points and slicing again 1397 if (!pass) { 1398 earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1); 1399 1400 // if this didn't work, try curing all small self-intersections locally 1401 } else if (pass === 1) { 1402 ear = cureLocalIntersections(ear, triangles, dim); 1403 earcutLinked(ear, triangles, dim, minX, minY, invSize, 2); 1404 1405 // as a last resort, try splitting the remaining polygon into two 1406 } else if (pass === 2) { 1407 splitEarcut(ear, triangles, dim, minX, minY, invSize); 1408 } 1409 1410 break; 1411 } 1412 } 1413 } 1414 1415 // check whether a polygon node forms a valid ear with adjacent nodes 1416 function isEar(ear) { 1417 var a = ear.prev, 1418 b = ear, 1419 c = ear.next; 1420 1421 if (area(a, b, c) >= 0) { return false; } // reflex, can't be an ear 1422 1423 // now make sure we don't have other points inside the potential ear 1424 var p = ear.next.next; 1425 1426 while (p !== ear.prev) { 1427 if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && 1428 area(p.prev, p, p.next) >= 0) { return false; } 1429 p = p.next; 1430 } 1431 1432 return true; 1433 } 1434 1435 function isEarHashed(ear, minX, minY, invSize) { 1436 var a = ear.prev, 1437 b = ear, 1438 c = ear.next; 1439 1440 if (area(a, b, c) >= 0) { return false; } // reflex, can't be an ear 1441 1442 // triangle bbox; min & max are calculated like this for speed 1443 var minTX = a.x < b.x ? (a.x < c.x ? a.x : c.x) : (b.x < c.x ? b.x : c.x), 1444 minTY = a.y < b.y ? (a.y < c.y ? a.y : c.y) : (b.y < c.y ? b.y : c.y), 1445 maxTX = a.x > b.x ? (a.x > c.x ? a.x : c.x) : (b.x > c.x ? b.x : c.x), 1446 maxTY = a.y > b.y ? (a.y > c.y ? a.y : c.y) : (b.y > c.y ? b.y : c.y); 1447 1448 // z-order range for the current triangle bbox; 1449 var minZ = zOrder(minTX, minTY, minX, minY, invSize), 1450 maxZ = zOrder(maxTX, maxTY, minX, minY, invSize); 1451 1452 var p = ear.prevZ, 1453 n = ear.nextZ; 1454 1455 // look for points inside the triangle in both directions 1456 while (p && p.z >= minZ && n && n.z <= maxZ) { 1457 if (p !== ear.prev && p !== ear.next && 1458 pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && 1459 area(p.prev, p, p.next) >= 0) { return false; } 1460 p = p.prevZ; 1461 1462 if (n !== ear.prev && n !== ear.next && 1463 pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) && 1464 area(n.prev, n, n.next) >= 0) { return false; } 1465 n = n.nextZ; 1466 } 1467 1468 // look for remaining points in decreasing z-order 1469 while (p && p.z >= minZ) { 1470 if (p !== ear.prev && p !== ear.next && 1471 pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && 1472 area(p.prev, p, p.next) >= 0) { return false; } 1473 p = p.prevZ; 1474 } 1475 1476 // look for remaining points in increasing z-order 1477 while (n && n.z <= maxZ) { 1478 if (n !== ear.prev && n !== ear.next && 1479 pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) && 1480 area(n.prev, n, n.next) >= 0) { return false; } 1481 n = n.nextZ; 1482 } 1483 1484 return true; 1485 } 1486 1487 // go through all polygon nodes and cure small local self-intersections 1488 function cureLocalIntersections(start, triangles, dim) { 1489 var p = start; 1490 do { 1491 var a = p.prev, 1492 b = p.next.next; 1493 1494 if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) { 1495 1496 triangles.push(a.i / dim); 1497 triangles.push(p.i / dim); 1498 triangles.push(b.i / dim); 1499 1500 // remove two nodes involved 1501 removeNode(p); 1502 removeNode(p.next); 1503 1504 p = start = b; 1505 } 1506 p = p.next; 1507 } while (p !== start); 1508 1509 return p; 1510 } 1511 1512 // try splitting polygon into two and triangulate them independently 1513 function splitEarcut(start, triangles, dim, minX, minY, invSize) { 1514 // look for a valid diagonal that divides the polygon into two 1515 var a = start; 1516 do { 1517 var b = a.next.next; 1518 while (b !== a.prev) { 1519 if (a.i !== b.i && isValidDiagonal(a, b)) { 1520 // split the polygon in two by the diagonal 1521 var c = splitPolygon(a, b); 1522 1523 // filter colinear points around the cuts 1524 a = filterPoints(a, a.next); 1525 c = filterPoints(c, c.next); 1526 1527 // run earcut on each half 1528 earcutLinked(a, triangles, dim, minX, minY, invSize); 1529 earcutLinked(c, triangles, dim, minX, minY, invSize); 1530 return; 1531 } 1532 b = b.next; 1533 } 1534 a = a.next; 1535 } while (a !== start); 1536 } 1537 1538 // link every hole into the outer loop, producing a single-ring polygon without holes 1539 function eliminateHoles(data, holeIndices, outerNode, dim) { 1540 var queue = [], 1541 i, len, start, end, list; 1542 1543 for (i = 0, len = holeIndices.length; i < len; i++) { 1544 start = holeIndices[i] * dim; 1545 end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; 1546 list = linkedList(data, start, end, dim, false); 1547 if (list === list.next) { list.steiner = true; } 1548 queue.push(getLeftmost(list)); 1549 } 1550 1551 queue.sort(compareX); 1552 1553 // process holes from left to right 1554 for (i = 0; i < queue.length; i++) { 1555 eliminateHole(queue[i], outerNode); 1556 outerNode = filterPoints(outerNode, outerNode.next); 1557 } 1558 1559 return outerNode; 1560 } 1561 1562 function compareX(a, b) { 1563 return a.x - b.x; 1564 } 1565 1566 // find a bridge between vertices that connects hole with an outer ring and and link it 1567 function eliminateHole(hole, outerNode) { 1568 outerNode = findHoleBridge(hole, outerNode); 1569 if (outerNode) { 1570 var b = splitPolygon(outerNode, hole); 1571 filterPoints(b, b.next); 1572 } 1573 } 1574 1575 // David Eberly's algorithm for finding a bridge between hole and outer polygon 1576 function findHoleBridge(hole, outerNode) { 1577 var p = outerNode, 1578 hx = hole.x, 1579 hy = hole.y, 1580 qx = -Infinity, 1581 m; 1582 1583 // find a segment intersected by a ray from the hole's leftmost point to the left; 1584 // segment's endpoint with lesser x will be potential connection point 1585 do { 1586 if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) { 1587 var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y); 1588 if (x <= hx && x > qx) { 1589 qx = x; 1590 if (x === hx) { 1591 if (hy === p.y) { return p; } 1592 if (hy === p.next.y) { return p.next; } 1593 } 1594 m = p.x < p.next.x ? p : p.next; 1595 } 1596 } 1597 p = p.next; 1598 } while (p !== outerNode); 1599 1600 if (!m) { return null; } 1601 1602 if (hx === qx) { return m.prev; } // hole touches outer segment; pick lower endpoint 1603 1604 // look for points inside the triangle of hole point, segment intersection and endpoint; 1605 // if there are no points found, we have a valid connection; 1606 // otherwise choose the point of the minimum angle with the ray as connection point 1607 1608 var stop = m, 1609 mx = m.x, 1610 my = m.y, 1611 tanMin = Infinity, 1612 tan; 1613 1614 p = m.next; 1615 1616 while (p !== stop) { 1617 if (hx >= p.x && p.x >= mx && hx !== p.x && 1618 pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) { 1619 1620 tan = Math.abs(hy - p.y) / (hx - p.x); // tangential 1621 1622 if ((tan < tanMin || (tan === tanMin && p.x > m.x)) && locallyInside(p, hole)) { 1623 m = p; 1624 tanMin = tan; 1625 } 1626 } 1627 1628 p = p.next; 1629 } 1630 1631 return m; 1632 } 1633 1634 // interlink polygon nodes in z-order 1635 function indexCurve(start, minX, minY, invSize) { 1636 var p = start; 1637 do { 1638 if (p.z === null) { p.z = zOrder(p.x, p.y, minX, minY, invSize); } 1639 p.prevZ = p.prev; 1640 p.nextZ = p.next; 1641 p = p.next; 1642 } while (p !== start); 1643 1644 p.prevZ.nextZ = null; 1645 p.prevZ = null; 1646 1647 sortLinked(p); 1648 } 1649 1650 // Simon Tatham's linked list merge sort algorithm 1651 // http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html 1652 function sortLinked(list) { 1653 var i, p, q, e, tail, numMerges, pSize, qSize, 1654 inSize = 1; 1655 1656 do { 1657 p = list; 1658 list = null; 1659 tail = null; 1660 numMerges = 0; 1661 1662 while (p) { 1663 numMerges++; 1664 q = p; 1665 pSize = 0; 1666 for (i = 0; i < inSize; i++) { 1667 pSize++; 1668 q = q.nextZ; 1669 if (!q) { break; } 1670 } 1671 qSize = inSize; 1672 1673 while (pSize > 0 || (qSize > 0 && q)) { 1674 1675 if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) { 1676 e = p; 1677 p = p.nextZ; 1678 pSize--; 1679 } else { 1680 e = q; 1681 q = q.nextZ; 1682 qSize--; 1683 } 1684 1685 if (tail) { tail.nextZ = e; } 1686 else { list = e; } 1687 1688 e.prevZ = tail; 1689 tail = e; 1690 } 1691 1692 p = q; 1693 } 1694 1695 tail.nextZ = null; 1696 inSize *= 2; 1697 1698 } while (numMerges > 1); 1699 1700 return list; 1701 } 1702 1703 // z-order of a point given coords and inverse of the longer side of data bbox 1704 function zOrder(x, y, minX, minY, invSize) { 1705 // coords are transformed into non-negative 15-bit integer range 1706 x = 32767 * (x - minX) * invSize; 1707 y = 32767 * (y - minY) * invSize; 1708 1709 x = (x | (x << 8)) & 0x00FF00FF; 1710 x = (x | (x << 4)) & 0x0F0F0F0F; 1711 x = (x | (x << 2)) & 0x33333333; 1712 x = (x | (x << 1)) & 0x55555555; 1713 1714 y = (y | (y << 8)) & 0x00FF00FF; 1715 y = (y | (y << 4)) & 0x0F0F0F0F; 1716 y = (y | (y << 2)) & 0x33333333; 1717 y = (y | (y << 1)) & 0x55555555; 1718 1719 return x | (y << 1); 1720 } 1721 1722 // find the leftmost node of a polygon ring 1723 function getLeftmost(start) { 1724 var p = start, 1725 leftmost = start; 1726 do { 1727 if (p.x < leftmost.x || (p.x === leftmost.x && p.y < leftmost.y)) { leftmost = p; } 1728 p = p.next; 1729 } while (p !== start); 1730 1731 return leftmost; 1732 } 1733 1734 // check if a point lies within a convex triangle 1735 function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) { 1736 return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 && 1737 (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 && 1738 (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0; 1739 } 1740 1741 // check if a diagonal between two polygon nodes is valid (lies in polygon interior) 1742 function isValidDiagonal(a, b) { 1743 return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && 1744 locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b); 1745 } 1746 1747 // signed area of a triangle 1748 function area(p, q, r) { 1749 return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y); 1750 } 1751 1752 // check if two points are equal 1753 function equals(p1, p2) { 1754 return p1.x === p2.x && p1.y === p2.y; 1755 } 1756 1757 // check if two segments intersect 1758 function intersects(p1, q1, p2, q2) { 1759 if ((equals(p1, q1) && equals(p2, q2)) || 1760 (equals(p1, q2) && equals(p2, q1))) { return true; } 1761 return area(p1, q1, p2) > 0 !== area(p1, q1, q2) > 0 && 1762 area(p2, q2, p1) > 0 !== area(p2, q2, q1) > 0; 1763 } 1764 1765 // check if a polygon diagonal intersects any polygon segments 1766 function intersectsPolygon(a, b) { 1767 var p = a; 1768 do { 1769 if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && 1770 intersects(p, p.next, a, b)) { return true; } 1771 p = p.next; 1772 } while (p !== a); 1773 1774 return false; 1775 } 1776 1777 // check if a polygon diagonal is locally inside the polygon 1778 function locallyInside(a, b) { 1779 return area(a.prev, a, a.next) < 0 ? 1780 area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : 1781 area(a, b, a.prev) < 0 || area(a, a.next, b) < 0; 1782 } 1783 1784 // check if the middle point of a polygon diagonal is inside the polygon 1785 function middleInside(a, b) { 1786 var p = a, 1787 inside = false, 1788 px = (a.x + b.x) / 2, 1789 py = (a.y + b.y) / 2; 1790 do { 1791 if (((p.y > py) !== (p.next.y > py)) && p.next.y !== p.y && 1792 (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x)) 1793 { inside = !inside; } 1794 p = p.next; 1795 } while (p !== a); 1796 1797 return inside; 1798 } 1799 1800 // link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two; 1801 // if one belongs to the outer ring and another to a hole, it merges it into a single ring 1802 function splitPolygon(a, b) { 1803 var a2 = new Node(a.i, a.x, a.y), 1804 b2 = new Node(b.i, b.x, b.y), 1805 an = a.next, 1806 bp = b.prev; 1807 1808 a.next = b; 1809 b.prev = a; 1810 1811 a2.next = an; 1812 an.prev = a2; 1813 1814 b2.next = a2; 1815 a2.prev = b2; 1816 1817 bp.next = b2; 1818 b2.prev = bp; 1819 1820 return b2; 1821 } 1822 1823 // create a node and optionally link it with previous one (in a circular doubly linked list) 1824 function insertNode(i, x, y, last) { 1825 var p = new Node(i, x, y); 1826 1827 if (!last) { 1828 p.prev = p; 1829 p.next = p; 1830 1831 } else { 1832 p.next = last.next; 1833 p.prev = last; 1834 last.next.prev = p; 1835 last.next = p; 1836 } 1837 return p; 1838 } 1839 1840 function removeNode(p) { 1841 p.next.prev = p.prev; 1842 p.prev.next = p.next; 1843 1844 if (p.prevZ) { p.prevZ.nextZ = p.nextZ; } 1845 if (p.nextZ) { p.nextZ.prevZ = p.prevZ; } 1846 } 1847 1848 function Node(i, x, y) { 1849 // vertex index in coordinates array 1850 this.i = i; 1851 1852 // vertex coordinates 1853 this.x = x; 1854 this.y = y; 1855 1856 // previous and next vertex nodes in a polygon ring 1857 this.prev = null; 1858 this.next = null; 1859 1860 // z-order curve value 1861 this.z = null; 1862 1863 // previous and next nodes in z-order 1864 this.prevZ = null; 1865 this.nextZ = null; 1866 1867 // indicates whether this is a steiner point 1868 this.steiner = false; 1869 } 1870 1871 // return a percentage difference between the polygon area and its triangulation area; 1872 // used to verify correctness of triangulation 1873 earcut.deviation = function (data, holeIndices, dim, triangles) { 1874 var hasHoles = holeIndices && holeIndices.length; 1875 var outerLen = hasHoles ? holeIndices[0] * dim : data.length; 1876 1877 var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim)); 1878 if (hasHoles) { 1879 for (var i = 0, len = holeIndices.length; i < len; i++) { 1880 var start = holeIndices[i] * dim; 1881 var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; 1882 polygonArea -= Math.abs(signedArea(data, start, end, dim)); 1883 } 1884 } 1885 1886 var trianglesArea = 0; 1887 for (i = 0; i < triangles.length; i += 3) { 1888 var a = triangles[i] * dim; 1889 var b = triangles[i + 1] * dim; 1890 var c = triangles[i + 2] * dim; 1891 trianglesArea += Math.abs( 1892 (data[a] - data[c]) * (data[b + 1] - data[a + 1]) - 1893 (data[a] - data[b]) * (data[c + 1] - data[a + 1])); 1894 } 1895 1896 return polygonArea === 0 && trianglesArea === 0 ? 0 : 1897 Math.abs((trianglesArea - polygonArea) / polygonArea); 1898 }; 1899 1900 function signedArea(data, start, end, dim) { 1901 var sum = 0; 1902 for (var i = start, j = end - dim; i < end; i += dim) { 1903 sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]); 1904 j = i; 1905 } 1906 return sum; 1907 } 1908 1909 // turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts 1910 earcut.flatten = function (data) { 1911 var dim = data[0][0].length, 1912 result = {vertices: [], holes: [], dimensions: dim}, 1913 holeIndex = 0; 1914 1915 for (var i = 0; i < data.length; i++) { 1916 for (var j = 0; j < data[i].length; j++) { 1917 for (var d = 0; d < dim; d++) { result.vertices.push(data[i][j][d]); } 1918 } 1919 if (i > 0) { 1920 holeIndex += data[i - 1].length; 1921 result.holes.push(holeIndex); 1922 } 1923 } 1924 return result; 1925 }; 1926 earcut_1.default = default_1; 1927
vendor: 51,963 bytes, lines 1928-3644
1928 var punycode = createCommonjsModule(function (module, exports) { 1929 /*! https://mths.be/punycode v1.3.2 by @mathias */ 1930 ;(function(root) { 1931 1932 /** Detect free variables */ 1933 var freeExports = 'object' == 'object' && exports && 1934 !exports.nodeType && exports; 1935 var freeModule = 'object' == 'object' && module && 1936 !module.nodeType && module; 1937 var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal; 1938 if ( 1939 freeGlobal.global === freeGlobal || 1940 freeGlobal.window === freeGlobal || 1941 freeGlobal.self === freeGlobal 1942 ) { 1943 root = freeGlobal; 1944 } 1945 1946 /** 1947 * The `punycode` object. 1948 * @name punycode 1949 * @type Object 1950 */ 1951 var punycode, 1952 1953 /** Highest positive signed 32-bit float value */ 1954 maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1 1955 1956 /** Bootstring parameters */ 1957 base = 36, 1958 tMin = 1, 1959 tMax = 26, 1960 skew = 38, 1961 damp = 700, 1962 initialBias = 72, 1963 initialN = 128, // 0x80 1964 delimiter = '-', // '\x2D' 1965 1966 /** Regular expressions */ 1967 regexPunycode = /^xn--/, 1968 regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars 1969 regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators 1970 1971 /** Error messages */ 1972 errors = { 1973 'overflow': 'Overflow: input needs wider integers to process', 1974 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', 1975 'invalid-input': 'Invalid input' 1976 }, 1977 1978 /** Convenience shortcuts */ 1979 baseMinusTMin = base - tMin, 1980 floor = Math.floor, 1981 stringFromCharCode = String.fromCharCode, 1982 1983 /** Temporary variable */ 1984 key; 1985 1986 /*--------------------------------------------------------------------------*/ 1987 1988 /** 1989 * A generic error utility function. 1990 * @private 1991 * @param {String} type The error type. 1992 * @returns {Error} Throws a `RangeError` with the applicable error message. 1993 */ 1994 function error(type) { 1995 throw RangeError(errors[type]); 1996 } 1997 1998 /** 1999 * A generic `Array#map` utility function. 2000 * @private 2001 * @param {Array} array The array to iterate over. 2002 * @param {Function} callback The function that gets called for every array 2003 * item. 2004 * @returns {Array} A new array of values returned by the callback function. 2005 */ 2006 function map(array, fn) { 2007 var length = array.length; 2008 var result = []; 2009 while (length--) { 2010 result[length] = fn(array[length]); 2011 } 2012 return result; 2013 } 2014 2015 /** 2016 * A simple `Array#map`-like wrapper to work with domain name strings or email 2017 * addresses. 2018 * @private 2019 * @param {String} domain The domain name or email address. 2020 * @param {Function} callback The function that gets called for every 2021 * character. 2022 * @returns {Array} A new string of characters returned by the callback 2023 * function. 2024 */ 2025 function mapDomain(string, fn) { 2026 var parts = string.split('@'); 2027 var result = ''; 2028 if (parts.length > 1) { 2029 // In email addresses, only the domain name should be punycoded. Leave 2030 // the local part (i.e. everything up to `@`) intact. 2031 result = parts[0] + '@'; 2032 string = parts[1]; 2033 } 2034 // Avoid `split(regex)` for IE8 compatibility. See #17. 2035 string = string.replace(regexSeparators, '\x2E'); 2036 var labels = string.split('.'); 2037 var encoded = map(labels, fn).join('.'); 2038 return result + encoded; 2039 } 2040 2041 /** 2042 * Creates an array containing the numeric code points of each Unicode 2043 * character in the string. While JavaScript uses UCS-2 internally, 2044 * this function will convert a pair of surrogate halves (each of which 2045 * UCS-2 exposes as separate characters) into a single code point, 2046 * matching UTF-16. 2047 * @see `punycode.ucs2.encode` 2048 * @see <https://mathiasbynens.be/notes/javascript-encoding> 2049 * @memberOf punycode.ucs2 2050 * @name decode 2051 * @param {String} string The Unicode input string (UCS-2). 2052 * @returns {Array} The new array of code points. 2053 */ 2054 function ucs2decode(string) { 2055 var output = [], 2056 counter = 0, 2057 length = string.length, 2058 value, 2059 extra; 2060 while (counter < length) { 2061 value = string.charCodeAt(counter++); 2062 if (value >= 0xD800 && value <= 0xDBFF && counter < length) { 2063 // high surrogate, and there is a next character 2064 extra = string.charCodeAt(counter++); 2065 if ((extra & 0xFC00) == 0xDC00) { // low surrogate 2066 output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); 2067 } else { 2068 // unmatched surrogate; only append this code unit, in case the next 2069 // code unit is the high surrogate of a surrogate pair 2070 output.push(value); 2071 counter--; 2072 } 2073 } else { 2074 output.push(value); 2075 } 2076 } 2077 return output; 2078 } 2079 2080 /** 2081 * Creates a string based on an array of numeric code points. 2082 * @see `punycode.ucs2.decode` 2083 * @memberOf punycode.ucs2 2084 * @name encode 2085 * @param {Array} codePoints The array of numeric code points. 2086 * @returns {String} The new Unicode string (UCS-2). 2087 */ 2088 function ucs2encode(array) { 2089 return map(array, function(value) { 2090 var output = ''; 2091 if (value > 0xFFFF) { 2092 value -= 0x10000; 2093 output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); 2094 value = 0xDC00 | value & 0x3FF; 2095 } 2096 output += stringFromCharCode(value); 2097 return output; 2098 }).join(''); 2099 } 2100 2101 /** 2102 * Converts a basic code point into a digit/integer. 2103 * @see `digitToBasic()` 2104 * @private 2105 * @param {Number} codePoint The basic numeric code point value. 2106 * @returns {Number} The numeric value of a basic code point (for use in 2107 * representing integers) in the range `0` to `base - 1`, or `base` if 2108 * the code point does not represent a value. 2109 */ 2110 function basicToDigit(codePoint) { 2111 if (codePoint - 48 < 10) { 2112 return codePoint - 22; 2113 } 2114 if (codePoint - 65 < 26) { 2115 return codePoint - 65; 2116 } 2117 if (codePoint - 97 < 26) { 2118 return codePoint - 97; 2119 } 2120 return base; 2121 } 2122 2123 /** 2124 * Converts a digit/integer into a basic code point. 2125 * @see `basicToDigit()` 2126 * @private 2127 * @param {Number} digit The numeric value of a basic code point. 2128 * @returns {Number} The basic code point whose value (when used for 2129 * representing integers) is `digit`, which needs to be in the range 2130 * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is 2131 * used; else, the lowercase form is used. The behavior is undefined 2132 * if `flag` is non-zero and `digit` has no uppercase form. 2133 */ 2134 function digitToBasic(digit, flag) { 2135 // 0..25 map to ASCII a..z or A..Z 2136 // 26..35 map to ASCII 0..9 2137 return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); 2138 } 2139 2140 /** 2141 * Bias adaptation function as per section 3.4 of RFC 3492. 2142 * http://tools.ietf.org/html/rfc3492#section-3.4 2143 * @private 2144 */ 2145 function adapt(delta, numPoints, firstTime) { 2146 var k = 0; 2147 delta = firstTime ? floor(delta / damp) : delta >> 1; 2148 delta += floor(delta / numPoints); 2149 for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) { 2150 delta = floor(delta / baseMinusTMin); 2151 } 2152 return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); 2153 } 2154 2155 /** 2156 * Converts a Punycode string of ASCII-only symbols to a string of Unicode 2157 * symbols. 2158 * @memberOf punycode 2159 * @param {String} input The Punycode string of ASCII-only symbols. 2160 * @returns {String} The resulting string of Unicode symbols. 2161 */ 2162 function decode(input) { 2163 // Don't use UCS-2 2164 var output = [], 2165 inputLength = input.length, 2166 out, 2167 i = 0, 2168 n = initialN, 2169 bias = initialBias, 2170 basic, 2171 j, 2172 index, 2173 oldi, 2174 w, 2175 k, 2176 digit, 2177 t, 2178 /** Cached calculation results */ 2179 baseMinusT; 2180 2181 // Handle the basic code points: let `basic` be the number of input code 2182 // points before the last delimiter, or `0` if there is none, then copy 2183 // the first basic code points to the output. 2184 2185 basic = input.lastIndexOf(delimiter); 2186 if (basic < 0) { 2187 basic = 0; 2188 } 2189 2190 for (j = 0; j < basic; ++j) { 2191 // if it's not a basic code point 2192 if (input.charCodeAt(j) >= 0x80) { 2193 error('not-basic'); 2194 } 2195 output.push(input.charCodeAt(j)); 2196 } 2197 2198 // Main decoding loop: start just after the last delimiter if any basic code 2199 // points were copied; start at the beginning otherwise. 2200 2201 for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) { 2202 2203 // `index` is the index of the next character to be consumed. 2204 // Decode a generalized variable-length integer into `delta`, 2205 // which gets added to `i`. The overflow checking is easier 2206 // if we increase `i` as we go, then subtract off its starting 2207 // value at the end to obtain `delta`. 2208 for (oldi = i, w = 1, k = base; /* no condition */; k += base) { 2209 2210 if (index >= inputLength) { 2211 error('invalid-input'); 2212 } 2213 2214 digit = basicToDigit(input.charCodeAt(index++)); 2215 2216 if (digit >= base || digit > floor((maxInt - i) / w)) { 2217 error('overflow'); 2218 } 2219 2220 i += digit * w; 2221 t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); 2222 2223 if (digit < t) { 2224 break; 2225 } 2226 2227 baseMinusT = base - t; 2228 if (w > floor(maxInt / baseMinusT)) { 2229 error('overflow'); 2230 } 2231 2232 w *= baseMinusT; 2233 2234 } 2235 2236 out = output.length + 1; 2237 bias = adapt(i - oldi, out, oldi == 0); 2238 2239 // `i` was supposed to wrap around from `out` to `0`, 2240 // incrementing `n` each time, so we'll fix that now: 2241 if (floor(i / out) > maxInt - n) { 2242 error('overflow'); 2243 } 2244 2245 n += floor(i / out); 2246 i %= out; 2247 2248 // Insert `n` at position `i` of the output 2249 output.splice(i++, 0, n); 2250 2251 } 2252 2253 return ucs2encode(output); 2254 } 2255 2256 /** 2257 * Converts a string of Unicode symbols (e.g. a domain name label) to a 2258 * Punycode string of ASCII-only symbols. 2259 * @memberOf punycode 2260 * @param {String} input The string of Unicode symbols. 2261 * @returns {String} The resulting Punycode string of ASCII-only symbols. 2262 */ 2263 function encode(input) { 2264 var n, 2265 delta, 2266 handledCPCount, 2267 basicLength, 2268 bias, 2269 j, 2270 m, 2271 q, 2272 k, 2273 t, 2274 currentValue, 2275 output = [], 2276 /** `inputLength` will hold the number of code points in `input`. */ 2277 inputLength, 2278 /** Cached calculation results */ 2279 handledCPCountPlusOne, 2280 baseMinusT, 2281 qMinusT; 2282 2283 // Convert the input in UCS-2 to Unicode 2284 input = ucs2decode(input); 2285 2286 // Cache the length 2287 inputLength = input.length; 2288 2289 // Initialize the state 2290 n = initialN; 2291 delta = 0; 2292 bias = initialBias; 2293 2294 // Handle the basic code points 2295 for (j = 0; j < inputLength; ++j) { 2296 currentValue = input[j]; 2297 if (currentValue < 0x80) { 2298 output.push(stringFromCharCode(currentValue)); 2299 } 2300 } 2301 2302 handledCPCount = basicLength = output.length; 2303 2304 // `handledCPCount` is the number of code points that have been handled; 2305 // `basicLength` is the number of basic code points. 2306 2307 // Finish the basic string - if it is not empty - with a delimiter 2308 if (basicLength) { 2309 output.push(delimiter); 2310 } 2311 2312 // Main encoding loop: 2313 while (handledCPCount < inputLength) { 2314 2315 // All non-basic code points < n have been handled already. Find the next 2316 // larger one: 2317 for (m = maxInt, j = 0; j < inputLength; ++j) { 2318 currentValue = input[j]; 2319 if (currentValue >= n && currentValue < m) { 2320 m = currentValue; 2321 } 2322 } 2323 2324 // Increase `delta` enough to advance the decoder's <n,i> state to <m,0>, 2325 // but guard against overflow 2326 handledCPCountPlusOne = handledCPCount + 1; 2327 if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { 2328 error('overflow'); 2329 } 2330 2331 delta += (m - n) * handledCPCountPlusOne; 2332 n = m; 2333 2334 for (j = 0; j < inputLength; ++j) { 2335 currentValue = input[j]; 2336 2337 if (currentValue < n && ++delta > maxInt) { 2338 error('overflow'); 2339 } 2340 2341 if (currentValue == n) { 2342 // Represent delta as a generalized variable-length integer 2343 for (q = delta, k = base; /* no condition */; k += base) { 2344 t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); 2345 if (q < t) { 2346 break; 2347 } 2348 qMinusT = q - t; 2349 baseMinusT = base - t; 2350 output.push( 2351 stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) 2352 ); 2353 q = floor(qMinusT / baseMinusT); 2354 } 2355 2356 output.push(stringFromCharCode(digitToBasic(q, 0))); 2357 bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); 2358 delta = 0; 2359 ++handledCPCount; 2360 } 2361 } 2362 2363 ++delta; 2364 ++n; 2365 2366 } 2367 return output.join(''); 2368 } 2369 2370 /** 2371 * Converts a Punycode string representing a domain name or an email address 2372 * to Unicode. Only the Punycoded parts of the input will be converted, i.e. 2373 * it doesn't matter if you call it on a string that has already been 2374 * converted to Unicode. 2375 * @memberOf punycode 2376 * @param {String} input The Punycoded domain name or email address to 2377 * convert to Unicode. 2378 * @returns {String} The Unicode representation of the given Punycode 2379 * string. 2380 */ 2381 function toUnicode(input) { 2382 return mapDomain(input, function(string) { 2383 return regexPunycode.test(string) 2384 ? decode(string.slice(4).toLowerCase()) 2385 : string; 2386 }); 2387 } 2388 2389 /** 2390 * Converts a Unicode string representing a domain name or an email address to 2391 * Punycode. Only the non-ASCII parts of the domain name will be converted, 2392 * i.e. it doesn't matter if you call it with a domain that's already in 2393 * ASCII. 2394 * @memberOf punycode 2395 * @param {String} input The domain name or email address to convert, as a 2396 * Unicode string. 2397 * @returns {String} The Punycode representation of the given domain name or 2398 * email address. 2399 */ 2400 function toASCII(input) { 2401 return mapDomain(input, function(string) { 2402 return regexNonASCII.test(string) 2403 ? 'xn--' + encode(string) 2404 : string; 2405 }); 2406 } 2407 2408 /*--------------------------------------------------------------------------*/ 2409 2410 /** Define the public API */ 2411 punycode = { 2412 /** 2413 * A string representing the current Punycode.js version number. 2414 * @memberOf punycode 2415 * @type String 2416 */ 2417 'version': '1.3.2', 2418 /** 2419 * An object of methods to convert from JavaScript's internal character 2420 * representation (UCS-2) to Unicode code points, and back. 2421 * @see <https://mathiasbynens.be/notes/javascript-encoding> 2422 * @memberOf punycode 2423 * @type Object 2424 */ 2425 'ucs2': { 2426 'decode': ucs2decode, 2427 'encode': ucs2encode 2428 }, 2429 'decode': decode, 2430 'encode': encode, 2431 'toASCII': toASCII, 2432 'toUnicode': toUnicode 2433 }; 2434 2435 /** Expose `punycode` */ 2436 // Some AMD build optimizers, like r.js, check for specific condition patterns 2437 // like the following: 2438 if ( 2439 typeof undefined == 'function' && 2440 typeof undefined.amd == 'object' && 2441 undefined.amd 2442 ) { 2443 undefined('punycode', function() { 2444 return punycode; 2445 }); 2446 } else if (freeExports && freeModule) { 2447 if (module.exports == freeExports) { // in Node.js or RingoJS v0.8.0+ 2448 freeModule.exports = punycode; 2449 } else { // in Narwhal or RingoJS v0.7.0- 2450 for (key in punycode) { 2451 punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]); 2452 } 2453 } 2454 } else { // in Rhino or a web browser 2455 root.punycode = punycode; 2456 } 2457 2458 }(commonjsGlobal)); 2459 }); 2460 2461 'use strict'; 2462 2463 var util = { 2464 isString: function(arg) { 2465 return typeof(arg) === 'string'; 2466 }, 2467 isObject: function(arg) { 2468 return typeof(arg) === 'object' && arg !== null; 2469 }, 2470 isNull: function(arg) { 2471 return arg === null; 2472 }, 2473 isNullOrUndefined: function(arg) { 2474 return arg == null; 2475 } 2476 }; 2477 var util_1 = util.isString; 2478 var util_2 = util.isObject; 2479 var util_3 = util.isNull; 2480 var util_4 = util.isNullOrUndefined; 2481 2482 // Copyright Joyent, Inc. and other Node contributors. 2483 // 2484 // Permission is hereby granted, free of charge, to any person obtaining a 2485 // copy of this software and associated documentation files (the 2486 // "Software"), to deal in the Software without restriction, including 2487 // without limitation the rights to use, copy, modify, merge, publish, 2488 // distribute, sublicense, and/or sell copies of the Software, and to permit 2489 // persons to whom the Software is furnished to do so, subject to the 2490 // following conditions: 2491 // 2492 // The above copyright notice and this permission notice shall be included 2493 // in all copies or substantial portions of the Software. 2494 // 2495 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 2496 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2497 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 2498 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 2499 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 2500 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 2501 // USE OR OTHER DEALINGS IN THE SOFTWARE. 2502 2503 'use strict'; 2504 2505 // If obj.hasOwnProperty has been overridden, then calling 2506 // obj.hasOwnProperty(prop) will break. 2507 // See: https://github.com/joyent/node/issues/1707 2508 function hasOwnProperty$1(obj, prop) { 2509 return Object.prototype.hasOwnProperty.call(obj, prop); 2510 } 2511 2512 var decode = function(qs, sep, eq, options) { 2513 sep = sep || '&'; 2514 eq = eq || '='; 2515 var obj = {}; 2516 2517 if (typeof qs !== 'string' || qs.length === 0) { 2518 return obj; 2519 } 2520 2521 var regexp = /\+/g; 2522 qs = qs.split(sep); 2523 2524 var maxKeys = 1000; 2525 if (options && typeof options.maxKeys === 'number') { 2526 maxKeys = options.maxKeys; 2527 } 2528 2529 var len = qs.length; 2530 // maxKeys <= 0 means that we should not limit keys count 2531 if (maxKeys > 0 && len > maxKeys) { 2532 len = maxKeys; 2533 } 2534 2535 for (var i = 0; i < len; ++i) { 2536 var x = qs[i].replace(regexp, '%20'), 2537 idx = x.indexOf(eq), 2538 kstr, vstr, k, v; 2539 2540 if (idx >= 0) { 2541 kstr = x.substr(0, idx); 2542 vstr = x.substr(idx + 1); 2543 } else { 2544 kstr = x; 2545 vstr = ''; 2546 } 2547 2548 k = decodeURIComponent(kstr); 2549 v = decodeURIComponent(vstr); 2550 2551 if (!hasOwnProperty$1(obj, k)) { 2552 obj[k] = v; 2553 } else if (Array.isArray(obj[k])) { 2554 obj[k].push(v); 2555 } else { 2556 obj[k] = [obj[k], v]; 2557 } 2558 } 2559 2560 return obj; 2561 }; 2562 2563 // Copyright Joyent, Inc. and other Node contributors. 2564 // 2565 // Permission is hereby granted, free of charge, to any person obtaining a 2566 // copy of this software and associated documentation files (the 2567 // "Software"), to deal in the Software without restriction, including 2568 // without limitation the rights to use, copy, modify, merge, publish, 2569 // distribute, sublicense, and/or sell copies of the Software, and to permit 2570 // persons to whom the Software is furnished to do so, subject to the 2571 // following conditions: 2572 // 2573 // The above copyright notice and this permission notice shall be included 2574 // in all copies or substantial portions of the Software. 2575 // 2576 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 2577 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2578 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 2579 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 2580 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 2581 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 2582 // USE OR OTHER DEALINGS IN THE SOFTWARE. 2583 2584 'use strict'; 2585 2586 var stringifyPrimitive = function(v) { 2587 switch (typeof v) { 2588 case 'string': 2589 return v; 2590 2591 case 'boolean': 2592 return v ? 'true' : 'false'; 2593 2594 case 'number': 2595 return isFinite(v) ? v : ''; 2596 2597 default: 2598 return ''; 2599 } 2600 }; 2601 2602 var encode = function(obj, sep, eq, name) { 2603 sep = sep || '&'; 2604 eq = eq || '='; 2605 if (obj === null) { 2606 obj = undefined; 2607 } 2608 2609 if (typeof obj === 'object') { 2610 return Object.keys(obj).map(function(k) { 2611 var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; 2612 if (Array.isArray(obj[k])) { 2613 return obj[k].map(function(v) { 2614 return ks + encodeURIComponent(stringifyPrimitive(v)); 2615 }).join(sep); 2616 } else { 2617 return ks + encodeURIComponent(stringifyPrimitive(obj[k])); 2618 } 2619 }).join(sep); 2620 2621 } 2622 2623 if (!name) { return ''; } 2624 return encodeURIComponent(stringifyPrimitive(name)) + eq + 2625 encodeURIComponent(stringifyPrimitive(obj)); 2626 }; 2627 2628 var querystring = createCommonjsModule(function (module, exports) { 2629 'use strict'; 2630 2631 exports.decode = exports.parse = decode; 2632 exports.encode = exports.stringify = encode; 2633 }); 2634 var querystring_1 = querystring.decode; 2635 var querystring_2 = querystring.parse; 2636 var querystring_3 = querystring.encode; 2637 var querystring_4 = querystring.stringify; 2638 2639 // Copyright Joyent, Inc. and other Node contributors. 2640 // 2641 // Permission is hereby granted, free of charge, to any person obtaining a 2642 // copy of this software and associated documentation files (the 2643 // "Software"), to deal in the Software without restriction, including 2644 // without limitation the rights to use, copy, modify, merge, publish, 2645 // distribute, sublicense, and/or sell copies of the Software, and to permit 2646 // persons to whom the Software is furnished to do so, subject to the 2647 // following conditions: 2648 // 2649 // The above copyright notice and this permission notice shall be included 2650 // in all copies or substantial portions of the Software. 2651 // 2652 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 2653 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2654 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 2655 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 2656 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 2657 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 2658 // USE OR OTHER DEALINGS IN THE SOFTWARE. 2659 2660 'use strict'; 2661 2662 2663 2664 2665 var parse = urlParse; 2666 var resolve = urlResolve; 2667 var resolveObject = urlResolveObject; 2668 var format = urlFormat; 2669 2670 var Url_1 = Url; 2671 2672 function Url() { 2673 this.protocol = null; 2674 this.slashes = null; 2675 this.auth = null; 2676 this.host = null; 2677 this.port = null; 2678 this.hostname = null; 2679 this.hash = null; 2680 this.search = null; 2681 this.query = null; 2682 this.pathname = null; 2683 this.path = null; 2684 this.href = null; 2685 } 2686 2687 // Reference: RFC 3986, RFC 1808, RFC 2396 2688 2689 // define these here so at least they only have to be 2690 // compiled once on the first module load. 2691 var protocolPattern = /^([a-z0-9.+-]+:)/i, 2692 portPattern = /:[0-9]*$/, 2693 2694 // Special case for a simple path URL 2695 simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/, 2696 2697 // RFC 2396: characters reserved for delimiting URLs. 2698 // We actually just auto-escape these. 2699 delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'], 2700 2701 // RFC 2396: characters not allowed for various reasons. 2702 unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims), 2703 2704 // Allowed by RFCs, but cause of XSS attacks. Always escape these. 2705 autoEscape = ['\''].concat(unwise), 2706 // Characters that are never ever allowed in a hostname. 2707 // Note that any invalid chars are also handled, but these 2708 // are the ones that are *expected* to be seen, so we fast-path 2709 // them. 2710 nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape), 2711 hostEndingChars = ['/', '?', '#'], 2712 hostnameMaxLen = 255, 2713 hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/, 2714 hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/, 2715 // protocols that can allow "unsafe" and "unwise" chars. 2716 unsafeProtocol = { 2717 'javascript': true, 2718 'javascript:': true 2719 }, 2720 // protocols that never have a hostname. 2721 hostlessProtocol = { 2722 'javascript': true, 2723 'javascript:': true 2724 }, 2725 // protocols that always contain a // bit. 2726 slashedProtocol = { 2727 'http': true, 2728 'https': true, 2729 'ftp': true, 2730 'gopher': true, 2731 'file': true, 2732 'http:': true, 2733 'https:': true, 2734 'ftp:': true, 2735 'gopher:': true, 2736 'file:': true 2737 }; 2738 2739 function urlParse(url, parseQueryString, slashesDenoteHost) { 2740 if (url && util.isObject(url) && url instanceof Url) { return url; } 2741 2742 var u = new Url; 2743 u.parse(url, parseQueryString, slashesDenoteHost); 2744 return u; 2745 } 2746 2747 Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) { 2748 if (!util.isString(url)) { 2749 throw new TypeError("Parameter 'url' must be a string, not " + typeof url); 2750 } 2751 2752 // Copy chrome, IE, opera backslash-handling behavior. 2753 // Back slashes before the query string get converted to forward slashes 2754 // See: https://code.google.com/p/chromium/issues/detail?id=25916 2755 var queryIndex = url.indexOf('?'), 2756 splitter = 2757 (queryIndex !== -1 && queryIndex < url.indexOf('#')) ? '?' : '#', 2758 uSplit = url.split(splitter), 2759 slashRegex = /\\/g; 2760 uSplit[0] = uSplit[0].replace(slashRegex, '/'); 2761 url = uSplit.join(splitter); 2762 2763 var rest = url; 2764 2765 // trim before proceeding. 2766 // This is to support parse stuff like " http://foo.com \n" 2767 rest = rest.trim(); 2768 2769 if (!slashesDenoteHost && url.split('#').length === 1) { 2770 // Try fast path regexp 2771 var simplePath = simplePathPattern.exec(rest); 2772 if (simplePath) { 2773 this.path = rest; 2774 this.href = rest; 2775 this.pathname = simplePath[1]; 2776 if (simplePath[2]) { 2777 this.search = simplePath[2]; 2778 if (parseQueryString) { 2779 this.query = querystring.parse(this.search.substr(1)); 2780 } else { 2781 this.query = this.search.substr(1); 2782 } 2783 } else if (parseQueryString) { 2784 this.search = ''; 2785 this.query = {}; 2786 } 2787 return this; 2788 } 2789 } 2790 2791 var proto = protocolPattern.exec(rest); 2792 if (proto) { 2793 proto = proto[0]; 2794 var lowerProto = proto.toLowerCase(); 2795 this.protocol = lowerProto; 2796 rest = rest.substr(proto.length); 2797 } 2798 2799 // figure out if it's got a host 2800 // user@server is *always* interpreted as a hostname, and url 2801 // resolution will treat //foo/bar as host=foo,path=bar because that's 2802 // how the browser resolves relative URLs. 2803 if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) { 2804 var slashes = rest.substr(0, 2) === '//'; 2805 if (slashes && !(proto && hostlessProtocol[proto])) { 2806 rest = rest.substr(2); 2807 this.slashes = true; 2808 } 2809 } 2810 2811 if (!hostlessProtocol[proto] && 2812 (slashes || (proto && !slashedProtocol[proto]))) { 2813 2814 // there's a hostname. 2815 // the first instance of /, ?, ;, or # ends the host. 2816 // 2817 // If there is an @ in the hostname, then non-host chars *are* allowed 2818 // to the left of the last @ sign, unless some host-ending character 2819 // comes *before* the @-sign. 2820 // URLs are obnoxious. 2821 // 2822 // ex: 2823 // http://a@b@c/ => user:a@b host:c 2824 // http://a@b?@c => user:a host:c path:/?@c 2825 2826 // v0.12 TODO(isaacs): This is not quite how Chrome does things. 2827 // Review our test case against browsers more comprehensively. 2828 2829 // find the first instance of any hostEndingChars 2830 var hostEnd = -1; 2831 for (var i = 0; i < hostEndingChars.length; i++) { 2832 var hec = rest.indexOf(hostEndingChars[i]); 2833 if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) 2834 { hostEnd = hec; } 2835 } 2836 2837 // at this point, either we have an explicit point where the 2838 // auth portion cannot go past, or the last @ char is the decider. 2839 var auth, atSign; 2840 if (hostEnd === -1) { 2841 // atSign can be anywhere. 2842 atSign = rest.lastIndexOf('@'); 2843 } else { 2844 // atSign must be in auth portion. 2845 // http://a@b/c@d => host:b auth:a path:/c@d 2846 atSign = rest.lastIndexOf('@', hostEnd); 2847 } 2848 2849 // Now we have a portion which is definitely the auth. 2850 // Pull that off. 2851 if (atSign !== -1) { 2852 auth = rest.slice(0, atSign); 2853 rest = rest.slice(atSign + 1); 2854 this.auth = decodeURIComponent(auth); 2855 } 2856 2857 // the host is the remaining to the left of the first non-host char 2858 hostEnd = -1; 2859 for (var i = 0; i < nonHostChars.length; i++) { 2860 var hec = rest.indexOf(nonHostChars[i]); 2861 if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) 2862 { hostEnd = hec; } 2863 } 2864 // if we still have not hit it, then the entire thing is a host. 2865 if (hostEnd === -1) 2866 { hostEnd = rest.length; } 2867 2868 this.host = rest.slice(0, hostEnd); 2869 rest = rest.slice(hostEnd); 2870 2871 // pull out port. 2872 this.parseHost(); 2873 2874 // we've indicated that there is a hostname, 2875 // so even if it's empty, it has to be present. 2876 this.hostname = this.hostname || ''; 2877 2878 // if hostname begins with [ and ends with ] 2879 // assume that it's an IPv6 address. 2880 var ipv6Hostname = this.hostname[0] === '[' && 2881 this.hostname[this.hostname.length - 1] === ']'; 2882 2883 // validate a little. 2884 if (!ipv6Hostname) { 2885 var hostparts = this.hostname.split(/\./); 2886 for (var i = 0, l = hostparts.length; i < l; i++) { 2887 var part = hostparts[i]; 2888 if (!part) { continue; } 2889 if (!part.match(hostnamePartPattern)) { 2890 var newpart = ''; 2891 for (var j = 0, k = part.length; j < k; j++) { 2892 if (part.charCodeAt(j) > 127) { 2893 // we replace non-ASCII char with a temporary placeholder 2894 // we need this to make sure size of hostname is not 2895 // broken by replacing non-ASCII by nothing 2896 newpart += 'x'; 2897 } else { 2898 newpart += part[j]; 2899 } 2900 } 2901 // we test again with ASCII char only 2902 if (!newpart.match(hostnamePartPattern)) { 2903 var validParts = hostparts.slice(0, i); 2904 var notHost = hostparts.slice(i + 1); 2905 var bit = part.match(hostnamePartStart); 2906 if (bit) { 2907 validParts.push(bit[1]); 2908 notHost.unshift(bit[2]); 2909 } 2910 if (notHost.length) { 2911 rest = '/' + notHost.join('.') + rest; 2912 } 2913 this.hostname = validParts.join('.'); 2914 break; 2915 } 2916 } 2917 } 2918 } 2919 2920 if (this.hostname.length > hostnameMaxLen) { 2921 this.hostname = ''; 2922 } else { 2923 // hostnames are always lower case. 2924 this.hostname = this.hostname.toLowerCase(); 2925 } 2926 2927 if (!ipv6Hostname) { 2928 // IDNA Support: Returns a punycoded representation of "domain". 2929 // It only converts parts of the domain name that 2930 // have non-ASCII characters, i.e. it doesn't matter if 2931 // you call it with a domain that already is ASCII-only. 2932 this.hostname = punycode.toASCII(this.hostname); 2933 } 2934 2935 var p = this.port ? ':' + this.port : ''; 2936 var h = this.hostname || ''; 2937 this.host = h + p; 2938 this.href += this.host; 2939 2940 // strip [ and ] from the hostname 2941 // the host field still retains them, though 2942 if (ipv6Hostname) { 2943 this.hostname = this.hostname.substr(1, this.hostname.length - 2); 2944 if (rest[0] !== '/') { 2945 rest = '/' + rest; 2946 } 2947 } 2948 } 2949 2950 // now rest is set to the post-host stuff. 2951 // chop off any delim chars. 2952 if (!unsafeProtocol[lowerProto]) { 2953 2954 // First, make 100% sure that any "autoEscape" chars get 2955 // escaped, even if encodeURIComponent doesn't think they 2956 // need to be. 2957 for (var i = 0, l = autoEscape.length; i < l; i++) { 2958 var ae = autoEscape[i]; 2959 if (rest.indexOf(ae) === -1) 2960 { continue; } 2961 var esc = encodeURIComponent(ae); 2962 if (esc === ae) { 2963 esc = escape(ae); 2964 } 2965 rest = rest.split(ae).join(esc); 2966 } 2967 } 2968 2969 2970 // chop off from the tail first. 2971 var hash = rest.indexOf('#'); 2972 if (hash !== -1) { 2973 // got a fragment string. 2974 this.hash = rest.substr(hash); 2975 rest = rest.slice(0, hash); 2976 } 2977 var qm = rest.indexOf('?'); 2978 if (qm !== -1) { 2979 this.search = rest.substr(qm); 2980 this.query = rest.substr(qm + 1); 2981 if (parseQueryString) { 2982 this.query = querystring.parse(this.query); 2983 } 2984 rest = rest.slice(0, qm); 2985 } else if (parseQueryString) { 2986 // no query string, but parseQueryString still requested 2987 this.search = ''; 2988 this.query = {}; 2989 } 2990 if (rest) { this.pathname = rest; } 2991 if (slashedProtocol[lowerProto] && 2992 this.hostname && !this.pathname) { 2993 this.pathname = '/'; 2994 } 2995 2996 //to support http.request 2997 if (this.pathname || this.search) { 2998 var p = this.pathname || ''; 2999 var s = this.search || ''; 3000 this.path = p + s; 3001 } 3002 3003 // finally, reconstruct the href based on what has been validated. 3004 this.href = this.format(); 3005 return this; 3006 }; 3007 3008 // format a parsed object into a url string 3009 function urlFormat(obj) { 3010 // ensure it's an object, and not a string url. 3011 // If it's an obj, this is a no-op. 3012 // this way, you can call url_format() on strings 3013 // to clean up potentially wonky urls. 3014 if (util.isString(obj)) { obj = urlParse(obj); } 3015 if (!(obj instanceof Url)) { return Url.prototype.format.call(obj); } 3016 return obj.format(); 3017 } 3018 3019 Url.prototype.format = function() { 3020 var auth = this.auth || ''; 3021 if (auth) { 3022 auth = encodeURIComponent(auth); 3023 auth = auth.replace(/%3A/i, ':'); 3024 auth += '@'; 3025 } 3026 3027 var protocol = this.protocol || '', 3028 pathname = this.pathname || '', 3029 hash = this.hash || '', 3030 host = false, 3031 query = ''; 3032 3033 if (this.host) { 3034 host = auth + this.host; 3035 } else if (this.hostname) { 3036 host = auth + (this.hostname.indexOf(':') === -1 ? 3037 this.hostname : 3038 '[' + this.hostname + ']'); 3039 if (this.port) { 3040 host += ':' + this.port; 3041 } 3042 } 3043 3044 if (this.query && 3045 util.isObject(this.query) && 3046 Object.keys(this.query).length) { 3047 query = querystring.stringify(this.query); 3048 } 3049 3050 var search = this.search || (query && ('?' + query)) || ''; 3051 3052 if (protocol && protocol.substr(-1) !== ':') { protocol += ':'; } 3053 3054 // only the slashedProtocols get the //. Not mailto:, xmpp:, etc. 3055 // unless they had them to begin with. 3056 if (this.slashes || 3057 (!protocol || slashedProtocol[protocol]) && host !== false) { 3058 host = '//' + (host || ''); 3059 if (pathname && pathname.charAt(0) !== '/') { pathname = '/' + pathname; } 3060 } else if (!host) { 3061 host = ''; 3062 } 3063 3064 if (hash && hash.charAt(0) !== '#') { hash = '#' + hash; } 3065 if (search && search.charAt(0) !== '?') { search = '?' + search; } 3066 3067 pathname = pathname.replace(/[?#]/g, function(match) { 3068 return encodeURIComponent(match); 3069 }); 3070 search = search.replace('#', '%23'); 3071 3072 return protocol + host + pathname + search + hash; 3073 }; 3074 3075 function urlResolve(source, relative) { 3076 return urlParse(source, false, true).resolve(relative); 3077 } 3078 3079 Url.prototype.resolve = function(relative) { 3080 return this.resolveObject(urlParse(relative, false, true)).format(); 3081 }; 3082 3083 function urlResolveObject(source, relative) { 3084 if (!source) { return relative; } 3085 return urlParse(source, false, true).resolveObject(relative); 3086 } 3087 3088 Url.prototype.resolveObject = function(relative) { 3089 if (util.isString(relative)) { 3090 var rel = new Url(); 3091 rel.parse(relative, false, true); 3092 relative = rel; 3093 } 3094 3095 var result = new Url(); 3096 var tkeys = Object.keys(this); 3097 for (var tk = 0; tk < tkeys.length; tk++) { 3098 var tkey = tkeys[tk]; 3099 result[tkey] = this[tkey]; 3100 } 3101 3102 // hash is always overridden, no matter what. 3103 // even href="" will remove it. 3104 result.hash = relative.hash; 3105 3106 // if the relative url is empty, then there's nothing left to do here. 3107 if (relative.href === '') { 3108 result.href = result.format(); 3109 return result; 3110 } 3111 3112 // hrefs like //foo/bar always cut to the protocol. 3113 if (relative.slashes && !relative.protocol) { 3114 // take everything except the protocol from relative 3115 var rkeys = Object.keys(relative); 3116 for (var rk = 0; rk < rkeys.length; rk++) { 3117 var rkey = rkeys[rk]; 3118 if (rkey !== 'protocol') 3119 { result[rkey] = relative[rkey]; } 3120 } 3121 3122 //urlParse appends trailing / to urls like http://www.example.com 3123 if (slashedProtocol[result.protocol] && 3124 result.hostname && !result.pathname) { 3125 result.path = result.pathname = '/'; 3126 } 3127 3128 result.href = result.format(); 3129 return result; 3130 } 3131 3132 if (relative.protocol && relative.protocol !== result.protocol) { 3133 // if it's a known url protocol, then changing 3134 // the protocol does weird things 3135 // first, if it's not file:, then we MUST have a host, 3136 // and if there was a path 3137 // to begin with, then we MUST have a path. 3138 // if it is file:, then the host is dropped, 3139 // because that's known to be hostless. 3140 // anything else is assumed to be absolute. 3141 if (!slashedProtocol[relative.protocol]) { 3142 var keys = Object.keys(relative); 3143 for (var v = 0; v < keys.length; v++) { 3144 var k = keys[v]; 3145 result[k] = relative[k]; 3146 } 3147 result.href = result.format(); 3148 return result; 3149 } 3150 3151 result.protocol = relative.protocol; 3152 if (!relative.host && !hostlessProtocol[relative.protocol]) { 3153 var relPath = (relative.pathname || '').split('/'); 3154 while (relPath.length && !(relative.host = relPath.shift())){ ; } 3155 if (!relative.host) { relative.host = ''; } 3156 if (!relative.hostname) { relative.hostname = ''; } 3157 if (relPath[0] !== '') { relPath.unshift(''); } 3158 if (relPath.length < 2) { relPath.unshift(''); } 3159 result.pathname = relPath.join('/'); 3160 } else { 3161 result.pathname = relative.pathname; 3162 } 3163 result.search = relative.search; 3164 result.query = relative.query; 3165 result.host = relative.host || ''; 3166 result.auth = relative.auth; 3167 result.hostname = relative.hostname || relative.host; 3168 result.port = relative.port; 3169 // to support http.request 3170 if (result.pathname || result.search) { 3171 var p = result.pathname || ''; 3172 var s = result.search || ''; 3173 result.path = p + s; 3174 } 3175 result.slashes = result.slashes || relative.slashes; 3176 result.href = result.format(); 3177 return result; 3178 } 3179 3180 var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'), 3181 isRelAbs = ( 3182 relative.host || 3183 relative.pathname && relative.pathname.charAt(0) === '/' 3184 ), 3185 mustEndAbs = (isRelAbs || isSourceAbs || 3186 (result.host && relative.pathname)), 3187 removeAllDots = mustEndAbs, 3188 srcPath = result.pathname && result.pathname.split('/') || [], 3189 relPath = relative.pathname && relative.pathname.split('/') || [], 3190 psychotic = result.protocol && !slashedProtocol[result.protocol]; 3191 3192 // if the url is a non-slashed url, then relative 3193 // links like ../.. should be able 3194 // to crawl up to the hostname, as well. This is strange. 3195 // result.protocol has already been set by now. 3196 // Later on, put the first path part into the host field. 3197 if (psychotic) { 3198 result.hostname = ''; 3199 result.port = null; 3200 if (result.host) { 3201 if (srcPath[0] === '') { srcPath[0] = result.host; } 3202 else { srcPath.unshift(result.host); } 3203 } 3204 result.host = ''; 3205 if (relative.protocol) { 3206 relative.hostname = null; 3207 relative.port = null; 3208 if (relative.host) { 3209 if (relPath[0] === '') { relPath[0] = relative.host; } 3210 else { relPath.unshift(relative.host); } 3211 } 3212 relative.host = null; 3213 } 3214 mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === ''); 3215 } 3216 3217 if (isRelAbs) { 3218 // it's absolute. 3219 result.host = (relative.host || relative.host === '') ? 3220 relative.host : result.host; 3221 result.hostname = (relative.hostname || relative.hostname === '') ? 3222 relative.hostname : result.hostname; 3223 result.search = relative.search; 3224 result.query = relative.query; 3225 srcPath = relPath; 3226 // fall through to the dot-handling below. 3227 } else if (relPath.length) { 3228 // it's relative 3229 // throw away the existing file, and take the new path instead. 3230 if (!srcPath) { srcPath = []; } 3231 srcPath.pop(); 3232 srcPath = srcPath.concat(relPath); 3233 result.search = relative.search; 3234 result.query = relative.query; 3235 } else if (!util.isNullOrUndefined(relative.search)) { 3236 // just pull out the search. 3237 // like href='?foo'. 3238 // Put this after the other two cases because it simplifies the booleans 3239 if (psychotic) { 3240 result.hostname = result.host = srcPath.shift(); 3241 //occationaly the auth can get stuck only in host 3242 //this especially happens in cases like 3243 //url.resolveObject('mailto:local1@domain1', 'local2@domain2') 3244 var authInHost = result.host && result.host.indexOf('@') > 0 ? 3245 result.host.split('@') : false; 3246 if (authInHost) { 3247 result.auth = authInHost.shift(); 3248 result.host = result.hostname = authInHost.shift(); 3249 } 3250 } 3251 result.search = relative.search; 3252 result.query = relative.query; 3253 //to support http.request 3254 if (!util.isNull(result.pathname) || !util.isNull(result.search)) { 3255 result.path = (result.pathname ? result.pathname : '') + 3256 (result.search ? result.search : ''); 3257 } 3258 result.href = result.format(); 3259 return result; 3260 } 3261 3262 if (!srcPath.length) { 3263 // no path at all. easy. 3264 // we've already handled the other stuff above. 3265 result.pathname = null; 3266 //to support http.request 3267 if (result.search) { 3268 result.path = '/' + result.search; 3269 } else { 3270 result.path = null; 3271 } 3272 result.href = result.format(); 3273 return result; 3274 } 3275 3276 // if a url ENDs in . or .., then it must get a trailing slash. 3277 // however, if it ends in anything else non-slashy, 3278 // then it must NOT get a trailing slash. 3279 var last = srcPath.slice(-1)[0]; 3280 var hasTrailingSlash = ( 3281 (result.host || relative.host || srcPath.length > 1) && 3282 (last === '.' || last === '..') || last === ''); 3283 3284 // strip single dots, resolve double dots to parent dir 3285 // if the path tries to go above the root, `up` ends up > 0 3286 var up = 0; 3287 for (var i = srcPath.length; i >= 0; i--) { 3288 last = srcPath[i]; 3289 if (last === '.') { 3290 srcPath.splice(i, 1); 3291 } else if (last === '..') { 3292 srcPath.splice(i, 1); 3293 up++; 3294 } else if (up) { 3295 srcPath.splice(i, 1); 3296 up--; 3297 } 3298 } 3299 3300 // if the path is allowed to go above the root, restore leading ..s 3301 if (!mustEndAbs && !removeAllDots) { 3302 for (; up--; up) { 3303 srcPath.unshift('..'); 3304 } 3305 } 3306 3307 if (mustEndAbs && srcPath[0] !== '' && 3308 (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { 3309 srcPath.unshift(''); 3310 } 3311 3312 if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) { 3313 srcPath.push(''); 3314 } 3315 3316 var isAbsolute = srcPath[0] === '' || 3317 (srcPath[0] && srcPath[0].charAt(0) === '/'); 3318 3319 // put the host back 3320 if (psychotic) { 3321 result.hostname = result.host = isAbsolute ? '' : 3322 srcPath.length ? srcPath.shift() : ''; 3323 //occationaly the auth can get stuck only in host 3324 //this especially happens in cases like 3325 //url.resolveObject('mailto:local1@domain1', 'local2@domain2') 3326 var authInHost = result.host && result.host.indexOf('@') > 0 ? 3327 result.host.split('@') : false; 3328 if (authInHost) { 3329 result.auth = authInHost.shift(); 3330 result.host = result.hostname = authInHost.shift(); 3331 } 3332 } 3333 3334 mustEndAbs = mustEndAbs || (result.host && srcPath.length); 3335 3336 if (mustEndAbs && !isAbsolute) { 3337 srcPath.unshift(''); 3338 } 3339 3340 if (!srcPath.length) { 3341 result.pathname = null; 3342 result.path = null; 3343 } else { 3344 result.pathname = srcPath.join('/'); 3345 } 3346 3347 //to support request.http 3348 if (!util.isNull(result.pathname) || !util.isNull(result.search)) { 3349 result.path = (result.pathname ? result.pathname : '') + 3350 (result.search ? result.search : ''); 3351 } 3352 result.auth = relative.auth || result.auth; 3353 result.slashes = result.slashes || relative.slashes; 3354 result.href = result.format(); 3355 return result; 3356 }; 3357 3358 Url.prototype.parseHost = function() { 3359 var host = this.host; 3360 var port = portPattern.exec(host); 3361 if (port) { 3362 port = port[0]; 3363 if (port !== ':') { 3364 this.port = port.substr(1); 3365 } 3366 host = host.substr(0, host.length - port.length); 3367 } 3368 if (host) { this.hostname = host; } 3369 }; 3370 3371 var url = { 3372 parse: parse, 3373 resolve: resolve, 3374 resolveObject: resolveObject, 3375 format: format, 3376 Url: Url_1 3377 }; 3378 3379 /*! 3380 * @pixi/constants - v5.0.0-rc.3 3381 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 3382 * 3383 * @pixi/constants is licensed under the MIT License. 3384 * http://www.opensource.org/licenses/mit-license 3385 */ 3386 /** 3387 * Different types of environments for WebGL. 3388 * 3389 * @static 3390 * @memberof PIXI 3391 * @name ENV 3392 * @enum {number} 3393 * @property {number} WEBGL_LEGACY - Used for older v1 WebGL devices. PixiJS will aim to ensure compatibility 3394 * with older / less advanced devices. If you experience unexplained flickering prefer this environment. 3395 * @property {number} WEBGL - Version 1 of WebGL 3396 * @property {number} WEBGL2 - Version 2 of WebGL 3397 */ 3398 var ENV = { 3399 WEBGL_LEGACY: 0, 3400 WEBGL: 1, 3401 WEBGL2: 2, 3402 }; 3403 3404 /** 3405 * Constant to identify the Renderer Type. 3406 * 3407 * @static 3408 * @memberof PIXI 3409 * @name RENDERER_TYPE 3410 * @enum {number} 3411 * @property {number} UNKNOWN - Unknown render type. 3412 * @property {number} WEBGL - WebGL render type. 3413 * @property {number} CANVAS - Canvas render type. 3414 */ 3415 var RENDERER_TYPE = { 3416 UNKNOWN: 0, 3417 WEBGL: 1, 3418 CANVAS: 2, 3419 }; 3420 3421 /** 3422 * Various blend modes supported by PIXI. 3423 * 3424 * IMPORTANT - The WebGL renderer only supports the NORMAL, ADD, MULTIPLY and SCREEN blend modes. 3425 * Anything else will silently act like NORMAL. 3426 * 3427 * @memberof PIXI 3428 * @name BLEND_MODES 3429 * @enum {number} 3430 * @property {number} NORMAL 3431 * @property {number} ADD 3432 * @property {number} MULTIPLY 3433 * @property {number} SCREEN 3434 * @property {number} OVERLAY 3435 * @property {number} DARKEN 3436 * @property {number} LIGHTEN 3437 * @property {number} COLOR_DODGE 3438 * @property {number} COLOR_BURN 3439 * @property {number} HARD_LIGHT 3440 * @property {number} SOFT_LIGHT 3441 * @property {number} DIFFERENCE 3442 * @property {number} EXCLUSION 3443 * @property {number} HUE 3444 * @property {number} SATURATION 3445 * @property {number} COLOR 3446 * @property {number} LUMINOSITY 3447 * @property {number} NORMAL_NPM 3448 * @property {number} ADD_NPM 3449 * @property {number} SCREEN_NPM 3450 * @property {number} NONE 3451 * @property {number} SRC_IN 3452 * @property {number} SRC_OUT 3453 * @property {number} SRC_ATOP 3454 * @property {number} DST_OVER 3455 * @property {number} DST_IN 3456 * @property {number} DST_OUT 3457 * @property {number} DST_ATOP 3458 * @property {number} SUBTRACT 3459 * @property {number} SRC_OVER 3460 * @property {number} ERASE 3461 */ 3462 var BLEND_MODES = { 3463 NORMAL: 0, 3464 ADD: 1, 3465 MULTIPLY: 2, 3466 SCREEN: 3, 3467 OVERLAY: 4, 3468 DARKEN: 5, 3469 LIGHTEN: 6, 3470 COLOR_DODGE: 7, 3471 COLOR_BURN: 8, 3472 HARD_LIGHT: 9, 3473 SOFT_LIGHT: 10, 3474 DIFFERENCE: 11, 3475 EXCLUSION: 12, 3476 HUE: 13, 3477 SATURATION: 14, 3478 COLOR: 15, 3479 LUMINOSITY: 16, 3480 NORMAL_NPM: 17, 3481 ADD_NPM: 18, 3482 SCREEN_NPM: 19, 3483 NONE: 20, 3484 3485 SRC_OVER: 0, 3486 SRC_IN: 21, 3487 SRC_OUT: 22, 3488 SRC_ATOP: 23, 3489 DST_OVER: 24, 3490 DST_IN: 25, 3491 DST_OUT: 26, 3492 DST_ATOP: 27, 3493 ERASE: 26, 3494 SUBTRACT: 28, 3495 }; 3496 3497 /** 3498 * Various webgl draw modes. These can be used to specify which GL drawMode to use 3499 * under certain situations and renderers. 3500 * 3501 * @memberof PIXI 3502 * @static 3503 * @name DRAW_MODES 3504 * @enum {number} 3505 * @property {number} POINTS 3506 * @property {number} LINES 3507 * @property {number} LINE_LOOP 3508 * @property {number} LINE_STRIP 3509 * @property {number} TRIANGLES 3510 * @property {number} TRIANGLE_STRIP 3511 * @property {number} TRIANGLE_FAN 3512 */ 3513 var DRAW_MODES = { 3514 POINTS: 0, 3515 LINES: 1, 3516 LINE_LOOP: 2, 3517 LINE_STRIP: 3, 3518 TRIANGLES: 4, 3519 TRIANGLE_STRIP: 5, 3520 TRIANGLE_FAN: 6, 3521 }; 3522 3523 /** 3524 * Various GL texture/resources formats. 3525 * 3526 * @memberof PIXI 3527 * @static 3528 * @name FORMATS 3529 * @enum {number} 3530 * @property {number} RGBA=6408 3531 * @property {number} RGB=6407 3532 * @property {number} ALPHA=6406 3533 * @property {number} LUMINANCE=6409 3534 * @property {number} LUMINANCE_ALPHA=6410 3535 * @property {number} DEPTH_COMPONENT=6402 3536 * @property {number} DEPTH_STENCIL=34041 3537 */ 3538 var FORMATS = { 3539 RGBA: 6408, 3540 RGB: 6407, 3541 ALPHA: 6406, 3542 LUMINANCE: 6409, 3543 LUMINANCE_ALPHA: 6410, 3544 DEPTH_COMPONENT: 6402, 3545 DEPTH_STENCIL: 34041, 3546 }; 3547 3548 /** 3549 * Various GL target types. 3550 * 3551 * @memberof PIXI 3552 * @static 3553 * @name TARGETS 3554 * @enum {number} 3555 * @property {number} TEXTURE_2D=3553 3556 * @property {number} TEXTURE_CUBE_MAP=34067 3557 * @property {number} TEXTURE_2D_ARRAY=35866 3558 * @property {number} TEXTURE_CUBE_MAP_POSITIVE_X=34069 3559 * @property {number} TEXTURE_CUBE_MAP_NEGATIVE_X=34070 3560 * @property {number} TEXTURE_CUBE_MAP_POSITIVE_Y=34071 3561 * @property {number} TEXTURE_CUBE_MAP_NEGATIVE_Y=34072 3562 * @property {number} TEXTURE_CUBE_MAP_POSITIVE_Z=34073 3563 * @property {number} TEXTURE_CUBE_MAP_NEGATIVE_Z=34074 3564 */ 3565 var TARGETS = { 3566 TEXTURE_2D: 3553, 3567 TEXTURE_CUBE_MAP: 34067, 3568 TEXTURE_2D_ARRAY: 35866, 3569 TEXTURE_CUBE_MAP_POSITIVE_X: 34069, 3570 TEXTURE_CUBE_MAP_NEGATIVE_X: 34070, 3571 TEXTURE_CUBE_MAP_POSITIVE_Y: 34071, 3572 TEXTURE_CUBE_MAP_NEGATIVE_Y: 34072, 3573 TEXTURE_CUBE_MAP_POSITIVE_Z: 34073, 3574 TEXTURE_CUBE_MAP_NEGATIVE_Z: 34074, 3575 }; 3576 3577 /** 3578 * Various GL data format types. 3579 * 3580 * @memberof PIXI 3581 * @static 3582 * @name TYPES 3583 * @enum {number} 3584 * @property {number} UNSIGNED_BYTE=5121 3585 * @property {number} UNSIGNED_SHORT=5123 3586 * @property {number} UNSIGNED_SHORT_5_6_5=33635 3587 * @property {number} UNSIGNED_SHORT_4_4_4_4=32819 3588 * @property {number} UNSIGNED_SHORT_5_5_5_1=32820 3589 * @property {number} FLOAT=5126 3590 * @property {number} HALF_FLOAT=36193 3591 */ 3592 var TYPES = { 3593 UNSIGNED_BYTE: 5121, 3594 UNSIGNED_SHORT: 5123, 3595 UNSIGNED_SHORT_5_6_5: 33635, 3596 UNSIGNED_SHORT_4_4_4_4: 32819, 3597 UNSIGNED_SHORT_5_5_5_1: 32820, 3598 FLOAT: 5126, 3599 HALF_FLOAT: 36193, 3600 }; 3601 3602 /** 3603 * The scale modes that are supported by pixi. 3604 * 3605 * The {@link PIXI.settings.SCALE_MODE} scale mode affects the default scaling mode of future operations. 3606 * It can be re-assigned to either LINEAR or NEAREST, depending upon suitability. 3607 * 3608 * @memberof PIXI 3609 * @static 3610 * @name SCALE_MODES 3611 * @enum {number} 3612 * @property {number} LINEAR Smooth scaling 3613 * @property {number} NEAREST Pixelating scaling 3614 */ 3615 var SCALE_MODES = { 3616 LINEAR: 1, 3617 NEAREST: 0, 3618 }; 3619 3620 /** 3621 * The wrap modes that are supported by pixi. 3622 * 3623 * The {@link PIXI.settings.WRAP_MODE} wrap mode affects the default wrapping mode of future operations. 3624 * It can be re-assigned to either CLAMP or REPEAT, depending upon suitability. 3625 * If the texture is non power of two then clamp will be used regardless as WebGL can 3626 * only use REPEAT if the texture is po2. 3627 * 3628 * This property only affects WebGL. 3629 * 3630 * @name WRAP_MODES 3631 * @memberof PIXI 3632 * @static 3633 * @enum {number} 3634 * @property {number} CLAMP - The textures uvs are clamped 3635 * @property {number} REPEAT - The texture uvs tile and repeat 3636 * @property {number} MIRRORED_REPEAT - The texture uvs tile and repeat with mirroring 3637 */ 3638 var WRAP_MODES = { 3639 CLAMP: 33071, 3640 REPEAT: 10497, 3641 MIRRORED_REPEAT: 33648, 3642 }; 3643 3644 /**
3645 * Mipmap filtering modes that are supported by pixi. 3646 * 3647 * The {@link PIXI.settings.MIPMAP_TEXTURES} affects default texture filtering. 3648 * Mipmaps are generated for a baseTexture if its `mipmap` field is `ON`, 3649 * or its `POW2` and texture dimensions are powers of 2. 3650 * Due to platform restriction, `ON` option will work like `POW2` for webgl-1. 3651 * 3652 * This property only affects WebGL. 3653 * 3654 * @name MIPMAP_MODES 3655 * @memberof PIXI 3656 * @static 3657 * @enum {number} 3658 * @property {number} OFF - No mipmaps 3659 * @property {number} POW2 - Generate mipmaps if texture dimensions are pow2 3660 * @property {number} ON - Always generate mipmaps 3661 */ 3662 var MIPMAP_MODES = { 3663 OFF: 0, 3664 POW2: 1, 3665 ON: 2, 3666 }; 3667 3668 /** 3669 * The gc modes that are supported by pixi. 3670 * 3671 * The {@link PIXI.settings.GC_MODE} Garbage Collection mode for PixiJS textures is AUTO 3672 * If set to GC_MODE, the renderer will occasionally check textures usage. If they are not 3673 * used for a specified period of time they will be removed from the GPU. They will of course 3674 * be uploaded again when they are required. This is a silent behind the scenes process that 3675 * should ensure that the GPU does not get filled up. 3676 * 3677 * Handy for mobile devices! 3678 * This property only affects WebGL. 3679 * 3680 * @name GC_MODES 3681 * @enum {number} 3682 * @static 3683 * @memberof PIXI 3684 * @property {number} AUTO - Garbage collection will happen periodically automatically 3685 * @property {number} MANUAL - Garbage collection will need to be called manually 3686 */ 3687 var GC_MODES = { 3688 AUTO: 0, 3689 MANUAL: 1, 3690 }; 3691 3692 /** 3693 * Constants that specify float precision in shaders. 3694 * 3695 * @name PRECISION 3696 * @memberof PIXI 3697 * @static 3698 * @enum {string} 3699 * @constant 3700 * @property {string} LOW='lowp' 3701 * @property {string} MEDIUM='mediump' 3702 * @property {string} HIGH='highp' 3703 */ 3704 var PRECISION = { 3705 LOW: 'lowp', 3706 MEDIUM: 'mediump', 3707 HIGH: 'highp', 3708 }; 3709 3710 /*! 3711 * @pixi/utils - v5.0.0-rc.3 3712 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 3713 * 3714 * @pixi/utils is licensed under the MIT License. 3715 * http://www.opensource.org/licenses/mit-license 3716 */ 3717 3718 /** 3719 * The prefix that denotes a URL is for a retina asset. 3720 * 3721 * @static 3722 * @name RETINA_PREFIX 3723 * @memberof PIXI.settings 3724 * @type {RegExp} 3725 * @default /@([0-9\.]+)x/ 3726 * @example `@2x` 3727 */ 3728 settings.RETINA_PREFIX = /@([0-9\.]+)x/; 3729 3730 var saidHello = false; 3731 var VERSION = '5.0.0-rc.3'; 3732 3733 /** 3734 * Skips the hello message of renderers that are created after this is run. 3735 * 3736 * @function skipHello 3737 * @memberof PIXI.utils 3738 */ 3739 function skipHello() 3740 { 3741 saidHello = true; 3742 } 3743 3744 /** 3745 * Logs out the version and renderer information for this running instance of PIXI. 3746 * If you don't want to see this message you can run `PIXI.utils.skipHello()` before 3747 * creating your renderer. Keep in mind that doing that will forever makes you a jerk face. 3748 * 3749 * @static 3750 * @function sayHello 3751 * @memberof PIXI.utils 3752 * @param {string} type - The string renderer type to log. 3753 */ 3754 function sayHello(type) 3755 { 3756 if (saidHello) 3757 { 3758 return; 3759 } 3760 3761 if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) 3762 { 3763 var args = [ 3764 ("\n %c %c %c PixiJS " + VERSION + " - ✰ " + type + " ✰ %c %c http://www.pixijs.com/ %c %c ♥%c♥%c♥ \n\n"), 3765 'background: #ff66a5; padding:5px 0;', 3766 'background: #ff66a5; padding:5px 0;', 3767 'color: #ff66a5; background: #030307; padding:5px 0;', 3768 'background: #ff66a5; padding:5px 0;', 3769 'background: #ffc3dc; padding:5px 0;', 3770 'background: #ff66a5; padding:5px 0;', 3771 'color: #ff2424; background: #fff; padding:5px 0;', 3772 'color: #ff2424; background: #fff; padding:5px 0;', 3773 'color: #ff2424; background: #fff; padding:5px 0;' ]; 3774 3775 window.console.log.apply(console, args); 3776 } 3777 else if (window.console) 3778 { 3779 window.console.log(("PixiJS " + VERSION + " - " + type + " - http://www.pixijs.com/")); 3780 } 3781 3782 saidHello = true; 3783 } 3784 3785 /** 3786 * Helper for checking for WebGL support. 3787 * 3788 * @memberof PIXI.utils 3789 * @function isWebGLSupported 3790 * @return {boolean} Is WebGL supported. 3791 */ 3792 function isWebGLSupported() 3793 { 3794 var contextOptions = { stencil: true, failIfMajorPerformanceCaveat: true }; 3795 3796 try 3797 { 3798 if (!window.WebGLRenderingContext) 3799 { 3800 return false;
3801 } 3802 3803 var canvas = document.createElement('canvas'); 3804 var gl = canvas.getContext('webgl', contextOptions) || canvas.getContext('experimental-webgl', contextOptions); 3805 3806 var success = !!(gl && gl.getContextAttributes().stencil); 3807 3808 if (gl) 3809 { 3810 var loseContext = gl.getExtension('WEBGL_lose_context'); 3811 3812 if (loseContext) 3813 { 3814 loseContext.loseContext(); 3815 } 3816 } 3817 3818 gl = null; 3819 3820 return success; 3821 } 3822 catch (e) 3823 { 3824 return false; 3825 } 3826 } 3827 3828 /** 3829 * Converts a hexadecimal color number to an [R, G, B] array of normalized floats (numbers from 0.0 to 1.0). 3830 * 3831 * @example 3832 * PIXI.utils.hex2rgb(0xffffff); // returns [1, 1, 1] 3833 * @memberof PIXI.utils 3834 * @function hex2rgb 3835 * @param {number} hex - The hexadecimal number to convert 3836 * @param {number[]} [out=[]] If supplied, this array will be used rather than returning a new one 3837 * @return {number[]} An array representing the [R, G, B] of the color where all values are floats. 3838 */ 3839 function hex2rgb(hex, out) 3840 { 3841 out = out || []; 3842 3843 out[0] = ((hex >> 16) & 0xFF) / 255; 3844 out[1] = ((hex >> 8) & 0xFF) / 255; 3845 out[2] = (hex & 0xFF) / 255; 3846 3847 return out; 3848 } 3849 3850 /** 3851 * Converts a hexadecimal color number to a string. 3852 * 3853 * @example 3854 * PIXI.utils.hex2string(0xffffff); // returns "#ffffff" 3855 * @memberof PIXI.utils 3856 * @function hex2string 3857 * @param {number} hex - Number in hex (e.g., `0xffffff`) 3858 * @return {string} The string color (e.g., `"#ffffff"`). 3859 */ 3860 function hex2string(hex) 3861 { 3862 hex = hex.toString(16); 3863 hex = '000000'.substr(0, 6 - hex.length) + hex; 3864 3865 return ("#" + hex); 3866 } 3867 3868 /** 3869 * Converts a hexadecimal string to a hexadecimal color number. 3870 * 3871 * @example 3872 * PIXI.utils.string2hex("#ffffff"); // returns 0xffffff 3873 * @memberof PIXI.utils 3874 * @function string2hex 3875 * @param {string} The string color (e.g., `"#ffffff"`) 3876 * @return {number} Number in hexadecimal. 3877 */ 3878 function string2hex(string) 3879 { 3880 if (typeof string === 'string' && string[0] === '#') 3881 { 3882 string = string.substr(1); 3883 } 3884 3885 return parseInt(string, 16); 3886 } 3887 3888 /** 3889 * Converts a color as an [R, G, B] array of normalized floats to a hexadecimal number. 3890 * 3891 * @example 3892 * PIXI.utils.rgb2hex([1, 1, 1]); // returns 0xffffff 3893 * @memberof PIXI.utils 3894 * @function rgb2hex 3895 * @param {number[]} rgb - Array of numbers where all values are normalized floats from 0.0 to 1.0. 3896 * @return {number} Number in hexadecimal. 3897 */ 3898 function rgb2hex(rgb) 3899 { 3900 return (((rgb[0] * 255) << 16) + ((rgb[1] * 255) << 8) + (rgb[2] * 255 | 0)); 3901 } 3902 3903 /** 3904 * Corrects PixiJS blend, takes premultiplied alpha into account 3905 * 3906 * @memberof PIXI.utils 3907 * @function mapPremultipliedBlendModes 3908 * @private 3909 * @param {Array<number[]>} [array] - The array to output into. 3910 * @return {Array<number[]>} Mapped modes. 3911 */ 3912 function mapPremultipliedBlendModes() 3913 { 3914 var pm = []; 3915 var npm = []; 3916 3917 for (var i = 0; i < 32; i++) 3918 { 3919 pm[i] = i; 3920 npm[i] = i; 3921 } 3922 3923 pm[BLEND_MODES.NORMAL_NPM] = BLEND_MODES.NORMAL; 3924 pm[BLEND_MODES.ADD_NPM] = BLEND_MODES.ADD; 3925 pm[BLEND_MODES.SCREEN_NPM] = BLEND_MODES.SCREEN; 3926 3927 npm[BLEND_MODES.NORMAL] = BLEND_MODES.NORMAL_NPM; 3928 npm[BLEND_MODES.ADD] = BLEND_MODES.ADD_NPM; 3929 npm[BLEND_MODES.SCREEN] = BLEND_MODES.SCREEN_NPM; 3930 3931 var array = []; 3932 3933 array.push(npm); 3934 array.push(pm); 3935 3936 return array; 3937 } 3938 3939 /** 3940 * maps premultiply flag and blendMode to adjusted blendMode 3941 * @memberof PIXI.utils 3942 * @const premultiplyBlendMode 3943 * @type {Array<number[]>} 3944 */ 3945 var premultiplyBlendMode = mapPremultipliedBlendModes(); 3946 3947 /** 3948 * changes blendMode according to texture format 3949 * 3950 * @memberof PIXI.utils 3951 * @function correctBlendMode 3952 * @param {number} blendMode supposed blend mode 3953 * @param {boolean} premultiplied whether source is premultiplied 3954 * @returns {number} true blend mode for this texture 3955 */ 3956 function correctBlendMode(blendMode, premultiplied) 3957 { 3958 return premultiplyBlendMode[premultiplied ? 1 : 0][blendMode]; 3959 } 3960 3961 /** 3962 * combines rgb and alpha to out array 3963 * 3964 * @memberof PIXI.utils 3965 * @function premultiplyRgba 3966 * @param {Float32Array|number[]} rgb input rgb 3967 * @param {number} alpha alpha param 3968 * @param {Float32Array} [out] output 3969 * @param {boolean} [premultiply=true] do premultiply it 3970 * @returns {Float32Array} vec4 rgba 3971 */ 3972 function premultiplyRgba(rgb, alpha, out, premultiply) 3973 { 3974 out = out || new Float32Array(4); 3975 if (premultiply || premultiply === undefined) 3976 { 3977 out[0] = rgb[0] * alpha; 3978 out[1] = rgb[1] * alpha; 3979 out[2] = rgb[2] * alpha; 3980 } 3981 else 3982 { 3983 out[0] = rgb[0]; 3984 out[1] = rgb[1]; 3985 out[2] = rgb[2]; 3986 } 3987 out[3] = alpha; 3988 3989 return out; 3990 } 3991 3992 /** 3993 * premultiplies tint 3994 * 3995 * @memberof PIXI.utils 3996 * @function premultiplyTint 3997 * @param {number} tint integer RGB 3998 * @param {number}
3998 alpha floating point alpha (0.0-1.0) 3999 * @returns {number} tint multiplied by alpha 4000 */ 4001 function premultiplyTint(tint, alpha) 4002 { 4003 if (alpha === 1.0) 4004 { 4005 return (alpha * 255 << 24) + tint; 4006 } 4007 if (alpha === 0.0) 4008 { 4009 return 0; 4010 } 4011 var R = ((tint >> 16) & 0xFF); 4012 var G = ((tint >> 8) & 0xFF); 4013 var B = (tint & 0xFF); 4014 4015 R = ((R * alpha) + 0.5) | 0; 4016 G = ((G * alpha) + 0.5) | 0; 4017 B = ((B * alpha) + 0.5) | 0; 4018 4019 return (alpha * 255 << 24) + (R << 16) + (G << 8) + B; 4020 } 4021 4022 /** 4023 * converts integer tint and float alpha to vec4 form, premultiplies by default 4024 * 4025 * @memberof PIXI.utils 4026 * @function premultiplyTintToRgba 4027 * @param {number} tint input tint 4028 * @param {number} alpha alpha param 4029 * @param {Float32Array} [out] output 4030 * @param {boolean} [premultiply=true] do premultiply it 4031 * @returns {Float32Array} vec4 rgba 4032 */ 4033 function premultiplyTintToRgba(tint, alpha, out, premultiply) 4034 { 4035 out = out || new Float32Array(4); 4036 out[0] = ((tint >> 16) & 0xFF) / 255.0; 4037 out[1] = ((tint >> 8) & 0xFF) / 255.0; 4038 out[2] = (tint & 0xFF) / 255.0; 4039 if (premultiply || premultiply === undefined) 4040 { 4041 out[0] *= alpha; 4042 out[1] *= alpha; 4043 out[2] *= alpha; 4044 } 4045 out[3] = alpha; 4046 4047 return out; 4048 } 4049 4050 /** 4051 * Generic Mask Stack data structure 4052 * 4053 * @memberof PIXI 4054 * @function createIndicesForQuads 4055 * @private 4056 * @param {number} size - Number of quads 4057 * @return {Uint16Array} indices 4058 */ 4059 function createIndicesForQuads(size) 4060 { 4061 // the total number of indices in our array, there are 6 points per quad. 4062 4063 var totalIndices = size * 6; 4064 4065 var indices = new Uint16Array(totalIndices); 4066 4067 // fill the indices with the quads to draw 4068 for (var i = 0, j = 0; i < totalIndices; i += 6, j += 4) 4069 { 4070 indices[i + 0] = j + 0; 4071 indices[i + 1] = j + 1; 4072 indices[i + 2] = j + 2; 4073 indices[i + 3] = j + 0; 4074 indices[i + 4] = j + 2; 4075 indices[i + 5] = j + 3; 4076 } 4077 4078 return indices; 4079 } 4080 4081 /** 4082 * Remove items from a javascript array without generating garbage 4083 * 4084 * @function removeItems 4085 * @memberof PIXI.utils 4086 * @param {Array} arr Array to remove elements from 4087 * @param {number} startIdx starting index 4088 * @param {number} removeCount how many to remove 4089 */ 4090 function removeItems(arr, startIdx, removeCount) 4091 { 4092 var length = arr.length; 4093 var i; 4094 4095 if (startIdx >= length || removeCount === 0) 4096 { 4097 return; 4098 } 4099 4100 removeCount = (startIdx + removeCount > length ? length - startIdx : removeCount); 4101 4102 var len = length - removeCount; 4103 4104 for (i = startIdx; i < len; ++i) 4105 { 4106 arr[i] = arr[i + removeCount]; 4107 } 4108 4109 arr.length = len; 4110 } 4111 4112 var nextUid = 0; 4113 4114 /** 4115 * Gets the next unique identifier 4116 * 4117 * @memberof PIXI.utils 4118 * @function uid 4119 * @return {number} The next unique identifier to use. 4120 */ 4121 function uid() 4122 { 4123 return ++nextUid; 4124 } 4125 4126 /** 4127 * Returns sign of number 4128 * 4129 * @memberof PIXI.utils 4130 * @function sign 4131 * @param {number} n - the number to check the sign of 4132 * @returns {number} 0 if `n` is 0, -1 if `n` is negative, 1 if `n` is positive 4133 */ 4134 function sign(n) 4135 { 4136 if (n === 0) { return 0; } 4137 4138 return n < 0 ? -1 : 1; 4139 } 4140 4141 // Taken from the bit-twiddle package 4142 4143 /** 4144 * Rounds to next power of two. 4145 * 4146 * @function isPow2 4147 * @memberof PIXI.utils 4148 * @param {number} v input value 4149 * @return {number} 4150 */ 4151 function nextPow2(v) 4152 { 4153 v += v === 0; 4154 --v; 4155 v |= v >>> 1; 4156 v |= v >>> 2; 4157 v |= v >>> 4; 4158 v |= v >>> 8; 4159 v |= v >>> 16; 4160 4161 return v + 1; 4162 } 4163 4164 /** 4165 * Checks if a number is a power of two. 4166 * 4167 * @function isPow2 4168 * @memberof PIXI.utils 4169 * @param {number} v input value 4170 * @return {boolean} `true` if value is power of two 4171 */ 4172 function isPow2(v) 4173 { 4174 return !(v & (v - 1)) && (!!v); 4175 } 4176 4177 /** 4178 * Computes ceil of log base 2 4179 * 4180 * @function log2 4181 * @memberof PIXI.utils 4182 * @param {number} v input value 4183 * @return {number} logarithm base 2 4184 */ 4185 function log2(v) 4186 { 4187 var r = (v > 0xFFFF) << 4; 4188 4189 v >>>= r; 4190 4191 var shift = (v > 0xFF) << 3; 4192 4193 v >>>= shift; r |= shift; 4194 shift = (v > 0xF) << 2; 4195 v >>>= shift; r |= shift; 4196 shift = (v > 0x3) << 1; 4197 v >>>= shift; r |= shift; 4198 4199 return r | (v >> 1); 4200 } 4201 4202 /** 4203 * @todo Describe property usage 4204 * 4205 * @static 4206 * @name ProgramCache 4207 * @memberof PIXI.utils 4208 * @type {Object} 4209 */ 4210 var ProgramCache = {}; 4211 4212 /** 4213 * @todo Describe property usage 4214 * 4215 * @static 4216 * @name TextureCache 4217 * @memberof PIXI.utils 4218 * @type {Object} 4219 */ 4220 var TextureCache = Object.create(null); 4221 4222 /** 4223 * @todo Describe property usage 4224 * 4225 * @static 4226 * @name BaseTextureCache 4227 * @memberof PIXI.utils 4228 * @type {Object} 4229 */ 4230 4231 var BaseTextureCache = Object.create(null); 4232 /** 4233 * Destroys all texture in the cache 4234 * 4235 * @memberof PIXI.utils 4236 * @function destroyTextureCache 4237 */ 4238 function destroyTextureCache() 4239 { 4240 var key; 4241 4242 for (key in TextureCache) 4243 { 4244 TextureCache[key].destroy(); 4245 } 4246 for (key in BaseTextureCache) 4247 { 4248 BaseTextureCache[key].destroy(); 4249 } 4250 } 4251
4252 /** 4253 * Removes all textures from cache, but does not destroy them 4254 * 4255 * @memberof PIXI.utils 4256 * @function clearTextureCache 4257 */ 4258 function clearTextureCache() 4259 { 4260 var key; 4261 4262 for (key in TextureCache) 4263 { 4264 delete TextureCache[key]; 4265 } 4266 for (key in BaseTextureCache) 4267 { 4268 delete BaseTextureCache[key]; 4269 } 4270 } 4271 4272 /** 4273 * Trim transparent borders from a canvas 4274 * 4275 * @memberof PIXI.utils 4276 * @function trimCanvas 4277 * @param {HTMLCanvasElement} canvas - the canvas to trim 4278 * @returns {object} Trim data 4279 */ 4280 function trimCanvas(canvas) 4281 { 4282 // https://gist.github.com/remy/784508 4283 4284 var width = canvas.width; 4285 var height = canvas.height; 4286 4287 var context = canvas.getContext('2d'); 4288 var imageData = context.getImageData(0, 0, width, height); 4289 var pixels = imageData.data; 4290 var len = pixels.length; 4291 4292 var bound = { 4293 top: null, 4294 left: null, 4295 right: null, 4296 bottom: null, 4297 }; 4298 var data = null; 4299 var i; 4300 var x; 4301 var y; 4302 4303 for (i = 0; i < len; i += 4) 4304 { 4305 if (pixels[i + 3] !== 0) 4306 { 4307 x = (i / 4) % width; 4308 y = ~~((i / 4) / width); 4309 4310 if (bound.top === null) 4311 { 4312 bound.top = y; 4313 } 4314 4315 if (bound.left === null) 4316 { 4317 bound.left = x; 4318 } 4319 else if (x < bound.left) 4320 { 4321 bound.left = x; 4322 } 4323 4324 if (bound.right === null) 4325 { 4326 bound.right = x + 1; 4327 } 4328 else if (bound.right < x) 4329 { 4330 bound.right = x + 1; 4331 } 4332 4333 if (bound.bottom === null) 4334 { 4335 bound.bottom = y; 4336 } 4337 else if (bound.bottom < y) 4338 { 4339 bound.bottom = y; 4340 } 4341 } 4342 } 4343 4344 if (bound.top !== null) 4345 { 4346 width = bound.right - bound.left; 4347 height = bound.bottom - bound.top + 1; 4348 data = context.getImageData(bound.left, bound.top, width, height); 4349 } 4350 4351 return { 4352 height: height, 4353 width: width, 4354 data: data, 4355 }; 4356 } 4357 4358 /** 4359 * Creates a Canvas element of the given size to be used as a target for rendering to. 4360 * 4361 * @class 4362 * @memberof PIXI.utils 4363 */ 4364 var CanvasRenderTarget = function CanvasRenderTarget(width, height, resolution) 4365 { 4366 /** 4367 * The Canvas object that belongs to this CanvasRenderTarget. 4368 * 4369 * @member {HTMLCanvasElement} 4370 */ 4371 this.canvas = document.createElement('canvas'); 4372 4373 /** 4374 * A CanvasRenderingContext2D object representing a two-dimensional rendering context. 4375 * 4376 * @member {CanvasRenderingContext2D} 4377 */ 4378 this.context = this.canvas.getContext('2d'); 4379 4380 this.resolution = resolution || settings.RESOLUTION; 4381 4382 this.resize(width, height); 4383 }; 4384 4385 var prototypeAccessors = { width: { configurable: true },height: { configurable: true } }; 4386 4387 /** 4388 * Clears the canvas that was created by the CanvasRenderTarget class. 4389 * 4390 * @private 4391 */ 4392 CanvasRenderTarget.prototype.clear = function clear () 4393 { 4394 this.context.setTransform(1, 0, 0, 1, 0, 0); 4395 this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); 4396 }; 4397 4398 /** 4399 * Resizes the canvas to the specified width and height. 4400 * 4401 * @param {number} width - the new width of the canvas 4402 * @param {number} height - the new height of the canvas 4403 */ 4404 CanvasRenderTarget.prototype.resize = function resize (width, height) 4405 { 4406 this.canvas.width = width * this.resolution; 4407 this.canvas.height = height * this.resolution; 4408 }; 4409 4410 /** 4411 * Destroys this canvas. 4412 * 4413 */ 4414 CanvasRenderTarget.prototype.destroy = function destroy () 4415 { 4416 this.context = null; 4417 this.canvas = null; 4418 }; 4419 4420 /** 4421 * The width of the canvas buffer in pixels. 4422 * 4423 * @member {number} 4424 */ 4425 prototypeAccessors.width.get = function () 4426 { 4427 return this.canvas.width; 4428 }; 4429 4430 prototypeAccessors.width.set = function (val) // eslint-disable-line require-jsdoc 4431 { 4432 this.canvas.width = val; 4433 }; 4434 4435 /** 4436 * The height of the canvas buffer in pixels. 4437 * 4438 * @member {number} 4439 */ 4440 prototypeAccessors.height.get = function () 4441 { 4442 return this.canvas.height; 4443 }; 4444 4445 prototypeAccessors.height.set = function (val) // eslint-disable-line require-jsdoc 4446 { 4447 this.canvas.height = val; 4448 }; 4449 4450 Object.defineProperties( CanvasRenderTarget.prototype, prototypeAccessors ); 4451 4452 /** 4453 * Regexp for data URI. 4454 * Based on: {@link https://github.com/ragingwind/data-uri-regex} 4455 * 4456 * @static 4457 * @constant {RegExp|string} DATA_URI 4458 * @memberof PIXI 4459 * @example data:image/png;base64 4460 */ 4461 var DATA_URI = /^\s*data:(?:([\w-]+)\/([\w+.-]+))?(?:;charset=([\w-]+))?(?:;(base64))?,(.*)/i; 4462 4463 /** 4464 * Typedef for decomposeDataUri return object. 4465 * 4466 * @memberof PIXI.utils 4467 * @typedef {object} DecomposedDataUri 4468 * @property {string} mediaType Media type, eg. `image` 4469 * @property {string} subType Sub type, eg. `png` 4470 * @property {string} encoding Data encoding, eg. `base64` 4471 * @property {string} data The actual data 4472 */ 4473 4474 /** 4475 * Split a data URI into components. Returns undefined if 4476 * parameter `dataUri` is not a valid data URI. 4477 * 4478 * @memberof PIXI.utils 4479 * @function decomposeDataUri 4480 * @param {string} dataUri - the data URI to check 4481 * @return {PIXI.utils.DecomposedDataUri|undefined} The decomposed data uri or undefined 4482 */ 4483 function decomposeDataUri(dataUri) 4484 {
4485 var dataUriMatch = DATA_URI.exec(dataUri); 4486 4487 if (dataUriMatch) 4488 { 4489 return { 4490 mediaType: dataUriMatch[1] ? dataUriMatch[1].toLowerCase() : undefined, 4491 subType: dataUriMatch[2] ? dataUriMatch[2].toLowerCase() : undefined, 4492 charset: dataUriMatch[3] ? dataUriMatch[3].toLowerCase() : undefined, 4493 encoding: dataUriMatch[4] ? dataUriMatch[4].toLowerCase() : undefined, 4494 data: dataUriMatch[5], 4495 }; 4496 } 4497 4498 return undefined; 4499 } 4500 4501 var tempAnchor; 4502 4503 /** 4504 * Sets the `crossOrigin` property for this resource based on if the url 4505 * for this resource is cross-origin. If crossOrigin was manually set, this 4506 * function does nothing. 4507 * Nipped from the resource loader! 4508 * 4509 * @ignore 4510 * @param {string} url - The url to test. 4511 * @param {object} [loc=window.location] - The location object to test against. 4512 * @return {string} The crossOrigin value to use (or empty string for none). 4513 */ 4514 function determineCrossOrigin(url$1, loc) 4515 { 4516 if ( loc === void 0 ) { loc = window.location; } 4517 4518 // data: and javascript: urls are considered same-origin 4519 if (url$1.indexOf('data:') === 0) 4520 { 4521 return ''; 4522 } 4523 4524 // default is window.location 4525 loc = loc || window.location; 4526 4527 if (!tempAnchor) 4528 { 4529 tempAnchor = document.createElement('a'); 4530 } 4531 4532 // let the browser determine the full href for the url of this resource and then 4533 // parse with the node url lib, we can't use the properties of the anchor element 4534 // because they don't work in IE9 :( 4535 tempAnchor.href = url$1; 4536 url$1 = url.parse(tempAnchor.href); 4537 4538 var samePort = (!url$1.port && loc.port === '') || (url$1.port === loc.port); 4539 4540 // if cross origin 4541 if (url$1.hostname !== loc.hostname || !samePort || url$1.protocol !== loc.protocol) 4542 { 4543 return 'anonymous'; 4544 } 4545 4546 return ''; 4547 } 4548 4549 /** 4550 * get the resolution / device pixel ratio of an asset by looking for the prefix 4551 * used by spritesheets and image urls 4552 * 4553 * @memberof PIXI.utils 4554 * @function getResolutionOfUrl 4555 * @param {string} url - the image path 4556 * @param {number} [defaultValue=1] - the defaultValue if no filename prefix is set. 4557 * @return {number} resolution / device pixel ratio of an asset 4558 */ 4559 function getResolutionOfUrl(url, defaultValue) 4560 { 4561 var resolution = settings.RETINA_PREFIX.exec(url); 4562 4563 if (resolution) 4564 { 4565 return parseFloat(resolution[1]); 4566 } 4567 4568 return defaultValue !== undefined ? defaultValue : 1; 4569 } 4570 4571 // A map of warning messages already fired 4572 var warnings = {}; 4573 4574 /** 4575 * Helper for warning developers about deprecated features & settings. 4576 * A stack track for warnings is given; useful for tracking-down where 4577 * deprecated methods/properties/classes are being used within the code. 4578 * 4579 * @memberof PIXI.utils 4580 * @function deprecation 4581 * @param {string} version - The version where the feature became deprecated 4582 * @param {string} message - Message should include what is deprecated, where, and the new solution 4583 * @param {number} [ignoreDepth=3] - The number of steps to ignore at the top of the error stack 4584 * this is mostly to ignore internal deprecation calls. 4585 */ 4586 function deprecation(version, message, ignoreDepth) 4587 { 4588 if ( ignoreDepth === void 0 ) { ignoreDepth = 3; } 4589 4590 // Ignore duplicat 4591 if (warnings[message]) 4592 { 4593 return; 4594 } 4595 4596 /* eslint-disable no-console */ 4597 var stack = new Error().stack; 4598 4599 // Handle IE < 10 and Safari < 6 4600 if (typeof stack === 'undefined') 4601 { 4602 console.warn('PixiJS Deprecation Warning: ', (message + "\nDeprecated since v" + version)); 4603 } 4604 else 4605 { 4606 // chop off the stack trace which includes PixiJS internal calls 4607 stack = stack.split('\n').splice(ignoreDepth).join('\n'); 4608 4609 if (console.groupCollapsed) 4610 { 4611 console.groupCollapsed( 4612 '%cPixiJS Deprecation Warning: %c%s', 4613 'color:#614108;background:#fffbe6', 4614 'font-weight:normal;color:#614108;background:#fffbe6', 4615 (message + "\nDeprecated since v" + version) 4616 ); 4617 console.warn(stack); 4618 console.groupEnd(); 4619 } 4620 else 4621 { 4622 console.warn('PixiJS Deprecation Warning: ', (message + "\nDeprecated since v" + version)); 4623 console.warn(stack); 4624 } 4625 } 4626 /* eslint-enable no-console */ 4627 4628 warnings[message] = true; 4629 } 4630 4631 var utils_es = ({ 4632 BaseTextureCache: BaseTextureCache, 4633 CanvasRenderTarget: CanvasRenderTarget, 4634 DATA_URI: DATA_URI, 4635 ProgramCache: ProgramCache, 4636 TextureCache: TextureCache, 4637 clearTextureCache: clearTextureCache, 4638 correctBlendMode: correctBlendMode, 4639 createIndicesForQuads: createIndicesForQuads, 4640 decomposeDataUri: decomposeDataUri, 4641 deprecation: deprecation, 4642 destroyTextureCache: destroyTextureCache, 4643 determineCrossOrigin: determineCrossOrigin, 4644 getResolutionOfUrl: getResolutionOfUrl, 4645 hex2rgb: hex2rgb, 4646 hex2string: hex2string, 4647 isPow2: isPow2,
4648 isWebGLSupported: isWebGLSupported, 4649 log2: log2, 4650 nextPow2: nextPow2, 4651 premultiplyBlendMode: premultiplyBlendMode, 4652 premultiplyRgba: premultiplyRgba, 4653 premultiplyTint: premultiplyTint, 4654 premultiplyTintToRgba: premultiplyTintToRgba, 4655 removeItems: removeItems, 4656 rgb2hex: rgb2hex, 4657 sayHello: sayHello, 4658 sign: sign, 4659 skipHello: skipHello, 4660 string2hex: string2hex, 4661 trimCanvas: trimCanvas, 4662 uid: uid, 4663 isMobile: isMobile_min, 4664 EventEmitter: eventemitter3, 4665 earcut: earcut_1, 4666 url: url 4667 }); 4668 4669 /*! 4670 * @pixi/math - v5.0.0-rc.3 4671 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 4672 * 4673 * @pixi/math is licensed under the MIT License. 4674 * http://www.opensource.org/licenses/mit-license 4675 */ 4676 /** 4677 * The Point object represents a location in a two-dimensional coordinate system, where x represents 4678 * the horizontal axis and y represents the vertical axis. 4679 * 4680 * @class 4681 * @memberof PIXI 4682 */ 4683 var Point = function Point(x, y) 4684 { 4685 if ( x === void 0 ) { x = 0; } 4686 if ( y === void 0 ) { y = 0; } 4687 4688 /** 4689 * @member {number} 4690 * @default 0 4691 */ 4692 this.x = x; 4693 4694 /** 4695 * @member {number} 4696 * @default 0 4697 */ 4698 this.y = y; 4699 }; 4700 4701 /** 4702 * Creates a clone of this point 4703 * 4704 * @return {PIXI.Point} a copy of the point 4705 */ 4706 Point.prototype.clone = function clone () 4707 { 4708 return new Point(this.x, this.y); 4709 }; 4710 4711 /** 4712 * Copies x and y from the given point 4713 * 4714 * @param {PIXI.IPoint} p - The point to copy from 4715 * @returns {PIXI.IPoint} Returns itself. 4716 */ 4717 Point.prototype.copyFrom = function copyFrom (p) 4718 { 4719 this.set(p.x, p.y); 4720 4721 return this; 4722 }; 4723 4724 /** 4725 * Copies x and y into the given point 4726 * 4727 * @param {PIXI.IPoint} p - The point to copy. 4728 * @returns {PIXI.IPoint} Given point with values updated 4729 */ 4730 Point.prototype.copyTo = function copyTo (p) 4731 { 4732 p.set(this.x, this.y); 4733 4734 return p; 4735 }; 4736 4737 /** 4738 * Returns true if the given point is equal to this point 4739 * 4740 * @param {PIXI.IPoint} p - The point to check 4741 * @returns {boolean} Whether the given point equal to this point 4742 */ 4743 Point.prototype.equals = function equals (p) 4744 { 4745 return (p.x === this.x) && (p.y === this.y); 4746 }; 4747 4748 /** 4749 * Sets the point to a new x and y position. 4750 * If y is omitted, both x and y will be set to x. 4751 * 4752 * @param {number} [x=0] - position of the point on the x axis 4753 * @param {number} [y=0] - position of the point on the y axis 4754 */ 4755 Point.prototype.set = function set (x, y) 4756 { 4757 this.x = x || 0; 4758 this.y = y || ((y !== 0) ? this.x : 0); 4759 }; 4760 4761 /** 4762 * The Point object represents a location in a two-dimensional coordinate system, where x represents 4763 * the horizontal axis and y represents the vertical axis. 4764 * 4765 * An ObservablePoint is a point that triggers a callback when the point's position is changed. 4766 * 4767 * @class 4768 * @memberof PIXI 4769 */ 4770 var ObservablePoint = function ObservablePoint(cb, scope, x, y) 4771 { 4772 if ( x === void 0 ) { x = 0; } 4773 if ( y === void 0 ) { y = 0; } 4774 4775 this._x = x; 4776 this._y = y; 4777 4778 this.cb = cb; 4779 this.scope = scope; 4780 }; 4781 4782 var prototypeAccessors$1 = { x: { configurable: true },y: { configurable: true } }; 4783 4784 /** 4785 * Creates a clone of this point. 4786 * The callback and scope params can be overidden otherwise they will default 4787 * to the clone object's values. 4788 * 4789 * @override 4790 * @param {Function} [cb=null] - callback when changed 4791 * @param {object} [scope=null] - owner of callback 4792 * @return {PIXI.ObservablePoint} a copy of the point 4793 */ 4794 ObservablePoint.prototype.clone = function clone (cb, scope) 4795 { 4796 if ( cb === void 0 ) { cb = null; } 4797 if ( scope === void 0 ) { scope = null; } 4798 4799 var _cb = cb || this.cb; 4800 var _scope = scope || this.scope; 4801 4802 return new ObservablePoint(_cb, _scope, this._x, this._y); 4803 }; 4804 4805 /** 4806 * Sets the point to a new x and y position. 4807 * If y is omitted, both x and y will be set to x. 4808 * 4809 * @param {number} [x=0] - position of the point on the x axis 4810 * @param {number} [y=0] - position of the point on the y axis 4811 */ 4812 ObservablePoint.prototype.set = function set (x, y) 4813 { 4814 var _x = x || 0; 4815 var _y = y || ((y !== 0) ? _x : 0); 4816 4817 if (this._x !== _x || this._y !== _y) 4818 { 4819 this._x = _x; 4820 this._y = _y; 4821 this.cb.call(this.scope); 4822 } 4823 }; 4824 4825 /** 4826 * Copies x and y from the given point 4827 * 4828 * @param {PIXI.IPoint} p - The point to copy from. 4829 * @returns {PIXI.IPoint} Returns itself. 4830 */ 4831 ObservablePoint.prototype.copyFrom = function copyFrom (p) 4832 { 4833 if (this._x !== p.x || this._y !== p.y) 4834 { 4835 this._x = p.x; 4836 this._y = p.y; 4837 this.cb.call(this.scope); 4838 } 4839 4840 return this; 4841 }; 4842 4843 /** 4844 * Copies x and y into the given point 4845 * 4846 * @param {PIXI.IPoint} p - The point to copy. 4847 * @returns {PIXI.IPoint} Given point with values updated 4848 */ 4849 ObservablePoint.prototype.copyTo = function copyTo (p) 4850 { 4851 p.set(this._x, this._y); 4852 4853 return p; 4854 }; 4855 4856 /** 4857 * Returns true if the given point is equal to this point 4858 * 4859 * @param {PIXI.IPoint} p - The point to check 4860 * @returns {boolean} Whether the given point equal to this point 4861 */ 4862 ObservablePoint.prototype.equals = function equals (p) 4863 { 4864 return (p.x === this._x) && (p.y === this._y); 4865 }; 4866 4867 /** 4868 * The position of the displayObject on the x axis relative to the local coordinates of the parent. 4869 * 4870 * @member {number} 4871 */ 4872 prototypeAccessors$1.x.get = function () 4873 { 4874 return this._x; 4875 }; 4876 4877 prototypeAccessors$1.x.set = function (value) // eslint-disable-line require-jsdoc 4878 { 4879 if (this._x !== value) 4880 { 4881 this._x = value; 4882 this.cb.call(this.scope); 4883 } 4884 }; 4885 4886 /** 4887 * The position of the displayObject on the x axis relative to the local coordinates of the parent. 4888 * 4889 * @member {number} 4890 */ 4891 prototypeAccessors$1.y.get = function () 4892 { 4893 return this._y; 4894 }; 4895 4896 prototypeAccessors$1.y.set = function (value) // eslint-disable-line require-jsdoc 4897 { 4898 if (this._y !== value) 4899 { 4900 this._y = value; 4901 this.cb.call(this.scope); 4902 } 4903 }; 4904 4905 Object.defineProperties( ObservablePoint.prototype, prototypeAccessors$1 ); 4906 4907 /** 4908 * A number, or a string containing a number. 4909 * @memberof PIXI
4910 * @typedef {(PIXI.Point|PIXI.ObservablePoint)} IPoint 4911 */ 4912 4913 /** 4914 * Two Pi. 4915 * 4916 * @static 4917 * @constant {number} PI_2 4918 * @memberof PIXI 4919 */ 4920 var PI_2 = Math.PI * 2; 4921 4922 /** 4923 * Conversion factor for converting radians to degrees. 4924 * 4925 * @static 4926 * @constant {number} RAD_TO_DEG 4927 * @memberof PIXI 4928 */ 4929 var RAD_TO_DEG = 180 / Math.PI; 4930 4931 /** 4932 * Conversion factor for converting degrees to radians. 4933 * 4934 * @static 4935 * @constant {number} DEG_TO_RAD 4936 * @memberof PIXI 4937 */ 4938 var DEG_TO_RAD = Math.PI / 180; 4939 4940 /** 4941 * Constants that identify shapes, mainly to prevent `instanceof` calls. 4942 * 4943 * @static 4944 * @constant 4945 * @name SHAPES 4946 * @memberof PIXI 4947 * @type {object} 4948 * @property {number} POLY Polygon 4949 * @property {number} RECT Rectangle 4950 * @property {number} CIRC Circle 4951 * @property {number} ELIP Ellipse 4952 * @property {number} RREC Rounded Rectangle 4953 */ 4954 var SHAPES = { 4955 POLY: 0, 4956 RECT: 1, 4957 CIRC: 2, 4958 ELIP: 3, 4959 RREC: 4, 4960 }; 4961 4962 /** 4963 * The PixiJS Matrix as a class makes it a lot faster. 4964 * 4965 * Here is a representation of it: 4966 * ```js 4967 * | a | c | tx| 4968 * | b | d | ty| 4969 * | 0 | 0 | 1 | 4970 * ``` 4971 * @class 4972 * @memberof PIXI 4973 */ 4974 var Matrix = function Matrix(a, b, c, d, tx, ty) 4975 { 4976 if ( a === void 0 ) { a = 1; } 4977 if ( b === void 0 ) { b = 0; } 4978 if ( c === void 0 ) { c = 0; } 4979 if ( d === void 0 ) { d = 1; } 4980 if ( tx === void 0 ) { tx = 0; } 4981 if ( ty === void 0 ) { ty = 0; } 4982 4983 /** 4984 * @member {number} 4985 * @default 1 4986 */ 4987 this.a = a; 4988 4989 /** 4990 * @member {number} 4991 * @default 0 4992 */ 4993 this.b = b; 4994 4995 /** 4996 * @member {number} 4997 * @default 0 4998 */ 4999 this.c = c; 5000 5001 /** 5002 * @member {number} 5003 * @default 1 5004 */ 5005 this.d = d; 5006 5007 /** 5008 * @member {number} 5009 * @default 0 5010 */ 5011 this.tx = tx; 5012 5013 /** 5014 * @member {number} 5015 * @default 0 5016 */ 5017 this.ty = ty; 5018 5019 this.array = null; 5020 }; 5021 5022 var staticAccessors = { IDENTITY: { configurable: true },TEMP_MATRIX: { configurable: true } }; 5023 5024 /** 5025 * Creates a Matrix object based on the given array. The Element to Matrix mapping order is as follows: 5026 * 5027 * a = array[0] 5028 * b = array[1] 5029 * c = array[3] 5030 * d = array[4] 5031 * tx = array[2] 5032 * ty = array[5] 5033 * 5034 * @param {number[]} array - The array that the matrix will be populated from. 5035 */ 5036 Matrix.prototype.fromArray = function fromArray (array) 5037 { 5038 this.a = array[0]; 5039 this.b = array[1]; 5040 this.c = array[3]; 5041 this.d = array[4]; 5042 this.tx = array[2]; 5043 this.ty = array[5]; 5044 }; 5045 5046 /** 5047 * sets the matrix properties 5048 * 5049 * @param {number} a - Matrix component 5050 * @param {number} b - Matrix component 5051 * @param {number} c - Matrix component 5052 * @param {number} d - Matrix component 5053 * @param {number} tx - Matrix component 5054 * @param {number} ty - Matrix component 5055 * 5056 * @return {PIXI.Matrix} This matrix. Good for chaining method calls. 5057 */ 5058 Matrix.prototype.set = function set (a, b, c, d, tx, ty) 5059 { 5060 this.a = a; 5061 this.b = b; 5062 this.c = c; 5063 this.d = d; 5064 this.tx = tx; 5065 this.ty = ty; 5066 5067 return this; 5068 }; 5069 5070 /** 5071 * Creates an array from the current Matrix object. 5072 * 5073 * @param {boolean} transpose - Whether we need to transpose the matrix or not 5074 * @param {Float32Array} [out=new Float32Array(9)] - If provided the array will be assigned to out 5075 * @return {number[]} the newly created array which contains the matrix 5076 */ 5077 Matrix.prototype.toArray = function toArray (transpose, out) 5078 { 5079 if (!this.array) 5080 { 5081 this.array = new Float32Array(9); 5082 } 5083 5084 var array = out || this.array; 5085 5086 if (transpose) 5087 { 5088 array[0] = this.a; 5089 array[1] = this.b; 5090 array[2] = 0; 5091 array[3] = this.c; 5092 array[4] = this.d; 5093 array[5] = 0; 5094 array[6] = this.tx; 5095 array[7] = this.ty; 5096 array[8] = 1; 5097 } 5098 else 5099 { 5100 array[0] = this.a; 5101 array[1] = this.c; 5102 array[2] = this.tx; 5103 array[3] = this.b; 5104 array[4] = this.d; 5105 array[5] = this.ty; 5106 array[6] = 0; 5107 array[7] = 0; 5108 array[8] = 1; 5109 } 5110 5111 return array; 5112 }; 5113 5114 /** 5115 * Get a new position with the current transformation applied. 5116 * Can be used to go from a child's coordinate space to the world coordinate space. (e.g. rendering) 5117 * 5118 * @param {PIXI.Point} pos - The origin 5119 * @param {PIXI.Point} [newPos] - The point that the new position is assigned to (allowed to be same as input) 5120 * @return {PIXI.Point} The new point, transformed through this matrix 5121 */ 5122 Matrix.prototype.apply = function apply (pos, newPos) 5123 { 5124 newPos = newPos || new Point(); 5125 5126 var x = pos.x; 5127 var y = pos.y; 5128 5129 newPos.x = (this.a * x) + (this.c * y) + this.tx; 5130 newPos.y = (this.b * x) + (this.d * y) + this.ty; 5131 5132 return newPos; 5133 }; 5134 5135 /** 5136 * Get a new position with the inverse of the current transformation applied. 5137 * Can be used to go from the world coordinate space to a child's coordinate space. (e.g. input) 5138 * 5139 * @param {PIXI.Point} pos - The origin 5140 * @param {PIXI.Point} [newPos] - The point that the new position is assigned to (allowed to be same as input) 5141 * @return {PIXI.Point} The new point, inverse-transformed through this matrix 5142 */ 5143 Matrix.prototype.applyInverse = function applyInverse (pos, newPos) 5144 { 5145 newPos = newPos || new Point(); 5146 5147 var id = 1 / ((this.a * this.d) + (this.c * -this.b)); 5148 5149 var x = pos.x; 5150 var y = pos.y; 5151 5152 newPos.x = (this.d * id * x) + (-this.c * id * y) + (((this.ty * this.c) - (this.tx * this.d)) * i
5152d); 5153 newPos.y = (this.a * id * y) + (-this.b * id * x) + (((-this.ty * this.a) + (this.tx * this.b)) * id); 5154 5155 return newPos; 5156 }; 5157 5158 /** 5159 * Translates the matrix on the x and y. 5160 * 5161 * @param {number} x How much to translate x by 5162 * @param {number} y How much to translate y by 5163 * @return {PIXI.Matrix} This matrix. Good for chaining method calls. 5164 */ 5165 Matrix.prototype.translate = function translate (x, y) 5166 { 5167 this.tx += x; 5168 this.ty += y; 5169 5170 return this; 5171 }; 5172 5173 /** 5174 * Applies a scale transformation to the matrix. 5175 * 5176 * @param {number} x The amount to scale horizontally 5177 * @param {number} y The amount to scale vertically 5178 * @return {PIXI.Matrix} This matrix. Good for chaining method calls. 5179 */ 5180 Matrix.prototype.scale = function scale (x, y) 5181 { 5182 this.a *= x; 5183 this.d *= y; 5184 this.c *= x; 5185 this.b *= y; 5186 this.tx *= x; 5187 this.ty *= y; 5188 5189 return this; 5190 }; 5191 5192 /** 5193 * Applies a rotation transformation to the matrix. 5194 * 5195 * @param {number} angle - The angle in radians. 5196 * @return {PIXI.Matrix} This matrix. Good for chaining method calls. 5197 */ 5198 Matrix.prototype.rotate = function rotate (angle) 5199 { 5200 var cos = Math.cos(angle); 5201 var sin = Math.sin(angle); 5202 5203 var a1 = this.a; 5204 var c1 = this.c; 5205 var tx1 = this.tx; 5206 5207 this.a = (a1 * cos) - (this.b * sin); 5208 this.b = (a1 * sin) + (this.b * cos); 5209 this.c = (c1 * cos) - (this.d * sin); 5210 this.d = (c1 * sin) + (this.d * cos); 5211 this.tx = (tx1 * cos) - (this.ty * sin); 5212 this.ty = (tx1 * sin) + (this.ty * cos); 5213 5214 return this; 5215 }; 5216 5217 /** 5218 * Appends the given Matrix to this Matrix. 5219 * 5220 * @param {PIXI.Matrix} matrix - The matrix to append. 5221 * @return {PIXI.Matrix} This matrix. Good for chaining method calls. 5222 */ 5223 Matrix.prototype.append = function append (matrix) 5224 { 5225 var a1 = this.a; 5226 var b1 = this.b; 5227 var c1 = this.c; 5228 var d1 = this.d; 5229 5230 this.a = (matrix.a * a1) + (matrix.b * c1); 5231 this.b = (matrix.a * b1) + (matrix.b * d1); 5232 this.c = (matrix.c * a1) + (matrix.d * c1); 5233 this.d = (matrix.c * b1) + (matrix.d * d1); 5234 5235 this.tx = (matrix.tx * a1) + (matrix.ty * c1) + this.tx; 5236 this.ty = (matrix.tx * b1) + (matrix.ty * d1) + this.ty; 5237 5238 return this; 5239 }; 5240 5241 /** 5242 * Sets the matrix based on all the available properties 5243 * 5244 * @param {number} x - Position on the x axis 5245 * @param {number} y - Position on the y axis 5246 * @param {number} pivotX - Pivot on the x axis 5247 * @param {number} pivotY - Pivot on the y axis 5248 * @param {number} scaleX - Scale on the x axis 5249 * @param {number} scaleY - Scale on the y axis 5250 * @param {number} rotation - Rotation in radians 5251 * @param {number} skewX - Skew on the x axis 5252 * @param {number} skewY - Skew on the y axis 5253 * @return {PIXI.Matrix} This matrix. Good for chaining method calls. 5254 */ 5255 Matrix.prototype.setTransform = function setTransform (x, y, pivotX, pivotY, scaleX, scaleY, rotation, skewX, skewY) 5256 { 5257 this.a = Math.cos(rotation + skewY) * scaleX; 5258 this.b = Math.sin(rotation + skewY) * scaleX; 5259 this.c = -Math.sin(rotation - skewX) * scaleY; 5260 this.d = Math.cos(rotation - skewX) * scaleY; 5261 5262 this.tx = x - ((pivotX * this.a) + (pivotY * this.c)); 5263 this.ty = y - ((pivotX * this.b) + (pivotY * this.d)); 5264 5265 return this; 5266 }; 5267 5268 /** 5269 * Prepends the given Matrix to this Matrix. 5270 * 5271 * @param {PIXI.Matrix} matrix - The matrix to prepend 5272 * @return {PIXI.Matrix} This matrix. Good for chaining method calls. 5273 */ 5274 Matrix.prototype.prepend = function prepend (matrix) 5275 { 5276 var tx1 = this.tx; 5277 5278 if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) 5279 { 5280 var a1 = this.a; 5281 var c1 = this.c; 5282 5283 this.a = (a1 * matrix.a) + (this.b * matrix.c); 5284 this.b = (a1 * matrix.b) + (this.b * matrix.d); 5285 this.c = (c1 * matrix.a) + (this.d * matrix.c); 5286 this.d = (c1 * matrix.b) + (this.d * matrix.d); 5287 } 5288 5289 this.tx = (tx1 * matrix.a) + (this.ty * matrix.c) + matrix.tx; 5290 this.ty = (tx1 * matrix.b) + (this.ty * matrix.d) + matrix.ty; 5291 5292 return this; 5293 }; 5294 5295 /** 5296 * Decomposes the matrix (x, y, scaleX, scaleY, and rotation) and sets the properties on to a transform. 5297 * 5298 * @param {PIXI.Transform} transform - The transform to apply the properties to. 5299 * @return {PIXI.Transform} The transform with the newly applied properties 5300 */ 5301 Matrix.prototype.decompose = function decompose (transform) 5302 { 5303 // sort out rotation / skew.. 5304 var a = this.a; 5305 var b = this.b; 5306 var c = this.c; 5307 var d = this.d; 5308 5309 var skewX = -Math.atan2(-c, d); 5310 var skewY = Math.atan2(b, a); 5311 5312 var delta = Math.abs(skewX + skewY); 5313 5314 if (delta < 0.00001 || Math.abs(PI_2 - delta) < 0.00001) 5315 { 5316 transform.rotation = skewY; 5317 transform.skew.x = transform.skew.y = 0; 5318 } 5319 else 5320 { 5321 transform.rotation = 0; 5322 transform.skew.x = skewX; 5323 transform.skew.y = skewY; 5324 } 5325 5326 // next set scale 5327 transform.scale.x = Math.sqrt((a * a) + (b * b)); 5328 transform.scale.y = Math.sqrt((c * c) + (d * d)); 5329 5330 // next set position 5331 transform.position.x = this.tx; 5332 transform.position.y = this.ty; 5333 5334 return transform; 5335 }; 5336 5337 /** 5338 * Inverts this matrix 5339 * 5340 * @return {PIXI.Matrix} This matrix. Good for chaining method calls. 5341 */ 5342 Matrix.prototype.invert = function invert () 5343 { 5344 var a1 = this.a; 5345 var b1 = this.b; 5346 var c1 = this.c; 5347 var d1 = this.d; 5348 var tx1 = this.tx; 5349 var n = (a1 * d1) - (b1 * c1); 5350 5351 this.a = d1 / n; 5352 this.b = -b1 / n; 5353 this.c = -c1 / n; 5354 this.d = a1 / n; 5355 this.tx = ((c1 * this.ty) - (d1 * tx1)) / n; 5356 this.ty = -((a1 * this.ty) - (b1 * tx1)) / n; 5357 5358 return this; 5359 }; 5360 5361 /** 5362 * Resets this Matrix to an identity (default) matrix. 5363 * 5364 * @return {PIXI.Matrix} This matrix. Good for chaining method calls. 5365 */ 5366 Matrix.prototype.identity = function identity () 5367 { 5368 this.a = 1; 5369 this.b = 0; 5370 this.c = 0; 5371 this.d = 1; 5372 this.tx = 0; 5373 this.ty = 0; 5374 5375 return this; 5376 }; 5377 5378 /** 5379 * Creates a new Matrix object with the same values as this one. 5380 * 5381 * @return {PIXI.Matrix} A copy of this matrix. Good for chaining method calls. 5382 */ 5383 Matrix.prototype.clone = function clone () 5384 { 5385 var matrix = new Matrix(); 5386 5387 matrix.a = this.a; 5388 matrix.b = this.b; 5389 matrix.c = this.c; 5390 matrix.d = this.d; 5391 matrix.tx = this.tx; 5392 matrix.ty = this.ty; 5393 5394 return matrix; 5395 }; 5396 5397 /** 5398 * Changes the values of the given matrix to be the same as the ones in this matrix 5399 * 5400 * @param {PIXI.Matrix} matrix - The matrix to copy to. 5401 * @return {PIXI.Matrix} The matrix given in parameter with its values updated. 5402 */ 5403 Matrix.prototype.copyTo = function copyTo (matrix) 5404 { 5405 matrix.a = this.a; 5406 matrix.b = this.b; 5407 matrix.c = this.c; 5408 matrix.d = this.d; 5409 matrix.tx = this.tx; 5410 matrix.ty = this.ty; 5411 5412 return matrix; 5413 }; 5414 5415 /** 5416 * Changes the values of the matrix to be the same as the ones in given matrix 5417 * 5418 * @param {PIXI.Matrix} matrix - The matrix to copy from. 5419 * @return {PIXI.Matrix} this 5420 */ 5421 Matrix.prototype.copyFrom = function copyFrom (matrix) 5422 { 5423 this.a = matrix.a; 5424 this.b = matrix.b; 5425 this.c = matrix.c; 5426 this.d = matrix.d; 5427 this.tx = matrix.tx; 5428 this.ty = matrix.ty; 5429 5430 return this; 5431 }; 5432 5433 /** 5434 * A default (identity) matrix 5435 * 5436 * @static 5437 * @const 5438 * @member {PIXI.Matrix} 5439 */ 5440 staticAccessors.IDENTITY.get = function () 5441 { 5442 return new Matrix(); 5443 }; 5444 5445 /** 5446 * A temp matrix 5447 * 5448 * @static 5449 * @const 5450 * @member {PIXI.Matrix} 5451 */ 5452 staticAccessors.TEMP_MATRIX.get = function () 5453 { 5454 return new Matrix(); 5455 }; 5456 5457 Object.defineProperties( Matrix, staticAccessors ); 5458 5459 // Your friendly neighbour https://en.wikipedia.org/wiki/Dihedral_group of order 16 5460 5461 var ux = [1, 1, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, -1, -1, 0, 1]; 5462 var uy = [0, 1, 1, 1, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, -1, -1]; 5463 var vx = [0, -1, -1, -1, 0, 1, 1, 1, 0, 1, 1, 1, 0, -1, -1, -1]; 5464 var vy = [1, 1, 0, -1, -1, -1, 0, 1, -1, -1, 0, 1, 1, 1, 0, -1]; 5465 var tempMatrices = []; 5466 5467 var mul = []; 5468 5469 function signum(x) 5470 { 5471 if (x < 0) 5472 { 5473 return -1; 5474 } 5475 if (x > 0) 5476 { 5477 return 1; 5478 } 5479 5480 return 0; 5481 } 5482
5483 function init() 5484 { 5485 for (var i = 0; i < 16; i++) 5486 { 5487 var row = []; 5488 5489 mul.push(row); 5490 5491 for (var j = 0; j < 16; j++) 5492 { 5493 var _ux = signum((ux[i] * ux[j]) + (vx[i] * uy[j])); 5494 var _uy = signum((uy[i] * ux[j]) + (vy[i] * uy[j])); 5495 var _vx = signum((ux[i] * vx[j]) + (vx[i] * vy[j])); 5496 var _vy = signum((uy[i] * vx[j]) + (vy[i] * vy[j])); 5497 5498 for (var k = 0; k < 16; k++) 5499 { 5500 if (ux[k] === _ux && uy[k] === _uy && vx[k] === _vx && vy[k] === _vy) 5501 { 5502 row.push(k); 5503 break; 5504 } 5505 } 5506 } 5507 } 5508 5509 for (var i$1 = 0; i$1 < 16; i$1++) 5510 { 5511 var mat = new Matrix(); 5512 5513 mat.set(ux[i$1], uy[i$1], vx[i$1], vy[i$1], 0, 0); 5514 tempMatrices.push(mat); 5515 } 5516 } 5517 5518 init(); 5519 5520 /** 5521 * Implements Dihedral Group D_8, see [group D4]{@link http://mathworld.wolfram.com/DihedralGroupD4.html}, 5522 * D8 is the same but with diagonals. Used for texture rotations. 5523 * 5524 * Vector xX(i), xY(i) is U-axis of sprite with rotation i 5525 * Vector yY(i), yY(i) is V-axis of sprite with rotation i 5526 * Rotations: 0 grad (0), 90 grad (2), 180 grad (4), 270 grad (6) 5527 * Mirrors: vertical (8), main diagonal (10), horizontal (12), reverse diagonal (14) 5528 * This is the small part of gameofbombs.com portal system. It works. 5529 * 5530 * @author Ivan @ivanpopelyshev 5531 * @class 5532 * @memberof PIXI 5533 */ 5534 var GroupD8 = { 5535 E: 0, 5536 SE: 1, 5537 S: 2, 5538 SW: 3, 5539 W: 4, 5540 NW: 5, 5541 N: 6, 5542 NE: 7, 5543 MIRROR_VERTICAL: 8, 5544 MIRROR_HORIZONTAL: 12, 5545 uX: function (ind) { return ux[ind]; }, 5546 uY: function (ind) { return uy[ind]; }, 5547 vX: function (ind) { return vx[ind]; }, 5548 vY: function (ind) { return vy[ind]; }, 5549 inv: function (rotation) { 5550 if (rotation & 8) 5551 { 5552 return rotation & 15; 5553 } 5554 5555 return (-rotation) & 7; 5556 }, 5557 add: function (rotationSecond, rotationFirst) { return mul[rotationSecond][rotationFirst]; }, 5558 sub: function (rotationSecond, rotationFirst) { return mul[rotationSecond][GroupD8.inv(rotationFirst)]; }, 5559 5560 /** 5561 * Adds 180 degrees to rotation. Commutative operation. 5562 * 5563 * @memberof PIXI.GroupD8 5564 * @param {number} rotation - The number to rotate. 5565 * @returns {number} rotated number 5566 */ 5567 rotate180: function (rotation) { return rotation ^ 4; }, 5568 5569 /** 5570 * Direction of main vector can be horizontal, vertical or diagonal. 5571 * Some objects work with vertical directions different. 5572 * 5573 * @memberof PIXI.GroupD8 5574 * @param {number} rotation - The number to check. 5575 * @returns {boolean} Whether or not the direction is vertical 5576 */ 5577 isVertical: function (rotation) { return (rotation & 3) === 2; }, 5578 5579 /** 5580 * @memberof PIXI.GroupD8 5581 * @param {number} dx - TODO 5582 * @param {number} dy - TODO 5583 * 5584 * @return {number} TODO 5585 */ 5586 byDirection: function (dx, dy) { 5587 if (Math.abs(dx) * 2 <= Math.abs(dy)) 5588 { 5589 if (dy >= 0) 5590 { 5591 return GroupD8.S; 5592 } 5593 5594 return GroupD8.N; 5595 } 5596 else if (Math.abs(dy) * 2 <= Math.abs(dx)) 5597 { 5598 if (dx > 0) 5599 { 5600 return GroupD8.E; 5601 } 5602 5603 return GroupD8.W; 5604 } 5605 else if (dy > 0) 5606 { 5607 if (dx > 0) 5608 { 5609 return GroupD8.SE; 5610 } 5611 5612 return GroupD8.SW; 5613 } 5614 else if (dx > 0) 5615 { 5616 return GroupD8.NE; 5617 } 5618 5619 return GroupD8.NW; 5620 }, 5621 5622 /** 5623 * Helps sprite to compensate texture packer rotation. 5624 * 5625 * @memberof PIXI.GroupD8 5626 * @param {PIXI.Matrix} matrix - sprite world matrix 5627 * @param {number} rotation - The rotation factor to use. 5628 * @param {number} tx - sprite anchoring 5629 * @param {number} ty - sprite anchoring 5630 */ 5631 matrixAppendRotationInv: function (matrix, rotation, tx, ty) { 5632 if ( tx === void 0 ) { tx = 0; } 5633 if ( ty === void 0 ) { ty = 0; } 5634 5635 // Packer used "rotation", we use "inv(rotation)" 5636 var mat = tempMatrices[GroupD8.inv(rotation)]; 5637 5638 mat.tx = tx; 5639 mat.ty = ty; 5640 matrix.append(mat); 5641 }, 5642 }; 5643 5644 /** 5645 * Transform that takes care about its versions 5646 * 5647 * @class 5648 * @memberof PIXI 5649 */ 5650 var Transform = function Transform() 5651 { 5652 /** 5653 * The global matrix transform. It can be swapped temporarily by some functions like getL
5653ocalBounds() 5654 * 5655 * @member {PIXI.Matrix} 5656 */ 5657 this.worldTransform = new Matrix(); 5658 5659 /** 5660 * The local matrix transform 5661 * 5662 * @member {PIXI.Matrix} 5663 */ 5664 this.localTransform = new Matrix(); 5665 5666 /** 5667 * The coordinate of the object relative to the local coordinates of the parent. 5668 * 5669 * @member {PIXI.ObservablePoint} 5670 */ 5671 this.position = new ObservablePoint(this.onChange, this, 0, 0); 5672 5673 /** 5674 * The scale factor of the object. 5675 * 5676 * @member {PIXI.ObservablePoint} 5677 */ 5678 this.scale = new ObservablePoint(this.onChange, this, 1, 1); 5679 5680 /** 5681 * The pivot point of the displayObject that it rotates around. 5682 * 5683 * @member {PIXI.ObservablePoint} 5684 */ 5685 this.pivot = new ObservablePoint(this.onChange, this, 0, 0); 5686 5687 /** 5688 * The skew amount, on the x and y axis. 5689 * 5690 * @member {PIXI.ObservablePoint} 5691 */ 5692 this.skew = new ObservablePoint(this.updateSkew, this, 0, 0); 5693 5694 this._rotation = 0; 5695 5696 this._cx = 1; // cos rotation + skewY; 5697 this._sx = 0; // sin rotation + skewY; 5698 this._cy = 0; // cos rotation + Math.PI/2 - skewX; 5699 this._sy = 1; // sin rotation + Math.PI/2 - skewX; 5700 5701 this._localID = 0; 5702 this._currentLocalID = 0; 5703 5704 this._worldID = 0; 5705 this._parentID = 0; 5706 }; 5707 5708 var prototypeAccessors$1$1 = { rotation: { configurable: true } }; 5709 5710 /** 5711 * Called when a value changes. 5712 * 5713 * @private 5714 */ 5715 Transform.prototype.onChange = function onChange () 5716 { 5717 this._localID++; 5718 }; 5719 5720 /** 5721 * Called when skew or rotation changes 5722 * 5723 * @private 5724 */ 5725 Transform.prototype.updateSkew = function updateSkew () 5726 { 5727 this._cx = Math.cos(this._rotation + this.skew._y); 5728 this._sx = Math.sin(this._rotation + this.skew._y); 5729 this._cy = -Math.sin(this._rotation - this.skew._x); // cos, added PI/2 5730 this._sy = Math.cos(this._rotation - this.skew._x); // sin, added PI/2 5731 5732 this._localID++; 5733 }; 5734 5735 /** 5736 * Updates only local matrix 5737 */ 5738 Transform.prototype.updateLocalTransform = function updateLocalTransform () 5739 { 5740 var lt = this.localTransform; 5741 5742 if (this._localID !== this._currentLocalID) 5743 { 5744 // get the matrix values of the displayobject based on its transform properties.. 5745 lt.a = this._cx * this.scale._x; 5746 lt.b = this._sx * this.scale._x; 5747 lt.c = this._cy * this.scale._y; 5748 lt.d = this._sy * this.scale._y; 5749 5750 lt.tx = this.position._x - ((this.pivot._x * lt.a) + (this.pivot._y * lt.c)); 5751 lt.ty = this.position._y - ((this.pivot._x * lt.b) + (this.pivot._y * lt.d)); 5752 this._currentLocalID = this._localID; 5753 5754 // force an update.. 5755 this._parentID = -1; 5756 } 5757 }; 5758 5759 /** 5760 * Updates the values of the object and applies the parent's transform. 5761 * 5762 * @param {PIXI.Transform} parentTransform - The transform of the parent of this object 5763 */ 5764 Transform.prototype.updateTransform = function updateTransform (parentTransform) 5765 { 5766 var lt = this.localTransform; 5767 5768 if (this._localID !== this._currentLocalID) 5769 { 5770 // get the matrix values of the displayobject based on its transform properties.. 5771 lt.a = this._cx * this.scale._x; 5772 lt.b = this._sx * this.scale._x; 5773 lt.c = this._cy * this.scale._y; 5774 lt.d = this._sy * this.scale._y; 5775 5776 lt.tx = this.position._x - ((this.pivot._x * lt.a) + (this.pivot._y * lt.c)); 5777 lt.ty = this.position._y - ((this.pivot._x * lt.b) + (this.pivot._y * lt.d)); 5778 this._currentLocalID = this._localID; 5779 5780 // force an update.. 5781 this._parentID = -1; 5782 } 5783 5784 if (this._parentID !== parentTransform._worldID) 5785 { 5786 // concat the parent matrix with the objects transform. 5787 var pt = parentTransform.worldTransform; 5788 var wt = this.worldTransform; 5789 5790 wt.a = (lt.a * pt.a) + (lt.b * pt.c); 5791 wt.b = (lt.a * pt.b) + (lt.b * pt.d); 5792 wt.c = (lt.c * pt.a) + (lt.d * pt.c); 5793 wt.d = (lt.c * pt.b) + (lt.d * pt.d); 5794 wt.tx = (lt.tx * pt.a) + (lt.ty * pt.c) + pt.tx; 5795 wt.ty = (lt.tx * pt.b) + (lt.ty * pt.d) + pt.ty; 5796 5797 this._parentID = parentTransform._worldID; 5798 5799 // update the id of the transform.. 5800 this._worldID++; 5801 } 5802 }; 5803 5804 /** 5805 * Decomposes a matrix and sets the transforms properties based on it. 5806 * 5807 * @param {PIXI.Matrix} matrix - The matrix to decompose 5808 */ 5809 Transform.prototype.setFromMatrix = function setFromMatrix (matrix) 5810 { 5811 matrix.decompose(this); 5812 this._localID++; 5813 }; 5814 5815 /** 5816 * The rotation of the object in radians. 5817 * 5818 * @member {number} 5819 */ 5820 prototypeAccessors$1$1.rotation.get = function () 5821 { 5822 return this._rotation; 5823 }; 5824 5825 prototypeAccessors$1$1.rotation.set = function (value) // eslint-disable-line require-jsdoc 5826 { 5827 if (this._rotation !== value) 5828 { 5829 this._rotation = value; 5830 this.updateSkew(); 5831 } 5832 }; 5833 5834 Object.defineProperties( Transform.prototype, prototypeAccessors$1$1 ); 5835 5836 Transform.IDENTITY = new Transform(); 5837 5838 /** 5839 * Rectangle object is an area defined by its position, as indicated by its top-left corner 5840 * point (x, y) and by its width and its height. 5841 * 5842 * @class 5843 * @memberof PIXI 5844 */ 5845 var Rectangle = function Rectangle(x, y, width, height) 5846 { 5847 if ( x === void 0 ) { x = 0; } 5848 if ( y === void 0 ) { y = 0; } 5849 if ( width === void 0 ) { width = 0; } 5850 if ( height === void 0 ) { height = 0; } 5851 5852 /** 5853 * @member {number} 5854 * @default 0 5855 */ 5856 this.x = Number(x); 5857 5858 /** 5859 * @member {number} 5860 * @default 0 5861 */ 5862 this.y = Number(y); 5863 5864 /** 5865 * @member {number} 5866 * @default 0 5867 */ 5868 this.width = Number(width); 5869 5870 /** 5871 * @member {number} 5872 * @default 0 5873 */ 5874 this.height = Number(height); 5875 5876 /** 5877 * The type of the object, mainly used to avoid `instanceof` checks 5878 * 5879 * @member {number} 5880 * @readOnly 5881 * @default PIXI.SHAPES.RECT 5882 * @see PIXI.SHAPES 5883 */ 5884 this.type = SHAPES.RECT; 5885 }; 5886 5887 var prototypeAccessors$2 = { left: { configurable: true },right: { configurable: true },top: { configurable: true },bottom: { configurable: true } }; 5888 var staticAccessors$1 = { EMPTY: { configurable: true } }; 5889 5890 /** 5891 * returns the left edge of the rectangle 5892 * 5893 * @member {number} 5894 */ 5895 prototypeAccessors$2.left.get = function () 5896 { 5897 return this.x; 5898 }; 5899 5900 /** 5901 * returns the right edge of the rectangle 5902 * 5903 * @member {number} 5904 */ 5905 prototypeAccessors$2.right.get = function () 5906 { 5907 return this.x + this.width; 5908 }; 5909 5910 /** 5911 * returns the top edge of the rectangle 5912 * 5913 * @member {number} 5914 */ 5915 prototypeAccessors$2.top.get = function () 5916 { 5917 return this.y; 5918 }; 5919 5920 /** 5921 * returns the bottom edge of the rectangle 5922 * 5923 * @member {number} 5924 */ 5925 prototypeAccessors$2.bottom.get = function () 5926 { 5927 return this.y + this.height; 5928 }; 5929 5930 /** 5931 * A constant empty rectangle. 5932 * 5933 * @static 5934 * @constant 5935 * @member {PIXI.Rectangle} 5936 */
5937 staticAccessors$1.EMPTY.get = function () 5938 { 5939 return new Rectangle(0, 0, 0, 0); 5940 }; 5941 5942 /** 5943 * Creates a clone of this Rectangle 5944 * 5945 * @return {PIXI.Rectangle} a copy of the rectangle 5946 */ 5947 Rectangle.prototype.clone = function clone () 5948 { 5949 return new Rectangle(this.x, this.y, this.width, this.height); 5950 }; 5951 5952 /** 5953 * Copies another rectangle to this one. 5954 * 5955 * @param {PIXI.Rectangle} rectangle - The rectangle to copy from. 5956 * @return {PIXI.Rectangle} Returns itself. 5957 */ 5958 Rectangle.prototype.copyFrom = function copyFrom (rectangle) 5959 { 5960 this.x = rectangle.x; 5961 this.y = rectangle.y; 5962 this.width = rectangle.width; 5963 this.height = rectangle.height; 5964 5965 return this; 5966 }; 5967 5968 /** 5969 * Copies this rectangle to another one. 5970 * 5971 * @param {PIXI.Rectangle} rectangle - The rectangle to copy to. 5972 * @return {PIXI.Rectangle} Returns given parameter. 5973 */ 5974 Rectangle.prototype.copyTo = function copyTo (rectangle) 5975 { 5976 rectangle.x = this.x; 5977 rectangle.y = this.y; 5978 rectangle.width = this.width; 5979 rectangle.height = this.height; 5980 5981 return rectangle; 5982 }; 5983 5984 /** 5985 * Checks whether the x and y coordinates given are contained within this Rectangle 5986 * 5987 * @param {number} x - The X coordinate of the point to test 5988 * @param {number} y - The Y coordinate of the point to test 5989 * @return {boolean} Whether the x/y coordinates are within this Rectangle 5990 */ 5991 Rectangle.prototype.contains = function contains (x, y) 5992 { 5993 if (this.width <= 0 || this.height <= 0) 5994 { 5995 return false; 5996 } 5997 5998 if (x >= this.x && x < this.x + this.width) 5999 { 6000 if (y >= this.y && y < this.y + this.height) 6001 { 6002 return true; 6003 } 6004 } 6005 6006 return false; 6007 }; 6008 6009 /** 6010 * Pads the rectangle making it grow in all directions. 6011 * 6012 * @param {number} paddingX - The horizontal padding amount. 6013 * @param {number} paddingY - The vertical padding amount. 6014 */ 6015 Rectangle.prototype.pad = function pad (paddingX, paddingY) 6016 { 6017 paddingX = paddingX || 0; 6018 paddingY = paddingY || ((paddingY !== 0) ? paddingX : 0); 6019 6020 this.x -= paddingX; 6021 this.y -= paddingY; 6022 6023 this.width += paddingX * 2; 6024 this.height += paddingY * 2; 6025 }; 6026 6027 /** 6028 * Fits this rectangle around the passed one. 6029 * 6030 * @param {PIXI.Rectangle} rectangle - The rectangle to fit. 6031 */ 6032 Rectangle.prototype.fit = function fit (rectangle) 6033 { 6034 var x1 = Math.max(this.x, rectangle.x); 6035 var x2 = Math.min(this.x + this.width, rectangle.x + rectangle.width); 6036 var y1 = Math.max(this.y, rectangle.y); 6037 var y2 = Math.min(this.y + this.height, rectangle.y + rectangle.height); 6038 6039 this.x = x1; 6040 this.width = Math.max(x2 - x1, 0); 6041 this.y = y1; 6042 this.height = Math.max(y2 - y1, 0); 6043 }; 6044 6045 /** 6046 * Enlarges rectangle that way its corners lie on grid 6047 * 6048 * @param {number} [resolution=1] resolution 6049 * @param {number} [eps=0.001] precision 6050 */ 6051 Rectangle.prototype.ceil = function ceil (resolution, eps) 6052 { 6053 if ( resolution === void 0 ) { resolution = 1; } 6054 if ( eps === void 0 ) { eps = 0.001; } 6055 6056 var x2 = Math.ceil((this.x + this.width - eps) * resolution) / resolution; 6057 var y2 = Math.ceil((this.y + this.height - eps) * resolution) / resolution; 6058 6059 this.x = Math.floor((this.x + eps) * resolution) / resolution; 6060 this.y = Math.floor((this.y + eps) * resolution) / resolution; 6061 6062 this.width = x2 - this.x; 6063 this.height = y2 - this.y; 6064 }; 6065 6066 /** 6067 * Enlarges this rectangle to include the passed rectangle. 6068 * 6069 * @param {PIXI.Rectangle} rectangle - The rectangle to include. 6070 */ 6071 Rectangle.prototype.enlarge = function enlarge (rectangle) 6072 { 6073 var x1 = Math.min(this.x, rectangle.x); 6074 var x2 = Math.max(this.x + this.width, rectangle.x + rectangle.width); 6075 var y1 = Math.min(this.y, rectangle.y); 6076 var y2 = Math.max(this.y + this.height, rectangle.y + rectangle.height); 6077 6078 this.x = x1; 6079 this.width = x2 - x1; 6080 this.y = y1; 6081 this.height = y2 - y1; 6082 }; 6083 6084 Object.defineProperties( Rectangle.prototype, prototypeAccessors$2 ); 6085 Object.defineProperties( Rectangle, staticAccessors$1 ); 6086 6087 /** 6088 * The Circle object is used to help draw graphics and can also be used to specify a hit area for displayObjects. 6089 * 6090 * @class 6091 * @memberof PIXI 6092 */ 6093 var Circle = function Circle(x, y, radius) 6094 { 6095 if ( x === void 0 ) { x = 0; } 6096 if ( y === void 0 ) { y = 0; }
6097 if ( radius === void 0 ) { radius = 0; } 6098 6099 /** 6100 * @member {number} 6101 * @default 0 6102 */ 6103 this.x = x; 6104 6105 /** 6106 * @member {number} 6107 * @default 0 6108 */ 6109 this.y = y; 6110 6111 /** 6112 * @member {number} 6113 * @default 0 6114 */ 6115 this.radius = radius; 6116 6117 /** 6118 * The type of the object, mainly used to avoid `instanceof` checks 6119 * 6120 * @member {number} 6121 * @readOnly 6122 * @default PIXI.SHAPES.CIRC 6123 * @see PIXI.SHAPES 6124 */ 6125 this.type = SHAPES.CIRC; 6126 }; 6127 6128 /** 6129 * Creates a clone of this Circle instance 6130 * 6131 * @return {PIXI.Circle} a copy of the Circle 6132 */ 6133 Circle.prototype.clone = function clone () 6134 { 6135 return new Circle(this.x, this.y, this.radius); 6136 }; 6137 6138 /** 6139 * Checks whether the x and y coordinates given are contained within this circle 6140 * 6141 * @param {number} x - The X coordinate of the point to test 6142 * @param {number} y - The Y coordinate of the point to test 6143 * @return {boolean} Whether the x/y coordinates are within this Circle 6144 */ 6145 Circle.prototype.contains = function contains (x, y) 6146 { 6147 if (this.radius <= 0) 6148 { 6149 return false; 6150 } 6151 6152 var r2 = this.radius * this.radius; 6153 var dx = (this.x - x); 6154 var dy = (this.y - y); 6155 6156 dx *= dx; 6157 dy *= dy; 6158 6159 return (dx + dy <= r2); 6160 }; 6161 6162 /** 6163 * Returns the framing rectangle of the circle as a Rectangle object 6164 * 6165 * @return {PIXI.Rectangle} the framing rectangle 6166 */ 6167 Circle.prototype.getBounds = function getBounds () 6168 { 6169 return new Rectangle(this.x - this.radius, this.y - this.radius, this.radius * 2, this.radius * 2); 6170 }; 6171 6172 /** 6173 * The Ellipse object is used to help draw graphics and can also be used to specify a hit area for displayObjects. 6174 * 6175 * @class 6176 * @memberof PIXI 6177 */ 6178 var Ellipse = function Ellipse(x, y, halfWidth, halfHeight) 6179 { 6180 if ( x === void 0 ) { x = 0; } 6181 if ( y === void 0 ) { y = 0; } 6182 if ( halfWidth === void 0 ) { halfWidth = 0; } 6183 if ( halfHeight === void 0 ) { halfHeight = 0; } 6184 6185 /** 6186 * @member {number} 6187 * @default 0 6188 */ 6189 this.x = x; 6190 6191 /** 6192 * @member {number} 6193 * @default 0 6194 */ 6195 this.y = y; 6196 6197 /** 6198 * @member {number} 6199 * @default 0 6200 */ 6201 this.width = halfWidth; 6202 6203 /** 6204 * @member {number} 6205 * @default 0 6206 */ 6207 this.height = halfHeight; 6208 6209 /** 6210 * The type of the object, mainly used to avoid `instanceof` checks 6211 * 6212 * @member {number} 6213 * @readOnly 6214 * @default PIXI.SHAPES.ELIP 6215 * @see PIXI.SHAPES 6216 */ 6217 this.type = SHAPES.ELIP; 6218 }; 6219 6220 /** 6221 * Creates a clone of this Ellipse instance 6222 * 6223 * @return {PIXI.Ellipse} a copy of the ellipse 6224 */ 6225 Ellipse.prototype.clone = function clone () 6226 { 6227 return new Ellipse(this.x, this.y, this.width, this.height); 6228 }; 6229 6230 /** 6231 * Checks whether the x and y coordinates given are contained within this ellipse 6232 * 6233 * @param {number} x - The X coordinate of the point to test 6234 * @param {number} y - The Y coordinate of the point to test 6235 * @return {boolean} Whether the x/y coords are within this ellipse 6236 */ 6237 Ellipse.prototype.contains = function contains (x, y) 6238 { 6239 if (this.width <= 0 || this.height <= 0) 6240 { 6241 return false; 6242 } 6243 6244 // normalize the coords to an ellipse with center 0,0 6245 var normx = ((x - this.x) / this.width); 6246 var normy = ((y - this.y) / this.height); 6247 6248 normx *= normx; 6249 normy *= normy; 6250 6251 return (normx + normy <= 1); 6252 }; 6253 6254 /** 6255 * Returns the framing rectangle of the ellipse as a Rectangle object 6256 * 6257 * @return {PIXI.Rectangle} the framing rectangle 6258 */ 6259 Ellipse.prototype.getBounds = function getBounds () 6260 { 6261 return new Rectangle(this.x - this.width, this.y - this.height, this.width, this.height); 6262 }; 6263 6264 /** 6265 * A class to define a shape via user defined co-orinates. 6266 * 6267 * @class 6268 * @memberof PIXI 6269 */ 6270 var Polygon = function Polygon() 6271 { 6272 var arguments$1 = arguments; 6273 6274 var points = [], len = arguments.length; 6275 while ( len-- ) { points[ len ] = arguments$1[ len ]; } 6276 6277 if (Array.isArray(points[0])) 6278 { 6279 points = points[0]; 6280 } 6281 6282 // if this is an array of points, convert it to a flat array of numbers 6283 if (points[0] instanceof Point) 6284 { 6285 var p = []; 6286 6287 for (var i = 0, il = points.length; i < il; i++) 6288 { 6289 p.push(points[i].x, points[i].y); 6290 } 6291 6292 points = p; 6293 } 6294 6295 /** 6296 * An array of the points of this polygon 6297 * 6298 * @member {number[]} 6299 */ 6300 this.points = points; 6301 6302 /** 6303 * The type of the object, mainly used to avoid `instanceof` checks 6304 * 6305 * @member {number} 6306 * @readOnly 6307 * @default PIXI.SHAPES.POLY 6308 * @see PIXI.SHAPES 6309 */ 6310 this.type = SHAPES.POLY; 6311 6312 /** 6313 * `false` after moveTo, `true` after `closePath`. In all other cases it is `true`. 6314 * @member {boolean} 6315 * @default true 6316 */ 6317 this.closeStroke = true; 6318 }; 6319 6320 /** 6321 * Creates a clone of this polygon 6322 * 6323 * @return {PIXI.Polygon} a copy of the polygon 6324 */ 6325 Polygon.prototype.clone = function clone () 6326 { 6327 var polygon = new Polygon(this.points.slice()); 6328
6329 polygon.closeStroke = this.closeStroke; 6330 6331 return polygon; 6332 }; 6333 6334 /** 6335 * Checks whether the x and y coordinates passed to this function are contained within this polygon 6336 * 6337 * @param {number} x - The X coordinate of the point to test 6338 * @param {number} y - The Y coordinate of the point to test 6339 * @return {boolean} Whether the x/y coordinates are within this polygon 6340 */ 6341 Polygon.prototype.contains = function contains (x, y) 6342 { 6343 var inside = false; 6344 6345 // use some raycasting to test hits 6346 // https://github.com/substack/point-in-polygon/blob/master/index.js 6347 var length = this.points.length / 2; 6348 6349 for (var i = 0, j = length - 1; i < length; j = i++) 6350 { 6351 var xi = this.points[i * 2]; 6352 var yi = this.points[(i * 2) + 1]; 6353 var xj = this.points[j * 2]; 6354 var yj = this.points[(j * 2) + 1]; 6355 var intersect = ((yi > y) !== (yj > y)) && (x < ((xj - xi) * ((y - yi) / (yj - yi))) + xi); 6356 6357 if (intersect) 6358 { 6359 inside = !inside; 6360 } 6361 } 6362 6363 return inside; 6364 }; 6365 6366 /** 6367 * The Rounded Rectangle object is an area that has nice rounded corners, as indicated by its 6368 * top-left corner point (x, y) and by its width and its height and its radius. 6369 * 6370 * @class 6371 * @memberof PIXI 6372 */ 6373 var RoundedRectangle = function RoundedRectangle(x, y, width, height, radius) 6374 { 6375 if ( x === void 0 ) { x = 0; } 6376 if ( y === void 0 ) { y = 0; } 6377 if ( width === void 0 ) { width = 0; } 6378 if ( height === void 0 ) { height = 0; } 6379 if ( radius === void 0 ) { radius = 20; } 6380 6381 /** 6382 * @member {number} 6383 * @default 0 6384 */ 6385 this.x = x; 6386 6387 /** 6388 * @member {number} 6389 * @default 0 6390 */ 6391 this.y = y; 6392 6393 /** 6394 * @member {number} 6395 * @default 0 6396 */ 6397 this.width = width; 6398 6399 /** 6400 * @member {number} 6401 * @default 0 6402 */ 6403 this.height = height; 6404 6405 /** 6406 * @member {number} 6407 * @default 20 6408 */ 6409 this.radius = radius; 6410 6411 /** 6412 * The type of the object, mainly used to avoid `instanceof` checks 6413 * 6414 * @member {number} 6415 * @readonly 6416 * @default PIXI.SHAPES.RREC 6417 * @see PIXI.SHAPES 6418 */ 6419 this.type = SHAPES.RREC; 6420 }; 6421 6422 /** 6423 * Creates a clone of this Rounded Rectangle 6424 * 6425 * @return {PIXI.RoundedRectangle} a copy of the rounded rectangle 6426 */ 6427 RoundedRectangle.prototype.clone = function clone () 6428 { 6429 return new RoundedRectangle(this.x, this.y, this.width, this.height, this.radius); 6430 }; 6431 6432 /** 6433 * Checks whether the x and y coordinates given are contained within this Rounded Rectangle 6434 * 6435 * @param {number} x - The X coordinate of the point to test 6436 * @param {number} y - The Y coordinate of the point to test 6437 * @return {boolean} Whether the x/y coordinates are within this Rounded Rectangle 6438 */ 6439 RoundedRectangle.prototype.contains = function contains (x, y) 6440 { 6441 if (this.width <= 0 || this.height <= 0) 6442 { 6443 return false; 6444 } 6445 if (x >= this.x && x <= this.x + this.width) 6446 { 6447 if (y >= this.y && y <= this.y + this.height) 6448 { 6449 if ((y >= this.y + this.radius && y <= this.y + this.height - this.radius) 6450 || (x >= this.x + this.radius && x <= this.x + this.width - this.radius)) 6451 { 6452 return true; 6453 } 6454 var dx = x - (this.x + this.radius); 6455 var dy = y - (this.y + this.radius); 6456 var radius2 = this.radius * this.radius; 6457 6458 if ((dx * dx) + (dy * dy) <= radius2) 6459 { 6460 return true; 6461 } 6462 dx = x - (this.x + this.width - this.radius); 6463 if ((dx * dx) + (dy * dy) <= radius2) 6464 { 6465 return true; 6466 } 6467 dy = y - (this.y + this.height - this.radius); 6468 if ((dx * dx) + (dy * dy) <= radius2) 6469 { 6470 return true; 6471 } 6472 dx = x - (this.x + this.radius); 6473 if ((dx * dx) + (dy * dy) <= radius2) 6474 { 6475 return true; 6476 } 6477 } 6478 } 6479 6480 return false;
6481 }; 6482 6483 /*! 6484 * @pixi/display - v5.0.0-rc.3 6485 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 6486 * 6487 * @pixi/display is licensed under the MIT License. 6488 * http://www.opensource.org/licenses/mit-license 6489 */ 6490 6491 /** 6492 * Sets the default value for the container property 'sortableChildren'. 6493 * If set to true, the container will sort its children by zIndex value 6494 * when updateTransform() is called, or manually if sortChildren() is called. 6495 * 6496 * This actually changes the order of elements in the array, so should be treated 6497 * as a basic solution that is not performant compared to other solutions, 6498 * such as @link https://github.com/pixijs/pixi-display 6499 * 6500 * Also be aware of that this may not work nicely with the addChildAt() function, 6501 * as the zIndex sorting may cause the child to automatically sorted to another position. 6502 * 6503 * @static 6504 * @constant 6505 * @name SORTABLE_CHILDREN 6506 * @memberof PIXI.settings 6507 * @type {boolean} 6508 * @default false 6509 */ 6510 settings.SORTABLE_CHILDREN = false; 6511 6512 /** 6513 * 'Builder' pattern for bounds rectangles. 6514 * 6515 * This could be called an Axis-Aligned Bounding Box. 6516 * It is not an actual shape. It is a mutable thing; no 'EMPTY' or those kind of problems. 6517 * 6518 * @class 6519 * @memberof PIXI 6520 */ 6521 var Bounds = function Bounds() 6522 { 6523 /** 6524 * @member {number} 6525 * @default 0 6526 */ 6527 this.minX = Infinity; 6528 6529 /** 6530 * @member {number} 6531 * @default 0 6532 */ 6533 this.minY = Infinity; 6534 6535 /** 6536 * @member {number} 6537 * @default 0 6538 */ 6539 this.maxX = -Infinity; 6540 6541 /** 6542 * @member {number} 6543 * @default 0 6544 */ 6545 this.maxY = -Infinity; 6546 6547 this.rect = null; 6548 }; 6549 6550 /** 6551 * Checks if bounds are empty. 6552 * 6553 * @return {boolean} True if empty. 6554 */ 6555 Bounds.prototype.isEmpty = function isEmpty () 6556 { 6557 return this.minX > this.maxX || this.minY > this.maxY; 6558 }; 6559 6560 /** 6561 * Clears the bounds and resets. 6562 * 6563 */ 6564 Bounds.prototype.clear = function clear () 6565 { 6566 this.updateID++; 6567 6568 this.minX = Infinity; 6569 this.minY = Infinity; 6570 this.maxX = -Infinity; 6571 this.maxY = -Infinity; 6572 }; 6573 6574 /** 6575 * Can return Rectangle.EMPTY constant, either construct new rectangle, either use your rectangle 6576 * It is not guaranteed that it will return tempRect 6577 * 6578 * @param {PIXI.Rectangle} rect - temporary object will be used if AABB is not empty 6579 * @returns {PIXI.Rectangle} A rectangle of the bounds 6580 */ 6581 Bounds.prototype.getRectangle = function getRectangle (rect) 6582 { 6583 if (this.minX > this.maxX || this.minY > this.maxY) 6584 { 6585 return Rectangle.EMPTY; 6586 } 6587 6588 rect = rect || new Rectangle(0, 0, 1, 1); 6589 6590 rect.x = this.minX; 6591 rect.y = this.minY; 6592 rect.width = this.maxX - this.minX; 6593 rect.height = this.maxY - this.minY; 6594 6595 return rect; 6596 }; 6597 6598 /** 6599 * This function should be inlined when its possible. 6600 * 6601 * @param {PIXI.Point} point - The point to add. 6602 */ 6603 Bounds.prototype.addPoint = function addPoint (point) 6604 { 6605 this.minX = Math.min(this.minX, point.x); 6606 this.maxX = Math.max(this.maxX, point.x); 6607 this.minY = Math.min(this.minY, point.y); 6608 this.maxY = Math.max(this.maxY, point.y); 6609 }; 6610 6611 /** 6612 * Adds a quad, not transformed 6613 * 6614 * @param {Float32Array} vertices - The verts to add. 6615 */ 6616 Bounds.prototype.addQuad = function addQuad (vertices) 6617 { 6618 var minX = this.minX; 6619 var minY = this.minY; 6620 var maxX = this.maxX; 6621 var maxY = this.maxY; 6622 6623 var x = vertices[0]; 6624 var y = vertices[1]; 6625 6626 minX = x < minX ? x : minX; 6627 minY = y < minY ? y : minY; 6628 maxX = x > maxX ? x : maxX; 6629 maxY = y > maxY ? y : maxY; 6630 6631 x = vertices[2]; 6632 y = vertices[3]; 6633 minX = x < minX ? x : minX; 6634 minY = y < minY ? y : minY; 6635 maxX = x > maxX ? x : maxX; 6636 maxY = y > maxY ? y : maxY; 6637 6638 x = vertices[4]; 6639 y = vertices[5]; 6640 minX = x < minX ? x : minX; 6641 minY = y < minY ? y : minY; 6642 maxX = x > maxX ? x : maxX; 6643 maxY = y > maxY ? y : maxY; 6644 6645 x = vertices[6]; 6646 y = vertices[7]; 6647 minX = x < minX ? x : minX; 6648 minY = y < minY ? y : minY; 6649 maxX = x > maxX ? x : maxX; 6650 maxY = y > maxY ? y : maxY; 6651 6652 this.minX = minX; 6653 this.minY = minY; 6654 this.maxX = maxX; 6655 this.maxY = maxY; 6656 }; 6657 6658 /** 6659 * Adds sprite frame, transformed. 6660 * 6661 * @param {PIXI.Transform} transform - TODO 6662 * @param {number} x0 - TODO 6663 * @param {number} y0 - TODO 6664 * @param {number} x1 - TODO 6665 * @param {number} y1 - TODO 6666 */ 6667 Bounds.prototype.addFrame = function addFrame (transform, x0, y0, x1, y1) 6668 { 6669 var matrix = transform.worldTransform; 6670 var a = matrix.a; 6671 var b = matrix.b; 6672 var c = matrix.c; 6673 var d = matrix.d; 6674 var tx = matrix.tx; 6675 var ty = matrix.ty; 6676 6677 var minX = this.minX; 6678 var minY = this.minY; 6679 var maxX = this.maxX; 6680 var maxY = this.maxY; 6681 6682 var x = (a * x0) + (c * y0) + tx; 6683 var y = (b * x0) + (d * y0) + ty; 6684 6685 minX = x < minX ? x : minX; 6686 minY = y < minY ? y : minY; 6687 maxX = x > maxX ? x : maxX; 6688 maxY = y > maxY ? y : maxY; 6689 6690 x = (a * x1) + (c * y0) + tx; 6691 y = (b * x1) + (d * y0) + ty; 6692 minX = x < minX ? x : minX; 6693 minY = y < minY ? y : minY; 6694 maxX = x > maxX ? x : maxX; 6695 maxY = y > maxY ? y : maxY; 6696 6697 x = (a * x0) + (c * y1) + tx; 6698 y = (b * x0) + (d * y1) + ty; 6699 minX = x < minX ? x : minX; 6700 minY = y < minY ? y : minY; 6701 maxX = x > maxX ? x : maxX; 6702 maxY = y > maxY ? y : maxY; 6703 6704 x = (a * x1) + (c * y1) + tx; 6705 y = (b * x1) + (d * y1) + ty; 6706 minX = x < minX ? x : minX; 6707 minY = y < minY ? y : minY; 6708 maxX = x > maxX ? x : maxX; 6709 maxY = y > maxY ? y : maxY; 6710 6711 this.minX = minX; 6712 this.minY = minY; 6713 this.maxX = maxX; 6714 this.maxY = maxY; 6715 }; 6716 6717 /** 6718 * Adds screen vertices from array 6719 * 6720 * @param {Float32Array} vertexData - calculated vertices 6721 * @param {number} beginOffset - begin offset 6722 * @param {number} endOffset - end offset, excluded 6723 */ 6724 Bounds.prototype.addVertexData = function addVertexData (vertexData, beginOffset, endOffset) 6725 { 6726 var minX = this.minX; 6727 var minY = this.minY; 6728 var maxX = this.maxX; 6729 var maxY = this.maxY; 6730 6731 for (var i = beginOffset; i < endOffset; i += 2) 6732 { 6733 var x = vertexData[i]; 6734 var y = vertexData[i + 1]; 6735 6736 minX = x < minX ? x : minX; 6737 minY = y < minY ? y : minY; 6738 maxX = x > maxX ? x : maxX; 6739 maxY = y > maxY ? y : maxY; 6740 } 6741 6742 this.minX = minX; 6743 this.minY = minY; 6744 this.maxX = maxX; 6745 this.maxY = maxY; 6746 }; 6747 6748 /** 6749 * Add an array of mesh vertices 6750 * 6751 * @param {PIXI.Transform} transform - mesh transform 6752 * @param {Float32Array} vertices - mesh coordinates in array 6753 * @param {number} beginOffset - begin offset 6754 * @param {number} endOffset - end offset, excluded 6755 */ 6756 Bounds.prototype.addVertices = function addVertices (transform, vertices, beginOffset, endOffset) 6757 { 6758 var matrix = transform.worldTransform; 6759 var a = matrix.a; 6760 var b = matrix.b; 6761 var c = matrix.c; 6762 var d = matrix.d; 6763 var tx = matrix.tx; 6764 var ty = matrix.ty; 6765 6766 var minX = this.minX; 6767 var minY = this.minY; 6768 var maxX = this.maxX; 6769 var maxY = this.maxY; 6770 6771 for (var i = beginOffset; i < endOffset; i += 2) 6772 { 6773 var rawX = vertices[i]; 6774 var rawY = vertices[i + 1]; 6775 var x = (a * rawX) + (c * rawY) + tx; 6776 var y = (d * rawY) + (b * rawX) + ty; 6777 6778 minX = x < minX ? x : minX; 6779 minY = y < minY ? y : minY; 6780 maxX = x > maxX ? x : maxX; 6781 maxY = y > maxY ? y : maxY; 6782 } 6783 6784 this.minX = minX; 6785 this.minY = minY; 6786 this.maxX = maxX; 6787 this.maxY = maxY; 6788 }; 6789 6790 /** 6791 * Adds other Bounds 6792 * 6793 * @param {PIXI.Bounds} bounds - TODO 6794 */ 6795 Bounds.prototype.addBounds = function addBounds (bounds) 6796 { 6797 var minX = this.minX; 6798 var minY = this.minY; 6799 var maxX = this.maxX; 6800 var maxY = this.maxY; 6801 6802 this.minX = bounds.minX < minX ? bounds.minX : minX; 6803 this.minY = bounds.minY < minY ? bounds.minY : minY; 6804 this.maxX = bounds.maxX > maxX ? bounds.maxX : maxX; 6805 this.maxY = bounds.maxY > maxY ? bounds.maxY : maxY; 6806 }; 6807 6808 /** 6809 * Adds other Bounds, masked with Bounds 6810 * 6811 * @param {PIXI.Bounds} bounds - TODO 6812 * @param {PIXI.Bounds} mask - TODO 6813 */ 6814 Bounds.prototype.addBoundsMask = function addBoundsMask (bounds, mask) 6815 { 6816 var _minX = bounds.minX > mask.minX ? bounds.minX : mask.minX; 6817 var _minY = bounds.minY > mask.minY ? bounds.minY : mask.minY; 6818 var _maxX = bounds.maxX < mask.maxX ? bounds.maxX : mask.maxX; 6819 var _maxY = bounds.maxY < mask.maxY ? bounds.maxY : mask.maxY; 6820 6821 if (_minX <= _maxX && _minY <= _maxY) 6822 { 6823 var minX = this.minX; 6824 var minY = this.minY; 6825 var maxX = this.maxX; 6826 var maxY = this.maxY; 6827 6828 this.minX = _minX < minX ? _minX : minX; 6829 this.minY = _minY < minY ? _minY : minY; 6830 this.maxX = _maxX > maxX ? _maxX : maxX; 6831 this.maxY = _maxY > maxY ? _maxY : maxY; 6832 } 6833 }; 6834 6835 /** 6836 * Adds other Bounds, masked with Rectangle 6837 * 6838 * @param {PIXI.Bounds} bounds - TODO 6839 * @param {PIXI.Rectangle} area - TODO 6840 */ 6841 Bounds.prototype.addBoundsArea = function addBoundsArea (bounds, area) 6842 { 6843 var _minX = bounds.minX > area.x ? bounds.minX : area.x; 6844 var _minY = bounds.minY > area.y ? bounds.minY : area.y; 6845 var _maxX = bounds.maxX < area.x + area.width ? bounds.maxX : (area.x + area.width); 6846 var _maxY = bounds.maxY < area.y + area.height ? bounds.maxY : (area.y + area.height); 6847 6848 if (_minX <= _maxX && _minY <= _maxY) 6849 { 6850 var minX = this.minX; 6851 var minY = this.minY; 6852 var maxX = this.maxX; 6853 var maxY = this.maxY; 6854 6855 this.minX = _minX < minX ? _minX : minX; 6856 this.minY = _minY < minY ? _minY : minY; 6857 this.maxX = _maxX > maxX ? _maxX : maxX; 6858 this.maxY = _maxY > maxY ? _maxY : maxY; 6859 } 6860 }; 6861 6862 // _tempDisplayObjectParent = new DisplayObject(); 6863 6864 /** 6865 * The base class for all objects that are rendered on the screen. 6866 * 6867 * This is an abstract class and should not be used on its own; rather it should be extended. 6868 * 6869 * @class 6870 * @extends PIXI.utils.EventEmitter 6871 * @memberof PIXI 6872 */ 6873 var DisplayObject = /*@__PURE__*/(function (EventEmitter) {
6874 function DisplayObject() 6875 { 6876 EventEmitter.call(this); 6877 6878 this.tempDisplayObjectParent = null; 6879 6880 // TODO: need to create Transform from factory 6881 /** 6882 * World transform and local transform of this object. 6883 * This will become read-only later, please do not assign anything there unless you know what are you doing. 6884 * 6885 * @member {PIXI.Transform} 6886 */ 6887 this.transform = new Transform(); 6888 6889 /** 6890 * The opacity of the object. 6891 * 6892 * @member {number} 6893 */ 6894 this.alpha = 1; 6895 6896 /** 6897 * The visibility of the object. If false the object will not be drawn, and 6898 * the updateTransform function will not be called. 6899 * 6900 * Only affects recursive calls from parent. You can ask for bounds or call updateTransform manually. 6901 * 6902 * @member {boolean} 6903 */ 6904 this.visible = true; 6905 6906 /** 6907 * Can this object be rendered, if false the object will not be drawn but the updateTransform 6908 * methods will still be called. 6909 * 6910 * Only affects recursive calls from parent. You can ask for bounds manually. 6911 * 6912 * @member {boolean} 6913 */ 6914 this.renderable = true; 6915 6916 /** 6917 * The display object container that contains this display object. 6918 * 6919 * @member {PIXI.Container} 6920 * @readonly 6921 */ 6922 this.parent = null; 6923 6924 /** 6925 * The multiplied alpha of the displayObject. 6926 * 6927 * @member {number} 6928 * @readonly 6929 */ 6930 this.worldAlpha = 1; 6931 6932 /** 6933 * Which index in the children array the display component was before the previous zIndex sort. 6934 * Used by containers to help sort objects with the same zIndex, by using previous array index as the decider. 6935 * 6936 * @member {number} 6937 * @protected 6938 */ 6939 this._lastSortedIndex = 0; 6940 6941 /** 6942 * The zIndex of the displayObject. 6943 * A higher value will mean it will be rendered on top of other displayObjects within the same container. 6944 * 6945 * @member {number} 6946 * @protected 6947 */ 6948 this._zIndex = 0; 6949 6950 /** 6951 * The area the filter is applied to. This is used as more of an optimization 6952 * rather than figuring out the dimensions of the displayObject each frame you can set this rectangle. 6953 * 6954 * Also works as an interaction mask. 6955 * 6956 * @member {?PIXI.Rectangle} 6957 */ 6958 this.filterArea = null; 6959 6960 /** 6961 * Sets the filters for the displayObject. 6962 * * IMPORTANT: This is a WebGL only feature and will be ignored by the canvas renderer. 6963 * To remove filters simply set this property to `'null'`. 6964 * 6965 * @member {?PIXI.Filter[]} 6966 */ 6967 this.filters = null; 6968 this._enabledFilters = null; 6969 6970 /** 6971 * The bounds object, this is used to calculate and store the bounds of the displayObject. 6972 * 6973 * @member {PIXI.Bounds} 6974 * @protected 6975 */ 6976 this._bounds = new Bounds(); 6977 this._boundsID = 0; 6978 this._lastBoundsID = -1; 6979 this._boundsRect = null; 6980 this._localBoundsRect = null; 6981 6982 /** 6983 * The original, cached mask of the object. 6984 * 6985 * @member {PIXI.Graphics|PIXI.Sprite} 6986 * @protected 6987 */ 6988 this._mask = null; 6989 6990 /** 6991 * Fired when this DisplayObject is added to a Container. 6992 * 6993 * @event PIXI.DisplayObject#added 6994 * @param {PIXI.Container} container - The container added to. 6995 */ 6996 6997 /** 6998 * Fired when this DisplayObject is removed from a Container. 6999 * 7000 * @event PIXI.DisplayObject#removed 7001 * @param {PIXI.Container} container - The container removed from. 7002 */ 7003 7004 /** 7005 * If the object has been destroyed via destroy(). If true, it should not be used. 7006 * 7007 * @member {boolean} 7008 * @protected 7009 */ 7010 this._destroyed = false;
7011 7012 /** 7013 * used to fast check if a sprite is.. a sprite! 7014 * @member {boolean} 7015 */ 7016 this.isSprite = false; 7017 } 7018 7019 if ( EventEmitter ) { DisplayObject.__proto__ = EventEmitter; } 7020 DisplayObject.prototype = Object.create( EventEmitter && EventEmitter.prototype ); 7021 DisplayObject.prototype.constructor = DisplayObject; 7022 7023 var prototypeAccessors = { _tempDisplayObjectParent: { configurable: true },x: { configurable: true },y: { configurable: true },worldTransform: { configurable: true },localTransform: { configurable: true },position: { configurable: true },scale: { configurable: true },pivot: { configurable: true },skew: { configurable: true },rotation: { configurable: true },angle: { configurable: true },zIndex: { configurable: true },worldVisible: { configurable: true },mask: { configurable: true } }; 7024 7025 /** 7026 * @protected 7027 * @member {PIXI.DisplayObject} 7028 */ 7029 DisplayObject.mixin = function mixin (source) 7030 { 7031 // in ES8/ES2017, this would be really easy: 7032 // Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); 7033 7034 // get all the enumerable property keys 7035 var keys = Object.keys(source); 7036 7037 // loop through properties 7038 for (var i = 0; i < keys.length; ++i) 7039 { 7040 var propertyName = keys[i]; 7041 7042 // Set the property using the property descriptor - this works for accessors and normal value properties 7043 Object.defineProperty( 7044 DisplayObject.prototype, 7045 propertyName, 7046 Object.getOwnPropertyDescriptor(source, propertyName) 7047 ); 7048 } 7049 }; 7050 7051 prototypeAccessors._tempDisplayObjectParent.get = function () 7052 { 7053 if (this.tempDisplayObjectParent === null) 7054 { 7055 this.tempDisplayObjectParent = new DisplayObject(); 7056 } 7057 7058 return this.tempDisplayObjectParent; 7059 }; 7060 7061 /** 7062 * Updates the object transform for rendering. 7063 * 7064 * TODO - Optimization pass! 7065 */ 7066 DisplayObject.prototype.updateTransform = function updateTransform () 7067 { 7068 this.transform.updateTransform(this.parent.transform); 7069 // multiply the alphas.. 7070 this.worldAlpha = this.alpha * this.parent.worldAlpha; 7071 7072 this._bounds.updateID++; 7073 }; 7074 7075 /** 7076 * Recursively updates transform of all objects from the root to this one 7077 * internal function for toLocal() 7078 */ 7079 DisplayObject.prototype._recursivePostUpdateTransform = function _recursivePostUpdateTransform () 7080 { 7081 if (this.parent) 7082 { 7083 this.parent._recursivePostUpdateTransform(); 7084 this.transform.updateTransform(this.parent.transform); 7085 } 7086 else 7087 { 7088 this.transform.updateTransform(this._tempDisplayObjectParent.transform); 7089 } 7090 }; 7091 7092 /** 7093 * Retrieves the bounds of the displayObject as a rectangle object. 7094 * 7095 * @param {boolean} [skipUpdate] - Setting to `true` will stop the transforms of the scene graph from 7096 * being updated. This means the calculation returned MAY be out of date BUT will give you a 7097 * nice performance boost. 7098 * @param {PIXI.Rectangle} [rect] - Optional rectangle to store the result of the bounds calculation. 7099 * @return {PIXI.Rectangle} The rectangular bounding area. 7100 */ 7101 DisplayObject.prototype.getBounds = function getBounds (skipUpdate, rect) 7102 { 7103 if (!skipUpdate) 7104 { 7105 if (!this.parent) 7106 { 7107 this.parent = this._tempDisplayObjectParent; 7108 this.updateTransform(); 7109 this.parent = null; 7110 } 7111 else 7112 { 7113 this._recursivePostUpdateTransform(); 7114 this.updateTransform(); 7115 } 7116 } 7117 7118 if (this._boundsID !== this._lastBoundsID) 7119 { 7120 this.calculateBounds(); 7121 } 7122 7123 if (!rect) 7124 { 7125 if (!this._boundsRect) 7126 { 7127 this._boundsRect = new Rectangle(); 7128 } 7129 7130 rect = this._boundsRect; 7131 } 7132 7133 return this._bounds.getRectangle(rect); 7134 }; 7135 7136 /** 7137 * Retrieves the local bounds of the displayObject as a rectangle object. 7138 * 7139 * @param {PIXI.Rectangle} [rect] - Optional rectangle to store the result of the bounds calculation. 7140 * @return {PIXI.Rectangle} The rectangular bounding area. 7141 */ 7142 DisplayObject.prototype.getLocalBounds = function getLocalBounds (rect) 7143 { 7144 var transformRef = this.transform; 7145 var parentRef = this.parent; 7146 7147 this.parent = null; 7148 this.transform = this._tempDisplayObjectParent.transform; 7149 7150 if (!rect) 7151 { 7152 if (!this._localBoundsRect) 7153 { 7154 this._localBoundsRect = new Rectangle(); 7155 } 7156 7157 rect = this._localBoundsRect; 7158 } 7159 7160 var bounds = this.getBounds(false, rect); 7161 7162 this.parent = parentRef; 7163 this.transform = transformRef; 7164 7165 return bounds; 7166 }; 7167 7168 /** 7169 * Calculates the global position of the display object. 7170 * 7171 * @param {PIXI.IPoint} position - The world origin to calculate from. 7172 * @param {PIXI.IPoint} [point] - A Point object in which to store the value, optional 7173 * (otherwise will create a new Point). 7174 * @param {boolean} [skipUpdate=false] - Should we skip the update transform. 7175 * @return {PIXI.IPoint} A point object representing the position of this object. 7176 */ 7177 DisplayObject.prototype.toGlobal = function toGlobal (position, point, skipUpdate) 7178 { 7179 if ( skipUpdate === void 0 ) { skipUpdate = false; } 7180 7181 if (!skipUpdate) 7182 { 7183 this._recursivePostUpdateTransform(); 7184 7185 // this parent check is for just in case the item is a root object.
7186 // If it is we need to give it a temporary parent so that displayObjectUpdateTransform works correctly 7187 // this is mainly to avoid a parent check in the main loop. Every little helps for performance :) 7188 if (!this.parent) 7189 { 7190 this.parent = this._tempDisplayObjectParent; 7191 this.displayObjectUpdateTransform(); 7192 this.parent = null; 7193 } 7194 else 7195 { 7196 this.displayObjectUpdateTransform(); 7197 } 7198 } 7199 7200 // don't need to update the lot 7201 return this.worldTransform.apply(position, point); 7202 }; 7203 7204 /** 7205 * Calculates the local position of the display object relative to another point. 7206 * 7207 * @param {PIXI.IPoint} position - The world origin to calculate from. 7208 * @param {PIXI.DisplayObject} [from] - The DisplayObject to calculate the global position from. 7209 * @param {PIXI.IPoint} [point] - A Point object in which to store the value, optional 7210 * (otherwise will create a new Point). 7211 * @param {boolean} [skipUpdate=false] - Should we skip the update transform 7212 * @return {PIXI.IPoint} A point object representing the position of this object 7213 */ 7214 DisplayObject.prototype.toLocal = function toLocal (position, from, point, skipUpdate) 7215 { 7216 if (from) 7217 { 7218 position = from.toGlobal(position, point, skipUpdate); 7219 } 7220 7221 if (!skipUpdate) 7222 { 7223 this._recursivePostUpdateTransform(); 7224 7225 // this parent check is for just in case the item is a root object. 7226 // If it is we need to give it a temporary parent so that displayObjectUpdateTransform works correctly 7227 // this is mainly to avoid a parent check in the main loop. Every little helps for performance :) 7228 if (!this.parent) 7229 { 7230 this.parent = this._tempDisplayObjectParent; 7231 this.displayObjectUpdateTransform(); 7232 this.parent = null; 7233 } 7234 else 7235 { 7236 this.displayObjectUpdateTransform(); 7237 } 7238 } 7239 7240 // simply apply the matrix.. 7241 return this.worldTransform.applyInverse(position, point); 7242 }; 7243 7244 /**
7245 * Renders the object using the WebGL renderer. 7246 * 7247 * @param {PIXI.Renderer} renderer - The renderer. 7248 */ 7249 DisplayObject.prototype.render = function render (renderer) // eslint-disable-line no-unused-vars 7250 { 7251 // OVERWRITE; 7252 }; 7253 7254 /** 7255 * Set the parent Container of this DisplayObject. 7256 * 7257 * @param {PIXI.Container} container - The Container to add this DisplayObject to. 7258 * @return {PIXI.Container} The Container that this DisplayObject was added to. 7259 */ 7260 DisplayObject.prototype.setParent = function setParent (container) 7261 { 7262 if (!container || !container.addChild) 7263 { 7264 throw new Error('setParent: Argument must be a Container'); 7265 } 7266 7267 container.addChild(this); 7268 7269 return container; 7270 }; 7271 7272 /** 7273 * Convenience function to set the position, scale, skew and pivot at once. 7274 * 7275 * @param {number} [x=0] - The X position 7276 * @param {number} [y=0] - The Y position 7277 * @param {number} [scaleX=1] - The X scale value 7278 * @param {number} [scaleY=1] - The Y scale value 7279 * @param {number} [rotation=0] - The rotation 7280 * @param {number} [skewX=0] - The X skew value 7281 * @param {number} [skewY=0] - The Y skew value 7282 * @param {number} [pivotX=0] - The X pivot value 7283 * @param {number} [pivotY=0] - The Y pivot value 7284 * @return {PIXI.DisplayObject} The DisplayObject instance 7285 */ 7286 DisplayObject.prototype.setTransform = function setTransform (x, y, scaleX, scaleY, rotation, skewX, skewY, pivotX, pivotY) 7287 { 7288 if ( x === void 0 ) { x = 0; } 7289 if ( y === void 0 ) { y = 0; } 7290 if ( scaleX === void 0 ) { scaleX = 1; } 7291 if ( scaleY === void 0 ) { scaleY = 1; } 7292 if ( rotation === void 0 ) { rotation = 0; }
7293 if ( skewX === void 0 ) { skewX = 0; } 7294 if ( skewY === void 0 ) { skewY = 0; } 7295 if ( pivotX === void 0 ) { pivotX = 0; } 7296 if ( pivotY === void 0 ) { pivotY = 0; } 7297 7298 this.position.x = x; 7299 this.position.y = y; 7300 this.scale.x = !scaleX ? 1 : scaleX; 7301 this.scale.y = !scaleY ? 1 : scaleY; 7302 this.rotation = rotation; 7303 this.skew.x = skewX; 7304 this.skew.y = skewY; 7305 this.pivot.x = pivotX; 7306 this.pivot.y = pivotY; 7307 7308 return this; 7309 }; 7310 7311 /** 7312 * Base destroy method for generic display objects. This will automatically 7313 * remove the display object from its parent Container as well as remove 7314 * all current event listeners and internal references. Do not use a DisplayObject 7315 * after calling `destroy()`. 7316 * 7317 */ 7318 DisplayObject.prototype.destroy = function destroy () 7319 { 7320 this.removeAllListeners(); 7321 if (this.parent) 7322 { 7323 this.parent.removeChild(this); 7324 } 7325 this.transform = null; 7326 7327 this.parent = null; 7328 7329 this._bounds = null; 7330 this._currentBounds = null; 7331 this._mask = null; 7332 7333 this.filterArea = null; 7334 7335 this.interactive = false; 7336 this.interactiveChildren = false; 7337 7338 this._destroyed = true; 7339 }; 7340 7341 /** 7342 * The position of the displayObject on the x axis relative to the local coordinates of the parent. 7343 * An alias to position.x 7344 * 7345 * @member {number} 7346 */ 7347 prototypeAccessors.x.get = function () 7348 { 7349 return this.position.x; 7350 }; 7351 7352 prototypeAccessors.x.set = function (value) // eslint-disable-line require-jsdoc 7353 { 7354 this.transform.position.x = value; 7355 }; 7356 7357 /** 7358 * The position of the displayObject on the y axis relative to the local coordinates of the parent. 7359 * An alias to position.y 7360 * 7361 * @member {number} 7362 */ 7363 prototypeAccessors.y.get = function () 7364 { 7365 return this.position.y; 7366 }; 7367 7368 prototypeAccessors.y.set = function (value) // eslint-disable-line require-jsdoc 7369 { 7370 this.transform.position.y = value; 7371 }; 7372 7373 /** 7374 * Current transform of the object based on world (parent) factors. 7375 * 7376 * @member {PIXI.Matrix} 7377 * @readonly 7378 */ 7379 prototypeAccessors.worldTransform.get = function () 7380 { 7381 return this.transform.worldTransform; 7382 }; 7383 7384 /** 7385 * Current transform of the object based on local factors: position, scale, other stuff. 7386 * 7387 * @member {PIXI.Matrix} 7388 * @readonly 7389 */ 7390 prototypeAccessors.localTransform.get = function () 7391 { 7392 return this.transform.localTransform; 7393 }; 7394 7395 /** 7396 * The coordinate of the object relative to the local coordinates of the parent. 7397 * Assignment by value since pixi-v4. 7398 * 7399 * @member {PIXI.IPoint} 7400 */ 7401 prototypeAccessors.position.get = function () 7402 { 7403 return this.transform.position; 7404 }; 7405 7406 prototypeAccessors.position.set = function (value) // eslint-disable-line require-jsdoc 7407 { 7408 this.transform.position.copyFrom(value); 7409 }; 7410 7411 /** 7412 * The scale factor of the object. 7413 * Assignment by value since pixi-v4. 7414 * 7415 * @member {PIXI.IPoint} 7416 */ 7417 prototypeAccessors.scale.get = function () 7418 { 7419 return this.transform.scale; 7420 }; 7421 7422 prototypeAccessors.scale.set = function (value) // eslint-disable-line require-jsdoc 7423 { 7424 this.transform.scale.copyFrom(value); 7425 }; 7426 7427 /** 7428 * The pivot point of the displayObject that it rotates around. 7429 * Assignment by value since pixi-v4. 7430 * 7431 * @member {PIXI.IPoint} 7432 */ 7433 prototypeAccessors.pivot.get = function () 7434 { 7435 return this.transform.pivot; 7436 }; 7437 7438 prototypeAccessors.pivot.set = function (value) // eslint-disable-line require-jsdoc 7439 { 7440 this.transform.pivot.copyFrom(value); 7441 }; 7442 7443 /** 7444 * The skew factor for the object in radians. 7445 * Assignment by value since pixi-v4. 7446 *
7447 * @member {PIXI.ObservablePoint} 7448 */ 7449 prototypeAccessors.skew.get = function () 7450 { 7451 return this.transform.skew; 7452 }; 7453 7454 prototypeAccessors.skew.set = function (value) // eslint-disable-line require-jsdoc 7455 { 7456 this.transform.skew.copyFrom(value); 7457 }; 7458 7459 /** 7460 * The rotation of the object in radians. 7461 * 'rotation' and 'angle' have the same effect on a display object; rotation is in radians, angle is in degrees. 7462 * 7463 * @member {number} 7464 */ 7465 prototypeAccessors.rotation.get = function () 7466 { 7467 return this.transform.rotation; 7468 }; 7469 7470 prototypeAccessors.rotation.set = function (value) // eslint-disable-line require-jsdoc 7471 { 7472 this.transform.rotation = value; 7473 }; 7474 7475 /** 7476 * The angle of the object in degrees. 7477 * 'rotation' and 'angle' have the same effect on a display object; rotation is in radians, angle is in degrees. 7478 * 7479 * @member {number} 7480 */ 7481 prototypeAccessors.angle.get = function () 7482 { 7483 return this.transform.rotation * RAD_TO_DEG; 7484 }; 7485 7486 prototypeAccessors.angle.set = function (value) // eslint-disable-line require-jsdoc 7487 { 7488 this.transform.rotation = value * DEG_TO_RAD; 7489 }; 7490 7491 /** 7492 * The zIndex of the displayObject. 7493 * If a container has the sortableChildren property set to true, children will be automatically 7494 * sorted by zIndex value; a higher value will mean it will be moved towards the end of the array, 7495 * and thus rendered on top of other displayObjects within the same container. 7496 * 7497 * @member {number} 7498 */ 7499 prototypeAccessors.zIndex.get = function () 7500 { 7501 return this._zIndex; 7502 }; 7503 7504 prototypeAccessors.zIndex.set = function (value) // eslint-disable-line require-jsdoc 7505 { 7506 this._zIndex = value; 7507 if (this.parent) 7508 { 7509 this.parent.sortDirty = true; 7510 } 7511 }; 7512 7513 /** 7514 * Indicates if the object is globally visible. 7515 * 7516 * @member {boolean} 7517 * @readonly 7518 */ 7519 prototypeAccessors.worldVisible.get = function () 7520 { 7521 var item = this; 7522 7523 do 7524 { 7525 if (!item.visible) 7526 { 7527 return false; 7528 } 7529 7530 item = item.parent; 7531 } while (item); 7532 7533 return true; 7534 }; 7535 7536 /** 7537 * Sets a mask for the displayObject. A mask is an object that limits the visibility of an 7538 * object to the shape of the mask applied to it. In PixiJS a regular mask must be a 7539 * {@link PIXI.Graphics} or a {@link PIXI.Sprite} object. This allows for much faster masking in canvas as it 7540 * utilities shape clipping. To remove a mask, set this property to `null`. 7541 * 7542 * For sprite mask both alpha and red channel are used. Black mask is the same as transparent mask. 7543 * @example 7544 * const graphics = new PIXI.Graphics(); 7545 * graphics.beginFill(0xFF3300); 7546 * graphics.drawRect(50, 250, 100, 100); 7547 * graphics.endFill(); 7548 * 7549 * const sprite = new PIXI.Sprite(texture); 7550 * sprite.mask = graphics; 7551 * @todo At the moment, PIXI.CanvasRenderer doesn't support PIXI.Sprite as mask. 7552 * 7553 * @member {PIXI.Graphics|PIXI.Sprite} 7554 */ 7555 prototypeAccessors.mask.get = function () 7556 { 7557 return this._mask; 7558 }; 7559 7560 prototypeAccessors.mask.set = function (value) // eslint-disable-line require-jsdoc 7561 { 7562 if (this._mask) 7563 { 7564 this._mask.renderable = true; 7565 this._mask.isMask = false; 7566 } 7567 7568 this._mask = value; 7569 7570 if (this._mask) 7571 { 7572 this._mask.renderable = false; 7573 this._mask.isMask = true; 7574 } 7575 }; 7576 7577 Object.defineProperties( DisplayObject.prototype, prototypeAccessors ); 7578 7579 return DisplayObject; 7580 }(eventemitter3)); 7581 7582 // performance increase to avoid using call.. (10x faster) 7583 DisplayObject.prototype.displayObjectUpdateTransform = DisplayObject.prototype.updateTransform; 7584 7585 function sortChildren(a, b) 7586 { 7587 if (a.zIndex === b.zIndex) 7588 { 7589 return a._lastSortedIndex - b._lastSortedIndex; 7590 } 7591 7592 return a.zIndex - b.zIndex; 7593 } 7594 7595 /** 7596 * A Container represents a collection of display objects. 7597 * 7598 * It is the base class of all display objects that act as a container for other objects (like Sprites). 7599 * 7600 *```js 7601 * let container = new PIXI.Container(); 7602 * container.addChild(sprite); 7603 * ``` 7604 * 7605 * @class 7606 * @extends PIXI.DisplayObject 7607 * @memberof PIXI 7608 */ 7609 var Container = /*@__PURE__*/(function (DisplayObject) { 7610 function Container() 7611 { 7612 DisplayObject.call(this); 7613 7614 /** 7615 * The array of children of this container. 7616 * 7617 * @member {PIXI.DisplayObject[]} 7618 * @readonly 7619 */ 7620 this.children = []; 7621 7622 /** 7623 * If set to true, the container will sort its children by zIndex value 7624 * when updateTransform() is called, or manually if sortChildren() is called. 7625 * 7626 * This actually changes the order of elements in the array, so should be treated 7627 * as a basic solution that is not performant compared to other solutions, 7628 * such as @link https://github.com/pixijs/pixi-display 7629 * 7630 * Also be aware of that this may not work nicely with the addChildAt() function, 7631 * as the zIndex sorting may cause the child to automatically sorted to another position. 7632 * 7633 * @see PIXI.settings.SORTABLE_CHILDREN 7634 * 7635 * @member {boolean} 7636 */ 7637 this.sortableChildren = settings.SORTABLE_CHILDREN; 7638 7639 /** 7640 * Should children be sorted by zIndex at the next updateTransform call. 7641 * Will get automatically set to true if a new child is added, or if a child's zIndex changes. 7642 * 7643 * @member {boolean} 7644 */ 7645 this.sortDirty = false;
7646 7647 /** 7648 * Fired when a DisplayObject is added to this Container. 7649 * 7650 * @event PIXI.Container#childAdded 7651 * @param {PIXI.DisplayObject} child - The child added to the Container. 7652 * @param {PIXI.Container} container - The container that added the child. 7653 * @param {number} index - The children's index of the added child. 7654 */ 7655 7656 /** 7657 * Fired when a DisplayObject is removed from this Container. 7658 * 7659 * @event PIXI.DisplayObject#removedFrom 7660 * @param {PIXI.DisplayObject} child - The child removed from the Container. 7661 * @param {PIXI.Container} container - The container that removed removed the child. 7662 * @param {number} index - The former children's index of the removed child 7663 */ 7664 } 7665 7666 if ( DisplayObject ) { Container.__proto__ = DisplayObject; } 7667 Container.prototype = Object.create( DisplayObject && DisplayObject.prototype ); 7668 Container.prototype.constructor = Container; 7669 7670 var prototypeAccessors = { width: { configurable: true },height: { configurable: true } }; 7671 7672 /** 7673 * Overridable method that can be used by Container subclasses whenever the children array is modified 7674 * 7675 * @protected 7676 */ 7677 Container.prototype.onChildrenChange = function onChildrenChange () 7678 { 7679 /* empty */ 7680 }; 7681 7682 /** 7683 * Adds one or more children to the container. 7684 * 7685 * Multiple items can be added like so: `myContainer.addChild(thingOne, thingTwo, thingThree)` 7686 * 7687 * @param {...PIXI.DisplayObject} child - The DisplayObject(s) to add to the container 7688 * @return {PIXI.DisplayObject} The first child that was added. 7689 */ 7690 Container.prototype.addChild = function addChild (child) 7691 { 7692 var arguments$1 = arguments; 7693 7694 var argumentsLength = arguments.length; 7695 7696 // if there is only one argument we can bypass looping through the them 7697 if (argumentsLength > 1) 7698 { 7699 // loop through the arguments property and add all children 7700 // use it the right way (.length and [i]) so that this function can still be optimized by JS runtimes 7701 for (var i = 0; i < argumentsLength; i++) 7702 { 7703 this.addChild(arguments$1[i]); 7704 } 7705 } 7706 else 7707 { 7708 // if the child has a parent then lets remove it as PixiJS objects can only exist in one place 7709 if (child.parent) 7710 { 7711 child.parent.removeChild(child); 7712 } 7713 7714 child.parent = this; 7715 this.sortDirty = true; 7716 7717 // ensure child transform will be recalculated 7718 child.transform._parentID = -1; 7719 7720 this.children.push(child); 7721 7722 // ensure bounds will be recalculated 7723 this._boundsID++; 7724 7725 // TODO - lets either do all callbacks or all events.. not both! 7726 this.onChildrenChange(this.children.length - 1); 7727 this.emit('childAdded', child, this, this.children.length - 1); 7728 child.emit('added', this); 7729 } 7730 7731 return child; 7732 }; 7733 7734 /** 7735 * Adds a child to the container at a specified index. If the index is out of bounds an error will be thrown 7736 * 7737 * @param {PIXI.DisplayObject} child - The child to add 7738 * @param {number} index - The index to place the child in 7739 * @return {PIXI.DisplayObject} The child that was added. 7740 */ 7741 Container.prototype.addChildAt = function addChildAt (child, index) 7742 { 7743 if (index < 0 || index > this.children.length) 7744 { 7745 throw new Error((child + "addChildAt: The index " + index + " supplied is out of bounds " + (this.children.length))); 7746 } 7747 7748 if (child.parent) 7749 { 7750 child.parent.removeChild(child); 7751 } 7752 7753 child.parent = this; 7754 this.sortDirty = true; 7755 7756 // ensure child transform will be recalculated 7757 child.transform._parentID = -1; 7758 7759 this.children.splice(index, 0, child); 7760 7761 // ensure bounds will be recalculated 7762 this._boundsID++; 7763 7764 // TODO - lets either do all callbacks or all events.. not both! 7765 this.onChildrenChange(index);
7766 child.emit('added', this); 7767 this.emit('childAdded', child, this, index); 7768 7769 return child; 7770 }; 7771 7772 /** 7773 * Swaps the position of 2 Display Objects within this container. 7774 * 7775 * @param {PIXI.DisplayObject} child - First display object to swap 7776 * @param {PIXI.DisplayObject} child2 - Second display object to swap 7777 */ 7778 Container.prototype.swapChildren = function swapChildren (child, child2) 7779 { 7780 if (child === child2) 7781 { 7782 return; 7783 } 7784 7785 var index1 = this.getChildIndex(child); 7786 var index2 = this.getChildIndex(child2); 7787 7788 this.children[index1] = child2; 7789 this.children[index2] = child; 7790 this.onChildrenChange(index1 < index2 ? index1 : index2); 7791 }; 7792 7793 /** 7794 * Returns the index position of a child DisplayObject instance 7795 * 7796 * @param {PIXI.DisplayObject} child - The DisplayObject instance to identify 7797 * @return {number} The index position of the child display object to identify 7798 */ 7799 Container.prototype.getChildIndex = function getChildIndex (child) 7800 { 7801 var index = this.children.indexOf(child); 7802 7803 if (index === -1) 7804 { 7805 throw new Error('The supplied DisplayObject must be a child of the caller'); 7806 } 7807 7808 return index; 7809 }; 7810 7811 /** 7812 * Changes the position of an existing child in the display object container 7813 * 7814 * @param {PIXI.DisplayObject} child - The child DisplayObject instance for which you want to change the index number 7815 * @param {number} index - The resulting index number for the child display object 7816 */ 7817 Container.prototype.setChildIndex = function setChildIndex (child, index) 7818 { 7819 if (index < 0 || index >= this.children.length) 7820 { 7821 throw new Error(("The index " + index + " supplied is out of bounds " + (this.children.length))); 7822 } 7823 7824 var currentIndex = this.getChildIndex(child); 7825 7826 removeItems(this.children, currentIndex, 1); // remove from old position 7827 this.children.splice(index, 0, child); // add at new position 7828 7829 this.onChildrenChange(index); 7830 }; 7831 7832 /** 7833 * Returns the child at the specified index 7834 * 7835 * @param {number} index - The index to get the child at 7836 * @return {PIXI.DisplayObject} The child at the given index, if any. 7837 */ 7838 Container.prototype.getChildAt = function getChildAt (index) 7839 { 7840 if (index < 0 || index >= this.children.length) 7841 { 7842 throw new Error(("getChildAt: Index (" + index + ") does not exist.")); 7843 } 7844 7845 return this.children[index]; 7846 }; 7847 7848 /** 7849 * Removes one or more children from the container. 7850 * 7851 * @param {...PIXI.DisplayObject} child - The DisplayObject(s) to remove 7852 * @return {PIXI.DisplayObject} The first child that was removed. 7853 */ 7854 Container.prototype.removeChild = function removeChild (child) 7855 { 7856 var arguments$1 = arguments; 7857 7858 var argumentsLength = arguments.length; 7859 7860 // if there is only one argument we can bypass looping through the them 7861 if (argumentsLength > 1) 7862 { 7863 // loop through the arguments property and add all children 7864 // use it the right way (.length and [i]) so that this function can still be optimized by JS runtimes 7865 for (var i = 0; i < argumentsLength; i++) 7866 { 7867 this.removeChild(arguments$1[i]); 7868 } 7869 } 7870 else 7871 { 7872 var index = this.children.indexOf(child); 7873 7874 if (index === -1) { return null; } 7875 7876 child.parent = null; 7877 // ensure child transform will be recalculated 7878 child.transform._parentID = -1; 7879 removeItems(this.children, index, 1); 7880 7881 // ensure bounds will be recalculated 7882 this._boundsID++; 7883 7884 // TODO - lets either do all callbacks or all events.. not both! 7885 this.onChildrenChange(index);
7886 child.emit('removed', this); 7887 this.emit('childRemoved', child, this, index); 7888 } 7889 7890 return child; 7891 }; 7892 7893 /** 7894 * Removes a child from the specified index position. 7895 * 7896 * @param {number} index - The index to get the child from 7897 * @return {PIXI.DisplayObject} The child that was removed. 7898 */ 7899 Container.prototype.removeChildAt = function removeChildAt (index) 7900 { 7901 var child = this.getChildAt(index); 7902 7903 // ensure child transform will be recalculated.. 7904 child.parent = null; 7905 child.transform._parentID = -1; 7906 removeItems(this.children, index, 1); 7907 7908 // ensure bounds will be recalculated 7909 this._boundsID++; 7910 7911 // TODO - lets either do all callbacks or all events.. not both! 7912 this.onChildrenChange(index); 7913 child.emit('removed', this); 7914 this.emit('childRemoved', child, this, index); 7915 7916 return child; 7917 }; 7918 7919 /** 7920 * Removes all children from this container that are within the begin and end indexes. 7921 * 7922 * @param {number} [beginIndex=0] - The beginning position. 7923 * @param {number} [endIndex=this.children.length] - The ending position. Default value is size of the container. 7924 * @returns {DisplayObject[]} List of removed children 7925 */ 7926 Container.prototype.removeChildren = function removeChildren (beginIndex, endIndex) 7927 { 7928 if ( beginIndex === void 0 ) { beginIndex = 0; } 7929 7930 var begin = beginIndex; 7931 var end = typeof endIndex === 'number' ? endIndex : this.children.length; 7932 var range = end - begin; 7933 var removed; 7934 7935 if (range > 0 && range <= end) 7936 { 7937 removed = this.children.splice(begin, range); 7938 7939 for (var i = 0; i < removed.length; ++i) 7940 { 7941 removed[i].parent = null; 7942 if (removed[i].transform) 7943 { 7944 removed[i].transform._parentID = -1; 7945 } 7946 } 7947 7948 this._boundsID++; 7949 7950 this.onChildrenChange(beginIndex); 7951 7952 for (var i$1 = 0; i$1 < removed.length; ++i$1) 7953 { 7954 removed[i$1].emit('removed', this); 7955 this.emit('childRemoved', removed[i$1], this, i$1); 7956 } 7957 7958 return removed; 7959 } 7960 else if (range === 0 && this.children.length === 0) 7961 { 7962 return []; 7963 } 7964 7965 throw new RangeError('removeChildren: numeric values are outside the acceptable range.'); 7966 }; 7967 7968 /** 7969 * Sorts children by zIndex. Previous order is mantained for 2 children with the same zIndex. 7970 */ 7971 Container.prototype.sortChildren = function sortChildren$1 () 7972 { 7973 var sortRequired = false; 7974 7975 for (var i = 0, j = this.children.length; i < j; ++i) 7976 { 7977 var child = this.children[i]; 7978 7979 child._lastSortedIndex = i; 7980 7981 if (!sortRequired && child.zIndex !== 0) 7982 { 7983 sortRequired = true; 7984 } 7985 } 7986 7987 if (sortRequired && this.children.length > 1) 7988 { 7989 this.children.sort(sortChildren); 7990 } 7991 7992 this.sortDirty = false; 7993 }; 7994 7995 /** 7996 * Updates the transform on all children of this container for rendering 7997 */ 7998 Container.prototype.updateTransform = function updateTransform () 7999 { 8000 if (this.sortableChildren && this.sortDirty) 8001 { 8002 this.sortChildren(); 8003 } 8004 8005 this._boundsID++; 8006 8007 this.transform.updateTransform(this.parent.transform); 8008 8009 // TODO: check render flags, how to process stuff here 8010 this.worldAlpha = this.alpha * this.parent.worldAlpha; 8011 8012 for (var i = 0, j = this.children.length; i < j; ++i) 8013 { 8014 var child = this.children[i]; 8015 8016 if (child.visible) 8017 { 8018 child.updateTransform(); 8019 } 8020 } 8021 }; 8022 8023 /** 8024 * Recalculates the bounds of the container. 8025 * 8026 */ 8027 Container.prototype.calculateBounds = function calculateBounds () 8028 { 8029 this._bounds.clear(); 8030 8031 this._calculateBounds(); 8032 8033 for (var i = 0; i < this.children.length; i++) 8034 { 8035 var child = this.children[i]; 8036 8037 if (!child.visible || !child.renderable) 8038 { 8039 continue; 8040 } 8041 8042 child.calculateBounds(); 8043
8044 // TODO: filter+mask, need to mask both somehow 8045 if (child._mask) 8046 { 8047 child._mask.calculateBounds(); 8048 this._bounds.addBoundsMask(child._bounds, child._mask._bounds); 8049 } 8050 else if (child.filterArea) 8051 { 8052 this._bounds.addBoundsArea(child._bounds, child.filterArea); 8053 } 8054 else 8055 { 8056 this._bounds.addBounds(child._bounds); 8057 } 8058 } 8059 8060 this._lastBoundsID = this._boundsID; 8061 }; 8062 8063 /** 8064 * Recalculates the bounds of the object. Override this to 8065 * calculate the bounds of the specific object (not including children). 8066 * 8067 * @protected 8068 */ 8069 Container.prototype._calculateBounds = function _calculateBounds () 8070 { 8071 // FILL IN// 8072 }; 8073 8074 /** 8075 * Renders the object using the WebGL renderer 8076 * 8077 * @param {PIXI.Renderer} renderer - The renderer 8078 */ 8079 Container.prototype.render = function render (renderer) 8080 { 8081 // if the object is not visible or the alpha is 0 then no need to render this element 8082 if (!this.visible || this.worldAlpha <= 0 || !this.renderable) 8083 { 8084 return; 8085 } 8086 8087 // do a quick check to see if this element has a mask or a filter. 8088 if (this._mask || this.filters) 8089 { 8090 this.renderAdvanced(renderer); 8091 } 8092 else 8093 { 8094 this._render(renderer); 8095 8096 // simple render children! 8097 for (var i = 0, j = this.children.length; i < j; ++i) 8098 { 8099 this.children[i].render(renderer); 8100 } 8101 } 8102 }; 8103 8104 /**
8105 * Render the object using the WebGL renderer and advanced features. 8106 * 8107 * @protected 8108 * @param {PIXI.Renderer} renderer - The renderer 8109 */ 8110 Container.prototype.renderAdvanced = function renderAdvanced (renderer) 8111 { 8112 renderer.batch.flush(); 8113 8114 var filters = this.filters; 8115 var mask = this._mask; 8116 8117 // push filter first as we need to ensure the stencil buffer is correct for any masking 8118 if (filters) 8119 { 8120 if (!this._enabledFilters) 8121 { 8122 this._enabledFilters = []; 8123 } 8124 8125 this._enabledFilters.length = 0; 8126 8127 for (var i = 0; i < filters.length; i++) 8128 { 8129 if (filters[i].enabled) 8130 { 8131 this._enabledFilters.push(filters[i]); 8132 } 8133 } 8134 8135 if (this._enabledFilters.length) 8136 { 8137 renderer.filter.push(this, this._enabledFilters); 8138 } 8139 } 8140 8141 if (mask) 8142 { 8143 renderer.mask.push(this, this._mask); 8144 } 8145 8146 // add this object to the batch, only rendered if it has a texture. 8147 this._render(renderer); 8148 8149 // now loop through the children and make sure they get rendered 8150 for (var i$1 = 0, j = this.children.length; i$1 < j; i$1++) 8151 { 8152 this.children[i$1].render(renderer); 8153 } 8154 8155 renderer.batch.flush(); 8156 8157 if (mask) 8158 { 8159 renderer.mask.pop(this, this._mask); 8160 } 8161 8162 if (filters && this._enabledFilters && this._enabledFilters.length) 8163 { 8164 renderer.filter.pop(); 8165 } 8166 }; 8167 8168 /** 8169 * To be overridden by the subclasses. 8170 * 8171 * @protected 8172 * @param {PIXI.Renderer} renderer - The renderer 8173 */ 8174 Container.prototype._render = function _render (renderer) // eslint-disable-line no-unused-vars 8175 { 8176 // this is where content itself gets rendered... 8177 }; 8178 8179 /** 8180 * Removes all internal references and listeners as well as removes children from the display list. 8181 * Do not use a Container after calling `destroy`. 8182 * 8183 * @param {object|boolean} [options] - Options parameter. A boolean will act as if all options 8184 * have been set to that value 8185 * @param {boolean} [options.children=false] - if set to true, all the children will have their destroy 8186 * method called as well. 'options' will be passed on to those calls. 8187 * @param {boolean} [options.texture=false] - Only used for child Sprites if options.children is set to true 8188 * Should it destroy the texture of the child sprite 8189 * @param {boolean} [options.baseTexture=false] - Only used for child Sprites if options.children is set to true 8190 * Should it destroy the base texture of the child sprite 8191 */ 8192 Container.prototype.destroy = function destroy (options) 8193 { 8194 DisplayObject.prototype.destroy.call(this); 8195 8196 this.sortDirty = false; 8197 8198 var destroyChildren = typeof options === 'boolean' ? options : options && options.children; 8199 8200 var oldChildren = this.removeChildren(0, this.children.length); 8201 8202 if (destroyChildren) 8203 { 8204 for (var i = 0; i < oldChildren.length; ++i) 8205 { 8206 oldChildren[i].destroy(options); 8207 } 8208 } 8209 }; 8210 8211 /** 8212 * The width of the Container, setting this will actually modify the scale to achieve the value set 8213 * 8214 * @member {number} 8215 */ 8216 prototypeAccessors.width.get = function () 8217 { 8218 return this.scale.x * this.getLocalBounds().width; 8219 }; 8220 8221 prototypeAccessors.width.set = function (value) // eslint-disable-line require-jsdoc 8222 { 8223 var width = this.getLocalBounds().width; 8224 8225 if (width !== 0) 8226 { 8227 this.scale.x = value / width; 8228 } 8229 else 8230 { 8231 this.scale.x = 1; 8232 } 8233 8234 this._width = value; 8235 }; 8236 8237 /** 8238 * The height of the Container, setting this will actually modify the scale to achieve the value set 8239 * 8240 * @member {number} 8241 */ 8242 prototypeAccessors.height.get = function () 8243 { 8244 return this.scale.y * this.getLocalBounds().height; 8245 }; 8246 8247 prototypeAccessors.height.set = function (value) // eslint-disable-line require-jsdoc 8248 { 8249 var height = this.getLocalBounds().height; 8250 8251 if (height !== 0) 8252 { 8253 this.scale.y = value / height; 8254 } 8255 else 8256 { 8257 this.scale.y = 1; 8258 } 8259 8260 this._height = value; 8261 }; 8262 8263 Object.defineProperties( Container.prototype, prototypeAccessors ); 8264 8265 return Container; 8266 }(DisplayObject)); 8267 8268 // performance increase to avoid using call.. (10x faster) 8269 Container.prototype.containerUpdateTransform = Container.prototype.updateTransform; 8270 8271 /*! 8272 * @pixi/accessibility - v5.0.0-rc.3 8273 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 8274 * 8275 * @pixi/accessibility is licensed under the MIT License. 8276 * http://www.opensource.org/licenses/mit-license 8277 */ 8278 8279 /** 8280 * Default property values of accessible objects 8281 * used by {@link PIXI.accessibility.AccessibilityManager}. 8282 * 8283 * @private 8284 * @function accessibleTarget 8285 * @memberof PIXI.accessibility 8286 * @type {Object} 8287 * @example 8288 * function MyObject() {} 8289 * 8290 * Object.assign( 8291 * MyObject.prototype, 8292 * PIXI.accessibility.accessibleTarget 8293 * ); 8294 */ 8295 var accessibleTarget = { 8296 /** 8297 * Flag for if the object is accessible. If true AccessibilityManager will overlay a 8298 * shadow div with attributes set 8299 * 8300 * @member {boolean} 8301 * @memberof PIXI.DisplayObject# 8302 */ 8303 accessible: false, 8304 8305 /** 8306 * Sets the title attribute of the shadow div 8307 * If accessibleTitle AND accessibleHint has not been this will default to 'displayObject [tabIndex]' 8308 * 8309 * @member {?string} 8310 * @memberof PIXI.DisplayObject# 8311 */ 8312 accessibleTitle: null, 8313 8314 /** 8315 * Sets the aria-label attribute of the shadow div 8316 * 8317 * @member {string} 8318 * @memberof PIXI.DisplayObject# 8319 */ 8320 accessibleHint: null, 8321 8322 /** 8323 * @member {number} 8324 * @memberof PIXI.DisplayObject# 8325 * @private 8326 * @todo Needs docs. 8327 */ 8328 tabIndex: 0, 8329 8330 /** 8331 * @member {boolean} 8332 * @memberof PIXI.DisplayObject# 8333 * @todo Needs docs. 8334 */ 8335 _accessibleActive: false, 8336 8337 /** 8338 * @member {boolean} 8339 * @memberof PIXI.DisplayObject# 8340 * @todo Needs docs. 8341 */ 8342 _accessibleDiv: false, 8343 }; 8344 8345 // add some extra variables to the container.. 8346 DisplayObject.mixin(accessibleTarget); 8347 8348 var KEY_CODE_TAB = 9; 8349 8350 var DIV_TOUCH_SIZE = 100; 8351 var DIV_TOUCH_POS_X = 0; 8352 var DIV_TOUCH_POS_Y = 0; 8353 var DIV_TOUCH_ZINDEX = 2; 8354 8355 var DIV_HOOK_SIZE = 1; 8356 var DIV_HOOK_POS_X = -1000; 8357 var DIV_HOOK_POS_Y = -1000; 8358 var DIV_HOOK_ZINDEX = 2; 8359 8360 /** 8361 * The Accessibility manager recreates the ability to tab and have content read by screen readers. 8362 * This is very important as it can possibly help people with disabilities access PixiJS content. 8363 * 8364 * A DisplayObject can be made accessible just like it can be made interactive. This manager will map the 8365 * events as if the mouse was being used, minimizing the effort required to implement. 8366 * 8367 * An instance of this class is automatically created by default, and can be found at `renderer.plugins.accessibility` 8368 * 8369 * @class 8370 * @memberof PIXI.accessibility 8371 */ 8372 var AccessibilityManager = function AccessibilityManager(renderer) 8373 { 8374 /** 8375 * @type {?HTMLElement} 8376 * @private 8377 */ 8378 this._hookDiv = null; 8379 if (isMobile_min.tablet || isMobile_min.phone) 8380 { 8381 this.createTouchHook(); 8382 } 8383 8384 // first we create a div that will sit over the PixiJS element. This is where the div overlays will go. 8385 var div = document.createElement('div'); 8386 8387 div.style.width = DIV_TOUCH_SIZE + "px"; 8388 div.style.height = DIV_TOUCH_SIZE + "px"; 8389 div.style.position = 'absolute'; 8390 div.style.top = DIV_TOUCH_POS_X + "px"; 8391 div.style.left = DIV_TOUCH_POS_Y + "px"; 8392 div.style.zIndex = DIV_TOUCH_ZINDEX; 8393 8394 /** 8395 * This is the dom element that will sit over the PixiJS element. This is where the div overlays will go. 8396 * 8397 * @type {HTMLElement} 8398 * @private 8399 */ 8400 this.div = div; 8401 8402 /** 8403 * A simple pool for storing divs. 8404 * 8405 * @type {*} 8406 * @private 8407 */ 8408 this.pool = []; 8409 8410 /** 8411 * This is a tick used to check if an object is no longer being rendered. 8412 * 8413 * @type {Number} 8414 * @private 8415 */ 8416 this.renderId = 0; 8417 8418 /** 8419 * Setting this to true will visually show the divs. 8420 * 8421 * @type {boolean} 8422 */ 8423 this.debug = false;
8424 8425 /** 8426 * The renderer this accessibility manager works for. 8427 * 8428 * @member {PIXI.AbstractRenderer} 8429 */ 8430 this.renderer = renderer; 8431 8432 /** 8433 * The array of currently active accessible items. 8434 * 8435 * @member {Array<*>} 8436 * @private 8437 */ 8438 this.children = []; 8439 8440 /** 8441 * pre-bind the functions 8442 * 8443 * @type {Function} 8444 * @private 8445 */ 8446 this._onKeyDown = this._onKeyDown.bind(this); 8447 8448 /** 8449 * pre-bind the functions 8450 * 8451 * @type {Function} 8452 * @private 8453 */ 8454 this._onMouseMove = this._onMouseMove.bind(this); 8455 8456 /** 8457 * A flag 8458 * @type {boolean} 8459 * @readonly 8460 */ 8461 this.isActive = false; 8462 8463 /** 8464 * A flag 8465 * @type {boolean} 8466 * @readonly 8467 */ 8468 this.isMobileAccessibility = false; 8469 8470 // let listen for tab.. once pressed we can fire up and show the accessibility layer 8471 window.addEventListener('keydown', this._onKeyDown, false); 8472 }; 8473 8474 /** 8475 * Creates the touch hooks. 8476 * 8477 * @private 8478 */ 8479 AccessibilityManager.prototype.createTouchHook = function createTouchHook () 8480 { 8481 var this$1 = this; 8482 8483 var hookDiv = document.createElement('button'); 8484 8485 hookDiv.style.width = DIV_HOOK_SIZE + "px"; 8486 hookDiv.style.height = DIV_HOOK_SIZE + "px"; 8487 hookDiv.style.position = 'absolute'; 8488 hookDiv.style.top = DIV_HOOK_POS_X + "px"; 8489 hookDiv.style.left = DIV_HOOK_POS_Y + "px"; 8490 hookDiv.style.zIndex = DIV_HOOK_ZINDEX; 8491 hookDiv.style.backgroundColor = '#FF0000'; 8492 hookDiv.title = 'HOOK DIV'; 8493 8494 hookDiv.addEventListener('focus', function () { 8495 this$1.isMobileAccessibility = true; 8496 this$1.activate(); 8497 this$1.destroyTouchHook(); 8498 }); 8499 8500 document.body.appendChild(hookDiv); 8501 this._hookDiv = hookDiv; 8502 }; 8503 8504 /** 8505 * Destroys the touch hooks. 8506 * 8507 * @private 8508 */ 8509 AccessibilityManager.prototype.destroyTouchHook = function destroyTouchHook () 8510 { 8511 if (!this._hookDiv) 8512 { 8513 return; 8514 } 8515 document.body.removeChild(this._hookDiv); 8516 this._hookDiv = null; 8517 }; 8518 8519 /** 8520 * Activating will cause the Accessibility layer to be shown. 8521 * This is called when a user presses the tab key. 8522 * 8523 * @private 8524 */ 8525 AccessibilityManager.prototype.activate = function activate () 8526 { 8527 if (this.isActive) 8528 { 8529 return; 8530 } 8531 8532 this.isActive = true; 8533 8534 window.document.addEventListener('mousemove', this._onMouseMove, true); 8535 window.removeEventListener('keydown', this._onKeyDown, false); 8536 8537 this.renderer.on('postrender', this.update, this); 8538 8539 if (this.renderer.view.parentNode) 8540 { 8541 this.renderer.view.parentNode.appendChild(this.div); 8542 } 8543 }; 8544 8545 /** 8546 * Deactivating will cause the Accessibility layer to be hidden. 8547 * This is called when a user moves the mouse. 8548 * 8549 * @private 8550 */ 8551 AccessibilityManager.prototype.deactivate = function deactivate () 8552 { 8553 if (!this.isActive || this.isMobileAccessibility) 8554 { 8555 return; 8556 } 8557 8558 this.isActive = false; 8559 8560 window.document.removeEventListener('mousemove', this._onMouseMove, true); 8561 window.addEventListener('keydown', this._onKeyDown, false); 8562 8563 this.renderer.off('postrender', this.update); 8564 8565 if (this.div.parentNode) 8566 { 8567 this.div.parentNode.removeChild(this.div); 8568 } 8569 }; 8570 8571 /** 8572 * This recursive function will run through the scene graph and add any new accessible objects to the DOM layer. 8573 * 8574 * @private 8575 * @param {PIXI.Container} displayObject - The DisplayObject to check. 8576 */ 8577 AccessibilityManager.prototype.updateAccessibleObjects = function updateAccessibleObjects (displayObject) 8578 { 8579 if (!displayObject.visible) 8580 { 8581 return; 8582 } 8583 8584 if (displayObject.accessible && displayObject.interactive) 8585 { 8586 if (!displayObject._accessibleActive) 8587 { 8588 this.addChild(displayObject); 8589 } 8590 8591 displayObject.renderId = this.renderId; 8592 } 8593 8594 var children = displayObject.children; 8595 8596 for (var i = 0; i < children.length; i++) 8597 { 8598 this.updateAccessibleObjects(children[i]); 8599 } 8600 }; 8601 8602 /** 8603 * Before each render this function will ensure that all divs are mapped correctly to their DisplayObjects. 8604 * 8605 * @private 8606 */ 8607 AccessibilityManager.prototype.update = function update () 8608 { 8609 if (!this.renderer.renderingToScreen) 8610 { 8611 return; 8612 } 8613 8614 // update children... 8615 this.updateAccessibleObjects(this.renderer._lastObjectRendered); 8616 8617 var rect = this.renderer.view.getBoundingClientRect(); 8618 var sx = rect.width / this.renderer.width; 8619 var sy = rect.height / this.renderer.height; 8620 8621 var div = this.div; 8622 8623 div.style.left = (rect.left) + "px"; 8624 div.style.top = (rect.top) + "px"; 8625 div.style.width = (this.renderer.width) + "px"; 8626 div.style.height = (this.renderer.height) + "px"; 8627 8628 for (var i = 0; i < this.children.length; i++) 8629 { 8630 var child = this.children[i]; 8631 8632 if (child.renderId !== this.renderId) 8633 { 8634 child._accessibleActive = false;
8635 8636 removeItems(this.children, i, 1); 8637 this.div.removeChild(child._accessibleDiv); 8638 this.pool.push(child._accessibleDiv); 8639 child._accessibleDiv = null; 8640 8641 i--; 8642 8643 if (this.children.length === 0) 8644 { 8645 this.deactivate(); 8646 } 8647 } 8648 else 8649 { 8650 // map div to display.. 8651 div = child._accessibleDiv; 8652 var hitArea = child.hitArea; 8653 var wt = child.worldTransform; 8654 8655 if (child.hitArea) 8656 { 8657 div.style.left = ((wt.tx + (hitArea.x * wt.a)) * sx) + "px"; 8658 div.style.top = ((wt.ty + (hitArea.y * wt.d)) * sy) + "px"; 8659 8660 div.style.width = (hitArea.width * wt.a * sx) + "px"; 8661 div.style.height = (hitArea.height * wt.d * sy) + "px"; 8662 } 8663 else 8664 { 8665 hitArea = child.getBounds(); 8666 8667 this.capHitArea(hitArea); 8668 8669 div.style.left = (hitArea.x * sx) + "px"; 8670 div.style.top = (hitArea.y * sy) + "px"; 8671 8672 div.style.width = (hitArea.width * sx) + "px"; 8673 div.style.height = (hitArea.height * sy) + "px"; 8674 8675 // update button titles and hints if they exist and they've changed 8676 if (div.title !== child.accessibleTitle && child.accessibleTitle !== null) 8677 { 8678 div.title = child.accessibleTitle; 8679 } 8680 if (div.getAttribute('aria-label') !== child.accessibleHint 8681 && child.accessibleHint !== null) 8682 { 8683 div.setAttribute('aria-label', child.accessibleHint); 8684 } 8685 } 8686 } 8687 } 8688 8689 // increment the render id.. 8690 this.renderId++; 8691 }; 8692 8693 /** 8694 * Adjust the hit area based on the bounds of a display object 8695 * 8696 * @param {Rectangle} hitArea - Bounds of the child 8697 */ 8698 AccessibilityManager.prototype.capHitArea = function capHitArea (hitArea) 8699 { 8700 if (hitArea.x < 0) 8701 { 8702 hitArea.width += hitArea.x; 8703 hitArea.x = 0; 8704 } 8705 8706 if (hitArea.y < 0) 8707 { 8708 hitArea.height += hitArea.y; 8709 hitArea.y = 0; 8710 } 8711 8712 if (hitArea.x + hitArea.width > this.renderer.width) 8713 { 8714 hitArea.width = this.renderer.width - hitArea.x; 8715 } 8716 8717 if (hitArea.y + hitArea.height > this.renderer.height) 8718 { 8719 hitArea.height = this.renderer.height - hitArea.y; 8720 } 8721 }; 8722 8723 /** 8724 * Adds a DisplayObject to the accessibility manager 8725 * 8726 * @private 8727 * @param {DisplayObject} displayObject - The child to make accessible. 8728 */ 8729 AccessibilityManager.prototype.addChild = function addChild (displayObject) 8730 { 8731 //this.activate(); 8732 8733 var div = this.pool.pop(); 8734 8735 if (!div) 8736 { 8737 div = document.createElement('button'); 8738 8739 div.style.width = DIV_TOUCH_SIZE + "px"; 8740 div.style.height = DIV_TOUCH_SIZE + "px"; 8741 div.style.backgroundColor = this.debug ? 'rgba(255,0,0,0.5)' : 'transparent'; 8742 div.style.position = 'absolute'; 8743 div.style.zIndex = DIV_TOUCH_ZINDEX; 8744 div.style.borderStyle = 'none'; 8745 8746 // ARIA attributes ensure that button title and hint updates are announced properly 8747 if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) 8748 { 8749 // Chrome doesn't need aria-live to work as intended; in fact it just gets more confused. 8750 div.setAttribute('aria-live', 'off'); 8751 } 8752 else 8753 { 8754 div.setAttribute('aria-live', 'polite'); 8755 } 8756 8757 if (navigator.userAgent.match(/rv:.*Gecko\//)) 8758 { 8759 // FireFox needs this to announce only the new button name 8760 div.setAttribute('aria-relevant', 'additions'); 8761 } 8762 else 8763 { 8764 // required by IE, other browsers don't much care 8765 div.setAttribute('aria-relevant', 'text'); 8766 } 8767 8768 div.addEventListener('click', this._onClick.bind(this)); 8769 div.addEventListener('focus', this._onFocus.bind(this)); 8770 div.addEventListener('focusout', this._onFocusOut.bind(this)); 8771 } 8772 8773 if (displayObject.accessibleTitle && displayObject.accessibleTitle !== null) 8774 { 8775 div.title = displayObject.accessibleTitle; 8776 } 8777 else if (!displayObject.accessibleHint 8778 || displayObject.accessibleHint === null) 8779 { 8780 div.title = "displayObject " + (displayObject.tabIndex); 8781 } 8782 8783 if (displayObject.accessibleHint 8784 && displayObject.accessibleHint !== null) 8785 { 8786 div.setAttribute('aria-label', displayObject.accessibleHint); 8787 } 8788 8789 // 8790 8791 displayObject._accessibleActive = true; 8792 displayObject._accessibleDiv = div; 8793 div.displayObject = displayObject; 8794 8795 this.children.push(displayObject); 8796 this.div.appendChild(displayObject._accessibleDiv); 8797 displayObject._accessibleDiv.tabIndex = displayObject.tabIndex; 8798 }; 8799 8800 /** 8801 * Maps the div button press to pixi's InteractionManager (click) 8802 * 8803 * @private 8804 * @param {MouseEvent} e - The click event. 8805 */ 8806 AccessibilityManager.prototype._onClick = function _onClick (e) 8807 { 8808 var interactionManager = this.renderer.plugins.interaction; 8809 8810 interactionManager.dispatchEvent(e.target.displayObject, 'click', interactionManager.eventData); 8811 }; 8812 8813 /** 8814 * Maps the div focus events to pixi's InteractionManager (mouseover) 8815 * 8816 * @private 8817 * @param {FocusEvent} e - The focus event. 8818 */ 8819 AccessibilityManager.prototype._onFocus = function _onFocus (e) 8820 { 8821 if (!e.target.getAttribute('aria-live', 'off')) 8822 { 8823 e.target.setAttribute('aria-live', 'assertive'); 8824 } 8825 var interactionManager = this.renderer.plugins.interaction; 8826 8827 interactionManager.dispatchEvent(e.target.displayObject, 'mouseover', interactionManager.eventData); 8828 }; 8829 8830 /** 8831 * Maps the div focus events to pixi's InteractionManager (mouseout) 8832 * 8833 * @private 8834 * @param {FocusEvent} e - The focusout event. 8835 */ 8836 AccessibilityManager.prototype._onFocusOut = function _onFocusOut (e) 8837 { 8838 if (!e.target.getAttribute('aria-live', 'off')) 8839 { 8840 e.target.setAttribute('aria-live', 'polite'); 8841 } 8842 var interactionManager = this.renderer.plugins.interaction; 8843 8844 interactionManager.dispatchEvent(e.target.displayObject, 'mouseout', interactionManager.eventData); 8845 }; 8846 8847 /** 8848 * Is called when a key is pressed 8849 * 8850 * @private 8851 * @param {KeyboardEvent} e - The keydown event. 8852 */ 8853 AccessibilityManager.prototype._onKeyDown = function _onKeyDown (e) 8854 { 8855 if (e.keyCode !== KEY_CODE_TAB) 8856 { 8857 return; 8858 } 8859 8860 this.activate(); 8861 }; 8862 8863 /** 8864 * Is called when the mouse moves across the renderer element 8865 * 8866 * @private 8867 * @param {MouseEvent} e - The mouse event. 8868 */ 8869 AccessibilityManager.prototype._onMouseMove = function _onMouseMove (e) 8870 { 8871 if (e.movementX === 0 && e.movementY === 0) 8872 { 8873 return; 8874 } 8875 8876 this.deactivate(); 8877 }; 8878 8879 /** 8880 * Destroys the accessibility manager 8881 * 8882 */
8883 AccessibilityManager.prototype.destroy = function destroy () 8884 { 8885 this.destroyTouchHook(); 8886 this.div = null; 8887 8888 for (var i = 0; i < this.children.length; i++) 8889 { 8890 this.children[i].div = null; 8891 } 8892 8893 window.document.removeEventListener('mousemove', this._onMouseMove, true); 8894 window.removeEventListener('keydown', this._onKeyDown); 8895 8896 this.pool = null; 8897 this.children = null; 8898 this.renderer = null; 8899 }; 8900 8901 var accessibility_es = ({ 8902 AccessibilityManager: AccessibilityManager, 8903 accessibleTarget: accessibleTarget 8904 }); 8905 8906 /*! 8907 * @pixi/runner - v5.0.0-rc.3 8908 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 8909 * 8910 * @pixi/runner is licensed under the MIT License. 8911 * http://www.opensource.org/licenses/mit-license 8912 */ 8913 /** 8914 * A Runner is a highly performant and simple alternative to signals. Best used in situations 8915 * where events are dispatched to many objects at high frequency (say every frame!) 8916 * 8917 * 8918 * like a signal.. 8919 * ``` 8920 * const myObject = { 8921 * loaded: new PIXI.Runner('loaded') 8922 * } 8923 * 8924 * const listener = { 8925 * loaded: function(){ 8926 * // thin 8927 * } 8928 * } 8929 * 8930 * myObject.update.add(listener); 8931 * 8932 * myObject.loaded.emit(); 8933 * ``` 8934 * 8935 * Or for handling calling the same function on many items 8936 * ``` 8937 * const myGame = { 8938 * update: new PIXI.Runner('update') 8939 * } 8940 * 8941 * const gameObject = { 8942 * update: function(time){ 8943 * // update my gamey state 8944 * } 8945 * } 8946 * 8947 * myGame.update.add(gameObject1); 8948 * 8949 * myGame.update.emit(time); 8950 * ``` 8951 * @class 8952 * @memberof PIXI 8953 */ 8954 var Runner = function Runner(name) 8955 { 8956 this.items = []; 8957 this._name = name; 8958 }; 8959 8960 var prototypeAccessors$3 = { empty: { configurable: true },name: { configurable: true } }; 8961 8962 /** 8963 * Dispatch/Broadcast Runner to all listeners added to the queue. 8964 * @param {...any} params - optional parameters to pass to each listener 8965 */ 8966 Runner.prototype.emit = function emit (a0, a1, a2, a3, a4, a5, a6, a7) 8967 { 8968 if (arguments.length > 8) 8969 { 8970 throw new Error('max arguments reached'); 8971 } 8972 8973 var ref = this; 8974 var name = ref.name; 8975 var items = ref.items; 8976 8977 for (var i = 0, len = items.length; i < len; i++) 8978 { 8979 items[i][name](a0, a1, a2, a3, a4, a5, a6, a7); 8980 } 8981 8982 return this; 8983 }; 8984 8985 /** 8986 * Add a listener to the Runner 8987 * 8988 * Runners do not need to have scope or functions passed to them. 8989 * All that is required is to pass the listening object and ensure that it has contains a function that has the same name 8990 * as the name provided to the Runner when it was created. 8991 * 8992 * Eg A listener passed to this Runner will require a 'complete' function. 8993 * 8994 * ``` 8995 * const complete = new PIXI.Runner('complete'); 8996 * ``` 8997 * 8998 * The scope used will be the object itself. 8999 * 9000 * @param {any} item - The object that will be listening. 9001 */ 9002 Runner.prototype.add = function add (item) 9003 { 9004 if (item[this._name]) 9005 { 9006 this.remove(item); 9007 this.items.push(item); 9008 } 9009 9010 return this; 9011 }; 9012 9013 /** 9014 * Remove a single listener from the dispatch queue. 9015 * @param {any} item - The listenr that you would like to remove. 9016 */ 9017 Runner.prototype.remove = function remove (item) 9018 { 9019 var index = this.items.indexOf(item); 9020 9021 if (index !== -1) 9022 { 9023 this.items.splice(index, 1); 9024 } 9025 9026 return this; 9027 }; 9028 9029 /** 9030 * Check to see if the listener is already in the Runner 9031 * @param {any} item - The listener that you would like to check. 9032 */ 9033 Runner.prototype.contains = function contains (item) 9034 { 9035 return this.items.indexOf(item) !== -1; 9036 }; 9037 9038 /** 9039 * Remove all listeners from the Runner 9040 */ 9041 Runner.prototype.removeAll = function removeAll () 9042 { 9043 this.items.length = 0; 9044 9045 return this; 9046 }; 9047 9048 /** 9049 * Remove all references, don't use after this. 9050 */ 9051 Runner.prototype.destroy = function destroy () 9052 { 9053 this.removeAll(); 9054 this.items = null; 9055 this._name = null; 9056 }; 9057 9058 /**
9059 * `true` if there are no this Runner contains no listeners 9060 * 9061 * @member {boolean} 9062 * @readonly 9063 */ 9064 prototypeAccessors$3.empty.get = function () 9065 { 9066 return this.items.length === 0; 9067 }; 9068 9069 /** 9070 * The name of the runner. 9071 * 9072 * @member {string} 9073 * @readonly 9074 */ 9075 prototypeAccessors$3.name.get = function () 9076 { 9077 return this._name; 9078 }; 9079 9080 Object.defineProperties( Runner.prototype, prototypeAccessors$3 ); 9081 9082 /** 9083 * Alias for `emit` 9084 * @memberof PIXI.Runner# 9085 * @method dispatch 9086 * @see PIXI.Runner#emit 9087 */ 9088 Runner.prototype.dispatch = Runner.prototype.emit; 9089 9090 /** 9091 * Alias for `emit` 9092 * @memberof PIXI.Runner# 9093 * @method run 9094 * @see PIXI.Runner#emit 9095 */ 9096 Runner.prototype.run = Runner.prototype.emit; 9097 9098 /*! 9099 * @pixi/ticker - v5.0.0-rc.3 9100 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 9101 * 9102 * @pixi/ticker is licensed under the MIT License. 9103 * http://www.opensource.org/licenses/mit-license 9104 */ 9105 9106 /** 9107 * Target frames per millisecond. 9108 * 9109 * @static 9110 * @name TARGET_FPMS 9111 * @memberof PIXI.settings 9112 * @type {number} 9113 * @default 0.06 9114 */ 9115 settings.TARGET_FPMS = 0.06; 9116 9117 /** 9118 * Represents the update priorities used by internal PIXI classes when registered with 9119 * the {@link PIXI.Ticker} object. Higher priority items are updated first and lower 9120 * priority items, such as render, should go later. 9121 * 9122 * @static 9123 * @constant 9124 * @name UPDATE_PRIORITY 9125 * @memberof PIXI 9126 * @type {object} 9127 * @property {number} INTERACTION=50 Highest priority, used for {@link PIXI.interaction.InteractionManager} 9128 * @property {number} HIGH=25 High priority updating, {@link PIXI.VideoBaseTexture} and {@link PIXI.AnimatedSprite} 9129 * @property {number} NORMAL=0 Default priority for ticker events, see {@link PIXI.Ticker#add}. 9130 * @property {number} LOW=-25 Low priority used for {@link PIXI.Application} rendering. 9131 * @property {number} UTILITY=-50 Lowest priority used for {@link PIXI.prepare.BasePrepare} utility. 9132 */ 9133 var UPDATE_PRIORITY = { 9134 INTERACTION: 50, 9135 HIGH: 25, 9136 NORMAL: 0, 9137 LOW: -25, 9138 UTILITY: -50, 9139 }; 9140 9141 /** 9142 * Internal class for handling the priority sorting of ticker handlers. 9143 * 9144 * @private 9145 * @class 9146 * @memberof PIXI 9147 */ 9148 var TickerListener = function TickerListener(fn, context, priority, once) 9149 { 9150 if ( context === void 0 ) { context = null; } 9151 if ( priority === void 0 ) { priority = 0; } 9152 if ( once === void 0 ) { once = false; } 9153 9154 /** 9155 * The handler function to execute. 9156 * @private 9157 * @member {Function} 9158 */ 9159 this.fn = fn; 9160 9161 /** 9162 * The calling to execute. 9163 * @private 9164 * @member {*} 9165 */ 9166 this.context = context; 9167 9168 /** 9169 * The current priority. 9170 * @private 9171 * @member {number} 9172 */ 9173 this.priority = priority; 9174 9175 /** 9176 * If this should only execute once. 9177 * @private 9178 * @member {boolean} 9179 */ 9180 this.once = once; 9181 9182 /** 9183 * The next item in chain. 9184 * @private 9185 * @member {TickerListener} 9186 */ 9187 this.next = null; 9188 9189 /** 9190 * The previous item in chain. 9191 * @private 9192 * @member {TickerListener} 9193 */ 9194 this.previous = null; 9195 9196 /** 9197 * `true` if this listener has been destroyed already. 9198 * @member {boolean} 9199 * @private 9200 */ 9201 this._destroyed = false; 9202 }; 9203 9204 /**
9205 * Simple compare function to figure out if a function and context match. 9206 * @private 9207 * @param {Function} fn - The listener function to be added for one update 9208 * @param {Function} context - The listener context 9209 * @return {boolean} `true` if the listener match the arguments 9210 */ 9211 TickerListener.prototype.match = function match (fn, context) 9212 { 9213 context = context || null; 9214 9215 return this.fn === fn && this.context === context; 9216 }; 9217 9218 /** 9219 * Emit by calling the current function. 9220 * @private 9221 * @param {number} deltaTime - time since the last emit. 9222 * @return {TickerListener} Next ticker 9223 */ 9224 TickerListener.prototype.emit = function emit (deltaTime) 9225 { 9226 if (this.fn) 9227 { 9228 if (this.context) 9229 { 9230 this.fn.call(this.context, deltaTime); 9231 } 9232 else 9233 { 9234 this.fn(deltaTime); 9235 } 9236 } 9237 9238 var redirect = this.next; 9239 9240 if (this.once) 9241 { 9242 this.destroy(true); 9243 } 9244 9245 // Soft-destroying should remove 9246 // the next reference 9247 if (this._destroyed) 9248 { 9249 this.next = null; 9250 } 9251 9252 return redirect; 9253 }; 9254 9255 /** 9256 * Connect to the list. 9257 * @private 9258 * @param {TickerListener} previous - Input node, previous listener 9259 */ 9260 TickerListener.prototype.connect = function connect (previous) 9261 { 9262 this.previous = previous; 9263 if (previous.next) 9264 { 9265 previous.next.previous = this; 9266 } 9267 this.next = previous.next; 9268 previous.next = this; 9269 }; 9270 9271 /** 9272 * Destroy and don't use after this. 9273 * @private 9274 * @param {boolean} [hard = false] `true` to remove the `next` reference, this 9275 * is considered a hard destroy. Soft destroy maintains the next reference. 9276 * @return {TickerListener} The listener to redirect while emitting or removing. 9277 */ 9278 TickerListener.prototype.destroy = function destroy (hard) 9279 { 9280 if ( hard === void 0 ) { hard = false; } 9281 9282 this._destroyed = true; 9283 this.fn = null; 9284 this.context = null; 9285 9286 // Disconnect, hook up next and previous 9287 if (this.previous) 9288 { 9289 this.previous.next = this.next; 9290 } 9291 9292 if (this.next) 9293 { 9294 this.next.previous = this.previous; 9295 } 9296 9297 // Redirect to the next item 9298 var redirect = this.next; 9299 9300 // Remove references 9301 this.next = hard ? null : redirect; 9302 this.previous = null; 9303 9304 return redirect; 9305 }; 9306 9307 /** 9308 * A Ticker class that runs an update loop that other objects listen to. 9309 * 9310 * This class is composed around listeners meant for execution on the next requested animation frame. 9311 * Animation frames are requested only when necessary, e.g. When the ticker is started and the emitter has listeners. 9312 * 9313 * @class 9314 * @memberof PIXI 9315 */ 9316 var Ticker = function Ticker() 9317 { 9318 var this$1 = this; 9319 9320 /** 9321 * The first listener. All new listeners added are chained on this. 9322 * @private 9323 * @type {TickerListener} 9324 */ 9325 this._head = new TickerListener(null, null, Infinity); 9326 9327 /** 9328 * Internal current frame request ID 9329 * @type {?number} 9330 * @private 9331 */ 9332 this._requestId = null; 9333 9334 /** 9335 * Internal value managed by minFPS property setter and getter. 9336 * This is the maximum allowed milliseconds between updates. 9337 * @type {number} 9338 * @private 9339 */ 9340 this._maxElapsedMS = 100; 9341 9342 /** 9343 * Internal value managed by maxFPS property setter and getter. 9344 * This is the minimum allowed milliseconds between updates. 9345 * @private 9346 */ 9347 this._minElapsedMS = 0; 9348 9349 /** 9350 * Whether or not this ticker should invoke the method 9351 * {@link PIXI.Ticker#start} automatically 9352 * when a listener is added. 9353 * 9354 * @member {boolean} 9355 * @default false 9356 */ 9357 this.autoStart = false;
9358 9359 /** 9360 * Scalar time value from last frame to this frame. 9361 * This value is capped by setting {@link PIXI.Ticker#minFPS} 9362 * and is scaled with {@link PIXI.Ticker#speed}. 9363 * **Note:** The cap may be exceeded by scaling. 9364 * 9365 * @member {number} 9366 * @default 1 9367 */ 9368 this.deltaTime = 1; 9369 9370 /** 9371 * Scaler time elapsed in milliseconds from last frame to this frame. 9372 * This value is capped by setting {@link PIXI.Ticker#minFPS} 9373 * and is scaled with {@link PIXI.Ticker#speed}. 9374 * **Note:** The cap may be exceeded by scaling. 9375 * If the platform supports DOMHighResTimeStamp, 9376 * this value will have a precision of 1 µs. 9377 * Defaults to target frame time 9378 * 9379 * @member {number} 9380 * @default 16.66 9381 */ 9382 this.deltaMS = 1 / settings.TARGET_FPMS; 9383 9384 /** 9385 * Time elapsed in milliseconds from last frame to this frame. 9386 * Opposed to what the scalar {@link PIXI.Ticker#deltaTime} 9387 * is based, this value is neither capped nor scaled. 9388 * If the platform supports DOMHighResTimeStamp, 9389 * this value will have a precision of 1 µs. 9390 * Defaults to target frame time 9391 * 9392 * @member {number} 9393 * @default 16.66 9394 */ 9395 this.elapsedMS = 1 / settings.TARGET_FPMS; 9396 9397 /** 9398 * The last time {@link PIXI.Ticker#update} was invoked. 9399 * This value is also reset internally outside of invoking 9400 * update, but only when a new animation frame is requested. 9401 * If the platform supports DOMHighResTimeStamp, 9402 * this value will have a precision of 1 µs. 9403 * 9404 * @member {number} 9405 * @default -1 9406 */ 9407 this.lastTime = -1; 9408 9409 /** 9410 * Factor of current {@link PIXI.Ticker#deltaTime}. 9411 * @example 9412 * // Scales ticker.deltaTime to what would be 9413 * // the equivalent of approximately 120 FPS 9414 * ticker.speed = 2; 9415 * 9416 * @member {number} 9417 * @default 1 9418 */ 9419 this.speed = 1; 9420 9421 /** 9422 * Whether or not this ticker has been started. 9423 * `true` if {@link PIXI.Ticker#start} has been called. 9424 * `false` if {@link PIXI.Ticker#stop} has been called. 9425 * While `false`, this value may change to `true` in the 9426 * event of {@link PIXI.Ticker#autoStart} being `true` 9427 * and a listener is added. 9428 * 9429 * @member {boolean} 9430 * @default false 9431 */ 9432 this.started = false; 9433 9434 /** 9435 * If enabled, deleting is disabled. 9436 * @member {boolean} 9437 * @default false 9438 * @private 9439 */ 9440 this._protected = false; 9441 9442 /** 9443 * Internal tick method bound to ticker instance. 9444 * This is because in early 2015, Function.bind 9445 * is still 60% slower in high performance scenarios. 9446 * Also separating frame requests from update method 9447 * so listeners may be called at any time and with 9448 * any animation API, just invoke ticker.update(time). 9449 * 9450 * @private 9451 * @param {number} time - Time since last tick. 9452 */ 9453 this._tick = function (time) { 9454 this$1._requestId = null; 9455 9456 if (this$1.started) 9457 { 9458 // Invoke listeners now 9459 this$1.update(time); 9460 // Listener side effects may have modified ticker state. 9461 if (this$1.started && this$1._requestId === null && this$1._head.next) 9462 { 9463 this$1._requestId = requestAnimationFrame(this$1._tick); 9464 } 9465 } 9466 }; 9467 }; 9468 9469 var prototypeAccessors$4 = { FPS: { configurable: true },minFPS: { configurable: true },maxFPS: { configurable: true } }; 9470 var staticAccessors$2 = { shared: { configurable: true },system: { configurable: true } }; 9471 9472 /** 9473 * Conditionally requests a new animation frame. 9474 * If a frame has not already been requested, and if the internal 9475 * emitter has listeners, a new frame is requested. 9476 * 9477 * @private 9478 */ 9479 Ticker.prototype._requestIfNeeded = function _requestIfNeeded () 9480 { 9481 if (this._requestId === null && this._head.next) 9482 { 9483 // ensure callbacks get correct delta 9484 this.lastTime = performance.now(); 9485 this._requestId = requestAnimationFrame(this._tick); 9486 } 9487 }; 9488 9489 /** 9490 * Conditionally cancels a pending animation frame. 9491 * 9492 * @private 9493 */ 9494 Ticker.prototype._cancelIfNeeded = function _cancelIfNeeded () 9495 { 9496 if (this._requestId !== null) 9497 { 9498 cancelAnimationFrame(this._requestId); 9499 this._requestId = null; 9500 } 9501 }; 9502 9503 /** 9504 * Conditionally requests a new animation frame. 9505 * If the ticker has been started it checks if a frame has not already 9506 * been requested, and if the internal emitter has listeners. If these 9507 * conditions are met, a new frame is requested. If the ticker has not 9508 * been started, but autoStart is `true`, then the ticker starts now, 9509 * and continues with the previous conditions to request a new frame. 9510 * 9511 * @private 9512 */ 9513 Ticker.prototype._startIfPossible = function _startIfPossible () 9514 { 9515 if (this.started) 9516 { 9517 this._requestIfNeeded(); 9518 } 9519 else if (this.autoStart) 9520 { 9521 this.start(); 9522 } 9523 }; 9524 9525 /** 9526 * Register a handler for tick events. Calls continuously unless 9527 * it is removed or the ticker is stopped. 9528 * 9529 * @param {Function} fn - The listener function to be added for updates 9530 * @param {*} [context] - The listener context 9531 * @param {number} [priority=PIXI.UPDATE_PRIORITY.NORMAL] - The priority for emitting 9532 * @returns {PIXI.Ticker} This instance of a ticker 9533 */ 9534 Ticker.prototype.add = function add (fn, context, priority) 9535 { 9536 if ( priority === void 0 ) { priority = UPDATE_PRIORITY.NORMAL; } 9537 9538 return this._addListener(new TickerListener(fn, context, priority)); 9539 }; 9540 9541 /** 9542 * Add a handler for the tick event which is only execute once. 9543 * 9544 * @param {Function} fn - The listener function to be added for one update 9545 * @param {*} [context] - The listener context 9546 * @param {number} [priority=PIXI.UPDATE_PRIORITY.NORMAL] - The priority for emitting 9547 * @returns {PIXI.Ticker} This instance of a ticker 9548 */ 9549 Ticker.prototype.addOnce = function addOnce (fn, context, priority) 9550 { 9551 if ( priority === void 0 ) { priority = UPDATE_PRIORITY.NORMAL; } 9552 9553 return this._addListener(new TickerListener(fn, context, priority, true)); 9554 }; 9555 9556 /** 9557 * Internally adds the event handler so that it can be sorted by priority. 9558 * Priority allows certain handler (user, AnimatedSprite, Interaction) to be run 9559 * before the rendering. 9560 * 9561 * @private 9562 * @param {TickerListener} listener - Current listener being added. 9563 * @returns {PIXI.Ticker} This instance of a ticker 9564 */ 9565 Ticker.prototype._addListener = function _addListener (listener) 9566 { 9567 // For attaching to head 9568 var current = this._head.next; 9569 var previous = this._head; 9570 9571 // Add the first item 9572 if (!current) 9573 { 9574 listener.connect(previous); 9575 } 9576 else 9577 { 9578 // Go from highest to lowest priority 9579 while (current) 9580 { 9581 if (listener.priority > current.priority) 9582 { 9583 listener.connect(previous); 9584 break; 9585 } 9586 previous = current; 9587 current = current.next; 9588 } 9589 9590 // Not yet connected 9591 if (!listener.previous) 9592 { 9593 listener.connect(previous); 9594 } 9595 } 9596 9597 this._startIfPossible(); 9598 9599 return this; 9600 }; 9601 9602 /** 9603 * Removes any handlers matching the function and context parameters.
9604 * If no handlers are left after removing, then it cancels the animation frame. 9605 * 9606 * @param {Function} fn - The listener function to be removed 9607 * @param {*} [context] - The listener context to be removed 9608 * @returns {PIXI.Ticker} This instance of a ticker 9609 */ 9610 Ticker.prototype.remove = function remove (fn, context) 9611 { 9612 var listener = this._head.next; 9613 9614 while (listener) 9615 { 9616 // We found a match, lets remove it 9617 // no break to delete all possible matches 9618 // incase a listener was added 2+ times 9619 if (listener.match(fn, context)) 9620 { 9621 listener = listener.destroy(); 9622 } 9623 else 9624 { 9625 listener = listener.next; 9626 } 9627 } 9628 9629 if (!this._head.next) 9630 { 9631 this._cancelIfNeeded(); 9632 } 9633 9634 return this; 9635 }; 9636 9637 /** 9638 * Starts the ticker. If the ticker has listeners 9639 * a new animation frame is requested at this point. 9640 */ 9641 Ticker.prototype.start = function start () 9642 { 9643 if (!this.started) 9644 { 9645 this.started = true; 9646 this._requestIfNeeded(); 9647 } 9648 }; 9649 9650 /** 9651 * Stops the ticker. If the ticker has requested 9652 * an animation frame it is canceled at this point. 9653 */ 9654 Ticker.prototype.stop = function stop () 9655 { 9656 if (this.started) 9657 { 9658 this.started = false; 9659 this._cancelIfNeeded(); 9660 } 9661 }; 9662 9663 /** 9664 * Destroy the ticker and don't use after this. Calling 9665 * this method removes all references to internal events. 9666 */ 9667 Ticker.prototype.destroy = function destroy () 9668 { 9669 if (!this._protected) 9670 { 9671 this.stop(); 9672 9673 var listener = this._head.next; 9674 9675 while (listener) 9676 { 9677 listener = listener.destroy(true); 9678 } 9679 9680 this._head.destroy(); 9681 this._head = null; 9682 } 9683 }; 9684 9685 /** 9686 * Triggers an update. An update entails setting the 9687 * current {@link PIXI.Ticker#elapsedMS}, 9688 * the current {@link PIXI.Ticker#deltaTime}, 9689 * invoking all listeners with current deltaTime, 9690 * and then finally setting {@link PIXI.Ticker#lastTime} 9691 * with the value of currentTime that was provided. 9692 * This method will be called automatically by animation 9693 * frame callbacks if the ticker instance has been started 9694 * and listeners are added. 9695 * 9696 * @param {number} [currentTime=performance.now()] - the current time of execution 9697 */ 9698 Ticker.prototype.update = function update (currentTime) 9699 { 9700 if ( currentTime === void 0 ) { currentTime = performance.now(); } 9701 9702 var elapsedMS; 9703 9704 // If the difference in time is zero or negative, we ignore most of the work done here. 9705 // If there is no valid difference, then should be no reason to let anyone know about it. 9706 // A zero delta, is exactly that, nothing should update. 9707 // 9708 // The difference in time can be negative, and no this does not mean time traveling. 9709 // This can be the result of a race condition between when an animation frame is requested 9710 // on the current JavaScript engine event loop, and when the ticker's start method is invoked 9711 // (which invokes the internal _requestIfNeeded method). If a frame is requested before 9712 // _requestIfNeeded is invoked, then the callback for the animation frame the ticker requests, 9713 // can receive a time argument that can be less than the lastTime value that was set within 9714 // _requestIfNeeded. This difference is in microseconds, but this is enough to cause problems. 9715 // 9716 // This check covers this browser engine timing issue, as well as if consumers pass an invalid 9717 // currentTime value. This may happen if consumers opt-out of the autoStart, and update themselves. 9718 9719 if (currentTime > this.lastTime) 9720 { 9721 // Save uncapped elapsedMS for measurement 9722 elapsedMS = this.elapsedMS = currentTime - this.lastTime; 9723 9724 // cap the milliseconds elapsed used for deltaTime 9725 if (elapsedMS > this._maxElapsedMS) 9726 { 9727 elapsedMS = this._maxElapsedMS; 9728 } 9729 9730 elapsedMS *= this.speed; 9731 9732 // if not enough time has passed, exit the function. 9733 // We give an extra ms to elapsedMS for this check, because the nature of 9734 // request animation frame means that not all browsers will return precise values. 9735 // However, because rAF works based on v-sync, it's won't change the effective FPS. 9736 if (this._minElapsedMS && elapsedMS + 1 < this._minElapsedMS) 9737 { 9738 return; 9739 } 9740 9741 this.deltaMS = elapsedMS; 9742 this.deltaTime = this.deltaMS * settings.TARGET_FPMS; 9743 9744 // Cache a local reference, in-case ticker is destroyed 9745 // during the emit, we can still check for head.next 9746 var head = this._head; 9747 9748 // Invoke listeners added to internal emitter 9749 var listener = head.next; 9750 9751 while (listener) 9752 { 9753 listener = listener.emit(this.deltaTime); 9754 } 9755 9756 if (!head.next) 9757 { 9758 this._cancelIfNeeded(); 9759 } 9760 } 9761 else 9762 { 9763 this.deltaTime = this.deltaMS = this.elapsedMS = 0; 9764 } 9765 9766 this.lastTime = currentTime; 9767 }; 9768 9769 /** 9770 * The frames per second at which this ticker is running. 9771 * The default is approximately 60 in most modern browsers. 9772 * **Note:** This does not factor in the value of 9773 * {@link PIXI.Ticker#speed}, which is specific 9774 * to scaling {@link PIXI.Ticker#deltaTime}. 9775 * 9776 * @member {number} 9777 * @readonly 9778 */ 9779 prototypeAccessors$4.FPS.get = function () 9780 { 9781 return 1000 / this.elapsedMS; 9782 }; 9783 9784 /** 9785 * Manages the maximum amount of milliseconds allowed to 9786 * elapse between invoking {@link PIXI.Ticker#update}. 9787 * This value is used to cap {@link PIXI.Ticker#deltaTime}, 9788 * but does not effect the measured value of {@link PIXI.Ticker#FPS}. 9789 * When setting this property it is clamped to a value between 9790 * `0` and `PIXI.settings.TARGET_FPMS * 1000`. 9791 * 9792 * @member {number} 9793 * @default 10 9794 */ 9795 prototypeAccessors$4.minFPS.get = function () 9796 { 9797 return 1000 / this._maxElapsedMS; 9798 }; 9799 9800 prototypeAccessors$4.minFPS.set = function (fps) // eslint-disable-line require-jsdoc 9801 { 9802 // Minimum must be below the maxFPS 9803 var minFPS = Math.min(this.maxFPS, fps); 9804 9805 // Must be at least 0, but below 1 / settings.TARGET_FPMS 9806 var minFPMS = Math.min(Math.max(0, minFPS) / 1000, settings.TARGET_FPMS); 9807 9808 this._maxElapsedMS = 1 / minFPMS; 9809 }; 9810 9811 /** 9812 * Manages the minimum amount of milliseconds allowed to 9813 * elapse between invoking {@link PIXI.Ticker#update}. 9814 * This will effect the measured value of {@link PIXI.ticker.Ticker#FPS}. 9815 * When setting this property it is clamped to a value between 9816 * `1` and `TARGET_FPMS * 1000`. 9817 * 9818 * @member {number} 9819 * @default 60 9820 */ 9821 prototypeAccessors$4.maxFPS.get = function () 9822 { 9823 if (this._minElapsedMS) 9824 { 9825 return 1000 / this._minElapsedMS; 9826 } 9827 9828 return settings.TARGET_FPMS * 1000; 9829 }; 9830 9831 prototypeAccessors$4.maxFPS.set = function (fps) 9832 { 9833 if (fps / 1000 >= settings.TARGET_FPMS) 9834 { 9835 this._minElapsedMS = 0; 9836 } 9837 else 9838 { 9839 // Max must be at least the minFPS 9840 var maxFPS = Math.max(this.minFPS, fps); 9841 9842 // Must be at least 1, but below 1 / settings.TARGET_FPMS 9843 var maxFPMS = Math.min(Math.max(1, maxFPS) / 1000, settings.TARGET_FPMS); 9844 9845 this._minElapsedMS = 1 / maxFPMS; 9846 } 9847 }; 9848 9849 /** 9850 * The shared ticker instance used by {@link PIXI.AnimatedSprite} and by 9851 * {@link PIXI.VideoResource} to update animation frames / video textures. 9852 *
9853 * It may also be used by {@link PIXI.Application} if created with the `sharedTicker` option property set to true. 9854 * 9855 * The property {@link PIXI.Ticker#autoStart} is set to `true` for this instance. 9856 * Please follow the examples for usage, including how to opt-out of auto-starting the shared ticker. 9857 * 9858 * @example 9859 * let ticker = PIXI.Ticker.shared; 9860 * // Set this to prevent starting this ticker when listeners are added. 9861 * // By default this is true only for the PIXI.Ticker.shared instance. 9862 * ticker.autoStart = false; 9863 * // FYI, call this to ensure the ticker is stopped. It should be stopped 9864 * // if you have not attempted to render anything yet. 9865 * ticker.stop(); 9866 * // Call this when you are ready for a running shared ticker. 9867 * ticker.start(); 9868 * 9869 * @example 9870 * // You may use the shared ticker to render... 9871 * let renderer = PIXI.autoDetectRenderer(); 9872 * let stage = new PIXI.Container(); 9873 * document.body.appendChild(renderer.view); 9874 * ticker.add(function (time) { 9875 * renderer.render(stage); 9876 * }); 9877 * 9878 * @example 9879 * // Or you can just update it manually. 9880 * ticker.autoStart = false;
9881 * ticker.stop(); 9882 * function animate(time) { 9883 * ticker.update(time); 9884 * renderer.render(stage); 9885 * requestAnimationFrame(animate); 9886 * } 9887 * animate(performance.now()); 9888 * 9889 * @member {PIXI.Ticker} 9890 * @static 9891 */ 9892 staticAccessors$2.shared.get = function () 9893 { 9894 if (!Ticker._shared) 9895 { 9896 var shared = Ticker._shared = new Ticker(); 9897 9898 shared.autoStart = true; 9899 shared._protected = true; 9900 } 9901 9902 return Ticker._shared; 9903 }; 9904 9905 /** 9906 * The system ticker instance used by {@link PIXI.interaction.InteractionManager} and by 9907 * {@link PIXI.BasePrepare} for core timing functionality that shouldn't usually need to be paused, 9908 * unlike the `shared` ticker which drives visual animations and rendering which may want to be paused. 9909 * 9910 * The property {@link PIXI.Ticker#autoStart} is set to `true` for this instance. 9911 * 9912 * @member {PIXI.Ticker} 9913 * @static 9914 */ 9915 staticAccessors$2.system.get = function () 9916 { 9917 if (!Ticker._system) 9918 { 9919 var system = Ticker._system = new Ticker(); 9920 9921 system.autoStart = true; 9922 system._protected = true; 9923 } 9924 9925 return Ticker._system; 9926 }; 9927 9928 Object.defineProperties( Ticker.prototype, prototypeAccessors$4 ); 9929 Object.defineProperties( Ticker, staticAccessors$2 ); 9930 9931 /** 9932 * Middleware for for Application Ticker. 9933 * 9934 * @example 9935 * import {TickerPlugin} from '@pixi/ticker'; 9936 * import {Application} from '@pixi/app'; 9937 * Application.registerPlugin(TickerPlugin); 9938 * 9939 * @class 9940 * @memberof PIXI 9941 */ 9942 var TickerPlugin = function TickerPlugin () {}; 9943 9944 TickerPlugin.init = function init (options) 9945 { 9946 var this$1 = this; 9947 9948 // Set default 9949 options = Object.assign({ 9950 autoStart: true, 9951 sharedTicker: false, 9952 }, options); 9953 9954 // Create ticker setter 9955 Object.defineProperty(this, 'ticker', 9956 { 9957 set: function set(ticker) 9958 { 9959 if (this._ticker) 9960 { 9961 this._ticker.remove(this.render, this); 9962 } 9963 this._ticker = ticker; 9964 if (ticker) 9965 { 9966 ticker.add(this.render, this, UPDATE_PRIORITY.LOW); 9967 } 9968 }, 9969 get: function get() 9970 { 9971 return this._ticker; 9972 }, 9973 }); 9974 9975 /** 9976 * Convenience method for stopping the render. 9977 * 9978 * @method PIXI.Application#stop 9979 */ 9980 this.stop = function () { 9981 this$1._ticker.stop(); 9982 }; 9983 9984 /** 9985 * Convenience method for starting the render. 9986 * 9987 * @method PIXI.Application#start 9988 */ 9989 this.start = function () { 9990 this$1._ticker.start(); 9991 }; 9992 9993 /** 9994 * Internal reference to the ticker. 9995 * 9996 * @type {PIXI.Ticker} 9997 * @name _ticker 9998 * @memberof PIXI.Application# 9999 * @private 10000 */ 10001 this._ticker = null; 10002 10003 /** 10004 * Ticker for doing render updates. 10005 * 10006 * @type {PIXI.Ticker} 10007 * @name ticker 10008 * @memberof PIXI.Application# 10009 * @default PIXI.Ticker.shared 10010 */ 10011 this.ticker = options.sharedTicker ? Ticker.shared : new Ticker(); 10012 10013 // Start the rendering 10014 if (options.autoStart) 10015 { 10016 this.start(); 10017 } 10018 }; 10019 10020 /** 10021 * Clean up the ticker, scoped to application. 10022 * 10023 * @static 10024 * @private 10025 */ 10026 TickerPlugin.destroy = function destroy () 10027 { 10028 if (this._ticker) 10029 { 10030 var oldTicker = this._ticker; 10031 10032 this.ticker = null; 10033 oldTicker.destroy(); 10034 } 10035 }; 10036 10037 /*! 10038 * @pixi/core - v5.0.0-rc.3 10039 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 10040 * 10041 * @pixi/core is licensed under the MIT License. 10042 * http://www.opensource.org/licenses/mit-license 10043 */ 10044 10045 /** 10046 * Base resource class for textures that manages validation and uploading, depending on its type. 10047 * 10048 * Uploading of a base texture to the GPU is required. 10049 * 10050 * @class 10051 * @memberof PIXI.resources 10052 */ 10053 var Resource = function Resource(width, height) 10054 { 10055 if ( width === void 0 ) { width = 0; } 10056 if ( height === void 0 ) { height = 0; } 10057 10058 /** 10059 * Internal width of the resource 10060 * @member {number} 10061 * @protected 10062 */ 10063 this._width = width; 10064 10065 /** 10066 * Internal height of the resource 10067 * @member {number} 10068 * @protected 10069 */ 10070 this._height = height; 10071 10072 /** 10073 * If resource has been destroyed 10074 * @member {boolean} 10075 * @readonly 10076 * @default false 10077 */ 10078 this.destroyed = false;
10079 10080 /** 10081 * `true` if resource is created by BaseTexture 10082 * useful for doing cleanup with BaseTexture destroy 10083 * and not cleaning up resources that were created 10084 * externally. 10085 * @member {boolean} 10086 * @protected 10087 */ 10088 this.internal = false; 10089 10090 /** 10091 * Mini-runner for handling resize events 10092 * 10093 * @member {Runner} 10094 * @private 10095 */ 10096 this.onResize = new Runner('setRealSize', 2); 10097 10098 /** 10099 * Mini-runner for handling update events 10100 * 10101 * @member {Runner} 10102 * @private 10103 */ 10104 this.onUpdate = new Runner('update'); 10105 }; 10106 10107 var prototypeAccessors$5 = { valid: { configurable: true },width: { configurable: true },height: { configurable: true } }; 10108 10109 /** 10110 * Bind to a parent BaseTexture 10111 * 10112 * @param {PIXI.BaseTexture} baseTexture - Parent texture 10113 */ 10114 Resource.prototype.bind = function bind (baseTexture) 10115 { 10116 this.onResize.add(baseTexture); 10117 this.onUpdate.add(baseTexture); 10118 10119 // Call a resize immediate if we already 10120 // have the width and height of the resource 10121 if (this._width || this._height) 10122 { 10123 this.onResize.run(this._width, this._height); 10124 } 10125 }; 10126 10127 /** 10128 * Unbind to a parent BaseTexture 10129 * 10130 * @param {PIXI.BaseTexture} baseTexture - Parent texture 10131 */ 10132 Resource.prototype.unbind = function unbind (baseTexture) 10133 { 10134 this.onResize.remove(baseTexture); 10135 this.onUpdate.remove(baseTexture); 10136 }; 10137 10138 /** 10139 * Trigger a resize event 10140 */ 10141 Resource.prototype.resize = function resize (width, height) 10142 { 10143 if (width !== this._width || height !== this._height) 10144 { 10145 this._width = width; 10146 this._height = height; 10147 this.onResize.run(width, height); 10148 } 10149 }; 10150 10151 /** 10152 * Has been validated 10153 * @readonly 10154 * @member {boolean} 10155 */ 10156 prototypeAccessors$5.valid.get = function () 10157 { 10158 return !!this._width && !!this._height; 10159 }; 10160 10161 /** 10162 * Has been updated trigger event 10163 */ 10164 Resource.prototype.update = function update () 10165 { 10166 if (!this.destroyed) 10167 { 10168 this.onUpdate.run(); 10169 } 10170 }; 10171 10172 /** 10173 * This can be overridden to start preloading a resource 10174 * or do any other prepare step. 10175 * @protected 10176 * @return {Promise<void>} Handle the validate event 10177 */ 10178 Resource.prototype.load = function load () 10179 { 10180 return Promise.resolve(); 10181 }; 10182 10183 /** 10184 * The width of the resource. 10185 * 10186 * @member {number} 10187 * @readonly 10188 */ 10189 prototypeAccessors$5.width.get = function () 10190 { 10191 return this._width; 10192 }; 10193 10194 /** 10195 * The height of the resource. 10196 * 10197 * @member {number} 10198 * @readonly 10199 */ 10200 prototypeAccessors$5.height.get = function () 10201 { 10202 return this._height; 10203 }; 10204 10205 /** 10206 * Uploads the texture or returns false if it cant for some reason. Override this. 10207 * 10208 * @param {PIXI.Renderer} renderer - yeah, renderer! 10209 * @param {PIXI.BaseTexture} baseTexture - the texture 10210 * @param {PIXI.GLTexture} glTexture - texture instance for this webgl context 10211 * @returns {boolean} true is success 10212 */ 10213 Resource.prototype.upload = function upload (renderer, baseTexture, glTexture) // eslint-disable-line no-unused-vars 10214 { 10215 return false; 10216 }; 10217 10218 /** 10219 * Set the style, optional to override 10220 * 10221 * @param {PIXI.Renderer} renderer - yeah, renderer! 10222 * @param {PIXI.BaseTexture} baseTexture - the texture 10223 * @param {PIXI.GLTexture} glTexture - texture instance for this webgl context 10224 * @returns {boolean} `true` is success 10225 */ 10226 Resource.prototype.style = function style (renderer, baseTexture, glTexture) // eslint-disable-line no-unused-vars 10227 { 10228 return false; 10229 }; 10230 10231 /** 10232 * Clean up anything, this happens when destroying is ready. 10233 * 10234 * @protected 10235 */ 10236 Resource.prototype.dispose = function dispose () 10237 { 10238 // override 10239 }; 10240 10241 /** 10242 * Call when destroying resource, unbind any BaseTexture object 10243 * before calling this method, as reference counts are maintained 10244 * internally. 10245 */ 10246 Resource.prototype.destroy = function destroy () 10247 { 10248 if (!this.destroyed) 10249 { 10250 this.onResize.removeAll(); 10251 this.onResize = null; 10252 this.onUpdate.removeAll(); 10253 this.onUpdate = null; 10254 this.destroyed = true; 10255 this.dispose(); 10256 } 10257 }; 10258 10259 Object.defineProperties( Resource.prototype, prototypeAccessors$5 ); 10260 10261 /** 10262 * Base for all the image/canvas resources 10263 * @class 10264 * @extends PIXI.resources.Resource 10265 * @memberof PIXI.resources 10266 */ 10267 var BaseImageResource = /*@__PURE__*/(function (Resource) { 10268 function BaseImageResource(source) 10269 { 10270 Resource.call(this, source.width, source.height); 10271 10272 /** 10273 * The source element 10274 * @member {HTMLImageElement|HTMLCanvasElement|HTMLVideoElement|SVGElement} 10275 * @readonly 10276 */ 10277 this.source = source; 10278 } 10279 10280 if ( Resource ) { BaseImageResource.__proto__ = Resource; } 10281 BaseImageResource.prototype = Object.create( Resource && Resource.prototype ); 10282 BaseImageResource.prototype.constructor = BaseImageResource; 10283 10284 /** 10285 * Set cross origin based detecting the url and the crossorigin 10286 * @protected 10287 * @param {HTMLElement} element - Element to apply crossOrigin 10288 * @param {string} url - URL to check 10289 * @param {boolean|string} [crossorigin=true] - Cross origin value to use 10290 */ 10291 BaseImageResource.crossOrigin = function crossOrigin (element, url, crossorigin) 10292 { 10293 if (crossorigin === undefined && url.indexOf('data:') !== 0) 10294 { 10295 element.crossOrigin = determineCrossOrigin(url); 10296 } 10297 else if (crossorigin !== false) 10298 { 10299 element.crossOrigin = typeof crossorigin === 'string' ? crossorigin : 'anonymous'; 10300 } 10301 }; 10302 10303 /** 10304 * Upload the texture to the GPU. 10305 * @param {PIXI.Renderer} renderer Upload to the renderer 10306 * @param {PIXI.BaseTexture} baseTexture Reference to parent texture 10307 * @param {PIXI.GLTexture} glTexture 10308 * @param {HTMLImageElement|HTMLCanvasElement|HTMLVideoElement|SVGElement} [source] (optional) 10309 * @returns {boolean} true is success 10310 */ 10311 BaseImageResource.prototype.upload = function upload (renderer, baseTexture, glTexture, source) 10312 { 10313 var gl = renderer.gl; 10314 var width = baseTexture.realWidth; 10315 var height = baseTexture.realHeight; 10316 10317 source = source || this.source; 10318 10319 gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, baseTexture.premultiplyAlpha); 10320 10321 if (baseTexture.target === gl.TEXTURE_2D && glTexture.width === width && glTexture.height === height) 10322 { 10323 gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, baseTexture.format, baseTexture.type, source); 10324 } 10325 else 10326 { 10327 glTexture.width = width; 10328 glTexture.height = height; 10329 10330 gl.texImage2D(baseTexture.target, 0, baseTexture.format, baseTexture.format, baseTexture.type, source); 10331 } 10332 10333 return true; 10334 }; 10335 10336 /** 10337 * Destroy this BaseImageResource 10338 * @override 10339 * @param {PIXI.BaseTexture} [fromTexture] Optional base texture 10340 * @return {boolean} Destroy was successful 10341 */ 10342 BaseImageResource.prototype.dispose = function dispose () 10343 { 10344 this.source = null; 10345 }; 10346 10347 return BaseImageResource; 10348 }(Resource)); 10349 10350 /** 10351 * Resource type for HTMLImageElement. 10352 * @class 10353 * @extends PIXI.resources.BaseImageResource 10354 * @memberof PIXI.resources 10355 */ 10356 var ImageResource = /*@__PURE__*/(function (BaseImageResource) { 10357 function ImageResource(source, options) 10358 { 10359 options = options || {}; 10360 10361 if (!(source instanceof HTMLImageElement)) 10362 { 10363 var imageElement = new Image(); 10364 10365 BaseImageResource.crossOrigin(imageElement, source, options.crossorigin); 10366 10367 imageElement.src = source; 10368 source = imageElement; 10369 } 10370 10371 BaseImageResource.call(this, source); 10372 10373 /** 10374 * URL of the image source 10375 * @member {string} 10376 */ 10377 this.url = source.src; 10378 10379 /** 10380 * When process is completed 10381 * @member {Promise<void>} 10382 * @private 10383 */ 10384 this._process = null; 10385 10386 /** 10387 * If the image should be disposed after upload 10388 * @member {boolean} 10389 * @default false 10390 */ 10391 this.preserveBitmap = false;
10392 10393 /** 10394 * If capable, convert the image using createImageBitmap API 10395 * @member {boolean} 10396 * @default PIXI.settings.CREATE_IMAGE_BITMAP 10397 */ 10398 this.createBitmap = options.createBitmap !== false && settings.CREATE_IMAGE_BITMAP && !!window.createImageBitmap; 10399 10400 /** 10401 * Controls texture premultiplyAlpha field 10402 * Copies from options 10403 * @member {boolean|null} 10404 * @readonly 10405 */ 10406 this.premultiplyAlpha = options.premultiplyAlpha !== false; 10407 10408 /** 10409 * The ImageBitmap element created for HTMLImageElement 10410 * @member {ImageBitmap} 10411 * @default null 10412 */ 10413 this.bitmap = null; 10414 10415 /** 10416 * Promise when loading 10417 * @member {Promise<void>} 10418 * @private 10419 * @default null 10420 */ 10421 this._load = null; 10422 10423 if (options.autoLoad !== false) 10424 { 10425 this.load(); 10426 } 10427 } 10428 10429 if ( BaseImageResource ) { ImageResource.__proto__ = BaseImageResource; } 10430 ImageResource.prototype = Object.create( BaseImageResource && BaseImageResource.prototype ); 10431 ImageResource.prototype.constructor = ImageResource; 10432 10433 /** 10434 * returns a promise when image will be loaded and processed 10435 * 10436 * @param {boolean} [createBitmap=true] whether process image into bitmap 10437 * @returns {Promise<void>} 10438 */ 10439 ImageResource.prototype.load = function load (createBitmap) 10440 { 10441 var this$1 = this; 10442 10443 if (createBitmap !== undefined) 10444 { 10445 this.createBitmap = createBitmap; 10446 } 10447 10448 if (this._load) 10449 { 10450 return this._load; 10451 } 10452 10453 this._load = new Promise(function (resolve) { 10454 this$1.url = this$1.source.src; 10455 var ref = this$1; 10456 var source = ref.source; 10457 10458 var completed = function () { 10459 if (this$1.destroyed) 10460 { 10461 return; 10462 } 10463 source.onload = null; 10464 source.onerror = null; 10465 10466 this$1.resize(source.width, source.height); 10467 this$1._load = null; 10468 10469 if (this$1.createBitmap) 10470 { 10471 resolve(this$1.process()); 10472 } 10473 else 10474 { 10475 resolve(this$1); 10476 } 10477 }; 10478 10479 if (source.complete && source.src) 10480 { 10481 completed(); 10482 } 10483 else 10484 { 10485 source.onload = completed; 10486 } 10487 }); 10488 10489 return this._load; 10490 }; 10491 10492 /** 10493 * Called when we need to convert image into BitmapImage. 10494 * Can be called multiple times, real promise is cached inside. 10495 * 10496 * @returns {Promise<void>} cached promise to fill that bitmap 10497 */ 10498 ImageResource.prototype.process = function process () 10499 { 10500 var this$1 = this; 10501 10502 if (this._process !== null) 10503 { 10504 return this._process; 10505 } 10506 if (this.bitmap !== null || !window.createImageBitmap) 10507 { 10508 return Promise.resolve(this); 10509 } 10510 10511 this._process = window.createImageBitmap(this.source, 10512 0, 0, this.source.width, this.source.height, 10513 { 10514 premultiplyAlpha: this.premultiplyAlpha ? 'premultiply' : 'none', 10515 }) 10516 .then(function (bitmap) { 10517 if (this$1.destroyed) 10518 { 10519 return Promise.reject(); 10520 } 10521 this$1.bitmap = bitmap; 10522 this$1.update(); 10523 this$1._process = null; 10524 10525 return Promise.resolve(this$1); 10526 }); 10527 10528 return this._process; 10529 }; 10530 10531 /** 10532 * Upload the image resource to GPU. 10533 * 10534 * @param {PIXI.Renderer} renderer - Renderer to upload to 10535 * @param {PIXI.BaseTexture} baseTexture - BaseTexture for this resource 10536 * @param {PIXI.GLTexture} glTexture - GLTexture to use 10537 * @returns {boolean} true is success 10538 */ 10539 ImageResource.prototype.upload = function upload (renderer, baseTexture, glTexture) 10540 { 10541 baseTexture.premultiplyAlpha = this.premultiplyAlpha; 10542 10543 if (!this.createBitmap) 10544 { 10545 return BaseImageResource.prototype.upload.call(this, renderer, baseTexture, glTexture); 10546 } 10547 if (!this.bitmap) 10548 { 10549 // yeah, ignore the output 10550 this.process(); 10551 if (!this.bitmap) 10552 { 10553 return false;
10554 } 10555 } 10556 10557 BaseImageResource.prototype.upload.call(this, renderer, baseTexture, glTexture, this.bitmap); 10558 10559 if (!this.preserveBitmap) 10560 { 10561 // checks if there are other renderers that possibly need this bitmap 10562 10563 var flag = true; 10564 10565 for (var key in baseTexture._glTextures) 10566 { 10567 var otherTex = baseTexture._glTextures[key]; 10568 10569 if (otherTex !== glTexture && otherTex.dirtyId !== baseTexture.dirtyId) 10570 { 10571 flag = false; 10572 break; 10573 } 10574 } 10575 10576 if (flag) 10577 { 10578 if (this.bitmap.close) 10579 { 10580 this.bitmap.close(); 10581 } 10582 10583 this.bitmap = null; 10584 } 10585 } 10586 10587 return true; 10588 }; 10589 10590 /** 10591 * Destroys this texture 10592 * @override 10593 */ 10594 ImageResource.prototype.dispose = function dispose () 10595 { 10596 BaseImageResource.prototype.dispose.call(this); 10597 10598 if (this.bitmap) 10599 { 10600 this.bitmap.close(); 10601 this.bitmap = null; 10602 } 10603 this._process = null; 10604 this._load = null; 10605 }; 10606 10607 return ImageResource; 10608 }(BaseImageResource)); 10609 10610 /** 10611 * Collection of installed resource types, class must extend {@link PIXI.resources.Resource}. 10612 * @example 10613 * class CustomResource extends PIXI.resources.Resource { 10614 * // MUST have source, options constructor signature 10615 * // for auto-detected resources to be created. 10616 * constructor(source, options) { 10617 * super(); 10618 * } 10619 * upload(renderer, baseTexture, glTexture) { 10620 * // upload with GL 10621 * return true; 10622 * } 10623 * // used to auto-detect resource 10624 * static test(source, extension) { 10625 * return extension === 'xyz'|| source instanceof SomeClass; 10626 * } 10627 * } 10628 * // Install the new resource type 10629 * PIXI.resources.INSTALLED.push(CustomResource); 10630 * 10631 * @name PIXI.resources.INSTALLED 10632 * @type {Array<*>} 10633 * @static 10634 * @readonly 10635 */ 10636 var INSTALLED = []; 10637 10638 /** 10639 * Create a resource element from a single source element. This 10640 * auto-detects which type of resource to create. All resources that 10641 * are auto-detectable must have a static `test` method and a constructor 10642 * with the arguments `(source, options?)`. Currently, the supported 10643 * resources for auto-detection include: 10644 * - {@link PIXI.resources.ImageResource} 10645 * - {@link PIXI.resources.CanvasResource} 10646 * - {@link PIXI.resources.VideoResource} 10647 * - {@link PIXI.resources.SVGResource} 10648 * - {@link PIXI.resources.BufferResource} 10649 * @static 10650 * @function PIXI.resources.autoDetectResource 10651 * @param {string|*} source - Resource source, this can be the URL to the resource, 10652 * a typed-array (for BufferResource), HTMLVideoElement, SVG data-uri 10653 * or any other resource that can be auto-detected. If not resource is 10654 * detected, it's assumed to be an ImageResource. 10655 * @param {object} [options] - Pass-through options to use for Resource 10656 * @param {number} [options.width] - BufferResource's width 10657 * @param {number} [options.height] - BufferResource's height 10658 * @param {boolean} [options.autoLoad=true] - Image, SVG and Video flag to start loading 10659 * @param {number} [options.scale=1] - SVG source scale 10660 * @param {boolean} [options.createBitmap=true] - Image option to create Bitmap object 10661 * @param {boolean} [options.crossorigin=true] - Image and Video option to set crossOrigin 10662 * @param {boolean} [options.autoPlay=true] - Video option to start playing video immediately 10663 * @param {number} [options.updateFPS=0] - Video option to update how many times a second the 10664 * texture should be updated from the video. Leave at 0 to update at every render 10665 * @return {PIXI.resources.Resource} The created resource. 10666 */ 10667 function autoDetectResource(source, options) 10668 { 10669 if (!source) 10670 { 10671 return null; 10672 } 10673 10674 var extension = ''; 10675 10676 if (typeof source === 'string') 10677 { 10678 // search for file extension: period, 3-4 chars, then ?, # or EOL 10679 var result = (/\.(\w{3,4})(?:$|\?|#)/i).exec(source); 10680 10681 if (result) 10682 { 10683 extension = result[1].toLowerCase(); 10684 } 10685 } 10686 10687 for (var i = INSTALLED.length - 1; i >= 0; --i) 10688 { 10689 var ResourcePlugin = INSTALLED[i]; 10690 10691 if (ResourcePlugin.test && ResourcePlugin.test(source, extension)) 10692 { 10693 return new ResourcePlugin(source, options); 10694 } 10695 } 10696 10697 // When in doubt: probably an image 10698 // might be appropriate to throw an error or return null 10699 return new ImageResource(source, options); 10700 } 10701 10702 /** 10703 * @interface SharedArrayBuffer 10704 */ 10705 10706 /** 10707 * Buffer resource with data of typed array.
10708 * @class 10709 * @extends PIXI.resources.Resource 10710 * @memberof PIXI.resources 10711 */ 10712 var BufferResource = /*@__PURE__*/(function (Resource) { 10713 function BufferResource(source, options) 10714 { 10715 var ref = options || {}; 10716 var width = ref.width; 10717 var height = ref.height; 10718 10719 if (!width || !height) 10720 { 10721 throw new Error('BufferResource width or height invalid'); 10722 } 10723 10724 Resource.call(this, width, height); 10725 10726 /** 10727 * Source array 10728 * Cannot be ClampedUint8Array because it cant be uploaded to WebGL 10729 * 10730 * @member {Float32Array|Uint8Array|Uint32Array} 10731 */ 10732 this.data = source; 10733 } 10734 10735 if ( Resource ) { BufferResource.__proto__ = Resource; } 10736 BufferResource.prototype = Object.create( Resource && Resource.prototype ); 10737 BufferResource.prototype.constructor = BufferResource; 10738 10739 /** 10740 * Upload the texture to the GPU. 10741 * @param {PIXI.Renderer} renderer Upload to the renderer 10742 * @param {PIXI.BaseTexture} baseTexture Reference to parent texture 10743 * @param {PIXI.GLTexture} glTexture glTexture 10744 * @returns {boolean} true is success 10745 */ 10746 BufferResource.prototype.upload = function upload (renderer, baseTexture, glTexture) 10747 { 10748 var gl = renderer.gl; 10749 10750 gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, baseTexture.premultiplyAlpha); 10751 10752 if (glTexture.width === baseTexture.width && glTexture.height === baseTexture.height) 10753 { 10754 gl.texSubImage2D( 10755 baseTexture.target, 10756 0, 10757 0, 10758 0, 10759 baseTexture.width, 10760 baseTexture.height, 10761 baseTexture.format, 10762 baseTexture.type, 10763 this.data 10764 ); 10765 } 10766 else 10767 { 10768 glTexture.width = baseTexture.width; 10769 glTexture.height = baseTexture.height; 10770 10771 var internalFormat = baseTexture.format; 10772 10773 // guess sized format by type and format 10774 // https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/texImage2D 10775 if (renderer.context.webGLVersion === 2 10776 && baseTexture.type === renderer.gl.FLOAT 10777 && baseTexture.format === renderer.gl.RGBA) 10778 { 10779 internalFormat = renderer.gl.RGBA32F; 10780 } 10781 10782 gl.texImage2D( 10783 baseTexture.target, 10784 0, 10785 internalFormat, 10786 baseTexture.width, 10787 baseTexture.height, 10788 0, 10789 baseTexture.format, 10790 baseTexture.type, 10791 this.data 10792 ); 10793 } 10794 10795 return true; 10796 }; 10797 10798 /** 10799 * Destroy and don't use after this 10800 * @override 10801 */ 10802 BufferResource.prototype.dispose = function dispose () 10803 { 10804 this.data = null; 10805 }; 10806 10807 /** 10808 * Used to auto-detect the type of resource. 10809 * 10810 * @static 10811 * @param {*} source - The source object 10812 * @return {boolean} `true` if <canvas> 10813 */ 10814 BufferResource.test = function test (source) 10815 { 10816 return source instanceof Float32Array 10817 || source instanceof Uint8Array 10818 || source instanceof Uint32Array; 10819 }; 10820 10821 return BufferResource; 10822 }(Resource)); 10823 10824 var defaultBufferOptions = { 10825 scaleMode: SCALE_MODES.NEAREST, 10826 format: FORMATS.RGBA, 10827 premultiplyAlpha: false, 10828 }; 10829 10830 /** 10831 * A Texture stores the information that represents an image. 10832 * All textures have a base texture, which contains information about the source. 10833 * Therefore you can have many textures all using a single BaseTexture 10834 * 10835 * @class 10836 * @extends PIXI.utils.EventEmitter 10837 * @memberof PIXI 10838 * @param {PIXI.resources.Resource|string|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} [resource=null] 10839 * The current resource to use, for things that aren't Resource objects, will be converted 10840 * into a Resource. 10841 * @param {Object} [options] - Collection of options 10842 * @param {PIXI.MIPMAP_MODES} [options.mipmap=PIXI.settings.MIPMAP_TEXTURES] - If mipmapping is enabled for texture 10843 * @param {PIXI.WRAP_MODES} [options.wrapMode=PIXI.settings.WRAP_MODE] - Wrap mode for textures 10844 * @param {PIXI.SCALE_MODES} [options.scaleMode=PIXI.settings.SCALE_MODE] - Default scale mode, linear, nearest 10845 * @param {PIXI.FORMATS} [options.format=PIXI.FORMATS.RGBA] - GL format type 10846 * @param {PIXI.TYPES} [options.type=PIXI.TYPES.UNSIGNED_BYTE] - GL data type 10847 * @param {PIXI.TARGETS} [options.target=PIXI.TARGETS.TEXTURE_2D] - GL texture target 10848 * @param {boolean} [options.premultiplyAlpha=true] - Pre multiply the image alpha 10849 * @param {number} [options.width=0] - Width of the texture 10850 * @param {number} [options.height=0] - Height of the texture 10851 * @param {object} [options.resourceOptions] - Optional resource options, 10852 * see {@link PIXI.resources.autoDetectResource autoDetectResource} 10853 */ 10854 var BaseTexture = /*@__PURE__*/(function (EventEmitter) { 10855 function BaseTexture(resource, options) 10856 { 10857 if ( resource === void 0 ) { resource = null; } 10858 if ( options === void 0 ) { options = null; } 10859 10860 EventEmitter.call(this); 10861 10862 options = options || {}; 10863 10864 var premultiplyAlpha = options.premultiplyAlpha; 10865 var mipmap = options.mipmap; 10866 var scaleMode = options.scaleMode; 10867 var width = options.width; 10868 var height = options.height; 10869 var wrapMode = options.wrapMode; 10870 var format = options.format; 10871 var type = options.type; 10872 var target = options.target; 10873 var resolution = options.resolution; 10874 var resourceOptions = options.resourceOptions; 10875 10876 // Convert the resource to a Resource object 10877 if (resource && !(resource instanceof Resource)) 10878 { 10879 resource = autoDetectResource(resource, resourceOptions); 10880 resource.internal = true; 10881 } 10882 10883 /** 10884 * The width of the base texture set when the image has loaded 10885 * 10886 * @readonly 10887 * @member {number} 10888 */ 10889 this.width = width || 0; 10890 10891 /** 10892 * The height of the base texture set when the image has loaded 10893 * 10894 * @readonly 10895 * @member {number} 10896 */ 10897 this.height = height || 0; 10898 10899 /** 10900 * The resolution / device pixel ratio of the texture 10901 * 10902 * @member {number} 10903 * @default PIXI.settings.RESOLUTION 10904 */ 10905 this.resolution = resolution || settings.RESOLUTION; 10906 10907 /** 10908 * Mipmap mode of the texture, affects downscaled images 10909 * 10910 * @member {PIXI.MIPMAP_MODES} 10911 * @default PIXI.settings.MIPMAP_TEXTURES 10912 */ 10913 this.mipmap = mipmap !== undefined ? mipmap : settings.MIPMAP_TEXTURES; 10914 10915 /** 10916 * How the texture wraps 10917 * @member {number} 10918 */ 10919 this.wrapMode = wrapMode || settings.WRAP_MODE; 10920 10921 /** 10922 * The scale mode to apply when scaling this texture 10923 * 10924 * @member {PIXI.SCALE_MODES} 10925 * @default PIXI.settings.SCALE_MODE 10926 */ 10927 this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; 10928 10929 /** 10930 * The pixel format of the texture 10931 * 10932 * @member {PIXI.FORMATS} 10933 * @default PIXI.FORMATS.RGBA 10934 */ 10935 this.format = format || FORMATS.RGBA; 10936 10937 /** 10938 * The type of resource data 10939 * 10940 * @member {PIXI.TYPES} 10941 * @default PIXI.TYPES.UNSIGNED_BYTE 10942 */ 10943 this.type = type || TYPES.UNSIGNED_BYTE; 10944 10945 /** 10946 * The target type 10947 * 10948 * @member {PIXI.TARGETS} 10949 * @default PIXI.TARGETS.TEXTURE_2D 10950 */ 10951 this.target = target || TARGETS.TEXTURE_2D; 10952 10953 /** 10954 * Set to true to enable pre-multiplied alpha 10955 * 10956 * @member {boolean} 10957 * @default true 10958 */ 10959 this.premultiplyAlpha = premultiplyAlpha !== false; 10960 10961 /** 10962 * Global unique identifier for this BaseTexture 10963 * 10964 * @member {string} 10965 * @protected 10966 */ 10967 this.uid = uid(); 10968 10969 /**
10970 * TODO: fill in description 10971 * 10972 * @member {number} 10973 * @protected 10974 */ 10975 this.touched = 0; 10976 10977 /** 10978 * Whether or not the texture is a power of two, try to use power of two textures as much 10979 * as you can 10980 * 10981 * @readonly 10982 * @member {boolean} 10983 * @default false 10984 */ 10985 this.isPowerOfTwo = false; 10986 this._refreshPOT(); 10987 10988 /** 10989 * The map of render context textures where this is bound 10990 * 10991 * @member {Object} 10992 * @private 10993 */ 10994 this._glTextures = {}; 10995 10996 /** 10997 * Used by TextureSystem to only update texture to the GPU when needed. 10998 * 10999 * @protected 11000 * @member {number} 11001 */ 11002 this.dirtyId = 0; 11003 11004 /** 11005 * Used by TextureSystem to only update texture style when needed. 11006 * 11007 * @protected 11008 * @member {number} 11009 */ 11010 this.dirtyStyleId = 0; 11011 11012 /** 11013 * Currently default cache ID. 11014 * 11015 * @member {string} 11016 */ 11017 this.cacheId = null; 11018 11019 /** 11020 * Generally speaking means when resource is loaded. 11021 * @readonly 11022 * @member {boolean} 11023 */ 11024 this.valid = width > 0 && height > 0; 11025 11026 /** 11027 * The collection of alternative cache ids, since some BaseTextures 11028 * can have more than one ID, short name and longer full URL 11029 * 11030 * @member {Array<string>} 11031 * @readonly 11032 */ 11033 this.textureCacheIds = []; 11034 11035 /** 11036 * Flag if BaseTexture has been destroyed. 11037 * 11038 * @member {boolean} 11039 * @readonly 11040 */ 11041 this.destroyed = false; 11042 11043 /** 11044 * The resource used by this BaseTexture, there can only 11045 * be one resource per BaseTexture, but textures can share 11046 * resources. 11047 * 11048 * @member {PIXI.resources.Resource} 11049 * @readonly 11050 */ 11051 this.resource = null; 11052 11053 /** 11054 * Fired when a not-immediately-available source finishes loading. 11055 * 11056 * @protected 11057 * @event PIXI.BaseTexture#loaded 11058 * @param {PIXI.BaseTexture} baseTexture - Resource loaded. 11059 */ 11060 11061 /** 11062 * Fired when a not-immediately-available source fails to load. 11063 * 11064 * @protected 11065 * @event PIXI.BaseTexture#error 11066 * @param {PIXI.BaseTexture} baseTexture - Resource errored. 11067 */ 11068 11069 /** 11070 * Fired when BaseTexture is updated. 11071 * 11072 * @protected 11073 * @event PIXI.BaseTexture#loaded 11074 * @param {PIXI.BaseTexture} baseTexture - Resource loaded. 11075 */ 11076 11077 /** 11078 * Fired when BaseTexture is destroyed. 11079 * 11080 * @protected 11081 * @event PIXI.BaseTexture#error 11082 * @param {PIXI.BaseTexture} baseTexture - Resource errored. 11083 */ 11084 11085 /** 11086 * Fired when BaseTexture is updated. 11087 * 11088 * @protected 11089 * @event PIXI.BaseTexture#update 11090 * @param {PIXI.BaseTexture} baseTexture - Instance of texture being updated. 11091 */ 11092 11093 /** 11094 * Fired when BaseTexture is destroyed. 11095 * 11096 * @protected 11097 * @event PIXI.BaseTexture#dispose 11098 * @param {PIXI.BaseTexture} baseTexture - Instance of texture being destroyed. 11099 */ 11100 11101 // Set the resource 11102 this.setResource(resource); 11103 } 11104 11105 if ( EventEmitter ) { BaseTexture.__proto__ = EventEmitter; } 11106 BaseTexture.prototype = Object.create( EventEmitter && EventEmitter.prototype ); 11107 BaseTexture.prototype.constructor = BaseTexture; 11108 11109 var prototypeAccessors = { realWidth: { configurable: true },realHeight: { configurable: true } }; 11110 11111 /** 11112 * Pixel width of the source of this texture 11113 * 11114 * @readonly 11115 * @member {number} 11116 */ 11117 prototypeAccessors.realWidth.get = function () 11118 { 11119 return this.width * this.resolution; 11120 }; 11121 11122 /** 11123 * Pixel height of the source of this texture 11124 * 11125 * @readonly 11126 * @member {number} 11127 */ 11128 prototypeAccessors.realHeight.get = function () 11129 { 11130 return this.height * this.resolution; 11131 }; 11132 11133 /** 11134 * Changes style options of BaseTexture 11135 * 11136 * @param {PIXI.SCALE_MODES} [scaleMode] - Pixi scalemode 11137 * @param {PIXI.MIPMAP_MODES} [mipmap] - enable mipmaps 11138 * @returns {BaseTexture} this 11139 */ 11140 BaseTexture.prototype.setStyle = function setStyle (scaleMode, mipmap) 11141 { 11142 var dirty; 11143 11144 if (scaleMode !== undefined && scaleMode !== this.scaleMode) 11145 { 11146 this.scaleMode = scaleMode; 11147 dirty = true; 11148 } 11149 11150 if (mipmap !== undefined && mipmap !== this.mipmap) 11151 { 11152 this.mipmap = mipmap; 11153 dirty = true; 11154 } 11155
11156 if (dirty) 11157 { 11158 this.dirtyStyleId++; 11159 } 11160 11161 return this; 11162 }; 11163 11164 /** 11165 * Changes w/h/resolution. Texture becomes valid if width and height are greater than zero. 11166 * 11167 * @param {number} width Visual width 11168 * @param {number} height Visual height 11169 * @param {number} [resolution] Optionally set resolution 11170 * @returns {BaseTexture} this 11171 */ 11172 BaseTexture.prototype.setSize = function setSize (width, height, resolution) 11173 { 11174 this.resolution = resolution || this.resolution; 11175 this.width = width; 11176 this.height = height; 11177 this._refreshPOT(); 11178 this.update(); 11179 11180 return this; 11181 }; 11182 11183 /** 11184 * Sets real size of baseTexture, preserves current resolution. 11185 * 11186 * @param {number} realWidth Full rendered width 11187 * @param {number} realHeight Full rendered height 11188 * @param {number} [resolution] Optionally set resolution 11189 * @returns {BaseTexture} this 11190 */ 11191 BaseTexture.prototype.setRealSize = function setRealSize (realWidth, realHeight, resolution) 11192 { 11193 this.resolution = resolution || this.resolution; 11194 this.width = realWidth / this.resolution; 11195 this.height = realHeight / this.resolution; 11196 this._refreshPOT(); 11197 this.update(); 11198 11199 return this; 11200 }; 11201 11202 /** 11203 * Refresh check for isPowerOfTwo texture based on size 11204 * 11205 * @private 11206 */ 11207 BaseTexture.prototype._refreshPOT = function _refreshPOT () 11208 { 11209 this.isPowerOfTwo = isPow2(this.realWidth) && isPow2(this.realHeight); 11210 }; 11211 11212 /** 11213 * Changes resolution 11214 * 11215 * @param {number} [resolution] res 11216 * @returns {BaseTexture} this 11217 */ 11218 BaseTexture.prototype.setResolution = function setResolution (resolution) 11219 { 11220 var oldResolution = this.resolution; 11221 11222 if (oldResolution === resolution) 11223 { 11224 return this; 11225 } 11226 11227 this.resolution = resolution; 11228 11229 if (this.valid) 11230 { 11231 this.width = this.width * oldResolution / resolution; 11232 this.height = this.height * oldResolution / resolution; 11233 this.emit('update'); 11234 } 11235 11236 this._refreshPOT(); 11237 11238 return this; 11239 }; 11240 11241 /** 11242 * Sets the resource if it wasn't set. Throws error if resource already present 11243 * 11244 * @param {PIXI.resources.Resource} resource - that is managing this BaseTexture 11245 * @returns {BaseTexture} this 11246 */ 11247 BaseTexture.prototype.setResource = function setResource (resource) 11248 { 11249 if (this.resource === resource) 11250 { 11251 return this; 11252 } 11253 11254 if (this.resource) 11255 { 11256 throw new Error('Resource can be set only once'); 11257 } 11258 11259 resource.bind(this); 11260 11261 this.resource = resource; 11262 11263 return this; 11264 }; 11265 11266 /** 11267 * Invalidates the object. Texture becomes valid if width and height are greater than zero. 11268 */ 11269 BaseTexture.prototype.update = function update () 11270 { 11271 if (!this.valid) 11272 { 11273 if (this.width > 0 && this.height > 0) 11274 { 11275 this.valid = true; 11276 this.emit('loaded', this); 11277 this.emit('update', this); 11278 } 11279 } 11280 else 11281 { 11282 this.dirtyId++; 11283 this.dirtyStyleId++; 11284 this.emit('update', this); 11285 } 11286 }; 11287 11288 /** 11289 * Destroys this base texture. 11290 * The method stops if resource doesn't want this texture to be destroyed. 11291 * Removes texture from all caches. 11292 */ 11293 BaseTexture.prototype.destroy = function destroy () 11294 { 11295 // remove and destroy the resource 11296 if (this.resource) 11297 { 11298 this.resource.unbind(this); 11299 // only destroy resourced created internally 11300 if (this.resource.internal) 11301 { 11302 this.resource.destroy(); 11303 } 11304 this.resource = null; 11305 } 11306 11307 if (this.cacheId) 11308 { 11309 delete BaseTextureCache[this.cacheId]; 11310 delete TextureCache[this.cacheId]; 11311 11312 this.cacheId = null; 11313 } 11314 11315 // finally let the WebGL renderer know.. 11316 this.dispose(); 11317 11318 BaseTexture.removeFromCache(this); 11319 this.textureCacheIds = null; 11320 11321 this.destroyed = true; 11322 }; 11323 11324 /** 11325 * Frees the texture from WebGL memory without destroying this texture object. 11326 * This means you can still use the texture later which will upload it to GPU 11327 * memory again. 11328 * 11329 * @fires PIXI.BaseTexture#dispose 11330 */ 11331 BaseTexture.prototype.dispose = function dispose () 11332 {
11333 this.emit('dispose', this); 11334 }; 11335 11336 /** 11337 * Helper function that creates a base texture based on the source you provide. 11338 * The source can be - image url, image element, canvas element. If the 11339 * source is an image url or an image element and not in the base texture 11340 * cache, it will be created and loaded. 11341 * 11342 * @static 11343 * @param {string|HTMLImageElement|HTMLCanvasElement|SVGElement|HTMLVideoElement} source - The 11344 * source to create base texture from. 11345 * @param {object} [options] See {@link PIXI.BaseTexture}'s constructor for options. 11346 * @returns {PIXI.BaseTexture} The new base texture. 11347 */ 11348 BaseTexture.from = function from (source, options) 11349 { 11350 var cacheId = null; 11351 11352 if (typeof source === 'string') 11353 { 11354 cacheId = source; 11355 } 11356 else 11357 { 11358 if (!source._pixiId) 11359 { 11360 source._pixiId = "pixiid_" + (uid()); 11361 } 11362 11363 cacheId = source._pixiId; 11364 } 11365 11366 var baseTexture = BaseTextureCache[cacheId]; 11367 11368 if (!baseTexture) 11369 { 11370 baseTexture = new BaseTexture(source, options); 11371 baseTexture.cacheId = cacheId; 11372 BaseTexture.addToCache(baseTexture, cacheId); 11373 } 11374 11375 return baseTexture; 11376 }; 11377 11378 /** 11379 * Create a new BaseTexture with a BufferResource from a Float32Array. 11380 * RGBA values are floats from 0 to 1. 11381 * @static 11382 * @param {Float32Array|Uint8Array} buffer The optional array to use, if no data 11383 * is provided, a new Float32Array is created. 11384 * @param {number} width - Width of the resource 11385 * @param {number} height - Height of the resource 11386 * @param {object} [options] See {@link PIXI.BaseTexture}'s constructor for options. 11387 * @return {PIXI.BaseTexture} The resulting new BaseTexture 11388 */ 11389 BaseTexture.fromBuffer = function fromBuffer (buffer, width, height, options) 11390 { 11391 buffer = buffer || new Float32Array(width * height * 4); 11392 11393 var resource = new BufferResource(buffer, { width: width, height: height }); 11394 var type = buffer instanceof Float32Array ? TYPES.FLOAT : TYPES.UNSIGNED_BYTE; 11395 11396 return new BaseTexture(resource, Object.assign(defaultBufferOptions, options || { width: width, height: height, type: type })); 11397 }; 11398 11399 /** 11400 * Adds a BaseTexture to the global BaseTextureCache. This cache is shared across the whole PIXI object. 11401 * 11402 * @static 11403 * @param {PIXI.BaseTexture} baseTexture - The BaseTexture to add to the cache. 11404 * @param {string} id - The id that the BaseTexture will be stored against. 11405 */ 11406 BaseTexture.addToCache = function addToCache (baseTexture, id) 11407 { 11408 if (id) 11409 { 11410 if (baseTexture.textureCacheIds.indexOf(id) === -1) 11411 { 11412 baseTexture.textureCacheIds.push(id); 11413 } 11414 11415 if (BaseTextureCache[id]) 11416 { 11417 // eslint-disable-next-line no-console 11418 console.warn(("BaseTexture added to the cache with an id [" + id + "] that already had an entry")); 11419 } 11420 11421 BaseTextureCache[id] = baseTexture; 11422 } 11423 }; 11424 11425 /** 11426 * Remove a BaseTexture from the global BaseTextureCache. 11427 * 11428 * @static 11429 * @param {string|PIXI.BaseTexture} baseTexture - id of a BaseTexture to be removed, or a BaseTexture instance itself. 11430 * @return {PIXI.BaseTexture|null} The BaseTexture that was removed. 11431 */ 11432 BaseTexture.removeFromCache = function removeFromCache (baseTexture) 11433 { 11434 if (typeof baseTexture === 'string') 11435 { 11436 var baseTextureFromCache = BaseTextureCache[baseTexture]; 11437 11438 if (baseTextureFromCache) 11439 { 11440 var index = baseTextureFromCache.textureCacheIds.indexOf(baseTexture); 11441 11442 if (index > -1) 11443 { 11444 baseTextureFromCache.textureCacheIds.splice(index, 1); 11445 } 11446 11447 delete BaseTextureCache[baseTexture]; 11448 11449 return baseTextureFromCache; 11450 } 11451 } 11452 else if (baseTexture && baseTexture.textureCacheIds) 11453 { 11454 for (var i = 0; i < baseTexture.textureCacheIds.length; ++i) 11455 { 11456 delete BaseTextureCache[baseTexture.textureCacheIds[i]]; 11457 } 11458 11459 baseTexture.textureCacheIds.length = 0; 11460 11461 return baseTexture; 11462 } 11463 11464 return null; 11465 }; 11466 11467 Object.defineProperties( BaseTexture.prototype, prototypeAccessors ); 11468 11469 return BaseTexture; 11470 }(eventemitter3)); 11471 11472 /**
11473 * A resource that contains a number of sources. 11474 * 11475 * @class 11476 * @extends PIXI.resources.Resource 11477 * @memberof PIXI.resources 11478 * @param {number|Array<*>} source - Number of items in array or the collection 11479 * of image URLs to use. Can also be resources, image elements, canvas, etc. 11480 * @param {object} [options] Options to apply to {@link PIXI.resources.autoDetectResource} 11481 * @param {number} [options.width] - Width of the resource 11482 * @param {number} [options.height] - Height of the resource 11483 */ 11484 var ArrayResource = /*@__PURE__*/(function (Resource) { 11485 function ArrayResource(source, options) 11486 { 11487 options = options || {}; 11488 11489 var urls; 11490 var length = source; 11491 11492 if (Array.isArray(source)) 11493 { 11494 urls = source; 11495 length = source.length; 11496 } 11497 11498 Resource.call(this, options.width, options.height); 11499 11500 /** 11501 * Collection of resources. 11502 * @member {Array<PIXI.BaseTexture>} 11503 * @readonly 11504 */ 11505 this.items = []; 11506 11507 /** 11508 * Dirty IDs for each part 11509 * @member {Array<number>} 11510 * @readonly 11511 */ 11512 this.itemDirtyIds = []; 11513 11514 for (var i = 0; i < length; i++) 11515 { 11516 var partTexture = new BaseTexture(); 11517 11518 this.items.push(partTexture); 11519 this.itemDirtyIds.push(-1); 11520 } 11521 11522 /** 11523 * Number of elements in array 11524 * 11525 * @member {number} 11526 * @readonly 11527 */ 11528 this.length = length; 11529 11530 /** 11531 * Promise when loading 11532 * @member {Promise} 11533 * @private 11534 * @default null 11535 */ 11536 this._load = null; 11537 11538 if (urls) 11539 { 11540 for (var i$1 = 0; i$1 < length; i$1++) 11541 { 11542 this.addResourceAt(autoDetectResource(urls[i$1], options), i$1); 11543 } 11544 } 11545 } 11546 11547 if ( Resource ) { ArrayResource.__proto__ = Resource; } 11548 ArrayResource.prototype = Object.create( Resource && Resource.prototype ); 11549 ArrayResource.prototype.constructor = ArrayResource; 11550 11551 /** 11552 * Destroy this BaseImageResource 11553 * @override 11554 */ 11555 ArrayResource.prototype.dispose = function dispose () 11556 { 11557 for (var i = 0, len = this.length; i < len; i++) 11558 { 11559 this.items[i].destroy(); 11560 } 11561 this.items = null; 11562 this.itemDirtyIds = null; 11563 this._load = null; 11564 }; 11565 11566 /** 11567 * Set a resource by ID 11568 * 11569 * @param {PIXI.resources.Resource} resource 11570 * @param {number} index - Zero-based index of resource to set 11571 * @return {PIXI.resources.ArrayResource} Instance for chaining 11572 */ 11573 ArrayResource.prototype.addResourceAt = function addResourceAt (resource, index) 11574 { 11575 var baseTexture = this.items[index]; 11576 11577 if (!baseTexture) 11578 { 11579 throw new Error(("Index " + index + " is out of bounds")); 11580 } 11581 11582 // Inherit the first resource dimensions 11583 if (resource.valid && !this.valid) 11584 { 11585 this.resize(resource.width, resource.height); 11586 } 11587 11588 this.items[index].setResource(resource); 11589 11590 return this; 11591 }; 11592 11593 /** 11594 * Set the parent base texture 11595 * @member {PIXI.BaseTexture} 11596 * @override 11597 */ 11598 ArrayResource.prototype.bind = function bind (baseTexture) 11599 { 11600 Resource.prototype.bind.call(this, baseTexture); 11601 11602 baseTexture.target = TARGETS.TEXTURE_2D_ARRAY; 11603 11604 for (var i = 0; i < this.length; i++) 11605 { 11606 this.items[i].on('update', baseTexture.update, baseTexture); 11607 } 11608 }; 11609 11610 /** 11611 * Unset the parent base texture 11612 * @member {PIXI.BaseTexture} 11613 * @override 11614 */ 11615 ArrayResource.prototype.unbind = function unbind (baseTexture) 11616 { 11617 Resource.prototype.unbind.call(this, baseTexture); 11618 11619 for (var i = 0; i < this.length; i++) 11620 { 11621 this.items[i].off('update', baseTexture.update, baseTexture); 11622 } 11623 }; 11624 11625 /** 11626 * Load all the resources simultaneously 11627 * @override 11628 * @return {Promise<void>} When load is resolved 11629 */
11630 ArrayResource.prototype.load = function load () 11631 { 11632 var this$1 = this; 11633 11634 if (this._load) 11635 { 11636 return this._load; 11637 } 11638 11639 var resources = this.items.map(function (item) { return item.resource; }); 11640 11641 // TODO: also implement load part-by-part strategy 11642 var promises = resources.map(function (item) { return item.load(); }); 11643 11644 this._load = Promise.all(promises) 11645 .then(function () { 11646 var ref = resources[0]; 11647 var width = ref.width; 11648 var height = ref.height; 11649 11650 this$1.resize(width, height); 11651 11652 return Promise.resolve(this$1); 11653 } 11654 ); 11655 11656 return this._load; 11657 }; 11658 11659 /** 11660 * Upload the resources to the GPU. 11661 * @param {PIXI.Renderer} renderer 11662 * @param {PIXI.BaseTexture} texture 11663 * @param {PIXI.GLTexture} glTexture 11664 * @returns {boolean} whether texture was uploaded 11665 */ 11666 ArrayResource.prototype.upload = function upload (renderer, texture, glTexture) 11667 { 11668 var ref = this; 11669 var length = ref.length; 11670 var itemDirtyIds = ref.itemDirtyIds; 11671 var items = ref.items; 11672 var gl = renderer.gl; 11673 11674 if (glTexture.dirtyId < 0) 11675 { 11676 gl.texImage3D( 11677 gl.TEXTURE_2D_ARRAY, 11678 0, 11679 texture.format, 11680 this._width, 11681 this._height, 11682 length, 11683 0, 11684 texture.format, 11685 texture.type, 11686 null 11687 ); 11688 } 11689 11690 for (var i = 0; i < length; i++) 11691 { 11692 var item = items[i]; 11693 11694 if (itemDirtyIds[i] < item.dirtyId) 11695 { 11696 itemDirtyIds[i] = item.dirtyId; 11697 if (item.valid) 11698 { 11699 gl.texSubImage3D( 11700 gl.TEXTURE_2D_ARRAY, 11701 0, 11702 0, // xoffset 11703 0, // yoffset 11704 i, // zoffset 11705 item.resource.width, 11706 item.resource.height, 11707 1, 11708 texture.format, 11709 texture.type, 11710 item.resource.source 11711 ); 11712 } 11713 } 11714 } 11715 11716 return true; 11717 }; 11718 11719 return ArrayResource; 11720 }(Resource)); 11721 11722 /** 11723 * Resource type for HTMLCanvasElement. 11724 * @class 11725 * @extends PIXI.resources.BaseImageResource 11726 * @memberof PIXI.resources 11727 * @param {HTMLCanvasElement} source - Canvas element to use 11728 */ 11729 var CanvasResource = /*@__PURE__*/(function (BaseImageResource) { 11730 function CanvasResource () { 11731 BaseImageResource.apply(this, arguments); 11732 } 11733 11734 if ( BaseImageResource ) { CanvasResource.__proto__ = BaseImageResource; } 11735 CanvasResource.prototype = Object.create( BaseImageResource && BaseImageResource.prototype ); 11736 CanvasResource.prototype.constructor = CanvasResource; 11737 11738 CanvasResource.test = function test (source) 11739 { 11740 return (source instanceof HTMLCanvasElement); 11741 }; 11742 11743 return CanvasResource; 11744 }(BaseImageResource)); 11745 11746 /** 11747 * Resource for a CubeTexture which contains six resources. 11748 * 11749 * @class 11750 * @extends PIXI.resources.ArrayResource 11751 * @memberof PIXI.resources 11752 * @param {Array<string|PIXI.resources.Resource>} [source] Collection of URLs or resources 11753 * to use as the sides of the cube. 11754 * @param {object} [options] - ImageResource options 11755 * @param {number} [options.width] - Width of resource 11756 * @param {number} [options.height] - Height of resource 11757 */ 11758 var CubeResource = /*@__PURE__*/(function (ArrayResource) { 11759 function CubeResource(source, options) 11760 { 11761 options = options || {}; 11762 11763 ArrayResource.call(this, source, options); 11764 11765 if (this.length !== CubeResource.SIDES) 11766 { 11767 throw new Error(("Invalid length. Got " + (this.length) + ", expected 6")); 11768 } 11769 11770 for (var i = 0; i < CubeResource.SIDES; i++) 11771 { 11772 this.items[i].target = TARGETS.TEXTURE_CUBE_MAP_POSITIVE_X + i; 11773 } 11774 11775 if (options.autoLoad !== false) 11776 { 11777 this.load(); 11778 } 11779 } 11780
11781 if ( ArrayResource ) { CubeResource.__proto__ = ArrayResource; } 11782 CubeResource.prototype = Object.create( ArrayResource && ArrayResource.prototype ); 11783 CubeResource.prototype.constructor = CubeResource; 11784 11785 /** 11786 * Add binding 11787 * 11788 * @override 11789 * @param {PIXI.BaseTexture} baseTexture - parent base texture 11790 */ 11791 CubeResource.prototype.bind = function bind (baseTexture) 11792 { 11793 ArrayResource.prototype.bind.call(this, baseTexture); 11794 11795 baseTexture.target = TARGETS.TEXTURE_CUBE_MAP; 11796 }; 11797 11798 /** 11799 * Upload the resource 11800 * 11801 * @returns {boolean} true is success 11802 */ 11803 CubeResource.prototype.upload = function upload (renderer, baseTexture, glTexture) 11804 { 11805 var dirty = this.itemDirtyIds; 11806 11807 for (var i = 0; i < CubeResource.SIDES; i++) 11808 { 11809 var side = this.items[i]; 11810 11811 if (dirty[i] < side.dirtyId) 11812 { 11813 dirty[i] = side.dirtyId; 11814 if (side.valid) 11815 { 11816 side.resource.upload(renderer, side, glTexture); 11817 } 11818 } 11819 } 11820 11821 return true; 11822 }; 11823 11824 return CubeResource; 11825 }(ArrayResource)); 11826 11827 /** 11828 * Number of texture sides to store for CubeResources 11829 * 11830 * @name PIXI.resources.CubeResource.SIDES 11831 * @static 11832 * @member {number} 11833 * @default 6 11834 */ 11835 CubeResource.SIDES = 6; 11836 11837 /** 11838 * Resource type for SVG elements and graphics. 11839 * @class 11840 * @extends PIXI.resources.BaseImageResource 11841 * @memberof PIXI.resources 11842 * @param {string} source - Base64 encoded SVG element or URL for SVG file. 11843 * @param {object} [options] - Options to use 11844 * @param {number} [options.scale=1] Scale to apply to SVG. 11845 * @param {boolean} [options.autoLoad=true] Start loading right away. 11846 */ 11847 var SVGResource = /*@__PURE__*/(function (BaseImageResource) { 11848 function SVGResource(source, options) 11849 { 11850 options = options || {}; 11851 11852 BaseImageResource.call(this, document.createElement('canvas')); 11853 11854 /** 11855 * Base64 encoded SVG element or URL for SVG file 11856 * @readonly 11857 * @member {string} 11858 */ 11859 this.svg = source; 11860 11861 /** 11862 * The source scale to apply to render 11863 * @readonly 11864 * @member {number} 11865 */ 11866 this.scale = options.scale || 1; 11867 11868 /** 11869 * Call when completely loaded 11870 * @private 11871 * @member {function} 11872 */ 11873 this._resolve = null; 11874 11875 /** 11876 * Promise when loading 11877 * @member {Promise<void>} 11878 * @private 11879 * @default null 11880 */ 11881 this._load = null; 11882 11883 if (options.autoLoad !== false) 11884 { 11885 this.load(); 11886 } 11887 } 11888 11889 if ( BaseImageResource ) { SVGResource.__proto__ = BaseImageResource; } 11890 SVGResource.prototype = Object.create( BaseImageResource && BaseImageResource.prototype ); 11891 SVGResource.prototype.constructor = SVGResource; 11892 11893 SVGResource.prototype.load = function load () 11894 { 11895 var this$1 = this; 11896 11897 if (this._load) 11898 { 11899 return this._load; 11900 } 11901 11902 this._load = new Promise(function (resolve) { 11903 // Save this until after load is finished 11904 this$1._resolve = function () { 11905 this$1.resize(this$1.source.width, this$1.source.height); 11906 resolve(this$1); 11907 }; 11908 11909 // Convert SVG inline string to data-uri 11910 if ((/^\<svg/).test(this$1.svg.trim())) 11911 { 11912 this$1.svg = "data:image/svg+xml;utf8," + (this$1.svg); 11913 } 11914 11915 // Checks if `source` is an SVG image and whether it's 11916 // loaded via a URL or a data URI. Then calls 11917 // `_loadDataUri` or `_loadXhr`. 11918 var dataUri = decomposeDataUri(this$1.svg); 11919 11920 if (dataUri) 11921 { 11922 this$1._loadDataUri(dataUri); 11923 } 11924 else 11925 { 11926 // We got an URL, so we need to do an XHR to check the svg size 11927 this$1._loadXhr(); 11928 } 11929 }); 11930 11931 return this._load; 11932 }; 11933 11934 /** 11935 * Reads an SVG string from data URI and then calls `_loadString`. 11936 * 11937 * @param {string} dataUri - The data uri to load from. 11938 */ 11939 SVGResource.prototype._loadDataUri = function _loadDataUri (dataUri) 11940 { 11941 var svgString; 11942 11943 if (dataUri.encoding === 'base64') 11944 { 11945 if (!atob) 11946 { 11947 throw new Error('Your browser doesn\'t support base64 conversions.'); 11948 } 11949 svgString = atob(dataUri.data); 11950 } 11951 else 11952 { 11953 svgString = dataUri.data; 11954 } 11955 11956 this._loadString(svgString); 11957 }; 11958 11959 /** 11960 * Loads an SVG string from `imageUrl` using XHR and then calls `_loadString`. 11961 * 11962 * @private 11963 */ 11964 SVGResource.prototype._loadXhr = function _loadXhr () 11965 { 11966 var this$1 = this; 11967 11968 var svgXhr = new XMLHttpRequest(); 11969 11970 // This throws error on IE, so SVG Document can't be used 11971 // svgXhr.responseType = 'document'; 11972
11973 // This is not needed since we load the svg as string (breaks IE too) 11974 // but overrideMimeType() can be used to force the response to be parsed as XML 11975 // svgXhr.overrideMimeType('image/svg+xml'); 11976 11977 svgXhr.onload = function () { 11978 if (svgXhr.readyState !== svgXhr.DONE || svgXhr.status !== 200) 11979 { 11980 throw new Error('Failed to load SVG using XHR.'); 11981 } 11982 11983 this$1._loadString(svgXhr.response); 11984 }; 11985 11986 // svgXhr.onerror = () => this.emit('error', this); 11987 11988 svgXhr.open('GET', this.svg, true); 11989 svgXhr.send(); 11990 }; 11991 11992 /** 11993 * Loads texture using an SVG string. The original SVG Image is stored as `origSource` and the 11994 * created canvas is the new `source`. The SVG is scaled using `sourceScale`. Called by 11995 * `_loadXhr` or `_loadDataUri`. 11996 * 11997 * @private 11998 * @param {string} svgString SVG source as string 11999 * 12000 * @fires loaded 12001 */ 12002 SVGResource.prototype._loadString = function _loadString (svgString) 12003 { 12004 var svgSize = SVGResource.getSize(svgString); 12005 12006 // TODO do we need to wait for this to load? 12007 // seems instant! 12008 // 12009 var tempImage = new Image(); 12010 12011 tempImage.src = "data:image/svg+xml," + svgString; 12012 12013 var svgWidth = svgSize.width; 12014 var svgHeight = svgSize.height; 12015 12016 if (!svgWidth || !svgHeight) 12017 { 12018 throw new Error('The SVG image must have width and height defined (in pixels), canvas API needs them.'); 12019 } 12020 12021 // Scale realWidth and realHeight 12022 this._width = Math.round(svgWidth * this.scale); 12023 this._height = Math.round(svgHeight * this.scale); 12024 12025 // Create a canvas element 12026 var canvas = this.source; 12027 12028 canvas.width = this._width; 12029 canvas.height = this._height; 12030 canvas._pixiId = "canvas_" + (uid()); 12031 12032 // Draw the Svg to the canvas 12033 canvas 12034 .getContext('2d') 12035 .drawImage(tempImage, 0, 0, svgWidth, svgHeight, 0, 0, this.width, this.height); 12036 12037 this._resolve(); 12038 this._resolve = null; 12039 }; 12040 12041 /** 12042 * Typedef for Size object. 12043 * 12044 * @memberof PIXI.resources.SVGResource 12045 * @typedef {object} Size 12046 * @property {number} width - Width component 12047 * @property {number} height - Height component 12048 */ 12049 12050 /** 12051 * Get size from an svg string using regexp. 12052 * 12053 * @method 12054 * @param {string} svgString - a serialized svg element 12055 * @return {PIXI.resources.SVGResource.Size} image extension 12056 */ 12057 SVGResource.getSize = function getSize (svgString) 12058 { 12059 var sizeMatch = SVGResource.SVG_SIZE.exec(svgString); 12060 var size = {}; 12061 12062 if (sizeMatch) 12063 { 12064 size[sizeMatch[1]] = Math.round(parseFloat(sizeMatch[3])); 12065 size[sizeMatch[5]] = Math.round(parseFloat(sizeMatch[7])); 12066 } 12067 12068 return size; 12069 }; 12070 12071 /** 12072 * Destroys this texture 12073 * @override 12074 */ 12075 SVGResource.prototype.dispose = function dispose () 12076 { 12077 BaseImageResource.prototype.dispose.call(this); 12078 this._resolve = null; 12079 }; 12080 12081 /** 12082 * Used to auto-detect the type of resource. 12083 * 12084 * @static 12085 * @param {*} source - The source object 12086 * @param {string} extension - The extension of source, if set 12087 */ 12088 SVGResource.test = function test (source, extension) 12089 { 12090 // url file extension is SVG 12091 return extension === 'svg' 12092 // source is SVG data-uri 12093 || (typeof source === 'string' && source.indexOf('data:image/svg+xml') === 0); 12094 }; 12095 12096 return SVGResource; 12097 }(BaseImageResource)); 12098 12099 /** 12100 * RegExp for SVG size. 12101 * 12102 * @static 12103 * @constant {RegExp|string} SVG_SIZE 12104 * @memberof PIXI.resources.SVGResource 12105 * @example <svg width="100" height="100"></svg> 12106 */ 12107 SVGResource.SVG_SIZE = /<svg[^>]*(?:\s(width|height)=('|")(\d*(?:\.\d+)?)(?:px)?('|"))[^>]*(?:\s(width|height)=('|")(\d*(?:\.\d+)?)(?:px)?('|"))[^>]*>/i; // eslint-disable-line max-len 12108 12109 /** 12110 * Resource type for HTMLVideoElement. 12111 * @class 12112 * @extends PIXI.resources.BaseImageResource 12113 * @memberof PIXI.resources 12114 * @param {HTMLVideoElement|object|string|Array<string|object>} source - Video element to use. 12115 * @param {object} [options] - Options to use 12116 * @param {boolean} [options.autoLoad=true] - Start loading the video immediately 12117 * @param {boolean} [options.autoPlay=true] - Start playing video immediately 12118 * @param {number} [options.updateFPS=0] - How many times a second to update the texture from the video. 12119 * Leave at 0 to update at every render. 12120 * @param {boolean} [options.crossorigin=true] - Load image using cross origin 12121 */ 12122 var VideoResource = /*@__PURE__*/(function (BaseImageResource) { 12123 function VideoResource(source, options) 12124 { 12125 options = options || {}; 12126 12127 if (!(source instanceof HTMLVideoElement)) 12128 { 12129 var videoElement = document.createElement('video'); 12130 12131 videoElement.setAttribute('webkit-playsinline', ''); 12132 videoElement.setAttribute('playsinline', ''); 12133 12134 if (typeof source === 'string') 12135 { 12136 source = [source]; 12137 } 12138 12139 BaseImageResource.crossOrigin(videoElement, (source[0].src || source[0]), options.crossorigin); 12140 12141 // array of objects or strings 12142 for (var i = 0; i < source.length; ++i) 12143 { 12144 var sourceElement = document.createElement('source'); 12145 12146 var ref = source[i]; 12147 var src = ref.src; 12148 var mime = ref.mime; 12149 12150 src = src || source[i]; 12151 12152 var baseSrc = src.split('?').shift().toLowerCase(); 12153 var ext = baseSrc.substr(baseSrc.lastIndexOf('.') + 1); 12154 12155 mime = mime || ("video/" + ext); 12156 12157 sourceElement.src = src; 12158 sourceElement.type = mime; 12159 12160 videoElement.appendChild(sourceElement); 12161 } 12162 12163 // Override the source 12164 source = videoElement; 12165 } 12166 12167 BaseImageResource.call(this, source); 12168 12169 this._autoUpdate = true; 12170 this._isAutoUpdating = false;
12171 this._updateFPS = options.updateFPS || 0; 12172 this._msToNextUpdate = 0; 12173 12174 /** 12175 * When set to true will automatically play videos used by this texture once 12176 * they are loaded. If false, it will not modify the playing state. 12177 * 12178 * @member {boolean} 12179 * @default true 12180 */ 12181 this.autoPlay = options.autoPlay !== false; 12182 12183 /** 12184 * Promise when loading 12185 * @member {Promise<void>} 12186 * @private 12187 * @default null 12188 */ 12189 this._load = null; 12190 12191 /** 12192 * Callback when completed with load. 12193 * @member {function} 12194 * @private 12195 */ 12196 this._resolve = null; 12197 12198 // Bind for listeners 12199 this._onCanPlay = this._onCanPlay.bind(this); 12200 12201 if (options.autoLoad !== false) 12202 { 12203 this.load(); 12204 } 12205 } 12206 12207 if ( BaseImageResource ) { VideoResource.__proto__ = BaseImageResource; } 12208 VideoResource.prototype = Object.create( BaseImageResource && BaseImageResource.prototype ); 12209 VideoResource.prototype.constructor = VideoResource; 12210 12211 var prototypeAccessors = { autoUpdate: { configurable: true },updateFPS: { configurable: true } }; 12212 12213 /** 12214 * Trigger updating of the texture 12215 * 12216 * @param {number} [deltaTime=0] - time delta since last tick 12217 */ 12218 VideoResource.prototype.update = function update (deltaTime) 12219 { 12220 if ( deltaTime === void 0 ) { deltaTime = 0; } 12221 12222 if (!this.destroyed) 12223 { 12224 // account for if video has had its playbackRate changed 12225 var elapsedMS = Ticker.shared.elapsedMS * this.source.playbackRate; 12226 12227 this._msToNextUpdate = Math.floor(this._msToNextUpdate - elapsedMS); 12228 if (!this._updateFPS || this._msToNextUpdate <= 0) 12229 { 12230 BaseImageResource.prototype.update.call(this, deltaTime); 12231 this._msToNextUpdate = this._updateFPS ? Math.floor(1000 / this._updateFPS) : 0; 12232 } 12233 } 12234 }; 12235 12236 /** 12237 * Start preloading the video resource. 12238 * 12239 * @protected 12240 * @return {Promise<void>} Handle the validate event 12241 */ 12242 VideoResource.prototype.load = function load () 12243 { 12244 var this$1 = this; 12245 12246 if (this._load) 12247 { 12248 return this._load; 12249 } 12250 12251 var source = this.source; 12252 12253 if ((source.readyState === source.HAVE_ENOUGH_DATA || source.readyState === source.HAVE_FUTURE_DATA) 12254 && source.width && source.height) 12255 { 12256 source.complete = true; 12257 } 12258 12259 source.addEventListener('play', this._onPlayStart.bind(this)); 12260 source.addEventListener('pause', this._onPlayStop.bind(this)); 12261 12262 if (!this._isSourceReady()) 12263 { 12264 source.addEventListener('canplay', this._onCanPlay); 12265 source.addEventListener('canplaythrough', this._onCanPlay); 12266 } 12267 else 12268 { 12269 this._onCanPlay(); 12270 } 12271 12272 this._load = new Promise(function (resolve) { 12273 if (this$1.valid) 12274 { 12275 resolve(this$1); 12276 } 12277 else 12278 { 12279 this$1._resolve = resolve; 12280 12281 source.load(); 12282 } 12283 }); 12284 12285 return this._load; 12286 }; 12287 12288 /** 12289 * Returns true if the underlying source is playing. 12290 * 12291 * @private 12292 * @return {boolean} True if playing. 12293 */ 12294 VideoResource.prototype._isSourcePlaying = function _isSourcePlaying () 12295 { 12296 var source = this.source; 12297 12298 return (source.currentTime > 0 && source.paused === false && source.ended === false && source.readyState > 2); 12299 }; 12300 12301 /** 12302 * Returns true if the underlying source is ready for playing. 12303 * 12304 * @private 12305 * @return {boolean} True if ready. 12306 */ 12307 VideoResource.prototype._isSourceReady = function _isSourceReady () 12308 { 12309 return this.source.readyState === 3 || this.source.readyState === 4; 12310 }; 12311 12312 /** 12313 * Runs the update loop when the video is ready to play 12314 * 12315 * @private 12316 */ 12317 VideoResource.prototype._onPlayStart = function _onPlayStart () 12318 { 12319 // Just in case the video has not received its can play even yet.. 12320 if (!this.valid) 12321 { 12322 this._onCanPlay(); 12323 } 12324 12325 if (!this._isAutoUpdating && this.autoUpdate) 12326 { 12327 Ticker.shared.add(this.update, this); 12328 this._isAutoUpdating = true; 12329 } 12330 }; 12331 12332 /** 12333 * Fired when a pause event is triggered, stops the update loop 12334 * 12335 * @private 12336 */ 12337 VideoResource.prototype._onPlayStop = function _onPlayStop () 12338 { 12339 if (this._isAutoUpdating) 12340 { 12341 Ticker.shared.remove(this.update, this); 12342 this._isAutoUpdating = false;
12343 } 12344 }; 12345 12346 /** 12347 * Fired when the video is loaded and ready to play 12348 * 12349 * @private 12350 */ 12351 VideoResource.prototype._onCanPlay = function _onCanPlay () 12352 { 12353 var ref = this; 12354 var source = ref.source; 12355 12356 source.removeEventListener('canplay', this._onCanPlay); 12357 source.removeEventListener('canplaythrough', this._onCanPlay); 12358 12359 var valid = this.valid; 12360 12361 this.resize(source.videoWidth, source.videoHeight); 12362 12363 // prevent multiple loaded dispatches.. 12364 if (!valid && this._resolve) 12365 { 12366 this._resolve(this); 12367 this._resolve = null; 12368 } 12369 12370 if (this._isSourcePlaying()) 12371 { 12372 this._onPlayStart(); 12373 } 12374 else if (this.autoPlay) 12375 { 12376 source.play(); 12377 } 12378 }; 12379 12380 /** 12381 * Destroys this texture 12382 * @override 12383 */ 12384 VideoResource.prototype.dispose = function dispose () 12385 { 12386 if (this._isAutoUpdating) 12387 { 12388 Ticker.shared.remove(this.update, this); 12389 } 12390 12391 if (this.source) 12392 { 12393 this.source.pause(); 12394 this.source.src = ''; 12395 this.source.load(); 12396 } 12397 BaseImageResource.prototype.dispose.call(this); 12398 }; 12399 12400 /** 12401 * Should the base texture automatically update itself, set to true by default 12402 * 12403 * @member {boolean} 12404 */ 12405 prototypeAccessors.autoUpdate.get = function () 12406 { 12407 return this._autoUpdate; 12408 }; 12409 12410 prototypeAccessors.autoUpdate.set = function (value) // eslint-disable-line require-jsdoc 12411 { 12412 if (value !== this._autoUpdate) 12413 { 12414 this._autoUpdate = value; 12415 12416 if (!this._autoUpdate && this._isAutoUpdating) 12417 { 12418 Ticker.shared.remove(this.update, this); 12419 this._isAutoUpdating = false; 12420 } 12421 else if (this._autoUpdate && !this._isAutoUpdating) 12422 { 12423 Ticker.shared.add(this.update, this); 12424 this._isAutoUpdating = true; 12425 } 12426 } 12427 }; 12428 12429 /** 12430 * How many times a second to update the texture from the video. Leave at 0 to update at every render. 12431 * A lower fps can help performance, as updating the texture at 60fps on a 30ps video may not be efficient. 12432 * 12433 * @member {number} 12434 */ 12435 prototypeAccessors.updateFPS.get = function () 12436 { 12437 return this._updateFPS; 12438 }; 12439 12440 prototypeAccessors.updateFPS.set = function (value) // eslint-disable-line require-jsdoc 12441 { 12442 if (value !== this._updateFPS) 12443 { 12444 this._updateFPS = value; 12445 } 12446 }; 12447 12448 /** 12449 * Used to auto-detect the type of resource. 12450 * 12451 * @static 12452 * @param {*} source - The source object 12453 * @param {string} extension - The extension of source, if set 12454 * @return {boolean} `true` if video source 12455 */ 12456 VideoResource.test = function test (source, extension) 12457 { 12458 return (source instanceof HTMLVideoElement) 12459 || VideoResource.TYPES.indexOf(extension) > -1; 12460 }; 12461 12462 Object.defineProperties( VideoResource.prototype, prototypeAccessors ); 12463 12464 return VideoResource; 12465 }(BaseImageResource)); 12466 12467 /**
12468 * List of common video file extensions supported by VideoResource. 12469 * @constant 12470 * @member {Array<string>} 12471 * @static 12472 * @readonly 12473 */ 12474 VideoResource.TYPES = ['mp4', 'm4v', 'webm', 'ogg', 'ogv', 'h264', 'avi', 'mov']; 12475 12476 INSTALLED.push( 12477 ImageResource, 12478 CanvasResource, 12479 VideoResource, 12480 SVGResource, 12481 BufferResource, 12482 CubeResource, 12483 ArrayResource 12484 ); 12485 12486 var index = ({ 12487 INSTALLED: INSTALLED, 12488 autoDetectResource: autoDetectResource, 12489 ArrayResource: ArrayResource, 12490 BufferResource: BufferResource, 12491 CanvasResource: CanvasResource, 12492 CubeResource: CubeResource, 12493 ImageResource: ImageResource, 12494 SVGResource: SVGResource, 12495 VideoResource: VideoResource, 12496 Resource: Resource, 12497 BaseImageResource: BaseImageResource 12498 }); 12499 12500 /** 12501 * System is a base class used for extending systems used by the {@link PIXI.Renderer} 12502 * 12503 * @see PIXI.Renderer#addSystem 12504 * @class 12505 * @memberof PIXI 12506 */ 12507 var System = function System(renderer) 12508 { 12509 /** 12510 * The renderer this manager works for. 12511 * 12512 * @member {PIXI.Renderer} 12513 */ 12514 this.renderer = renderer; 12515 12516 this.renderer.runners.contextChange.add(this); 12517 }; 12518 12519 /** 12520 * Generic method called when there is a WebGL context change. 12521 * 12522 * @param {WebGLRenderingContext} gl new webgl context 12523 */ 12524 System.prototype.contextChange = function contextChange (gl) // eslint-disable-line no-unused-vars 12525 { 12526 // do some codes init! 12527 }; 12528 12529 /** 12530 * Generic destroy methods to be overridden by the subclass 12531 */ 12532 System.prototype.destroy = function destroy () 12533 { 12534 this.renderer.runners.contextChange.remove(this); 12535 this.renderer = null; 12536 }; 12537 12538 /** 12539 * Resource type for DepthTexture. 12540 * @class 12541 * @extends PIXI.resources.BufferResource 12542 * @memberof PIXI.resources 12543 */ 12544 var DepthResource = /*@__PURE__*/(function (BufferResource) { 12545 function DepthResource () { 12546 BufferResource.apply(this, arguments); 12547 } 12548 12549 if ( BufferResource ) { DepthResource.__proto__ = BufferResource; } 12550 DepthResource.prototype = Object.create( BufferResource && BufferResource.prototype ); 12551 DepthResource.prototype.constructor = DepthResource; 12552 12553 DepthResource.prototype.upload = function upload (renderer, baseTexture, glTexture) 12554 { 12555 var gl = renderer.gl; 12556 12557 gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, baseTexture.premultiplyAlpha); 12558 12559 if (glTexture.width === baseTexture.width && glTexture.height === baseTexture.height) 12560 { 12561 gl.texSubImage2D( 12562 baseTexture.target, 12563 0, 12564 0, 12565 0, 12566 baseTexture.width, 12567 baseTexture.height, 12568 baseTexture.format, 12569 baseTexture.type, 12570 this.data 12571 ); 12572 } 12573 else 12574 { 12575 glTexture.width = baseTexture.width; 12576 glTexture.height = baseTexture.height; 12577 12578 gl.texImage2D( 12579 baseTexture.target, 12580 0, 12581 gl.DEPTH_COMPONENT16, // Needed for depth to render properly in webgl2.0 12582 baseTexture.width, 12583 baseTexture.height, 12584 0, 12585 baseTexture.format, 12586 baseTexture.type, 12587 this.data 12588 ); 12589 } 12590 12591 return true; 12592 }; 12593 12594 return DepthResource; 12595 }(BufferResource)); 12596 12597 /** 12598 * Frame buffer used by the BaseRenderTexture 12599 * 12600 * @class 12601 * @memberof PIXI 12602 */ 12603 var Framebuffer = function Framebuffer(width, height) 12604 { 12605 this.width = Math.ceil(width || 100); 12606 this.height = Math.ceil(height || 100); 12607 12608 this.stencil = false; 12609 this.depth = false; 12610 12611 this.dirtyId = 0; 12612 this.dirtyFormat = 0; 12613 this.dirtySize = 0; 12614 12615 this.depthTexture = null; 12616 this.colorTextures = []; 12617 12618 this.glFramebuffers = {}; 12619 12620 this.disposeRunner = new Runner('disposeFramebuffer', 2); 12621 }; 12622 12623 var prototypeAccessors$1$2 = { colorTexture: { configurable: true } }; 12624 12625 /** 12626 * Reference to the colorTexture. 12627 * 12628 * @member {PIXI.Texture[]} 12629 * @readonly 12630 */ 12631 prototypeAccessors$1$2.colorTexture.get = function () 12632 { 12633 return this.colorTextures[0]; 12634 }; 12635 12636 /** 12637 * Add texture to the colorTexture array 12638 * 12639 * @param {number} [index=0] - Index of the array to add the texture to 12640 * @param {PIXI.Texture} [texture] - Texture to add to the array 12641 */ 12642 Framebuffer.prototype.addColorTexture = function addColorTexture (index, texture) 12643 { 12644 if ( index === void 0 ) { index = 0; } 12645 12646 // TODO add some validation to the texture - same width / height etc? 12647 this.colorTextures[index] = texture || new BaseTexture(null, { scaleMode: 0, 12648 resolution: 1, 12649 mipmap: false, 12650 width: this.width, 12651 height: this.height });// || new Texture(); 12652 12653 this.dirtyId++; 12654 this.dirtyFormat++; 12655 12656 return this; 12657 }; 12658 12659 /** 12660 * Add a depth texture to the frame buffer 12661 * 12662 * @param {PIXI.Texture} [texture] - Texture to add 12663 */ 12664 Framebuffer.prototype.addDepthTexture = function addDepthTexture (texture) 12665 { 12666 /* eslint-disable max-len */ 12667 this.depthTexture = texture || new BaseTexture(new DepthResource(null, { width: this.width, height: this.height }), { scaleMode: 0, 12668 resolution: 1, 12669 width: this.width, 12670 height: this.height, 12671 mipmap: false, 12672 format: FORMATS.DEPTH_COMPONENT, 12673 type: TYPES.UNSIGNED_SHORT });// UNSIGNED_SHORT; 12674 /* eslint-disable max-len */ 12675 this.dirtyId++; 12676 this.dirtyFormat++; 12677 12678 return this; 12679 }; 12680 12681 /** 12682 * Enable depth on the frame buffer 12683 */ 12684 Framebuffer.prototype.enableDepth = function enableDepth () 12685 { 12686 this.depth = true; 12687 12688 this.dirtyId++; 12689 this.dirtyFormat++; 12690 12691 return this; 12692 }; 12693 12694 /** 12695 * Enable stencil on the frame buffer 12696 */ 12697 Framebuffer.prototype.enableStencil = function enableStencil () 12698 { 12699 this.stencil = true; 12700 12701 this.dirtyId++; 12702 this.dirtyFormat++; 12703 12704 return this; 12705 }; 12706 12707 /** 12708 * Resize the frame buffer 12709 * 12710 * @param {number} width - Width of the frame buffer to resize to 12711 * @param {number} height - Height of the frame buffer to resize to 12712 */ 12713 Framebuffer.prototype.resize = function resize (width, height) 12714 { 12715 width = Math.ceil(width);
12716 height = Math.ceil(height); 12717 12718 if (width === this.width && height === this.height) { return; } 12719 12720 this.width = width; 12721 this.height = height; 12722 12723 this.dirtyId++; 12724 this.dirtySize++; 12725 12726 for (var i = 0; i < this.colorTextures.length; i++) 12727 { 12728 var texture = this.colorTextures[i]; 12729 var resolution = texture.resolution; 12730 12731 // take into acount the fact the texture may have a different resolution.. 12732 texture.setSize(width / resolution, height / resolution); 12733 } 12734 12735 if (this.depthTexture) 12736 { 12737 var resolution$1 = this.depthTexture.resolution; 12738 12739 this.depthTexture.setSize(width / resolution$1, height / resolution$1); 12740 } 12741 }; 12742 12743 /** 12744 * disposes WebGL resources that are connected to this geometry 12745 */ 12746 Framebuffer.prototype.dispose = function dispose () 12747 { 12748 this.disposeRunner.run(this, false); 12749 }; 12750 12751 Object.defineProperties( Framebuffer.prototype, prototypeAccessors$1$2 ); 12752 12753 /** 12754 * A BaseRenderTexture is a special texture that allows any PixiJS display object to be rendered to it. 12755 * 12756 * __Hint__: All DisplayObjects (i.e. Sprites) that render to a BaseRenderTexture should be preloaded 12757 * otherwise black rectangles will be drawn instead. 12758 * 12759 * A BaseRenderTexture takes a snapshot of any Display Object given to its render method. The position 12760 * and rotation of the given Display Objects is ignored. For example: 12761 * 12762 * ```js 12763 * let renderer = PIXI.autoDetectRenderer(); 12764 * let baseRenderTexture = new PIXI.BaseRenderTexture(800, 600); 12765 * let renderTexture = new PIXI.RenderTexture(baseRenderTexture); 12766 * let sprite = PIXI.Sprite.fromImage("spinObj_01.png"); 12767 * 12768 * sprite.position.x = 800/2; 12769 * sprite.position.y = 600/2; 12770 * sprite.anchor.x = 0.5; 12771 * sprite.anchor.y = 0.5; 12772 * 12773 * renderer.render(sprite, renderTexture); 12774 * ``` 12775 * 12776 * The Sprite in this case will be rendered using its local transform. To render this sprite at 0,0 12777 * you can clear the transform 12778 * 12779 * ```js 12780 * 12781 * sprite.setTransform() 12782 * 12783 * let baseRenderTexture = new PIXI.BaseRenderTexture(100, 100); 12784 * let renderTexture = new PIXI.RenderTexture(baseRenderTexture); 12785 * 12786 * renderer.render(sprite, renderTexture); // Renders to center of RenderTexture 12787 * ``` 12788 * 12789 * @class 12790 * @extends PIXI.BaseTexture 12791 * @memberof PIXI 12792 */ 12793 var BaseRenderTexture = /*@__PURE__*/(function (BaseTexture) { 12794 function BaseRenderTexture(options) 12795 { 12796 if (typeof options === 'number') 12797 { 12798 /* eslint-disable prefer-rest-params */ 12799 // Backward compatibility of signature 12800 var width$1 = arguments[0]; 12801 var height$1 = arguments[1]; 12802 var scaleMode = arguments[2]; 12803 var resolution = arguments[3]; 12804 12805 options = { width: width$1, height: height$1, scaleMode: scaleMode, resolution: resolution }; 12806 /* eslint-enable prefer-rest-params */ 12807 } 12808 12809 BaseTexture.call(this, null, options); 12810 12811 var ref = options || {}; 12812 var width = ref.width; 12813 var height = ref.height; 12814 12815 // Set defaults 12816 this.mipmap = false; 12817 this.width = Math.ceil(width) || 100; 12818 this.height = Math.ceil(height) || 100; 12819 this.valid = true; 12820 12821 /** 12822 * A reference to the canvas render target (we only need one as this can be shared across renderers) 12823 * 12824 * @protected 12825 * @member {object} 12826 */ 12827 this._canvasRenderTarget = null; 12828 12829 this.clearColor = [0, 0, 0, 0]; 12830 12831 this.framebuffer = new Framebuffer(this.width * this.resolution, this.height * this.resolution) 12832 .addColorTexture(0, this) 12833 .enableStencil(); 12834 12835 // TODO - could this be added the systems? 12836 12837 /** 12838 * The data structure for the stencil masks. 12839 * 12840 * @member {PIXI.Graphics[]} 12841 */ 12842 this.stencilMaskStack = []; 12843 12844 /** 12845 * The data structure for the filters. 12846 * 12847 * @member {PIXI.Graphics[]} 12848 */ 12849 this.filterStack = [{}]; 12850 } 12851 12852 if ( BaseTexture ) { BaseRenderTexture.__proto__ = BaseTexture; } 12853 BaseRenderTexture.prototype = Object.create( BaseTexture && BaseTexture.prototype ); 12854 BaseRenderTexture.prototype.constructor = BaseRenderTexture; 12855 12856 /** 12857 * Resizes the BaseRenderTexture. 12858 * 12859 * @param {number} width - The width to resize to. 12860 * @param {number} height - The height to resize to. 12861 */ 12862 BaseRenderTexture.prototype.resize = function resize (width, height) 12863 { 12864 width = Math.ceil(width);
12865 height = Math.ceil(height); 12866 this.framebuffer.resize(width * this.resolution, height * this.resolution); 12867 }; 12868 12869 /** 12870 * Frees the texture and framebuffer from WebGL memory without destroying this texture object. 12871 * This means you can still use the texture later which will upload it to GPU 12872 * memory again. 12873 * 12874 * @fires PIXI.BaseTexture#dispose 12875 */ 12876 BaseRenderTexture.prototype.dispose = function dispose () 12877 { 12878 this.framebuffer.dispose(); 12879 12880 BaseTexture.prototype.dispose.call(this); 12881 }; 12882 12883 /** 12884 * Destroys this texture. 12885 * 12886 */ 12887 BaseRenderTexture.prototype.destroy = function destroy () 12888 { 12889 BaseTexture.prototype.destroy.call(this, true); 12890 12891 this.framebuffer = null; 12892 12893 this.renderer = null; 12894 }; 12895 12896 return BaseRenderTexture; 12897 }(BaseTexture)); 12898 12899 /** 12900 * A standard object to store the Uvs of a texture 12901 * 12902 * @class 12903 * @protected 12904 * @memberof PIXI 12905 */ 12906 var TextureUvs = function TextureUvs() 12907 { 12908 this.x0 = 0; 12909 this.y0 = 0; 12910 12911 this.x1 = 1; 12912 this.y1 = 0; 12913 12914 this.x2 = 1; 12915 this.y2 = 1; 12916 12917 this.x3 = 0; 12918 this.y3 = 1; 12919 12920 this.uvsFloat32 = new Float32Array(8); 12921 }; 12922 12923 /** 12924 * Sets the texture Uvs based on the given frame information. 12925 * 12926 * @protected 12927 * @param {PIXI.Rectangle} frame - The frame of the texture 12928 * @param {PIXI.Rectangle} baseFrame - The base frame of the texture 12929 * @param {number} rotate - Rotation of frame, see {@link PIXI.GroupD8} 12930 */ 12931 TextureUvs.prototype.set = function set (frame, baseFrame, rotate) 12932 { 12933 var tw = baseFrame.width; 12934 var th = baseFrame.height; 12935 12936 if (rotate) 12937 { 12938 // width and height div 2 div baseFrame size 12939 var w2 = frame.width / 2 / tw; 12940 var h2 = frame.height / 2 / th; 12941 12942 // coordinates of center 12943 var cX = (frame.x / tw) + w2; 12944 var cY = (frame.y / th) + h2; 12945 12946 rotate = GroupD8.add(rotate, GroupD8.NW); // NW is top-left corner 12947 this.x0 = cX + (w2 * GroupD8.uX(rotate)); 12948 this.y0 = cY + (h2 * GroupD8.uY(rotate)); 12949 12950 rotate = GroupD8.add(rotate, 2); // rotate 90 degrees clockwise 12951 this.x1 = cX + (w2 * GroupD8.uX(rotate)); 12952 this.y1 = cY + (h2 * GroupD8.uY(rotate)); 12953 12954 rotate = GroupD8.add(rotate, 2); 12955 this.x2 = cX + (w2 * GroupD8.uX(rotate)); 12956 this.y2 = cY + (h2 * GroupD8.uY(rotate)); 12957 12958 rotate = GroupD8.add(rotate, 2); 12959 this.x3 = cX + (w2 * GroupD8.uX(rotate)); 12960 this.y3 = cY + (h2 * GroupD8.uY(rotate)); 12961 } 12962 else 12963 { 12964 this.x0 = frame.x / tw; 12965 this.y0 = frame.y / th; 12966 12967 this.x1 = (frame.x + frame.width) / tw; 12968 this.y1 = frame.y / th; 12969 12970 this.x2 = (frame.x + frame.width) / tw; 12971 this.y2 = (frame.y + frame.height) / th; 12972 12973 this.x3 = frame.x / tw; 12974 this.y3 = (frame.y + frame.height) / th; 12975 } 12976 12977 this.uvsFloat32[0] = this.x0; 12978 this.uvsFloat32[1] = this.y0; 12979 this.uvsFloat32[2] = this.x1; 12980 this.uvsFloat32[3] = this.y1; 12981 this.uvsFloat32[4] = this.x2; 12982 this.uvsFloat32[5] = this.y2; 12983 this.uvsFloat32[6] = this.x3; 12984 this.uvsFloat32[7] = this.y3; 12985 }; 12986 12987 var DEFAULT_UVS = new TextureUvs(); 12988 12989 /** 12990 * A texture stores the information that represents an image or part of an image. 12991 * 12992 * It cannot be added to the display list directly; instead use it as the texture for a Sprite. 12993 * If no frame is provided for a texture, then the whole image is used. 12994 * 12995 * You can directly create a texture from an image and then reuse it multiple times like this : 12996 * 12997 * ```js 12998 * let texture = PIXI.Texture.from('assets/image.png'); 12999 * let sprite1 = new PIXI.Sprite(texture); 13000 * let sprite2 = new PIXI.Sprite(texture); 13001 * ``` 13002 * 13003 * Textures made from SVGs, loaded or not, cannot be used before the file finishes processing. 13004 * You can check for this by checking the sprite's _textureID property. 13005 * ```js 13006 * var texture = PIXI.Texture.from('assets/image.svg'); 13007 * var sprite1 = new PIXI.Sprite(texture); 13008 * //sprite1._textureID should not be undefined if the texture has finished processing the SVG file 13009 * ``` 13010 * You can use a ticker or rAF to ensure your sprites load the finished textures after processing. See issue #3068. 13011 * 13012 * @class 13013 * @extends PIXI.utils.EventEmitter 13014 * @memberof PIXI 13015 */ 13016 var Texture = /*@__PURE__*/(function (EventEmitter) { 13017 function Texture(baseTexture, frame, orig, trim, rotate, anchor) 13018 { 13019 EventEmitter.call(this); 13020 13021 /** 13022 * Does this Texture have any frame data assigned to it? 13023 * 13024 * @member {boolean} 13025 */ 13026 this.noFrame = false;
13027 13028 if (!frame) 13029 { 13030 this.noFrame = true; 13031 frame = new Rectangle(0, 0, 1, 1); 13032 } 13033 13034 if (baseTexture instanceof Texture) 13035 { 13036 baseTexture = baseTexture.baseTexture; 13037 } 13038 13039 /** 13040 * The base texture that this texture uses. 13041 * 13042 * @member {PIXI.BaseTexture} 13043 */ 13044 this.baseTexture = baseTexture; 13045 13046 /** 13047 * This is the area of the BaseTexture image to actually copy to the Canvas / WebGL when rendering, 13048 * irrespective of the actual frame size or placement (which can be influenced by trimmed texture atlases) 13049 * 13050 * @member {PIXI.Rectangle} 13051 */ 13052 this._frame = frame; 13053 13054 /** 13055 * This is the trimmed area of original texture, before it was put in atlas 13056 * Please call `updateUvs()` after you change coordinates of `trim` manually. 13057 * 13058 * @member {PIXI.Rectangle} 13059 */ 13060 this.trim = trim; 13061 13062 /** 13063 * This will let the renderer know if the texture is valid. If it's not then it cannot be rendered. 13064 * 13065 * @member {boolean} 13066 */ 13067 this.valid = false; 13068 13069 /** 13070 * This will let a renderer know that a texture has been updated (used mainly for WebGL uv updates) 13071 * 13072 * @member {boolean} 13073 */ 13074 this.requiresUpdate = false; 13075 13076 /** 13077 * The WebGL UV data cache. Can be used as quad UV 13078 * 13079 * @member {PIXI.TextureUvs} 13080 * @protected 13081 */ 13082 this._uvs = DEFAULT_UVS; 13083 13084 /** 13085 * Default TextureMatrix instance for this texture 13086 * By default that object is not created because its heavy 13087 * 13088 * @member {PIXI.TextureMatrix} 13089 */ 13090 this.uvMatrix = null; 13091 13092 /** 13093 * This is the area of original texture, before it was put in atlas 13094 * 13095 * @member {PIXI.Rectangle} 13096 */ 13097 this.orig = orig || frame;// new Rectangle(0, 0, 1, 1); 13098 13099 this._rotate = Number(rotate || 0); 13100 13101 if (rotate === true) 13102 { 13103 // this is old texturepacker legacy, some games/libraries are passing "true" for rotated textures 13104 this._rotate = 2; 13105 } 13106 else if (this._rotate % 2 !== 0) 13107 { 13108 throw new Error('attempt to use diamond-shaped UVs. If you are sure, set rotation manually'); 13109 } 13110 13111 if (baseTexture.valid) 13112 { 13113 if (this.noFrame) 13114 { 13115 frame = new Rectangle(0, 0, baseTexture.width, baseTexture.height); 13116 13117 // if there is no frame we should monitor for any base texture changes.. 13118 baseTexture.on('update', this.onBaseTextureUpdated, this); 13119 } 13120 13121 this.frame = frame; 13122 } 13123 else 13124 { 13125 baseTexture.once('loaded', this.onBaseTextureUpdated, this); 13126 } 13127 13128 /** 13129 * Anchor point that is used as default if sprite is created with this texture. 13130 * Changing the `defaultAnchor` at a later point of time will not update Sprite's anchor point. 13131 * @member {PIXI.Point} 13132 * @default {0,0} 13133 */ 13134 this.defaultAnchor = anchor ? new Point(anchor.x, anchor.y) : new Point(0, 0); 13135 13136 /** 13137 * Update ID is observed by sprites and TextureMatrix instances. 13138 * Call updateUvs() to increment it. 13139 * 13140 * @member {number} 13141 * @protected 13142 */ 13143 13144 this._updateID = 0; 13145 13146 /** 13147 * The ids under which this Texture has been added to the texture cache. This is 13148 * automatically set as long as Texture.addToCache is used, but may not be set if a 13149 * Texture is added directly to the TextureCache array. 13150 * 13151 * @member {string[]} 13152 */ 13153 this.textureCacheIds = []; 13154 } 13155 13156 if ( EventEmitter ) { Texture.__proto__ = EventEmitter; } 13157 Texture.prototype = Object.create( EventEmitter && EventEmitter.prototype ); 13158 Texture.prototype.constructor = Texture; 13159 13160 var prototypeAccessors = { frame: { configurable: true },rotate: { configurable: true },width: { configurable: true },height: { configurable: true } }; 13161 13162 /** 13163 * Updates this texture on the gpu. 13164 * 13165 */ 13166 Texture.prototype.update = function update () 13167 {
13168 this.baseTexture.update(); 13169 }; 13170 13171 /** 13172 * Called when the base texture is updated 13173 * 13174 * @protected 13175 * @param {PIXI.BaseTexture} baseTexture - The base texture. 13176 */ 13177 Texture.prototype.onBaseTextureUpdated = function onBaseTextureUpdated (baseTexture) 13178 { 13179 this._updateID++; 13180 13181 // TODO this code looks confusing.. boo to abusing getters and setters! 13182 if (this.noFrame) 13183 { 13184 this.frame = new Rectangle(0, 0, baseTexture.width, baseTexture.height); 13185 } 13186 else 13187 { 13188 this.frame = this._frame; 13189 // TODO maybe watch out for the no frame option 13190 // updating the texture will should update the frame if it was set to no frame.. 13191 } 13192 13193 this.emit('update', this); 13194 }; 13195 13196 /** 13197 * Destroys this texture 13198 * 13199 * @param {boolean} [destroyBase=false] Whether to destroy the base texture as well 13200 */ 13201 Texture.prototype.destroy = function destroy (destroyBase) 13202 { 13203 if (this.baseTexture) 13204 { 13205 if (destroyBase) 13206 { 13207 // delete the texture if it exists in the texture cache.. 13208 // this only needs to be removed if the base texture is actually destroyed too.. 13209 if (TextureCache[this.baseTexture.imageUrl]) 13210 { 13211 Texture.removeFromCache(this.baseTexture.imageUrl); 13212 } 13213 13214 this.baseTexture.destroy(); 13215 } 13216 13217 this.baseTexture.off('update', this.onBaseTextureUpdated, this); 13218 13219 this.baseTexture = null; 13220 } 13221 13222 this._frame = null; 13223 this._uvs = null; 13224 this.trim = null; 13225 this.orig = null; 13226 13227 this.valid = false; 13228 13229 Texture.removeFromCache(this); 13230 this.textureCacheIds = null; 13231 }; 13232 13233 /** 13234 * Creates a new texture object that acts the same as this one. 13235 * 13236 * @return {PIXI.Texture} The new texture 13237 */ 13238 Texture.prototype.clone = function clone () 13239 { 13240 return new Texture(this.baseTexture, this.frame, this.orig, this.trim, this.rotate, this.defaultAnchor); 13241 }; 13242 13243 /** 13244 * Updates the internal WebGL UV cache. Use it after you change `frame` or `trim` of the texture. 13245 * Call it after changing the frame 13246 */ 13247 Texture.prototype.updateUvs = function updateUvs () 13248 { 13249 if (this._uvs === DEFAULT_UVS) 13250 { 13251 this._uvs = new TextureUvs(); 13252 } 13253 13254 this._uvs.set(this._frame, this.baseTexture, this.rotate); 13255 13256 this._updateID++; 13257 }; 13258 13259 /** 13260 * Helper function that creates a new Texture based on the source you provide. 13261 * The source can be - frame id, image url, video url, canvas element, video element, base texture 13262 * 13263 * @static 13264 * @param {number|string|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement|PIXI.BaseTexture} source 13265 * Source to create texture from 13266 * @param {object} [options] See {@link PIXI.BaseTexture}'s constructor for options. 13267 * @return {PIXI.Texture} The newly created texture 13268 */ 13269 Texture.from = function from (source, options) 13270 { 13271 if ( options === void 0 ) { options = {}; } 13272 13273 var cacheId = null; 13274 13275 if (typeof source === 'string') 13276 { 13277 cacheId = source; 13278 } 13279 else 13280 { 13281 if (!source._pixiId) 13282 { 13283 source._pixiId = "pixiid_" + (uid()); 13284 } 13285 13286 cacheId = source._pixiId; 13287 } 13288 13289 var texture = TextureCache[cacheId]; 13290 13291 if (!texture) 13292 { 13293 if (!options.resolution) 13294 { 13295 options.resolution = getResolutionOfUrl(source); 13296 } 13297 13298 texture = new Texture(new BaseTexture(source, options)); 13299 texture.baseTexture.cacheId = cacheId; 13300 13301 BaseTexture.addToCache(texture.baseTexture, cacheId); 13302 Texture.addToCache(texture, cacheId); 13303 } 13304 13305 // lets assume its a base texture! 13306 return texture; 13307 }; 13308 13309 /** 13310 * Create a new Texture with a BufferResource from a Float32Array. 13311 * RGBA values are floats from 0 to 1. 13312 * @static 13313 * @param {Float32Array|Uint8Array} buffer The optional array to use, if no data 13314 * is provided, a new Float32Array is created. 13315 * @param {number} width - Width of the resource 13316 * @param {number} height - Height of the resource 13317 * @param {object} [options] See {@link PIXI.BaseTexture}'s constructor for options. 13318 * @return {PIXI.Texture} The resulting new BaseTexture 13319 */ 13320 Texture.fromBuffer = function fromBuffer (buffer, width, height, options) 13321 {
13322 return new Texture(BaseTexture.fromBuffer(buffer, width, height, options)); 13323 }; 13324 13325 /** 13326 * Create a texture from a source and add to the cache. 13327 * 13328 * @static 13329 * @param {HTMLImageElement|HTMLCanvasElement} source - The input source. 13330 * @param {String} imageUrl - File name of texture, for cache and resolving resolution. 13331 * @param {String} [name] - Human readable name for the texture cache. If no name is 13332 * specified, only `imageUrl` will be used as the cache ID. 13333 * @return {PIXI.Texture} Output texture 13334 */ 13335 Texture.fromLoader = function fromLoader (source, imageUrl, name) 13336 { 13337 var resource = new ImageResource(source); 13338 13339 resource.url = imageUrl; 13340 13341 var baseTexture = new BaseTexture(resource, { 13342 scaleMode: settings.SCALE_MODE, 13343 resolution: getResolutionOfUrl(imageUrl), 13344 }); 13345 13346 var texture = new Texture(baseTexture); 13347 13348 // No name, use imageUrl instead 13349 if (!name) 13350 { 13351 name = imageUrl; 13352 } 13353 13354 // lets also add the frame to pixi's global cache for fromFrame and fromImage functions 13355 BaseTexture.addToCache(texture.baseTexture, name); 13356 Texture.addToCache(texture, name); 13357 13358 // also add references by url if they are different. 13359 if (name !== imageUrl) 13360 { 13361 BaseTexture.addToCache(texture.baseTexture, imageUrl); 13362 Texture.addToCache(texture, imageUrl); 13363 } 13364 13365 return texture; 13366 }; 13367 13368 /** 13369 * Adds a Texture to the global TextureCache. This cache is shared across the whole PIXI object. 13370 * 13371 * @static 13372 * @param {PIXI.Texture} texture - The Texture to add to the cache. 13373 * @param {string} id - The id that the Texture will be stored against. 13374 */ 13375 Texture.addToCache = function addToCache (texture, id) 13376 { 13377 if (id) 13378 { 13379 if (texture.textureCacheIds.indexOf(id) === -1) 13380 { 13381 texture.textureCacheIds.push(id); 13382 } 13383 13384 if (TextureCache[id]) 13385 { 13386 // eslint-disable-next-line no-console 13387 console.warn(("Texture added to the cache with an id [" + id + "] that already had an entry")); 13388 } 13389 13390 TextureCache[id] = texture; 13391 } 13392 }; 13393 13394 /** 13395 * Remove a Texture from the global TextureCache. 13396 * 13397 * @static 13398 * @param {string|PIXI.Texture} texture - id of a Texture to be removed, or a Texture instance itself 13399 * @return {PIXI.Texture|null} The Texture that was removed 13400 */ 13401 Texture.removeFromCache = function removeFromCache (texture) 13402 { 13403 if (typeof texture === 'string') 13404 { 13405 var textureFromCache = TextureCache[texture]; 13406 13407 if (textureFromCache) 13408 { 13409 var index = textureFromCache.textureCacheIds.indexOf(texture); 13410 13411 if (index > -1) 13412 { 13413 textureFromCache.textureCacheIds.splice(index, 1); 13414 } 13415 13416 delete TextureCache[texture]; 13417 13418 return textureFromCache; 13419 } 13420 } 13421 else if (texture && texture.textureCacheIds) 13422 { 13423 for (var i = 0; i < texture.textureCacheIds.length; ++i) 13424 { 13425 // Check that texture matches the one being passed in before deleting it from the cache. 13426 if (TextureCache[texture.textureCacheIds[i]] === texture) 13427 { 13428 delete TextureCache[texture.textureCacheIds[i]]; 13429 } 13430 } 13431 13432 texture.textureCacheIds.length = 0; 13433 13434 return texture; 13435 } 13436 13437 return null; 13438 }; 13439 13440 /** 13441 * The frame specifies the region of the base texture that this texture uses. 13442 * Please call `updateUvs()` after you change coordinates of `frame` manually. 13443 * 13444 * @member {PIXI.Rectangle} 13445 */ 13446 prototypeAccessors.frame.get = function () 13447 { 13448 return this._frame; 13449 }; 13450 13451 prototypeAccessors.frame.set = function (frame) // eslint-disable-line require-jsdoc 13452 { 13453 this._frame = frame; 13454 13455 this.noFrame = false;
13456 13457 var x = frame.x; 13458 var y = frame.y; 13459 var width = frame.width; 13460 var height = frame.height; 13461 var xNotFit = x + width > this.baseTexture.width; 13462 var yNotFit = y + height > this.baseTexture.height; 13463 13464 if (xNotFit || yNotFit) 13465 { 13466 var relationship = xNotFit && yNotFit ? 'and' : 'or'; 13467 var errorX = "X: " + x + " + " + width + " = " + (x + width) + " > " + (this.baseTexture.width); 13468 var errorY = "Y: " + y + " + " + height + " = " + (y + height) + " > " + (this.baseTexture.height); 13469 13470 throw new Error('Texture Error: frame does not fit inside the base Texture dimensions: ' 13471 + errorX + " " + relationship + " " + errorY); 13472 } 13473 13474 this.valid = width && height && this.baseTexture.valid; 13475 13476 if (!this.trim && !this.rotate) 13477 { 13478 this.orig = frame; 13479 } 13480 13481 if (this.valid) 13482 { 13483 this.updateUvs(); 13484 } 13485 }; 13486 13487 /** 13488 * Indicates whether the texture is rotated inside the atlas 13489 * set to 2 to compensate for texture packer rotation 13490 * set to 6 to compensate for spine packer rotation 13491 * can be used to rotate or mirror sprites 13492 * See {@link PIXI.GroupD8} for explanation 13493 * 13494 * @member {number} 13495 */ 13496 prototypeAccessors.rotate.get = function () 13497 { 13498 return this._rotate; 13499 }; 13500 13501 prototypeAccessors.rotate.set = function (rotate) // eslint-disable-line require-jsdoc 13502 { 13503 this._rotate = rotate; 13504 if (this.valid) 13505 { 13506 this.updateUvs(); 13507 } 13508 }; 13509 13510 /** 13511 * The width of the Texture in pixels. 13512 * 13513 * @member {number} 13514 */ 13515 prototypeAccessors.width.get = function () 13516 { 13517 return this.orig.width; 13518 }; 13519 13520 /** 13521 * The height of the Texture in pixels. 13522 * 13523 * @member {number} 13524 */ 13525 prototypeAccessors.height.get = function () 13526 { 13527 return this.orig.height; 13528 }; 13529 13530 Object.defineProperties( Texture.prototype, prototypeAccessors ); 13531 13532 return Texture; 13533 }(eventemitter3)); 13534 13535 function createWhiteTexture() 13536 { 13537 var canvas = document.createElement('canvas'); 13538 13539 canvas.width = 16; 13540 canvas.height = 16; 13541 13542 var context = canvas.getContext('2d'); 13543 13544 context.fillStyle = 'white'; 13545 context.fillRect(0, 0, 16, 16); 13546 13547 return new Texture(new BaseTexture(new CanvasResource(canvas))); 13548 } 13549 13550 function removeAllHandlers(tex) 13551 { 13552 tex.destroy = function _emptyDestroy() { /* empty */ }; 13553 tex.on = function _emptyOn() { /* empty */ }; 13554 tex.once = function _emptyOnce() { /* empty */ }; 13555 tex.emit = function _emptyEmit() { /* empty */ }; 13556 } 13557 13558 /** 13559 * An empty texture, used often to not have to create multiple empty textures. 13560 * Can not be destroyed. 13561 * 13562 * @static 13563 * @constant 13564 * @member {PIXI.Texture} 13565 */ 13566 Texture.EMPTY = new Texture(new BaseTexture()); 13567 removeAllHandlers(Texture.EMPTY); 13568 removeAllHandlers(Texture.EMPTY.baseTexture); 13569 13570 /** 13571 * A white texture of 10x10 size, used for graphics and other things 13572 * Can not be destroyed. 13573 * 13574 * @static 13575 * @constant 13576 * @member {PIXI.Texture} 13577 */ 13578 Texture.WHITE = createWhiteTexture(); 13579 removeAllHandlers(Texture.WHITE); 13580 removeAllHandlers(Texture.WHITE.baseTexture); 13581 13582 /** 13583 * A RenderTexture is a special texture that allows any PixiJS display object to be rendered to it. 13584 * 13585 * __Hint__: All DisplayObjects (i.e. Sprites) that render to a RenderTexture should be preloaded 13586 * otherwise black rectangles will be drawn instead. 13587 * 13588 * A RenderTexture takes a snapshot of any Display Object given to its render method. For example: 13589 * 13590 * ```js 13591 * let renderer = PIXI.autoDetectRenderer(); 13592 * let renderTexture = PIXI.RenderTexture.create(800, 600); 13593 * let sprite = PIXI.Sprite.from("spinObj_01.png"); 13594 * 13595 * sprite.position.x = 800/2; 13596 * sprite.position.y = 600/2; 13597 * sprite.anchor.x = 0.5; 13598 * sprite.anchor.y = 0.5; 13599 * 13600 * renderer.render(sprite, renderTexture); 13601 * ``` 13602 * 13603 * The Sprite in this case will be rendered using its local transform. To render this sprite at 0,0
13604 * you can clear the transform 13605 * 13606 * ```js 13607 * 13608 * sprite.setTransform() 13609 * 13610 * let renderTexture = new PIXI.RenderTexture.create(100, 100); 13611 * 13612 * renderer.render(sprite, renderTexture); // Renders to center of RenderTexture 13613 * ``` 13614 * 13615 * @class 13616 * @extends PIXI.Texture 13617 * @memberof PIXI 13618 */ 13619 var RenderTexture = /*@__PURE__*/(function (Texture) { 13620 function RenderTexture(baseRenderTexture, frame) 13621 { 13622 // support for legacy.. 13623 var _legacyRenderer = null; 13624 13625 if (!(baseRenderTexture instanceof BaseRenderTexture)) 13626 { 13627 /* eslint-disable prefer-rest-params, no-console */ 13628 var width = arguments[1]; 13629 var height = arguments[2]; 13630 var scaleMode = arguments[3]; 13631 var resolution = arguments[4]; 13632 13633 // we have an old render texture.. 13634 console.warn(("Please use RenderTexture.create(" + width + ", " + height + ") instead of the ctor directly.")); 13635 _legacyRenderer = arguments[0]; 13636 /* eslint-enable prefer-rest-params, no-console */ 13637 13638 frame = null; 13639 baseRenderTexture = new BaseRenderTexture({ 13640 width: width, 13641 height: height, 13642 scaleMode: scaleMode, 13643 resolution: resolution, 13644 }); 13645 } 13646 13647 /** 13648 * The base texture object that this texture uses 13649 * 13650 * @member {BaseTexture} 13651 */ 13652 Texture.call(this, baseRenderTexture, frame); 13653 13654 this.legacyRenderer = _legacyRenderer; 13655 13656 /** 13657 * This will let the renderer know if the texture is valid. If it's not then it cannot be rendered. 13658 * 13659 * @member {boolean} 13660 */ 13661 this.valid = true; 13662 13663 /** 13664 * FilterSystem temporary storage 13665 * @protected 13666 * @member {PIXI.Rectangle} 13667 */ 13668 this.filterFrame = null; 13669 13670 /** 13671 * The key for pooled texture of FilterSystem 13672 * @protected 13673 * @member {string} 13674 */ 13675 this.filterPoolKey = null; 13676 13677 this.updateUvs(); 13678 } 13679 13680 if ( Texture ) { RenderTexture.__proto__ = Texture; } 13681 RenderTexture.prototype = Object.create( Texture && Texture.prototype ); 13682 RenderTexture.prototype.constructor = RenderTexture; 13683 13684 /** 13685 * Resizes the RenderTexture. 13686 * 13687 * @param {number} width - The width to resize to. 13688 * @param {number} height - The height to resize to. 13689 * @param {boolean} [resizeBaseTexture=true] - Should the baseTexture.width and height values be resized as well? 13690 */ 13691 RenderTexture.prototype.resize = function resize (width, height, resizeBaseTexture) 13692 { 13693 if ( resizeBaseTexture === void 0 ) { resizeBaseTexture = true; } 13694 13695 width = Math.ceil(width); 13696 height = Math.ceil(height); 13697 13698 // TODO - could be not required.. 13699 this.valid = (width > 0 && height > 0); 13700 13701 this._frame.width = this.orig.width = width; 13702 this._frame.height = this.orig.height = height; 13703 13704 if (resizeBaseTexture) 13705 { 13706 this.baseTexture.resize(width, height); 13707 } 13708 13709 this.updateUvs(); 13710 }; 13711 13712 /** 13713 * A short hand way of creating a render texture. 13714 * 13715 * @param {object} [options] - Options 13716 * @param {number} [options.width=100] - The width of the render texture 13717 * @param {number} [options.height=100] - The height of the render texture 13718 * @param {number} [options.scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values 13719 * @param {number} [options.resolution=1] - The resolution / device pixel ratio of the texture being generated 13720 * @return {PIXI.RenderTexture} The new render texture 13721 */ 13722 RenderTexture.create = function create (options) 13723 { 13724 // fallback, old-style: create(width, height, scaleMode, resolution) 13725 if (typeof options === 'number') 13726 { 13727 /* eslint-disable prefer-rest-params */ 13728 options = { 13729 width: options, 13730 height: arguments[1], 13731 scaleMode: arguments[2], 13732 resolution: arguments[3], 13733 }; 13734 /* eslint-enable prefer-rest-params */ 13735 } 13736 13737 return new RenderTexture(new BaseRenderTexture(options)); 13738 }; 13739 13740 return RenderTexture; 13741 }(Texture)); 13742 13743 /* eslint-disable max-len */ 13744 13745 /** 13746 * Holds the information for a single attribute structure required to render geometry. 13747 * 13748 * This does not contain the actual data, but instead has a buffer id that maps to a {@link PIXI.Buffer} 13749 * This can include anything from positions, uvs, normals, colors etc. 13750 * 13751 * @class 13752 * @memberof PIXI 13753 */ 13754 var Attribute = function Attribute(buffer, size, normalized, type, stride, start, instance) 13755 { 13756 if ( normalized === void 0 ) { normalized = false; } 13757 if ( type === void 0 ) { type = 5126; } 13758 13759 this.buffer = buffer; 13760 this.size = size; 13761 this.normalized = normalized; 13762 this.type = type; 13763 this.stride = stride; 13764 this.start = start; 13765 this.instance = instance; 13766 }; 13767 13768 /** 13769 * Destroys the Attribute. 13770 */ 13771 Attribute.prototype.destroy = function destroy () 13772 { 13773 this.buffer = null; 13774 }; 13775 13776 /** 13777 * Helper function that creates an Attribute based on the information provided 13778 * 13779 * @static 13780 * @param {string} buffer the id of the buffer that this attribute will look for 13781 * @param {Number} [size=2] the size of the attribute. If you have 2 floats per vertex (eg position x and y) this would be 2 13782 * @param {Number} [stride=0] How far apart (in floats) the start of each value is. (used for interleaving data) 13783 * @param {Number} [start=0] How far into the array to start reading values (used for interleaving data) 13784 * @param {Boolean} [normalized=false] should the data be normalized. 13785 * 13786 * @returns {PIXI.Attribute} A new {@link PIXI.Attribute} based on the information provided 13787 */ 13788 Attribute.from = function from (buffer, size, stride, start, normalized) 13789 { 13790 return new Attribute(buffer, size, stride, start, normalized); 13791 }; 13792 13793 var UID = 0; 13794 /* eslint-disable max-len */ 13795 13796 /** 13797 * A wrapper for data so that it can be used and uploaded by WebGL 13798 * 13799 * @class 13800 * @memberof PIXI 13801 */ 13802 var Buffer = function Buffer(data, _static, index) 13803 { 13804 if ( _static === void 0 ) { _static = true; } 13805 if ( index === void 0 ) { index = false; } 13806 13807 /** 13808 * The data in the buffer, as a typed array 13809 * 13810 * @member {ArrayBuffer| SharedArrayBuffer|ArrayBufferView} 13811 */ 13812 this.data = data || new Float32Array(1); 13813 13814 /** 13815 * A map of renderer IDs to webgl buffer 13816 * 13817 * @private 13818 * @member {object<number, GLBuffer>} 13819 */ 13820 this._glBuffers = {}; 13821 13822 this._updateID = 0; 13823 13824 this.index = index; 13825 13826 this.static = _static; 13827 13828 this.id = UID++; 13829 13830 this.disposeRunner = new Runner('disposeBuffer', 2); 13831 }; 13832 13833 // TODO could explore flagging only a partial upload? 13834 /** 13835 * flags this buffer as requiring an upload to the GPU 13836 */ 13837 Buffer.prototype.update = function update (data) 13838 { 13839 this.data = data || this.data; 13840 this._updateID++; 13841 }; 13842 13843 /** 13844 * disposes WebGL resources that are connected to this geometry 13845 */ 13846 Buffer.prototype.dispose = function dispose () 13847 { 13848 this.disposeRunner.run(this, false); 13849 }; 13850 13851 /** 13852 * Destroys the buffer 13853 */ 13854 Buffer.prototype.destroy = function destroy () 13855 { 13856 this.dispose(); 13857 13858 this.data = null; 13859 }; 13860 13861 /** 13862 * Helper function that creates a buffer based on an array or TypedArray 13863 * 13864 * @static 13865 * @param {ArrayBufferView | number[]} data the TypedArray that the buffer will store. If this is a regular Array it will be converted to a Float32Array. 13866 * @return {PIXI.Buffer} A new Buffer based on the data provided. 13867 */ 13868 Buffer.from = function from (data) 13869 { 13870 if (data instanceof Array) 13871 { 13872 data = new Float32Array(data); 13873 } 13874 13875 return new Buffer(data); 13876 }; 13877 13878 function getBufferType(array) 13879 { 13880 if (array.BYTES_PER_ELEMENT === 4) 13881 { 13882 if (array instanceof Float32Array) 13883 { 13884 return 'Float32Array'; 13885 } 13886 else if (array instanceof Uint32Array) 13887 { 13888 return 'Uint32Array'; 13889 } 13890 13891 return 'Int32Array'; 13892 } 13893 else if (array.BYTES_PER_ELEMENT === 2) 13894 { 13895 if (array instanceof Uint16Array) 13896 { 13897 return 'Uint16Array'; 13898 } 13899 } 13900 else if (array.BYTES_PER_ELEMENT === 1) 13901 { 13902 if (array instanceof Uint8Array) 13903 { 13904 return 'Uint8Array'; 13905 } 13906 } 13907 13908 // TODO map out the rest of the array elements! 13909 return null; 13910 } 13911 13912 /* eslint-disable object-shorthand */ 13913 var map = { 13914 Float32Array: Float32Array, 13915 Uint32Array: Uint32Array, 13916 Int32Array: Int32Array, 13917 Uint8Array: Uint8Array, 13918 }; 13919 13920 function interleaveTypedArrays(arrays, sizes) 13921 { 13922 var outSize = 0; 13923 var stride = 0; 13924 var views = {}; 13925 13926 for (var i = 0; i < arrays.length; i++) 13927 {
13928 stride += sizes[i]; 13929 outSize += arrays[i].length; 13930 } 13931 13932 var buffer = new ArrayBuffer(outSize * 4); 13933 13934 var out = null; 13935 var littleOffset = 0; 13936 13937 for (var i$1 = 0; i$1 < arrays.length; i$1++) 13938 { 13939 var size = sizes[i$1]; 13940 var array = arrays[i$1]; 13941 13942 var type = getBufferType(array); 13943 13944 if (!views[type]) 13945 { 13946 views[type] = new map[type](buffer); 13947 } 13948 13949 out = views[type]; 13950 13951 for (var j = 0; j < array.length; j++) 13952 { 13953 var indexStart = ((j / size | 0) * stride) + littleOffset; 13954 var index = j % size; 13955 13956 out[indexStart + index] = array[j]; 13957 } 13958 13959 littleOffset += size; 13960 } 13961 13962 return new Float32Array(buffer); 13963 } 13964 13965 var byteSizeMap = { 5126: 4, 5123: 2, 5121: 1 }; 13966 var UID$1 = 0; 13967 13968 /* eslint-disable object-shorthand */ 13969 var map$1 = { 13970 Float32Array: Float32Array, 13971 Uint32Array: Uint32Array, 13972 Int32Array: Int32Array, 13973 Uint8Array: Uint8Array, 13974 Uint16Array: Uint16Array, 13975 }; 13976 13977 /* eslint-disable max-len */ 13978 13979 /** 13980 * The Geometry represents a model. It consists of two components: 13981 * - GeometryStyle - The structure of the model such as the attributes layout 13982 * - GeometryData - the data of the model - this consists of buffers. 13983 * This can include anything from positions, uvs, normals, colors etc. 13984 * 13985 * Geometry can be defined without passing in a style or data if required (thats how I prefer!) 13986 * 13987 * ```js 13988 * let geometry = new PIXI.Geometry(); 13989 * 13990 * geometry.addAttribute('positions', [0, 0, 100, 0, 100, 100, 0, 100], 2); 13991 * geometry.addAttribute('uvs', [0,0,1,0,1,1,0,1],2) 13992 * geometry.addIndex([0,1,2,1,3,2]) 13993 * 13994 * ``` 13995 * @class 13996 * @memberof PIXI 13997 */ 13998 var Geometry = function Geometry(buffers, attributes) 13999 { 14000 if ( buffers === void 0 ) { buffers = []; } 14001 if ( attributes === void 0 ) { attributes = {}; } 14002 14003 this.buffers = buffers; 14004 14005 this.indexBuffer = null; 14006 14007 this.attributes = attributes; 14008 14009 /** 14010 * A map of renderer IDs to webgl VAOs 14011 * 14012 * @protected 14013 * @type {object} 14014 */ 14015 this.glVertexArrayObjects = {}; 14016 14017 this.id = UID$1++; 14018 14019 this.instanced = false; 14020 14021 this.instanceCount = 1; 14022 14023 this._size = null; 14024 14025 this.disposeRunner = new Runner('disposeGeometry', 2); 14026 14027 /** 14028 * Count of existing (not destroyed) meshes that reference this geometry 14029 * @member {boolean} 14030 */ 14031 this.refCount = 0; 14032 }; 14033 14034 /** 14035 * 14036 * Adds an attribute to the geometry 14037 * 14038 * @param {String} id - the name of the attribute (matching up to a shader) 14039 * @param {PIXI.Buffer} [buffer] the buffer that holds the data of the attribute . You can also provide an Array and a buffer will be created from it. 14040 * @param {Number} [size=0] the size of the attribute. If you have 2 floats per vertex (eg position x and y) this would be 2 14041 * @param {Boolean} [normalized=false] should the data be normalized. 14042 * @param {Number} [type=PIXI.TYPES.FLOAT] what type of number is the attribute. Check {PIXI.TYPES} to see the ones available 14043 * @param {Number} [stride=0] How far apart (in floats) the start of each value is. (used for interleaving data) 14044 * @param {Number} [start=0] How far into the array to start reading values (used for interleaving data) 14045 * 14046 * @return {PIXI.Geometry} returns self, useful for chaining. 14047 */ 14048 Geometry.prototype.addAttribute = function addAttribute (id, buffer, size, normalized, type, stride, start, instance) 14049 { 14050 if ( normalized === void 0 ) { normalized = false; } 14051 if ( instance === void 0 ) { instance = false; } 14052 14053 if (!buffer) 14054 { 14055 throw new Error('You must pass a buffer when creating an attribute'); 14056 } 14057 14058 // check if this is a buffer! 14059 if (!buffer.data) 14060 { 14061 // its an array! 14062 if (buffer instanceof Array) 14063 { 14064 buffer = new Float32Array(buffer); 14065 } 14066 14067 buffer = new Buffer(buffer); 14068 } 14069 14070 var ids = id.split('|'); 14071 14072 if (ids.length > 1) 14073 { 14074 for (var i = 0; i < ids.length; i++) 14075 { 14076 this.addAttribute(ids[i], buffer, size, normalized, type); 14077 } 14078 14079 return this; 14080 } 14081 14082 var bufferIndex = this.buffers.indexOf(buffer); 14083 14084 if (bufferIndex === -1) 14085 { 14086 this.buffers.push(buffer); 14087 bufferIndex = this.buffers.length - 1; 14088 } 14089 14090 this.attributes[id] = new Attribute(bufferIndex, size, normalized, type, stride, start, instance); 14091 14092 // assuming that if there is instanced data then this will be drawn with instancing! 14093 this.instanced = this.instanced || instance; 14094 14095 return this; 14096 }; 14097 14098 /** 14099 * returns the requested attribute 14100 * 14101 * @param {String} id the name of the attribute required 14102 * @return {PIXI.Attribute} the attribute requested. 14103 */ 14104 Geometry.prototype.getAttribute = function getAttribute (id) 14105 { 14106 return this.buffers[this.attributes[id].buffer]; 14107 }; 14108 14109 /** 14110 * 14111 * Adds an index buffer to the geometry 14112 * The index buffer contains integers, three for each triangle in the geometry, which reference the various attribute buffers (position, colour, UV coordinates, other UV coordinates, normal, …). There is only ONE index buffer. 14113 * 14114 * @param {PIXI.Buffer} [buffer] the buffer that holds the data of the index buffer. You can also provide an Array and a buffer will be created from it. 14115 * @return {PIXI.Geometry} returns self, useful for chaining. 14116 */ 14117 Geometry.prototype.addIndex = function addIndex (buffer) 14118 { 14119 if (!buffer.data) 14120 { 14121 // its an array! 14122 if (buffer instanceof Array) 14123 { 14124 buffer = new Uint16Array(buffer); 14125 } 14126 14127 buffer = new Buffer(buffer); 14128 } 14129 14130 buffer.index = true; 14131 this.indexBuffer = buffer; 14132 14133 if (this.buffers.indexOf(buffer) === -1) 14134 { 14135 this.buffers.push(buffer); 14136 } 14137 14138 return this; 14139 }; 14140 14141 /** 14142 * returns the index buffer 14143 * 14144 * @return {PIXI.Buffer} the index buffer. 14145 */ 14146 Geometry.prototype.getIndex = function getIndex () 14147 { 14148 return this.indexBuffer; 14149 }; 14150 14151 /** 14152 * this function modifies the structure so that all current attributes become interleaved into a single buffer 14153 * This can be useful if your model remains static as it offers a little performance boost 14154 * 14155 * @return {PIXI.Geometry} returns self, useful for chaining. 14156 */ 14157 Geometry.prototype.interleave = function interleave () 14158 { 14159 // a simple check to see if buffers are already interleaved.. 14160 if (this.buffers.length === 1 || (this.buffers.length === 2 && this.indexBuffer)) { return this; } 14161 14162 // assume already that no buffers are interleaved 14163 var arrays = []; 14164 var sizes = []; 14165 var interleavedBuffer = new Buffer(); 14166 var i; 14167 14168 for (i in this.attributes) 14169 { 14170 var attribute = this.attributes[i]; 14171 14172 var buffer = this.buffers[attribute.buffer]; 14173 14174 arrays.push(buffer.data); 14175 14176 sizes.push((attribute.size * byteSizeMap[attribute.type]) / 4); 14177 14178 attribute.buffer = 0; 14179 } 14180 14181 interleavedBuffer.data = interleaveTypedArrays(arrays, sizes); 14182 14183 for (i = 0; i < this.buffers.length; i++) 14184 { 14185 if (this.buffers[i] !== this.indexBuffer) 14186 { 14187 this.buffers[i].destroy(); 14188 } 14189 } 14190 14191 this.buffers = [interleavedBuffer]; 14192 14193 if (this.indexBuffer) 14194 { 14195 this.buffers.push(this.indexBuffer); 14196 } 14197 14198 return this; 14199 }; 14200 14201 Geometry.prototype.getSize = function getSize () 14202 { 14203 for (var i in this.attributes) 14204 { 14205 var attribute = this.attributes[i]; 14206 var buffer = this.buffers[attribute.buffer]; 14207 14208 return buffer.data.length / ((attribute.stride / 4) || attribute.size); 14209 } 14210 14211 return 0; 14212 }; 14213 14214 /** 14215 * disposes WebGL resources that are connected to this geometry 14216 */ 14217 Geometry.prototype.dispose = function dispose () 14218 { 14219 this.disposeRunner.run(this, false); 14220 }; 14221 14222 /** 14223 * Destroys the geometry. 14224 */ 14225 Geometry.prototype.destroy = function destroy () 14226 { 14227 this.dispose(); 14228 14229 this.buffers = null; 14230 this.indexBuffer.destroy(); 14231 14232 this.attributes = null; 14233 }; 14234 14235 /** 14236 * returns a clone of the geometry 14237 * 14238 * @returns {PIXI.Geometry} a new clone of this geometry 14239 */ 14240 Geometry.prototype.clone = function clone () 14241 { 14242 var geometry = new Geometry(); 14243 14244 for (var i = 0; i < this.buffers.length; i++) 14245 { 14246 geometry.buffers[i] = new Buffer(this.buffers[i].data.slice()); 14247 } 14248 14249 for (var i$1 in this.attributes) 14250 { 14251 var attrib = this.attributes[i$1]; 14252 14253 geometry.attributes[i$1] = new Attribute( 14254 attrib.buffer, 14255 attrib.size, 14256 attrib.normalized, 14257 attrib.type, 14258 attrib.stride, 14259 attrib.start, 14260 attrib.instance 14261 ); 14262 } 14263 14264 if (this.indexBuffer) 14265 { 14266 geometry.indexBuffer = geometry.buffers[this.buffers.indexOf(this.indexBuffer)]; 14267 geometry.indexBuffer.index = true; 14268 } 14269 14270 return geometry; 14271 }; 14272 14273 /** 14274 * merges an array of geometries into a new single one 14275 * geometry attribute styles must match for this operation to work 14276 * 14277 * @param {PIXI.Geometry[]} geometries array of geometries to merge 14278 * @returns {PIXI.Geometry} shiny new geometry! 14279 */ 14280 Geometry.merge = function merge (geometries) 14281 { 14282 // todo add a geometry check! 14283 // also a size check.. cant be too big!] 14284 14285 var geometryOut = new Geometry(); 14286 14287 var arrays = []; 14288 var sizes = []; 14289 var offsets = []; 14290 14291 var geometry; 14292 14293 // pass one.. get sizes.. 14294 for (var i = 0; i < geometries.length; i++) 14295 { 14296 geometry = geometries[i]; 14297 14298 for (var j = 0; j < geometry.buffers.length; j++) 14299 { 14300 sizes[j] = sizes[j] || 0; 14301 sizes[j] += geometry.buffers[j].data.length; 14302 offsets[j] = 0; 14303 } 14304 } 14305 14306 // build the correct size arrays.. 14307 for (var i$1 = 0; i$1 < geometry.buffers.length; i$1++) 14308 { 14309 // TODO types! 14310 arrays[i$1] = new map$1[getBufferType(geometry.buffers[i$1].data)](sizes[i$1]); 14311 geometryOut.buffers[i$1] = new Buffer(arrays[i$1]); 14312 } 14313 14314 // pass to set data.. 14315 for (var i$2 = 0; i$2 < geometries.length; i$2++) 14316 { 14317 geometry = geometries[i$2]; 14318 14319 for (var j$1 = 0; j$1 < geometry.buffers.length; j$1++) 14320 { 14321 arrays[j$1].set(geometry.buffers[j$1].data, offsets[j$1]); 14322 offsets[j$1] += geometry.buffers[j$1].data.length; 14323 } 14324 } 14325 14326 geometryOut.attributes = geometry.attributes; 14327 14328 if (geometry.indexBuffer) 14329 { 14330 geometryOut.indexBuffer = geometryOut.buffers[geometry.buffers.indexOf(geometry.indexBuffer)]; 14331 geometryOut.indexBuffer.index = true; 14332 14333 var offset = 0; 14334 var stride = 0; 14335 var offset2 = 0; 14336 var bufferIndexToCount = 0; 14337 14338 // get a buffer 14339 for (var i$3 = 0; i$3 < geometry.buffers.length; i$3++) 14340 { 14341 if (geometry.buffers[i$3] !== geometry.indexBuffer) 14342 { 14343 bufferIndexToCount = i$3; 14344 break; 14345 } 14346 } 14347 14348 // figure out the stride of one buffer.. 14349 for (var i$4 in geometry.attributes) 14350 { 14351 var attribute = geometry.attributes[i$4]; 14352 14353 if ((attribute.buffer | 0) === bufferIndexToCount) 14354 {
14355 stride += ((attribute.size * byteSizeMap[attribute.type]) / 4); 14356 } 14357 } 14358 14359 // time to off set all indexes.. 14360 for (var i$5 = 0; i$5 < geometries.length; i$5++) 14361 { 14362 var indexBufferData = geometries[i$5].indexBuffer.data; 14363 14364 for (var j$2 = 0; j$2 < indexBufferData.length; j$2++) 14365 { 14366 geometryOut.indexBuffer.data[j$2 + offset2] += offset; 14367 } 14368 14369 offset += geometry.buffers[bufferIndexToCount].data.length / (stride); 14370 offset2 += indexBufferData.length; 14371 } 14372 } 14373 14374 return geometryOut; 14375 }; 14376 14377 /** 14378 * Helper class to create a quad 14379 * 14380 * @class 14381 * @memberof PIXI 14382 */ 14383 var Quad = /*@__PURE__*/(function (Geometry) { 14384 function Quad() 14385 { 14386 Geometry.call(this); 14387 14388 this.addAttribute('aVertexPosition', [ 14389 0, 0, 14390 1, 0, 14391 1, 1, 14392 0, 1 ]) 14393 .addIndex([0, 1, 3, 2]); 14394 } 14395 14396 if ( Geometry ) { Quad.__proto__ = Geometry; } 14397 Quad.prototype = Object.create( Geometry && Geometry.prototype ); 14398 Quad.prototype.constructor = Quad; 14399 14400 return Quad; 14401 }(Geometry)); 14402 14403 /** 14404 * Helper class to create a quad with uvs like in v4 14405 * 14406 * @class 14407 * @memberof PIXI 14408 */ 14409 var QuadUv = /*@__PURE__*/(function (Geometry) { 14410 function QuadUv() 14411 { 14412 Geometry.call(this); 14413 14414 /** 14415 * An array of vertices 14416 * 14417 * @member {Float32Array} 14418 */ 14419 this.vertices = new Float32Array([ 14420 -1, -1, 14421 1, -1, 14422 1, 1, 14423 -1, 1 ]); 14424 14425 /** 14426 * The Uvs of the quad 14427 * 14428 * @member {Float32Array} 14429 */ 14430 this.uvs = new Float32Array([ 14431 0, 0, 14432 1, 0, 14433 1, 1, 14434 0, 1 ]); 14435 14436 this.vertexBuffer = new Buffer(this.vertices); 14437 this.uvBuffer = new Buffer(this.uvs); 14438 14439 this.addAttribute('aVertexPosition', this.vertexBuffer) 14440 .addAttribute('aTextureCoord', this.uvBuffer) 14441 .addIndex([0, 1, 2, 0, 2, 3]); 14442 } 14443 14444 if ( Geometry ) { QuadUv.__proto__ = Geometry; } 14445 QuadUv.prototype = Object.create( Geometry && Geometry.prototype ); 14446 QuadUv.prototype.constructor = QuadUv; 14447 14448 /** 14449 * Maps two Rectangle to the quad. 14450 * 14451 * @param {PIXI.Rectangle} targetTextureFrame - the first rectangle 14452 * @param {PIXI.Rectangle} destinationFrame - the second rectangle 14453 * @return {PIXI.Quad} Returns itself. 14454 */ 14455 QuadUv.prototype.map = function map (targetTextureFrame, destinationFrame) 14456 { 14457 var x = 0; // destinationFrame.x / targetTextureFrame.width; 14458 var y = 0; // destinationFrame.y / targetTextureFrame.height; 14459 14460 this.uvs[0] = x; 14461 this.uvs[1] = y; 14462 14463 this.uvs[2] = x + (destinationFrame.width / targetTextureFrame.width); 14464 this.uvs[3] = y; 14465 14466 this.uvs[4] = x + (destinationFrame.width / targetTextureFrame.width); 14467 this.uvs[5] = y + (destinationFrame.height / targetTextureFrame.height); 14468 14469 this.uvs[6] = x; 14470 this.uvs[7] = y + (destinationFrame.height / targetTextureFrame.height); 14471 14472 x = destinationFrame.x; 14473 y = destinationFrame.y; 14474 14475 this.vertices[0] = x; 14476 this.vertices[1] = y; 14477 14478 this.vertices[2] = x + destinationFrame.width; 14479 this.vertices[3] = y; 14480 14481 this.vertices[4] = x + destinationFrame.width; 14482 this.vertices[5] = y + destinationFrame.height; 14483 14484 this.vertices[6] = x; 14485 this.vertices[7] = y + destinationFrame.height; 14486 14487 this.invalidate(); 14488 14489 return this; 14490 }; 14491 14492 /** 14493 * legacy upload method, just marks buffers dirty 14494 * @returns {PIXI.QuadUv} Returns itself. 14495 */
14496 QuadUv.prototype.invalidate = function invalidate () 14497 { 14498 this.vertexBuffer._updateID++; 14499 this.uvBuffer._updateID++; 14500 14501 return this; 14502 }; 14503 14504 return QuadUv; 14505 }(Geometry)); 14506 14507 /** 14508 * Calculates the mapped matrix 14509 * @param {PIXI.Matrix} outputMatrix matrix that will normalize map filter cords in the filter to screen space 14510 * @param {PIXI.Rectangle} filterArea filter area 14511 * @param {PIXI.Rectangle} textureSize texture size 14512 * @returns {PIXI.Matrix} same as outputMatrix 14513 * @private 14514 */ 14515 function calculateScreenSpaceMatrix(outputMatrix, filterArea, textureSize) 14516 { 14517 // TODO unwrap? 14518 var mappedMatrix = outputMatrix.identity(); 14519 14520 mappedMatrix.translate(filterArea.x / textureSize.width, filterArea.y / textureSize.height); 14521 14522 mappedMatrix.scale(textureSize.width, textureSize.height); 14523 14524 return mappedMatrix; 14525 } 14526 14527 // this will map the filter coord so that a texture can be used based on the transform of a sprite 14528 function calculateSpriteMatrix(outputMatrix, filterArea, textureSize, sprite) 14529 { 14530 var orig = sprite._texture.orig; 14531 var mappedMatrix = outputMatrix.set(textureSize.width, 0, 0, textureSize.height, filterArea.x, filterArea.y); 14532 var worldTransform = sprite.worldTransform.copyTo(Matrix.TEMP_MATRIX); 14533 14534 worldTransform.invert(); 14535 mappedMatrix.prepend(worldTransform); 14536 mappedMatrix.scale(1.0 / orig.width, 1.0 / orig.height); 14537 mappedMatrix.translate(sprite.anchor.x, sprite.anchor.y); 14538 14539 return mappedMatrix; 14540 } 14541 14542 var UID$2 = 0; 14543 14544 /** 14545 * Uniform group holds uniform map and some ID's for work 14546 * 14547 * @class 14548 * @memberof PIXI 14549 */ 14550 var UniformGroup = function UniformGroup(uniforms, _static) 14551 { 14552 /** 14553 * uniform values 14554 * @member {object} 14555 * @readonly 14556 */ 14557 this.uniforms = uniforms; 14558 14559 /** 14560 * Its a group and not a single uniforms 14561 * @member {boolean} 14562 * @readonly 14563 * @default true 14564 */ 14565 this.group = true; 14566 14567 // lets generate this when the shader ? 14568 this.syncUniforms = {}; 14569 14570 /** 14571 * dirty version 14572 * @protected 14573 * @member {number} 14574 */ 14575 this.dirtyId = 0; 14576 14577 /** 14578 * unique id 14579 * @protected 14580 * @member {number} 14581 */ 14582 this.id = UID$2++; 14583 14584 /** 14585 * Uniforms wont be changed after creation 14586 * @member {boolean} 14587 */ 14588 this.static = !!_static; 14589 }; 14590 14591 UniformGroup.prototype.update = function update () 14592 { 14593 this.dirtyId++; 14594 }; 14595 14596 UniformGroup.prototype.add = function add (name, uniforms, _static) 14597 { 14598 this.uniforms[name] = new UniformGroup(uniforms, _static); 14599 }; 14600 14601 UniformGroup.from = function from (uniforms, _static) 14602 { 14603 return new UniformGroup(uniforms, _static); 14604 }; 14605 14606 /** 14607 * System plugin to the renderer to manage filter states. 14608 * 14609 * @class 14610 * @private 14611 */ 14612 var FilterState = function FilterState() 14613 { 14614 this.renderTexture = null; 14615 14616 /** 14617 * Target of the filters 14618 * We store for case when custom filter wants to know the element it was applied on 14619 * @member {PIXI.DisplayObject} 14620 * @private 14621 */ 14622 this.target = null; 14623 14624 /** 14625 * Compatibility with PixiJS v4 filters 14626 * @member {boolean} 14627 * @default false 14628 * @private 14629 */ 14630 this.legacy = false; 14631 14632 /** 14633 * Resolution of filters 14634 * @member {number} 14635 * @default 1 14636 * @private 14637 */ 14638 this.resolution = 1; 14639 14640 // next three fields are created only for root 14641 // re-assigned for everything else 14642 14643 /** 14644 * Source frame 14645 * @member {PIXI.Rectangle} 14646 * @private 14647 */ 14648 this.sourceFrame = new Rectangle(); 14649 14650 /** 14651 * Destination frame 14652 * @member {PIXI.Rectangle} 14653 * @private 14654 */ 14655 this.destinationFrame = new Rectangle(); 14656 14657 /** 14658 * Collection of filters 14659 * @member {PIXI.Filter[]} 14660 * @private 14661 */ 14662 this.filters = []; 14663 }; 14664 14665 /** 14666 * clears the state 14667 * @private 14668 */ 14669 FilterState.prototype.clear = function clear () 14670 { 14671 this.target = null; 14672 this.filters = null; 14673 this.renderTexture = null; 14674 }; 14675 14676 var screenKey = 'screen'; 14677 14678 /** 14679 * System plugin to the renderer to manage the filters. 14680 * 14681 * @class 14682 * @memberof PIXI.systems 14683 * @extends PIXI.System 14684 */ 14685 var FilterSystem = /*@__PURE__*/(function (System) { 14686 function FilterSystem(renderer) 14687 { 14688 System.call(this, renderer); 14689 14690 /** 14691 * List of filters for the FilterSystem 14692 * @member {Object[]} 14693 * @readonly 14694 */ 14695 this.defaultFilterStack = [{}]; 14696 14697 /** 14698 * stores a bunch of PO2 textures used for filtering 14699 * @member {Object} 14700 */ 14701 this.texturePool = {}; 14702 14703 /** 14704 * a pool for storing filter states, save us creating new ones each tick 14705 * @member {Object[]} 14706 */ 14707 this.statePool = []; 14708 14709 /** 14710 * A very simple geometry used when drawing a filter effect to the screen 14711 * @member {PIXI.Quad} 14712 */ 14713 this.quad = new Quad(); 14714 14715 /** 14716 * Quad UVs 14717 * @member {PIXI.QuadUv} 14718 */ 14719 this.quadUv = new QuadUv(); 14720 14721 /** 14722 * Temporary rect for maths 14723 * @type {PIXI.Rectangle} 14724 */ 14725 this.tempRect = new Rectangle(); 14726 14727 /** 14728 * Active state 14729 * @member {object} 14730 */ 14731 this.activeState = {}; 14732 14733 /** 14734 * This uniform group is attached to filter uniforms when used 14735 * @member {PIXI.UniformGroup} 14736 * @property {PIXI.Rectangle} outputFrame 14737 * @property {Float32Array} inputSize 14738 * @property {Float32Array} inputPixel 14739 * @property {Float32Array} inputClamp 14740 * @property {Number} resolution 14741 * @property {Float32Array} filterArea 14742 * @property {Fload32Array} filterClamp 14743 */ 14744 this.globalUniforms = new UniformGroup({ 14745 outputFrame: this.tempRect, 14746 inputSize: new Float32Array(4), 14747 inputPixel: new Float32Array(4), 14748 inputClamp: new Float32Array(4), 14749 resolution: 1, 14750 14751 // legacy variables 14752 filterArea: new Float32Array(4), 14753 filterClamp: new Float32Array(4), 14754 }, true); 14755 14756 this._pixelsWidth = renderer.view.width; 14757 this._pixelsHeight = renderer.view.height; 14758 } 14759 14760 if ( System ) { FilterSystem.__proto__ = System; } 14761 FilterSystem.prototype = Object.create( System && System.prototype ); 14762 FilterSystem.prototype.constructor = FilterSystem; 14763 14764 /**
14765 * Adds a new filter to the System. 14766 * 14767 * @param {PIXI.DisplayObject} target - The target of the filter to render. 14768 * @param {PIXI.Filter[]} filters - The filters to apply. 14769 */ 14770 FilterSystem.prototype.push = function push (target, filters) 14771 { 14772 var renderer = this.renderer; 14773 var filterStack = this.defaultFilterStack; 14774 var state = this.statePool.pop() || new FilterState(); 14775 14776 var resolution = filters[0].resolution; 14777 var padding = filters[0].padding; 14778 var autoFit = filters[0].autoFit; 14779 var legacy = filters[0].legacy; 14780 14781 for (var i = 1; i < filters.length; i++) 14782 { 14783 var filter = filters[i]; 14784 14785 // lets use the lowest resolution.. 14786 resolution = Math.min(resolution, filter.resolution); 14787 // and the largest amount of padding! 14788 padding = Math.max(padding, filter.padding); 14789 // only auto fit if all filters are autofit 14790 autoFit = autoFit || filter.autoFit; 14791 14792 legacy = legacy || filter.legacy; 14793 } 14794 14795 if (filterStack.length === 1) 14796 { 14797 this.defaultFilterStack[0].renderTexture = renderer.renderTexture.current; 14798 } 14799 14800 filterStack.push(state); 14801 14802 state.resolution = resolution; 14803 14804 state.legacy = legacy; 14805 14806 state.target = target; 14807 14808 state.sourceFrame.copyFrom(target.filterArea || target.getBounds(true)); 14809 14810 state.sourceFrame.pad(padding); 14811 if (autoFit) 14812 { 14813 state.sourceFrame.fit(this.renderer.renderTexture.sourceFrame); 14814 } 14815 14816 // round to whole number based on resolution 14817 state.sourceFrame.ceil(resolution); 14818 14819 state.renderTexture = this.getOptimalFilterTexture(state.sourceFrame.width, state.sourceFrame.height, resolution); 14820 state.filters = filters; 14821 14822 state.destinationFrame.width = state.renderTexture.width; 14823 state.destinationFrame.height = state.renderTexture.height; 14824 14825 state.renderTexture.filterFrame = state.sourceFrame; 14826 14827 renderer.renderTexture.bind(state.renderTexture, state.sourceFrame);// /, state.destinationFrame); 14828 renderer.renderTexture.clear(); 14829 }; 14830 14831 /** 14832 * Pops off the filter and applies it. 14833 * 14834 */ 14835 FilterSystem.prototype.pop = function pop () 14836 { 14837 var filterStack = this.defaultFilterStack; 14838 var state = filterStack.pop(); 14839 var filters = state.filters; 14840 14841 this.activeState = state; 14842 14843 var globalUniforms = this.globalUniforms.uniforms; 14844 14845 globalUniforms.outputFrame = state.sourceFrame; 14846 globalUniforms.resolution = state.resolution; 14847 14848 var inputSize = globalUniforms.inputSize; 14849 var inputPixel = globalUniforms.inputPixel; 14850 var inputClamp = globalUniforms.inputClamp; 14851 14852 inputSize[0] = state.destinationFrame.width; 14853 inputSize[1] = state.destinationFrame.height; 14854 inputSize[2] = 1.0 / inputSize[0]; 14855 inputSize[3] = 1.0 / inputSize[1]; 14856 14857 inputPixel[0] = inputSize[0] * state.resolution; 14858 inputPixel[1] = inputSize[1] * state.resolution; 14859 inputPixel[2] = 1.0 / inputPixel[0]; 14860 inputPixel[3] = 1.0 / inputPixel[1]; 14861 14862 inputClamp[0] = 0.5 * inputPixel[2]; 14863 inputClamp[1] = 0.5 * inputPixel[3]; 14864 inputClamp[2] = (state.sourceFrame.width * inputSize[2]) - (0.5 * inputPixel[2]); 14865 inputClamp[3] = (state.sourceFrame.height * inputSize[3]) - (0.5 * inputPixel[3]); 14866 14867 // only update the rect if its legacy.. 14868 if (state.legacy) 14869 { 14870 var filterArea = globalUniforms.filterArea; 14871 14872 filterArea[0] = state.destinationFrame.width; 14873 filterArea[1] = state.destinationFrame.height; 14874 filterArea[2] = state.sourceFrame.x; 14875 filterArea[3] = state.sourceFrame.y; 14876 14877 globalUniforms.filterClamp = globalUniforms.inputClamp; 14878 } 14879 14880 this.globalUniforms.update(); 14881 14882 var lastState = filterStack[filterStack.length - 1]; 14883 14884 if (filters.length === 1) 14885 { 14886 filters[0].apply(this, state.renderTexture, lastState.renderTexture, false, state); 14887 14888 this.returnFilterTexture(state.renderTexture); 14889 } 14890 else 14891 { 14892 var flip = state.renderTexture; 14893 var flop = this.getOptimalFilterTexture( 14894 flip.width, 14895 flip.height, 14896 state.resolution 14897 ); 14898 14899 flop.filterFrame = flip.filterFrame; 14900 14901 var i = 0; 14902 14903 for (i = 0; i < filters.length - 1; ++i) 14904 { 14905 filters[i].apply(this, flip, flop, true, state); 14906 14907 var t = flip; 14908 14909 flip = flop; 14910 flop = t; 14911 } 14912 14913 filters[i].apply(this, flip, lastState.renderTexture, false, state); 14914 14915 this.returnFilterTexture(flip); 14916 this.returnFilterTexture(flop); 14917 } 14918 14919 state.clear(); 14920 this.statePool.push(state); 14921 }; 14922 14923 /** 14924 * Draws a filter. 14925 * 14926 * @param {PIXI.Filter} filter - The filter to draw. 14927 * @param {PIXI.RenderTexture} input - The input render target. 14928 * @param {PIXI.RenderTexture} output - The target to output to. 14929 * @param {boolean} clear - Should the output be cleared before rendering to it 14930 */ 14931 FilterSystem.prototype.applyFilter = function applyFilter (filter, input, output, clear) 14932 { 14933 var renderer = this.renderer; 14934
14935 renderer.renderTexture.bind(output, output ? output.filterFrame : null); 14936 14937 if (clear) 14938 { 14939 // gl.disable(gl.SCISSOR_TEST); 14940 renderer.renderTexture.clear(); 14941 // gl.enable(gl.SCISSOR_TEST); 14942 } 14943 14944 // set the uniforms.. 14945 filter.uniforms.uSampler = input; 14946 filter.uniforms.filterGlobals = this.globalUniforms; 14947 14948 // TODO make it so that the order of this does not matter.. 14949 // because it does at the moment cos of global uniforms. 14950 // they need to get resynced 14951 14952 renderer.state.setState(filter.state); 14953 renderer.shader.bind(filter); 14954 14955 if (filter.legacy) 14956 { 14957 this.quadUv.map(input._frame, input.filterFrame); 14958 14959 renderer.geometry.bind(this.quadUv); 14960 renderer.geometry.draw(DRAW_MODES.TRIANGLES); 14961 } 14962 else 14963 { 14964 renderer.geometry.bind(this.quad); 14965 renderer.geometry.draw(DRAW_MODES.TRIANGLE_STRIP); 14966 } 14967 }; 14968 14969 /** 14970 * Calculates the mapped matrix. 14971 * 14972 * TODO playing around here.. this is temporary - (will end up in the shader) 14973 * this returns a matrix that will normalize map filter cords in the filter to screen space 14974 * 14975 * @param {PIXI.Matrix} outputMatrix - the matrix to output to. 14976 * @return {PIXI.Matrix} The mapped matrix. 14977 */ 14978 FilterSystem.prototype.calculateScreenSpaceMatrix = function calculateScreenSpaceMatrix$1 (outputMatrix) 14979 { 14980 var currentState = this.activeState; 14981 14982 return calculateScreenSpaceMatrix( 14983 outputMatrix, 14984 currentState.sourceFrame, 14985 currentState.destinationFrame 14986 ); 14987 }; 14988 14989 /** 14990 * This will map the filter coord so that a texture can be used based on the transform of a sprite 14991 * 14992 * @param {PIXI.Matrix} outputMatrix - The matrix to output to. 14993 * @param {PIXI.Sprite} sprite - The sprite to map to. 14994 * @return {PIXI.Matrix} The mapped matrix. 14995 */ 14996 FilterSystem.prototype.calculateSpriteMatrix = function calculateSpriteMatrix$1 (outputMatrix, sprite) 14997 { 14998 var currentState = this.activeState; 14999 15000 return calculateSpriteMatrix( 15001 outputMatrix, 15002 currentState.sourceFrame, 15003 currentState.destinationFrame, 15004 sprite 15005 ); 15006 }; 15007 15008 /** 15009 * Destroys this Filter System. 15010 * 15011 * @param {boolean} [contextLost=false] context was lost, do not free shaders 15012 * 15013 */ 15014 FilterSystem.prototype.destroy = function destroy (contextLost) 15015 { 15016 if ( contextLost === void 0 ) { contextLost = false; } 15017 15018 if (!contextLost) 15019 { 15020 this.emptyPool(); 15021 } 15022 else 15023 { 15024 this.texturePool = {}; 15025 } 15026 }; 15027 15028 /** 15029 * Gets a Power-of-Two render texture or fullScreen texture 15030 * 15031 * TODO move to a separate class could be on renderer? 15032 * 15033 * @protected 15034 * @param {number} minWidth - The minimum width of the render texture in real pixels. 15035 * @param {number} minHeight - The minimum height of the render texture in real pixels. 15036 * @param {number} [resolution=1] - The resolution of the render texture. 15037 * @return {PIXI.RenderTexture} The new render texture. 15038 */ 15039 FilterSystem.prototype.getOptimalFilterTexture = function getOptimalFilterTexture (minWidth, minHeight, resolution) 15040 { 15041 if ( resolution === void 0 ) { resolution = 1; } 15042 15043 var key = screenKey; 15044 15045 minWidth *= resolution; 15046 minHeight *= resolution; 15047 15048 if (minWidth !== this._pixelsWidth || minHeight !== this._pixelsHeight) 15049 { 15050 minWidth = nextPow2(minWidth); 15051 minHeight = nextPow2(minHeight); 15052 key = ((minWidth & 0xFFFF) << 16) | (minHeight & 0xFFFF); 15053 } 15054 15055 if (!this.texturePool[key]) 15056 { 15057 this.texturePool[key] = []; 15058 } 15059 15060 var renderTexture = this.texturePool[key].pop(); 15061 15062 if (!renderTexture) 15063 { 15064 // temporary bypass cache.. 15065 // internally - this will cause a texture to be bound.. 15066 renderTexture = RenderTexture.create({ 15067 width: minWidth / resolution, 15068 height: minHeight / resolution, 15069 resolution: resolution, 15070 }); 15071 } 15072 15073 renderTexture.filterPoolKey = key; 15074 15075 return renderTexture; 15076 }; 15077 15078 /** 15079 * Gets extra render texture to use inside current filter 15080 * 15081 * @param {number} resolution resolution of the renderTexture 15082 * @returns {PIXI.RenderTexture} 15083 */ 15084 FilterSystem.prototype.getFilterTexture = function getFilterTexture (resolution) 15085 { 15086 var rt = this.activeState.renderTexture; 15087 15088 var filterTexture = this.getOptimalFilterTexture(rt.width, rt.height, resolution || rt.baseTexture.resolution); 15089 15090 filterTexture.filterFrame = rt.filterFrame; 15091 15092 return filterTexture; 15093 }; 15094 15095 /** 15096 * Frees a render texture back into the pool. 15097 * 15098 * @param {PIXI.RenderTexture} renderTexture - The renderTarget to free 15099 */ 15100 FilterSystem.prototype.returnFilterTexture = function returnFilterTexture (renderTexture) 15101 { 15102 var key = renderTexture.filterPoolKey; 15103 15104 renderTexture.filterFrame = null; 15105 this.texturePool[key].push(renderTexture); 15106 }; 15107 15108 /** 15109 * Empties the texture pool. 15110 * 15111 */ 15112 FilterSystem.prototype.emptyPool = function emptyPool () 15113 { 15114 for (var i in this.texturePool) 15115 { 15116 var textures = this.texturePool[i]; 15117 15118 if (textures) 15119 { 15120 for (var j = 0; j < textures.length; j++) 15121 { 15122 textures[j].destroy(true); 15123 } 15124 } 15125 } 15126 15127 this.texturePool = {}; 15128 }; 15129 15130 FilterSystem.prototype.resize = function resize () 15131 { 15132 var textures = this.texturePool[screenKey]; 15133 15134 if (textures) 15135 { 15136 for (var j = 0; j < textures.length; j++) 15137 { 15138 textures[j].destroy(true); 15139 } 15140 } 15141 this.texturePool[screenKey] = []; 15142 15143 this._pixelsWidth = this.renderer.view.width; 15144 this._pixelsHeight = this.renderer.view.height; 15145 }; 15146 15147 return FilterSystem; 15148 }(System)); 15149 15150 /** 15151 * Base for a common object renderer that can be used as a system renderer plugin. 15152 * 15153 * @class 15154 * @extends PIXI.System 15155 * @memberof PIXI 15156 */ 15157 var ObjectRenderer = /*@__PURE__*/(function (System) { 15158 function ObjectRenderer () {
15159 System.apply(this, arguments); 15160 } 15161 15162 if ( System ) { ObjectRenderer.__proto__ = System; } 15163 ObjectRenderer.prototype = Object.create( System && System.prototype ); 15164 ObjectRenderer.prototype.constructor = ObjectRenderer; 15165 15166 ObjectRenderer.prototype.start = function start () 15167 { 15168 // set the shader.. 15169 }; 15170 15171 /** 15172 * Stops the renderer 15173 * 15174 */ 15175 ObjectRenderer.prototype.stop = function stop () 15176 { 15177 this.flush(); 15178 }; 15179 15180 /** 15181 * Stub method for rendering content and emptying the current batch. 15182 * 15183 */ 15184 ObjectRenderer.prototype.flush = function flush () 15185 { 15186 // flush! 15187 }; 15188 15189 /** 15190 * Renders an object 15191 * 15192 * @param {PIXI.DisplayObject} object - The object to render. 15193 */ 15194 ObjectRenderer.prototype.render = function render (object) // eslint-disable-line no-unused-vars 15195 { 15196 // render the object 15197 }; 15198 15199 return ObjectRenderer; 15200 }(System)); 15201 15202 /** 15203 * System plugin to the renderer to manage batching. 15204 * 15205 * @class 15206 * @extends PIXI.System 15207 * @memberof PIXI.systems 15208 */ 15209 var BatchSystem = /*@__PURE__*/(function (System) { 15210 function BatchSystem(renderer) 15211 { 15212 System.call(this, renderer); 15213 15214 /** 15215 * An empty renderer. 15216 * 15217 * @member {PIXI.ObjectRenderer} 15218 */ 15219 this.emptyRenderer = new ObjectRenderer(renderer); 15220 15221 /** 15222 * The currently active ObjectRenderer. 15223 * 15224 * @member {PIXI.ObjectRenderer} 15225 */ 15226 this.currentRenderer = this.emptyRenderer; 15227 } 15228 15229 if ( System ) { BatchSystem.__proto__ = System; } 15230 BatchSystem.prototype = Object.create( System && System.prototype ); 15231 BatchSystem.prototype.constructor = BatchSystem; 15232 15233 /** 15234 * Changes the current renderer to the one given in parameter 15235 * 15236 * @param {PIXI.ObjectRenderer} objectRenderer - The object renderer to use. 15237 */ 15238 BatchSystem.prototype.setObjectRenderer = function setObjectRenderer (objectRenderer) 15239 { 15240 if (this.currentRenderer === objectRenderer) 15241 { 15242 return; 15243 } 15244 15245 this.currentRenderer.stop(); 15246 this.currentRenderer = objectRenderer; 15247 15248 this.currentRenderer.start(); 15249 }; 15250 15251 /** 15252 * This should be called if you wish to do some custom rendering 15253 * It will basically render anything that may be batched up such as sprites 15254 */ 15255 BatchSystem.prototype.flush = function flush () 15256 { 15257 this.setObjectRenderer(this.emptyRenderer); 15258 }; 15259 15260 /** 15261 * Reset the system to an empty renderer 15262 */ 15263 BatchSystem.prototype.reset = function reset () 15264 { 15265 this.setObjectRenderer(this.emptyRenderer); 15266 }; 15267 15268 return BatchSystem; 15269 }(System)); 15270 15271 /** 15272 * The maximum support for using WebGL. If a device does not 15273 * support WebGL version, for instance WebGL 2, it will still 15274 * attempt to fallback support to WebGL 1. If you want to 15275 * explicitly remove feature support to target a more stable 15276 * baseline, prefer a lower environment. 15277 * 15278 * Due to {@link https://bugs.chromium.org/p/chromium/issues/detail?id=934823|bug in chromium} 15279 * we disable webgl2 by default for all non-apple mobile devices. 15280 * 15281 * @static 15282 * @name PREFER_ENV 15283 * @memberof PIXI.settings 15284 * @type {number} 15285 * @default PIXI.ENV.WEBGL2 15286 */ 15287 settings.PREFER_ENV = isMobile_min.any ? ENV.WEBGL : ENV.WEBGL2; 15288 15289 var CONTEXT_UID = 0; 15290 15291 /** 15292 * System plugin to the renderer to manage the context. 15293 * 15294 * @class 15295 * @extends PIXI.System 15296 * @memberof PIXI.systems 15297 */ 15298 var ContextSystem = /*@__PURE__*/(function (System) { 15299 function ContextSystem(renderer) 15300 { 15301 System.call(this, renderer); 15302 15303 /** 15304 * Either 1 or 2 to reflect the WebGL version being used 15305 * @member {number} 15306 * @readonly 15307 */ 15308 this.webGLVersion = 1; 15309 15310 /** 15311 * Extensions being used 15312 * @member {object} 15313 * @readonly 15314 * @property {WEBGL_draw_buffers} drawBuffers - WebGL v1 extension 15315 * @property {WEBGL_depth_texture} depthTexture - WebGL v1 extension 15316 * @property {OES_texture_float} floatTexture - WebGL v1 extension 15317 * @property {WEBGL_lose_context} loseContext - WebGL v1 extension 15318 * @property {OES_vertex_array_object} vertexArrayObject - WebGL v1 extension 15319 */ 15320 this.extensions = {}; 15321 15322 // Bind functions 15323 this.handleContextLost = this.handleContextLost.bind(this); 15324 this.handleContextRestored = this.handleContextRestored.bind(this); 15325 15326 renderer.view.addEventListener('webglcontextlost', this.handleContextLost, false); 15327 renderer.view.addEventListener('webglcontextrestored', this.handleContextRestored, false); 15328 } 15329 15330 if ( System ) { ContextSystem.__proto__ = System; } 15331 ContextSystem.prototype = Object.create( System && System.prototype ); 15332 ContextSystem.prototype.constructor = ContextSystem; 15333 15334 var prototypeAccessors = { isLost: { configurable: true } }; 15335 15336 /** 15337 * `true` if the context is lost 15338 * @member {boolean} 15339 * @readonly 15340 */ 15341 prototypeAccessors.isLost.get = function () 15342 { 15343 return (!this.gl || this.gl.isContextLost()); 15344 }; 15345 15346 /** 15347 * Handle the context change event 15348 * @param {WebGLRenderingContext} gl new webgl context 15349 */ 15350 ContextSystem.prototype.contextChange = function contextChange (gl) 15351 { 15352 this.gl = gl; 15353 15354 // restore a context if it was previously lost 15355 if (gl.isContextLost() && gl.getExtension('WEBGL_lose_context')) 15356 { 15357 gl.getExtension('WEBGL_lose_context').restoreContext(); 15358 } 15359 }; 15360 15361 /** 15362 * Initialize the context 15363 * 15364 * @protected 15365 * @param {WebGLRenderingContext} gl - WebGL context 15366 */ 15367 ContextSystem.prototype.initFromContext = function initFromContext (gl) 15368 { 15369 this.gl = gl; 15370 this.validateContext(gl); 15371 this.renderer.gl = gl; 15372 this.renderer.CONTEXT_UID = CONTEXT_UID++; 15373 this.renderer.runners.contextChange.run(gl); 15374 }; 15375 15376 /** 15377 * Initialize from context options 15378 * 15379 * @protected 15380 * @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext 15381 * @param {object} options - context attributes 15382 */ 15383 ContextSystem.prototype.initFromOptions = function initFromOptions (options) 15384 { 15385 var gl = this.createContext(this.renderer.view, options); 15386 15387 this.initFromContext(gl); 15388 }; 15389 15390 /** 15391 * Helper class to create a WebGL Context 15392 * 15393 * @param canvas {HTMLCanvasElement} the canvas element that we will get the context from 15394 * @param options {object} An options object that gets passed in to the canvas element containing the context attributes 15395 * @see https://developer.mozilla.org/en/docs/Web/API/HTMLCanvasElement/getContext 15396 * @return {WebGLRenderingContext} the WebGL context 15397 */ 15398 ContextSystem.prototype.createContext = function createContext (canvas, options) 15399 { 15400 var gl; 15401 15402 if (settings.PREFER_ENV >= ENV.WEBGL2) 15403 { 15404 gl = canvas.getContext('webgl2', options); 15405 } 15406 15407 if (gl) 15408 { 15409 this.webGLVersion = 2; 15410 } 15411 else 15412 { 15413 this.webGLVersion = 1; 15414 15415 gl = canvas.getContext('webgl', options) 15416 || canvas.getContext('experimental-webgl', options); 15417 15418 if (!gl) 15419 { 15420 // fail, not able to get a context 15421 throw new Error('This browser does not support WebGL. Try using the canvas renderer'); 15422 } 15423 } 15424 15425 this.gl = gl; 15426 15427 this.getExtensions(); 15428 15429 return gl; 15430 }; 15431 15432 /** 15433 * Auto-populate the extensions 15434 * 15435 * @protected 15436 */ 15437 ContextSystem.prototype.getExtensions = function getExtensions () 15438 { 15439 // time to set up default extensions that Pixi uses. 15440 var ref = this; 15441 var gl = ref.gl; 15442 15443 if (this.webGLVersion === 1) 15444 { 15445 Object.assign(this.extensions, { 15446 drawBuffers: gl.getExtension('WEBGL_draw_buffers'), 15447 depthTexture: gl.getExtension('WEBKIT_WEBGL_depth_texture'), 15448 floatTexture: gl.getExtension('OES_texture_float'), 15449 loseContext: gl.getExtension('WEBGL_lose_context'), 15450 vertexArrayObject: gl.getExtension('OES_vertex_array_object') 15451 || gl.getExtension('MOZ_OES_vertex_array_object') 15452 || gl.getExtension('WEBKIT_OES_vertex_array_object'), 15453 }); 15454 } 15455 15456 // we don't use any specific WebGL 2 ones yet! 15457 }; 15458 15459 /** 15460 * Handles a lost webgl context 15461 * 15462 * @protected 15463 * @param {WebGLContextEvent} event - The context lost event. 15464 */ 15465 ContextSystem.prototype.handleContextLost = function handleContextLost (event) 15466 { 15467 event.preventDefault(); 15468 }; 15469 15470 /** 15471 * Handles a restored webgl context 15472 * 15473 * @protected 15474 */ 15475 ContextSystem.prototype.handleContextRestored = function handleContextRestored () 15476 { 15477 this.renderer.runners.contextChange.run(this.gl); 15478 }; 15479 15480 ContextSystem.prototype.destroy = function destroy () 15481 { 15482 var view = this.renderer.view; 15483 15484 // remove listeners 15485 view.removeEventListener('webglcontextlost', this.handleContextLost); 15486 view.removeEventListener('webglcontextrestored', this.handleContextRestored); 15487 15488 this.gl.useProgram(null); 15489 15490 if (this.extensions.loseContext) 15491 { 15492 this.extensions.loseContext.loseContext(); 15493 } 15494 }; 15495 15496 /** 15497 * Handle the post-render runner event 15498 * 15499 * @protected 15500 */ 15501 ContextSystem.prototype.postrender = function postrender () 15502 { 15503 this.gl.flush(); 15504 }; 15505 15506 /** 15507 * Validate context 15508 * 15509 * @protected 15510 * @param {WebGLRenderingContext} gl - Render context 15511 */ 15512 ContextSystem.prototype.validateContext = function validateContext (gl) 15513 { 15514 var attributes = gl.getContextAttributes(); 15515 15516 // this is going to be fairly simple for now.. but at least we have room to grow! 15517 if (!attributes.stencil) 15518 { 15519 /* eslint-disable max-len */ 15520 15521 /* eslint-disable no-console */ 15522 console.warn('Provided WebGL context does not have a stencil buffer, masks may not render correctly'); 15523 /* eslint-enable no-console */ 15524 15525 /* eslint-enable max-len */ 15526 } 15527 }; 15528 15529 Object.defineProperties( ContextSystem.prototype, prototypeAccessors ); 15530 15531 return ContextSystem; 15532 }(System)); 15533 15534 /** 15535 * System plugin to the renderer to manage framebuffers. 15536 * 15537 * @class 15538 * @extends PIXI.System 15539 * @memberof PIXI.systems 15540 */ 15541 var FramebufferSystem = /*@__PURE__*/(function (System) { 15542 function FramebufferSystem(renderer) 15543 { 15544 System.call(this, renderer); 15545 15546 /** 15547 * A list of managed framebuffers 15548 * @member {PIXI.Framebuffer[]} 15549 * @readonly 15550 */ 15551 this.managedFramebuffers = []; 15552 15553 /**
15554 * Framebuffer value that shows that we don't know what is bound 15555 * @member {Framebuffer} 15556 * @readonly 15557 */ 15558 this.unknownFramebuffer = new Framebuffer(10, 10); 15559 } 15560 15561 if ( System ) { FramebufferSystem.__proto__ = System; } 15562 FramebufferSystem.prototype = Object.create( System && System.prototype ); 15563 FramebufferSystem.prototype.constructor = FramebufferSystem; 15564 15565 var prototypeAccessors = { size: { configurable: true } }; 15566 15567 /** 15568 * Sets up the renderer context and necessary buffers. 15569 */ 15570 FramebufferSystem.prototype.contextChange = function contextChange () 15571 { 15572 var gl = this.gl = this.renderer.gl; 15573 15574 this.CONTEXT_UID = this.renderer.CONTEXT_UID; 15575 this.current = this.unknownFramebuffer; 15576 this.viewport = new Rectangle(); 15577 this.hasMRT = true; 15578 this.writeDepthTexture = true; 15579 15580 this.disposeAll(true); 15581 15582 // webgl2 15583 if (this.renderer.context.webGLVersion === 1) 15584 { 15585 // webgl 1! 15586 var nativeDrawBuffersExtension = this.renderer.context.extensions.drawBuffers; 15587 var nativeDepthTextureExtension = this.renderer.context.extensions.depthTexture; 15588 15589 if (settings.PREFER_ENV === ENV.WEBGL_LEGACY) 15590 { 15591 nativeDrawBuffersExtension = null; 15592 nativeDepthTextureExtension = null; 15593 } 15594 15595 if (nativeDrawBuffersExtension) 15596 { 15597 gl.drawBuffers = function (activeTextures) { return nativeDrawBuffersExtension.drawBuffersWEBGL(activeTextures); }; 15598 } 15599 else 15600 { 15601 this.hasMRT = false;
15602 gl.drawBuffers = function () { 15603 // empty 15604 }; 15605 } 15606 15607 if (!nativeDepthTextureExtension) 15608 { 15609 this.writeDepthTexture = false; 15610 } 15611 } 15612 }; 15613 15614 /** 15615 * Bind a framebuffer 15616 * 15617 * @param {PIXI.Framebuffer} framebuffer 15618 * @param {PIXI.Rectangle} [frame] frame, default is framebuffer size 15619 */ 15620 FramebufferSystem.prototype.bind = function bind (framebuffer, frame) 15621 { 15622 var ref = this; 15623 var gl = ref.gl; 15624 15625 if (framebuffer) 15626 { 15627 // TODO caching layer! 15628 15629 var fbo = framebuffer.glFramebuffers[this.CONTEXT_UID] || this.initFramebuffer(framebuffer); 15630 15631 if (this.current !== framebuffer) 15632 { 15633 this.current = framebuffer; 15634 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo.framebuffer); 15635 } 15636 // make sure all textures are unbound.. 15637 15638 // now check for updates... 15639 if (fbo.dirtyId !== framebuffer.dirtyId) 15640 { 15641 fbo.dirtyId = framebuffer.dirtyId; 15642 15643 if (fbo.dirtyFormat !== framebuffer.dirtyFormat) 15644 { 15645 fbo.dirtyFormat = framebuffer.dirtyFormat; 15646 this.updateFramebuffer(framebuffer); 15647 } 15648 else if (fbo.dirtySize !== framebuffer.dirtySize) 15649 { 15650 fbo.dirtySize = framebuffer.dirtySize; 15651 this.resizeFramebuffer(framebuffer); 15652 } 15653 } 15654 15655 for (var i = 0; i < framebuffer.colorTextures.length; i++) 15656 { 15657 if (framebuffer.colorTextures[i].texturePart) 15658 { 15659 this.renderer.texture.unbind(framebuffer.colorTextures[i].texture); 15660 } 15661 else 15662 { 15663 this.renderer.texture.unbind(framebuffer.colorTextures[i]); 15664 } 15665 } 15666 15667 if (framebuffer.depthTexture) 15668 { 15669 this.renderer.texture.unbind(framebuffer.depthTexture); 15670 } 15671 15672 if (frame) 15673 { 15674 this.setViewport(frame.x, frame.y, frame.width, frame.height); 15675 } 15676 else 15677 { 15678 this.setViewport(0, 0, framebuffer.width, framebuffer.height); 15679 } 15680 } 15681 else 15682 { 15683 if (this.current) 15684 { 15685 this.current = null; 15686 gl.bindFramebuffer(gl.FRAMEBUFFER, null); 15687 } 15688 15689 if (frame) 15690 { 15691 this.setViewport(frame.x, frame.y, frame.width, frame.height); 15692 } 15693 else 15694 { 15695 this.setViewport(0, 0, this.renderer.width, this.renderer.height); 15696 } 15697 } 15698 }; 15699 15700 /** 15701 * Set the WebGLRenderingContext's viewport. 15702 * 15703 * @param {Number} x - X position of viewport 15704 * @param {Number} y - Y position of viewport 15705 * @param {Number} width - Width of viewport 15706 * @param {Number} height - Height of viewport 15707 */ 15708 FramebufferSystem.prototype.setViewport = function setViewport (x, y, width, height) 15709 { 15710 var v = this.viewport; 15711 15712 if (v.width !== width || v.height !== height || v.x !== x || v.y !== y) 15713 { 15714 v.x = x; 15715 v.y = y; 15716 v.width = width; 15717 v.height = height; 15718 15719 this.gl.viewport(x, y, width, height); 15720 } 15721 }; 15722 15723 /** 15724 * Get the size of the current width and height. Returns object with `width` and `height` values. 15725 * 15726 * @member {object} 15727 * @readonly 15728 */ 15729 prototypeAccessors.size.get = function () 15730 { 15731 if (this.current) 15732 { 15733 // TODO store temp 15734 return { x: 0, y: 0, width: this.current.width, height: this.current.height }; 15735 } 15736 15737 return { x: 0, y: 0, width: this.renderer.width, height: this.renderer.height }; 15738 }; 15739 15740 /** 15741 * Clear the color of the context 15742 * 15743 * @param {Number} r - Red value from 0 to 1 15744 * @param {Number} g - Green value from 0 to 1 15745 * @param {Number} b - Blue value from 0 to 1 15746 * @param {Number} a - Alpha value from 0 to 1 15747 */ 15748 FramebufferSystem.prototype.clear = function clear (r, g, b, a) 15749 { 15750 var ref = this; 15751 var gl = ref.gl; 15752 15753 // TODO clear color can be set only one right? 15754 gl.clearColor(r, g, b, a); 15755 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 15756 }; 15757 15758 /** 15759 * Initialize framebuffer 15760 * 15761 * @protected 15762 * @param {PIXI.Framebuffer} framebuffer 15763 */ 15764 FramebufferSystem.prototype.initFramebuffer = function initFramebuffer (framebuffer) 15765 { 15766 var ref = this; 15767 var gl = ref.gl; 15768 15769 // TODO - make this a class? 15770 var fbo = { 15771 framebuffer: gl.createFramebuffer(), 15772 stencil: null, 15773 dirtyId: 0, 15774 dirtyFormat: 0, 15775 dirtySize: 0, 15776 }; 15777 15778 framebuffer.glFramebuffers[this.CONTEXT_UID] = fbo; 15779 15780 this.managedFramebuffers.push(framebuffer); 15781 framebuffer.disposeRunner.add(this); 15782 15783 return fbo; 15784 }; 15785 15786 /** 15787 * Resize the framebuffer 15788 * 15789 * @protected 15790 * @param {PIXI.Framebuffer} framebuffer 15791 */ 15792 FramebufferSystem.prototype.resizeFramebuffer = function resizeFramebuffer (framebuffer) 15793 { 15794 var ref = this; 15795 var gl = ref.gl; 15796 15797 var fbo = framebuffer.glFramebuffers[this.CONTEXT_UID]; 15798 15799 if (fbo.stencil) 15800 { 15801 gl.bindRenderbuffer(gl.RENDERBUFFER, fbo.stencil); 15802 gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, framebuffer.width, framebuffer.he
15802ight); 15803 } 15804 15805 var colorTextures = framebuffer.colorTextures; 15806 15807 for (var i = 0; i < colorTextures.length; i++) 15808 { 15809 this.renderer.texture.bind(colorTextures[i], 0); 15810 } 15811 15812 if (framebuffer.depthTexture) 15813 { 15814 this.renderer.texture.bind(framebuffer.depthTexture, 0); 15815 } 15816 }; 15817 15818 /** 15819 * Update the framebuffer 15820 * 15821 * @protected 15822 * @param {PIXI.Framebuffer} framebuffer 15823 */ 15824 FramebufferSystem.prototype.updateFramebuffer = function updateFramebuffer (framebuffer) 15825 { 15826 var ref = this; 15827 var gl = ref.gl; 15828 15829 var fbo = framebuffer.glFramebuffers[this.CONTEXT_UID]; 15830 15831 // bind the color texture 15832 var colorTextures = framebuffer.colorTextures; 15833 15834 var count = colorTextures.length; 15835 15836 if (!gl.drawBuffers) 15837 { 15838 count = Math.min(count, 1); 15839 } 15840 15841 var activeTextures = []; 15842 15843 for (var i = 0; i < count; i++) 15844 { 15845 var texture = framebuffer.colorTextures[i]; 15846 15847 if (texture.texturePart) 15848 { 15849 this.renderer.texture.bind(texture.texture, 0); 15850 15851 gl.framebufferTexture2D(gl.FRAMEBUFFER, 15852 gl.COLOR_ATTACHMENT0 + i, 15853 gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, 15854 texture.texture._glTextures[this.CONTEXT_UID].texture, 15855 0); 15856 } 15857 else 15858 { 15859 this.renderer.texture.bind(texture, 0); 15860 15861 gl.framebufferTexture2D(gl.FRAMEBUFFER, 15862 gl.COLOR_ATTACHMENT0 + i, 15863 gl.TEXTURE_2D, 15864 texture._glTextures[this.CONTEXT_UID].texture, 15865 0); 15866 } 15867 15868 activeTextures.push(gl.COLOR_ATTACHMENT0 + i); 15869 } 15870 15871 if (activeTextures.length > 1) 15872 { 15873 gl.drawBuffers(activeTextures); 15874 } 15875 15876 if (framebuffer.depthTexture) 15877 { 15878 var writeDepthTexture = this.writeDepthTexture; 15879 15880 if (writeDepthTexture) 15881 { 15882 var depthTexture = framebuffer.depthTexture; 15883 15884 this.renderer.texture.bind(depthTexture, 0); 15885 15886 gl.framebufferTexture2D(gl.FRAMEBUFFER, 15887 gl.DEPTH_ATTACHMENT, 15888 gl.TEXTURE_2D, 15889 depthTexture._glTextures[this.CONTEXT_UID].texture, 15890 0); 15891 } 15892 } 15893 15894 if (!fbo.stencil && (framebuffer.stencil || framebuffer.depth)) 15895 { 15896 fbo.stencil = gl.createRenderbuffer(); 15897 15898 gl.bindRenderbuffer(gl.RENDERBUFFER, fbo.stencil); 15899 15900 // TODO.. this is depth AND stencil? 15901 if (!framebuffer.depthTexture) 15902 { // you can't have both, so one should take priority if enabled 15903 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, fbo.stencil); 15904 } 15905 gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, framebuffer.width, framebuffer.height); 15906 // fbo.enableStencil(); 15907 } 15908 }; 15909 15910 /** 15911 * Disposes framebuffer 15912 * @param {PIXI.Framebuffer} framebuffer framebuffer that has to be disposed of 15913 * @param {boolean} [contextLost=false] If context was lost, we suppress all delete function calls 15914 */ 15915 FramebufferSystem.prototype.disposeFramebuffer = function disposeFramebuffer (framebuffer, contextLost) 15916 { 15917 var fbo = framebuffer.glFramebuffers[this.CONTEXT_UID]; 15918 var gl = this.gl; 15919 15920 if (!fbo) 15921 { 15922 return; 15923 } 15924 15925 delete framebuffer.glFramebuffers[this.CONTEXT_UID]; 15926 15927 var index = this.managedFramebuffers.indexOf(framebuffer); 15928 15929 if (index >= 0) 15930 { 15931 this.managedFramebuffers.splice(index, 1); 15932 } 15933 15934 framebuffer.disposeRunner.remove(this); 15935 15936 if (!contextLost) 15937 { 15938 gl.deleteFramebuffer(fbo.framebuffer); 15939 if (fbo.stencil) 15940 { 15941 gl.deleteRenderbuffer(fbo.stencil); 15942 } 15943 } 15944 }; 15945 15946 /**
15947 * Disposes all framebuffers, but not textures bound to them 15948 * @param {boolean} [contextLost=false] If context was lost, we suppress all delete function calls 15949 */ 15950 FramebufferSystem.prototype.disposeAll = function disposeAll (contextLost) 15951 { 15952 var list = this.managedFramebuffers; 15953 15954 this.managedFramebuffers = []; 15955 15956 for (var i = 0; i < list.count; i++) 15957 { 15958 this.disposeFramebuffer(list[i], contextLost); 15959 } 15960 }; 15961 15962 /** 15963 * resets framebuffer stored state, binds screen framebuffer 15964 * 15965 * should be called before renderTexture reset() 15966 */ 15967 FramebufferSystem.prototype.reset = function reset () 15968 { 15969 this.current = this.unknownFramebuffer; 15970 this.viewport = new Rectangle(); 15971 }; 15972 15973 Object.defineProperties( FramebufferSystem.prototype, prototypeAccessors ); 15974 15975 return FramebufferSystem; 15976 }(System)); 15977 15978 var GLBuffer = function GLBuffer(buffer) 15979 { 15980 this.buffer = buffer; 15981 this.updateID = -1; 15982 this.byteLength = -1; 15983 this.refCount = 0; 15984 }; 15985 15986 var byteSizeMap$1 = { 5126: 4, 5123: 2, 5121: 1 }; 15987 15988 /** 15989 * System plugin to the renderer to manage geometry. 15990 * 15991 * @class 15992 * @extends PIXI.System 15993 * @memberof PIXI.systems 15994 */ 15995 var GeometrySystem = /*@__PURE__*/(function (System) { 15996 function GeometrySystem(renderer) 15997 { 15998 System.call(this, renderer); 15999 16000 this._activeGeometry = null; 16001 this._activeVao = null; 16002 16003 /** 16004 * `true` if we has `*_vertex_array_object` extension 16005 * @member {boolean} 16006 * @readonly 16007 */ 16008 this.hasVao = true; 16009 16010 /** 16011 * `true` if has `ANGLE_instanced_arrays` extension 16012 * @member {boolean} 16013 * @readonly 16014 */ 16015 this.hasInstance = true; 16016 16017 /** 16018 * A cache of currently bound buffer, 16019 * contains only two members with keys ARRAY_BUFFER and ELEMENT_ARRAY_BUFFER 16020 * @member {Object.<number, PIXI.Buffer>} 16021 * @readonly 16022 */ 16023 this.boundBuffers = {}; 16024 16025 /** 16026 * Cache for all geometries by id, used in case renderer gets destroyed or for profiling 16027 * @member {object} 16028 * @readonly 16029 */ 16030 this.managedGeometries = {}; 16031 16032 /** 16033 * Cache for all buffers by id, used in case renderer gets destroyed or for profiling 16034 * @member {object} 16035 * @readonly 16036 */ 16037 this.managedBuffers = {}; 16038 } 16039 16040 if ( System ) { GeometrySystem.__proto__ = System; } 16041 GeometrySystem.prototype = Object.create( System && System.prototype ); 16042 GeometrySystem.prototype.constructor = GeometrySystem; 16043 16044 /** 16045 * Sets up the renderer context and necessary buffers. 16046 */ 16047 GeometrySystem.prototype.contextChange = function contextChange () 16048 { 16049 this.disposeAll(true); 16050 16051 var gl = this.gl = this.renderer.gl; 16052 16053 this.CONTEXT_UID = this.renderer.CONTEXT_UID; 16054 16055 // webgl2 16056 if (!gl.createVertexArray) 16057 { 16058 // webgl 1! 16059 var nativeVaoExtension = this.renderer.context.extensions.vertexArrayObject; 16060 16061 if (settings.PREFER_ENV === ENV.WEBGL_LEGACY) 16062 { 16063 nativeVaoExtension = null; 16064 } 16065 16066 if (nativeVaoExtension) 16067 { 16068 gl.createVertexArray = function () { return nativeVaoExtension.createVertexArrayOES(); }; 16069 16070 gl.bindVertexArray = function (vao) { return nativeVaoExtension.bindVertexArrayOES(vao); }; 16071 16072 gl.deleteVertexArray = function (vao) { return nativeVaoExtension.deleteVertexArrayOES(vao); }; 16073 } 16074 else 16075 { 16076 this.hasVao = false; 16077 gl.createVertexArray = function () { 16078 // empty 16079 }; 16080 16081 gl.bindVertexArray = function () { 16082 // empty 16083 }; 16084 16085 gl.deleteVertexArray = function () { 16086 // empty 16087 }; 16088 } 16089 } 16090 16091 if (!gl.vertexAttribDivisor) 16092 { 16093 var instanceExt = gl.getExtension('ANGLE_instanced_arrays'); 16094 16095 if (instanceExt) 16096 { 16097 gl.vertexAttribDivisor = function (a, b) { return instanceExt.vertexAttribDivisorANGLE(a, b); }; 16098 16099 gl.drawElementsInstanced = function (a, b, c, d, e) { return instanceExt.drawElementsInstancedANGLE(a, b, c, d, e); }; 16100 16101 gl.drawArraysInstanced = function (a, b, c, d) { return instanceExt.drawArraysInstancedANGLE(a, b, c, d); }; 16102 } 16103 else 16104 { 16105 this.hasInstance = false;
16106 } 16107 } 16108 }; 16109 16110 /** 16111 * Binds geometry so that is can be drawn. Creating a Vao if required 16112 * @protected 16113 * @param {PIXI.Geometry} geometry instance of geometry to bind 16114 * @param {PIXI.Shader} shader instance of shader to bind 16115 */ 16116 GeometrySystem.prototype.bind = function bind (geometry, shader) 16117 { 16118 shader = shader || this.renderer.shader.shader; 16119 16120 var ref = this; 16121 var gl = ref.gl; 16122 16123 // not sure the best way to address this.. 16124 // currently different shaders require different VAOs for the same geometry 16125 // Still mulling over the best way to solve this one.. 16126 // will likely need to modify the shader attribute locations at run time! 16127 var vaos = geometry.glVertexArrayObjects[this.CONTEXT_UID]; 16128 16129 if (!vaos) 16130 { 16131 this.managedGeometries[geometry.id] = geometry; 16132 geometry.disposeRunner.add(this); 16133 geometry.glVertexArrayObjects[this.CONTEXT_UID] = vaos = {}; 16134 } 16135 16136 var vao = vaos[shader.program.id] || this.initGeometryVao(geometry, shader.program); 16137 16138 this._activeGeometry = geometry; 16139 16140 if (this._activeVao !== vao) 16141 { 16142 this._activeVao = vao; 16143 16144 if (this.hasVao) 16145 { 16146 gl.bindVertexArray(vao); 16147 } 16148 else 16149 { 16150 this.activateVao(geometry, shader.program); 16151 } 16152 } 16153 16154 // TODO - optimise later! 16155 // don't need to loop through if nothing changed! 16156 // maybe look to add an 'autoupdate' to geometry? 16157 this.updateBuffers(); 16158 }; 16159 16160 /** 16161 * Reset and unbind any active VAO and geometry 16162 */ 16163 GeometrySystem.prototype.reset = function reset () 16164 { 16165 this.unbind(); 16166 }; 16167 16168 /** 16169 * Update buffers 16170 * @protected 16171 */ 16172 GeometrySystem.prototype.updateBuffers = function updateBuffers () 16173 { 16174 var geometry = this._activeGeometry; 16175 var ref = this; 16176 var gl = ref.gl; 16177 16178 for (var i = 0; i < geometry.buffers.length; i++) 16179 { 16180 var buffer = geometry.buffers[i]; 16181 16182 var glBuffer = buffer._glBuffers[this.CONTEXT_UID]; 16183 16184 if (buffer._updateID !== glBuffer.updateID) 16185 { 16186 glBuffer.updateID = buffer._updateID; 16187 16188 // TODO can cache this on buffer! maybe added a getter / setter? 16189 var type = buffer.index ? gl.ELEMENT_ARRAY_BUFFER : gl.ARRAY_BUFFER; 16190 16191 // TODO this could change if the VAO changes... 16192 // need to come up with a better way to cache.. 16193 // if (this.boundBuffers[type] !== glBuffer) 16194 // { 16195 // this.boundBuffers[type] = glBuffer; 16196 gl.bindBuffer(type, glBuffer.buffer); 16197 // } 16198 16199 this._boundBuffer = glBuffer; 16200 16201 if (glBuffer.byteLength >= buffer.data.byteLength) 16202 { 16203 // offset is always zero for now! 16204 gl.bufferSubData(type, 0, buffer.data); 16205 } 16206 else 16207 { 16208 var drawType = buffer.static ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW; 16209 16210 glBuffer.byteLength = buffer.data.byteLength; 16211 gl.bufferData(type, buffer.data, drawType); 16212 } 16213 } 16214 } 16215 }; 16216 16217 /** 16218 * Check compability between a geometry and a program 16219 * @protected 16220 * @param {PIXI.Geometry} geometry - Geometry instance 16221 * @param {PIXI.Program} program - Program instance 16222 */ 16223 GeometrySystem.prototype.checkCompatibility = function checkCompatibility (geometry, program) 16224 { 16225 // geometry must have at least all the attributes that the shader requires. 16226 var geometryAttributes = geometry.attributes; 16227 var shaderAttributes = program.attributeData; 16228 16229 for (var j in shaderAttributes) 16230 { 16231 if (!geometryAttributes[j]) 16232 { 16233 throw new Error(("shader and geometry incompatible, geometry missing the \"" + j + "\" attribute")); 16234 } 16235 } 16236 }; 16237 16238 /** 16239 * Takes a geometry and program and generates a unique signature for them. 16240 * 16241 * @param {PIXI.Geometry} geometry to get signature from 16242 * @param {PIXI.Program} program to test geometry against 16243 * @returns {String} Unique signature of the geometry and program 16244 * @protected 16245 */ 16246 GeometrySystem.prototype.getSignature = function getSignature (geometry, program) 16247 { 16248 var attribs = geometry.attributes; 16249 var shaderAttributes = program.attributeData; 16250 16251 var strings = ['g', geometry.id]; 16252 16253 for (var i in attribs) 16254 { 16255 if (shaderAttributes[i]) 16256 {
16257 strings.push(i); 16258 } 16259 } 16260 16261 return strings.join('-'); 16262 }; 16263 16264 /** 16265 * Creates a Vao with the same structure as the geometry and stores it on the geometry. 16266 * @protected 16267 * @param {PIXI.Geometry} geometry - Instance of geometry to to generate Vao for 16268 * @param {PIXI.Program} program - Instance of program 16269 */ 16270 GeometrySystem.prototype.initGeometryVao = function initGeometryVao (geometry, program) 16271 { 16272 this.checkCompatibility(geometry, program); 16273 16274 var gl = this.gl; 16275 var CONTEXT_UID = this.CONTEXT_UID; 16276 16277 var signature = this.getSignature(geometry, program); 16278 16279 var vaoObjectHash = geometry.glVertexArrayObjects[this.CONTEXT_UID]; 16280 16281 var vao = vaoObjectHash[signature]; 16282 16283 if (vao) 16284 { 16285 // this will give us easy access to the vao 16286 vaoObjectHash[program.id] = vao; 16287 16288 return vao; 16289 } 16290 16291 var buffers = geometry.buffers; 16292 var attributes = geometry.attributes; 16293 var tempStride = {}; 16294 var tempStart = {}; 16295 16296 for (var j in buffers) 16297 { 16298 tempStride[j] = 0; 16299 tempStart[j] = 0; 16300 } 16301 16302 for (var j$1 in attributes) 16303 { 16304 if (!attributes[j$1].size && program.attributeData[j$1]) 16305 { 16306 attributes[j$1].size = program.attributeData[j$1].size; 16307 } 16308 else if (!attributes[j$1].size) 16309 { 16310 console.warn(("PIXI Geometry attribute '" + j$1 + "' size cannot be determined (likely the bound shader does not have the attribute)")); // eslint-disable-line 16311 } 16312 16313 tempStride[attributes[j$1].buffer] += attributes[j$1].size * byteSizeMap$1[attributes[j$1].type]; 16314 } 16315 16316 for (var j$2 in attributes) 16317 { 16318 var attribute = attributes[j$2]; 16319 var attribSize = attribute.size; 16320 16321 if (attribute.stride === undefined) 16322 { 16323 if (tempStride[attribute.buffer] === attribSize * byteSizeMap$1[attribute.type]) 16324 { 16325 attribute.stride = 0; 16326 } 16327 else 16328 { 16329 attribute.stride = tempStride[attribute.buffer]; 16330 } 16331 } 16332 16333 if (attribute.start === undefined) 16334 { 16335 attribute.start = tempStart[attribute.buffer]; 16336 16337 tempStart[attribute.buffer] += attribSize * byteSizeMap$1[attribute.type]; 16338 } 16339 } 16340 16341 vao = gl.createVertexArray(); 16342 16343 gl.bindVertexArray(vao); 16344 16345 // first update - and create the buffers! 16346 // only create a gl buffer if it actually gets 16347 for (var i = 0; i < buffers.length; i++) 16348 { 16349 var buffer = buffers[i]; 16350 16351 if (!buffer._glBuffers[CONTEXT_UID]) 16352 { 16353 buffer._glBuffers[CONTEXT_UID] = new GLBuffer(gl.createBuffer()); 16354 this.managedBuffers[buffer.id] = buffer; 16355 buffer.disposeRunner.add(this); 16356 } 16357 16358 buffer._glBuffers[CONTEXT_UID].refCount++; 16359 } 16360 16361 // TODO - maybe make this a data object? 16362 // lets wait to see if we need to first! 16363 16364 this.activateVao(geometry, program); 16365 16366 gl.bindVertexArray(this._activeVao); 16367 16368 // add it to the cache! 16369 vaoObjectHash[program.id] = vao; 16370 vaoObjectHash[signature] = vao; 16371 16372 return vao; 16373 }; 16374 16375 /** 16376 * Disposes buffer 16377 * @param {PIXI.Buffer} buffer buffer with data 16378 * @param {boolean} [contextLost=false] If context was lost, we suppress deleteVertexArray 16379 */ 16380 GeometrySystem.prototype.disposeBuffer = function disposeBuffer (buffer, contextLost) 16381 { 16382 if (!this.managedBuffers[buffer.id]) 16383 { 16384 return; 16385 } 16386 16387 delete this.managedBuffers[buffer.id]; 16388 16389 var glBuffer = buffer._glBuffers[this.CONTEXT_UID]; 16390 var gl = this.gl; 16391 16392 buffer.disposeRunner.remove(this); 16393 16394 if (!glBuffer) 16395 { 16396 return; 16397 } 16398 16399 if (!contextLost) 16400 { 16401 gl.deleteBuffer(glBuffer.buffer); 16402 } 16403 16404 delete buffer._glBuffers[this.CONTEXT_UID]; 16405 }; 16406 16407 /**
16408 * Disposes geometry 16409 * @param {PIXI.Geometry} geometry Geometry with buffers. Only VAO will be disposed 16410 * @param {boolean} [contextLost=false] If context was lost, we suppress deleteVertexArray 16411 */ 16412 GeometrySystem.prototype.disposeGeometry = function disposeGeometry (geometry, contextLost) 16413 { 16414 if (!this.managedGeometries[geometry.id]) 16415 { 16416 return; 16417 } 16418 16419 delete this.managedGeometries[geometry.id]; 16420 16421 var vaos = geometry.glVertexArrayObjects[this.CONTEXT_UID]; 16422 var gl = this.gl; 16423 var buffers = geometry.buffers; 16424 16425 geometry.disposeRunner.remove(this); 16426 16427 if (!vaos) 16428 { 16429 return; 16430 } 16431 16432 for (var i = 0; i < buffers.length; i++) 16433 { 16434 var buf = buffers[i]._glBuffers[this.CONTEXT_UID]; 16435 16436 buf.refCount--; 16437 if (buf.refCount === 0 && !contextLost) 16438 { 16439 this.disposeBuffer(buffers[i], contextLost); 16440 } 16441 } 16442 16443 if (!contextLost) 16444 { 16445 for (var vaoId in vaos) 16446 { 16447 // delete only signatures, everything else are copies 16448 if (vaoId[0] === 'g') 16449 { 16450 gl.deleteVertexArray(vaos[vaoId]); 16451 } 16452 } 16453 } 16454 16455 delete geometry.glVertexArrayObjects[this.CONTEXT_UID]; 16456 }; 16457 16458 /** 16459 * dispose all WebGL resources of all managed geometries and buffers 16460 * @param {boolean} [contextLost=false] If context was lost, we suppress `gl.delete` calls 16461 */ 16462 GeometrySystem.prototype.disposeAll = function disposeAll (contextLost) 16463 { 16464 var all = Object.keys(this.managedGeometries); 16465 16466 for (var i = 0; i < all.length; i++) 16467 { 16468 this.disposeGeometry(this.managedGeometries[all[i]], contextLost); 16469 } 16470 all = Object.keys(this.managedBuffers); 16471 for (var i$1 = 0; i$1 < all.length; i$1++) 16472 { 16473 this.disposeBuffer(this.managedBuffers[all[i$1]], contextLost); 16474 } 16475 }; 16476 16477 /** 16478 * Activate vertex array object 16479 * 16480 * @protected 16481 * @param {PIXI.Geometry} geometry - Geometry instance 16482 * @param {PIXI.Program} program - Shader program instance 16483 */ 16484 GeometrySystem.prototype.activateVao = function activateVao (geometry, program) 16485 { 16486 var gl = this.gl; 16487 var CONTEXT_UID = this.CONTEXT_UID; 16488 var buffers = geometry.buffers; 16489 var attributes = geometry.attributes; 16490 16491 if (geometry.indexBuffer) 16492 { 16493 // first update the index buffer if we have one.. 16494 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, geometry.indexBuffer._glBuffers[CONTEXT_UID].buffer); 16495 } 16496 16497 var lastBuffer = null; 16498 16499 // add a new one! 16500 for (var j in attributes) 16501 { 16502 var attribute = attributes[j]; 16503 var buffer = buffers[attribute.buffer]; 16504 var glBuffer = buffer._glBuffers[CONTEXT_UID]; 16505 16506 if (program.attributeData[j]) 16507 { 16508 if (lastBuffer !== glBuffer) 16509 { 16510 gl.bindBuffer(gl.ARRAY_BUFFER, glBuffer.buffer); 16511 16512 lastBuffer = glBuffer; 16513 } 16514 16515 var location = program.attributeData[j].location; 16516 16517 // TODO introduce state again 16518 // we can optimise this for older devices that have no VAOs 16519 gl.enableVertexAttribArray(location); 16520 16521 gl.vertexAttribPointer(location, 16522 attribute.size, 16523 attribute.type || gl.FLOAT, 16524 attribute.normalized, 16525 attribute.stride, 16526 attribute.start); 16527 16528 if (attribute.instance) 16529 { 16530 // TODO calculate instance count based of this... 16531 if (this.hasInstance) 16532 { 16533 gl.vertexAttribDivisor(location, 1); 16534 } 16535 else 16536 { 16537 throw new Error('geometry error, GPU Instancing is not supported on this device'); 16538 } 16539 } 16540 } 16541 } 16542 }; 16543 16544 /** 16545 * Draw the geometry 16546 * 16547 * @param {Number} type - the type primitive to render 16548 * @param {Number} [size] - the number of elements to be rendered 16549 * @param {Number} [start] - Starting index 16550 * @param {Number} [instanceCount] - the number of instances of the set of elements to execute 16551 */ 16552 GeometrySystem.prototype.draw = function draw (type, size, start, instanceCount) 16553 { 16554 var ref = this; 16555 var gl = ref.gl; 16556 var geometry = this._activeGeometry; 16557 16558 // TODO.. this should not change so maybe cache the function? 16559 16560 if (geometry.indexBuffer) 16561 { 16562 if (geometry.instanced) 16563 { 16564 /* eslint-disable max-len */ 16565 gl.drawElementsInstanced(type, size || geometry.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2, instanceCount || 1); 16566 /* eslint-enable max-len */ 16567 } 16568 else 16569 { 16570 gl.drawElements(type, size || geometry.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2); 16571 } 16572 } 16573 else if (geometry.instanced) 16574 { 16575 // TODO need a better way to calculate size.. 16576 gl.drawArraysInstanced(type, start, size || geometry.getSize(), instanceCount || 1); 16577 } 16578 else 16579 { 16580 gl.drawArrays(type, start, size || geometry.getSize()); 16581 } 16582 16583 return this; 16584 }; 16585 16586 /** 16587 * Unbind/reset everything 16588 * @protected 16589 */ 16590 GeometrySystem.prototype.unbind = function unbind () 16591 { 16592 this.gl.bindVertexArray(null); 16593 this._activeVao = null; 16594 this._activeGeometry = null; 16595 }; 16596 16597 return GeometrySystem; 16598 }(System)); 16599 16600 /** 16601 * @method compileProgram 16602 * @private 16603 * @memberof PIXI.glCore.shader 16604 * @param gl {WebGLRenderingContext} The current WebGL context {WebGLProgram} 16605 * @param vertexSrc {string|string[]}
16605 The vertex shader source as an array of strings. 16606 * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings. 16607 * @param attributeLocations {Object} An attribute location map that lets you manually set the attribute locations 16608 * @return {WebGLProgram} the shader program 16609 */ 16610 function compileProgram(gl, vertexSrc, fragmentSrc, attributeLocations) 16611 { 16612 var glVertShader = compileShader(gl, gl.VERTEX_SHADER, vertexSrc); 16613 var glFragShader = compileShader(gl, gl.FRAGMENT_SHADER, fragmentSrc); 16614 16615 var program = gl.createProgram(); 16616 16617 gl.attachShader(program, glVertShader); 16618 gl.attachShader(program, glFragShader); 16619 16620 // optionally, set the attributes manually for the program rather than letting WebGL decide.. 16621 if (attributeLocations) 16622 { 16623 for (var i in attributeLocations) 16624 { 16625 gl.bindAttribLocation(program, attributeLocations[i], i); 16626 } 16627 } 16628 16629 gl.linkProgram(program); 16630 16631 // if linking fails, then log and cleanup 16632 if (!gl.getProgramParameter(program, gl.LINK_STATUS)) 16633 { 16634 console.error('Pixi.js Error: Could not initialize shader.'); 16635 console.error('gl.VALIDATE_STATUS', gl.getProgramParameter(program, gl.VALIDATE_STATUS)); 16636 console.error('gl.getError()', gl.getError()); 16637 16638 // if there is a program info log, log it 16639 if (gl.getProgramInfoLog(program) !== '') 16640 { 16641 console.warn('Pixi.js Warning: gl.getProgramInfoLog()', gl.getProgramInfoLog(program)); 16642 } 16643 16644 gl.deleteProgram(program); 16645 program = null; 16646 } 16647 16648 // clean up some shaders 16649 gl.deleteShader(glVertShader); 16650 gl.deleteShader(glFragShader); 16651 16652 return program; 16653 } 16654 16655 /** 16656 * @private 16657 * @param gl {WebGLRenderingContext} The current WebGL context {WebGLProgram} 16658 * @param type {Number} the type, can be either VERTEX_SHADER or FRAGMENT_SHADER 16659 * @param vertexSrc {string|string[]} The vertex shader source as an array of strings. 16660 * @return {WebGLShader} the shader 16661 */ 16662 function compileShader(gl, type, src) 16663 { 16664 var shader = gl.createShader(type); 16665 16666 gl.shaderSource(shader, src); 16667 gl.compileShader(shader); 16668 16669 if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) 16670 { 16671 console.warn(src); 16672 console.error(gl.getShaderInfoLog(shader)); 16673 16674 return null; 16675 } 16676 16677 return shader; 16678 } 16679 16680 /** 16681 * @method defaultValue 16682 * @memberof PIXI.glCore.shader 16683 * @param type {String} Type of value 16684 * @param size {Number} 16685 * @private 16686 */ 16687 function defaultValue(type, size) 16688 { 16689 switch (type) 16690 { 16691 case 'float': 16692 return 0; 16693 16694 case 'vec2': 16695 return new Float32Array(2 * size); 16696 16697 case 'vec3': 16698 return new Float32Array(3 * size); 16699 16700 case 'vec4': 16701 return new Float32Array(4 * size); 16702 16703 case 'int': 16704 case 'sampler2D': 16705 case 'sampler2DArray': 16706 return 0; 16707 16708 case 'ivec2': 16709 return new Int32Array(2 * size); 16710 16711 case 'ivec3': 16712 return new Int32Array(3 * size); 16713 16714 case 'ivec4': 16715 return new Int32Array(4 * size); 16716 16717 case 'bool': 16718 return false; 16719 16720 case 'bvec2': 16721 16722 return booleanArray(2 * size); 16723 16724 case 'bvec3': 16725 return booleanArray(3 * size); 16726 16727 case 'bvec4': 16728 return booleanArray(4 * size); 16729 16730 case 'mat2': 16731 return new Float32Array([1, 0, 16732 0, 1]); 16733 16734 case 'mat3': 16735 return new Float32Array([1, 0, 0, 16736 0, 1, 0, 16737 0, 0, 1]); 16738 16739 case 'mat4': 16740 return new Float32Array([1, 0, 0, 0, 16741 0, 1, 0, 0, 16742 0, 0, 1, 0, 16743 0, 0, 0, 1]); 16744 } 16745 16746 return null; 16747 } 16748 16749 function booleanArray(size) 16750 { 16751 var array = new Array(size); 16752 16753 for (var i = 0; i < array.length; i++) 16754 { 16755 array[i] = false; 16756 } 16757 16758 return array; 16759 } 16760 16761 /** 16762 * Sets the float precision on the shader. If the precision is already present this function will do nothing 16763 * @private 16764 * @param {string} src the shader source 16765 * @param {string} precision The float precision of the shader. Options are 'lowp', 'mediump' or 'highp'. 16766 * 16767 * @return {string} modified shader source 16768 */ 16769 function setPrecision(src, precision) 16770 { 16771 if (src.substring(0, 9) !== 'precision')// && src.substring(0, 1) !== '#') 16772 { 16773 return ("precision " + precision + " float;\n" + src); 16774 } 16775 16776 return src; 16777 } 16778 16779 var GLSL_TO_SIZE = { 16780 float: 1, 16781 vec2: 2, 16782 vec3: 3, 16783 vec4: 4, 16784 16785 int: 1, 16786 ivec2: 2, 16787 ivec3: 3, 16788 ivec4: 4, 16789 16790 bool: 1, 16791 bvec2: 2, 16792 bvec3: 3, 16793 bvec4: 4, 16794 16795 mat2: 4, 16796 mat3: 9, 16797 mat4: 16, 16798 16799 sampler2D: 1, 16800 }; 16801 16802 /** 16803 * @private 16804 * @method mapSize 16805 * @memberof PIXI.glCore.shader 16806 * @param type {String} 16807 * @return {Number} 16808 */ 16809 function mapSize(type) 16810 { 16811 return GLSL_TO_SIZE[type]; 16812 } 16813 16814 var GL_TABLE = null; 16815 16816 var GL_TO_GLSL_TYPES = { 16817 FLOAT: 'float', 16818 FLOAT_VEC2: 'vec2', 16819 FLOAT_VEC3: 'vec3', 16820 FLOAT_VEC4: 'vec4', 16821 16822 INT: 'int', 16823 INT_VEC2: 'ivec2', 16824 INT_VEC3: 'ivec3', 16825 INT_VEC4: 'ivec4', 16826 16827 BOOL: 'bool', 16828 BOOL_VEC2: 'bvec2', 16829 BOOL_VEC3: 'bvec3', 16830 BOOL_VEC4: 'bvec4', 16831 16832 FLOAT_MAT2: 'mat2', 16833 FLOAT_MAT3: 'mat3', 16834 FLOAT_MAT4: 'mat4', 16835 16836 SAMPLER_2D: 'sampler2D', 16837 SAMPLER_CUBE: 'samplerCube', 16838 SAMPLER_2D_ARRAY: 'sampler2DArray', 16839 }; 16840 16841 function mapType(gl, type) 16842 { 16843 if (!GL_TABLE) 16844 { 16845 var typeNames = Object.keys(GL_TO_GLSL_TYPES); 16846 16847 GL_TABLE = {}; 16848 16849 for (var i = 0; i < typeNames.length; ++i) 16850 { 16851 var tn = typeNames[i]; 16852 16853 GL_TABLE[gl[tn]] = GL_TO_GLSL_TYPES[tn]; 16854 } 16855 } 16856 16857 return GL_TABLE[type]; 16858 } 16859 16860 // cv = CachedValue 16861 // v = value 16862 // ud = uniformData 16863 // uv = uniformValue 16864 // l = location 16865 var GLSL_TO_SINGLE_SETTERS_CACHED = { 16866 16867 float: "\n if(cv !== v)\n {\n cv.v = v;\n gl.uniform1f(location, v)\n }", 16868 16869 vec2: "\n if(cv[0] !== v[0] || cv[1] !== v[1])\n {\n cv[0] = v[0];\n cv[1] = v[1];\n gl.uniform2f(location, v[0], v[1])\n }", 16870 16871 vec3: "\n if(cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2])\n {\n cv[0] = v[0];\n cv[1] = v[1];\n cv[2] = v[2];\n\n gl.uniform3f(location, v[0], v[1], v[2])\n }", 16872 16873 vec4: 'gl.uniform4f(location, v[0], v[1], v[2], v[3])', 16874 16875 int: 'gl.uniform1i(location, v)', 16876 ivec2: 'gl.uniform2i(location, v[0], v[1])', 16877 ivec3: 'gl.uniform3i(location, v[0], v[1], v[2])', 16878 ivec4: 'gl.uniform4i(location, v[0], v[1], v[2], v[3])', 16879 16880 bool: 'gl.uniform1i(location, v)', 16881 bvec2: 'gl.uniform2i(location, v[0], v[1])', 16882 bvec3: 'gl.uniform3i(location, v[0], v[1], v[2])', 16883 bvec4: 'gl.uniform4i(location, v[0], v[1], v[2], v[3])', 16884 16885 mat2: 'gl.uniformMatrix2fv(location, false, v)', 16886 mat3: 'gl.uniformMatrix3fv(location, false, v)', 16887 mat4: 'gl.uniformMatrix4fv(location, false, v)', 16888 16889 sampler2D: 'gl.uniform1i(location, v)', 16890 samplerCube: 'gl.uniform1i(location, v)', 16891 sampler2DArray: 'gl.uniform1i(location, v)', 16892 }; 16893 16894 var GLSL_TO_ARRAY_SETTERS = { 16895 16896 float: "gl.uniform1fv(location, v)", 16897 16898 vec2: "gl.uniform2fv(location, v)", 16899 vec3: "gl.uniform3fv(location, v)", 16900 vec4: 'gl.uniform4fv(location, v)', 16901 16902 mat4: 'gl.uniformMatrix4fv(location, false, v)', 16903 mat3: 'gl.uniformMatrix3fv(location, false, v)', 16904 mat2: 'gl.uniformMatrix2fv(location, false, v)', 16905 16906 int: 'gl.uniform1iv(location, v)', 16907 ivec2: 'gl.uniform2iv(location, v)', 16908 ivec3: 'gl.uniform3iv(location, v)', 16909 ivec4: 'gl.uniform4iv(location, v)', 16910 16911 bool: 'gl.uniform1iv(location, v)', 16912 bvec2: 'gl.uniform2iv(location, v)', 16913 bvec3: 'gl.uniform3iv(location, v)', 16914 bvec4: 'gl.uniform4iv(location, v)', 16915 16916 sampler2D: 'gl.uniform1iv(location, v)', 16917 samplerCube: 'gl.uniform1iv(location, v)', 16918 sampler2DArray: 'gl.uniform1iv(location, v)', 16919 }; 16920 16921 function generateUniformsSync(group, uniformData) 16922 { 16923 var textureCount = 0; 16924 var func = "var v = null;\n var cv = null\n var gl = renderer.gl"; 16925 16926 for (var i in group.uniforms) 16927 { 16928 var data = uniformData[i]; 16929 16930 if (!data) 16931 { 16932 if (group.uniforms[i].group) 16933 { 16934 func += "\n renderer.shader.syncUniformGroup(uv." + i + ");\n "; 16935 } 16936 16937 continue; 16938 } 16939 16940 // TODO && uniformData[i].value !== 0 <-- do we still need this? 16941 if (data.type === 'float' && data.size === 1) 16942 { 16943 func += "\n if(uv." + i + " !== ud." + i + ".value)\n {\n ud." + i + ".value = uv." + i + "\n gl.uniform1f(ud." + i + ".location, uv." + i + ")\n }\n"; 16944 } 16945 /* eslint-disable max-len */ 16946 else if ((data.type === 'sampler2D' || data.type === 'samplerCube' || data.type === 'sampler2DArray') && data.size === 1 && !data.isArray) 16947 /* eslint-disable max-len */ 16948 { 16949 func += "\n renderer.texture.bind(uv." + i + ", " + textureCount + ");\n\n if(ud." + i + ".value !== " + textureCount + ")\n {\n ud." + i + ".value = " + textureCount + ";\n gl.uniform1i(ud." + i + ".location, " + textureCount + ");\n; // eslint-disable-line max-len\n }\n"; 16950 16951 textureCount++; 16952 } 16953 else if (data.type === 'mat3' && data.size === 1) 16954 { 16955 if (group.uniforms[i].a !== undefined) 16956 { 16957 // TODO and some smart caching dirty ids here! 16958 func += "\n gl.uniformMatrix3fv(ud." + i + ".location, false, uv." + i + ".toArray(true));\n \n"; 16959 } 16960 else 16961 { 16962 func += "\n gl.uniformMatrix3fv(ud." + i + ".location, false, uv." + i + ");\n \n"; 16963 } 16964 } 16965 else if (data.type === 'vec2' && data.size === 1) 16966 { 16967 // TODO - do we need both here? 16968 // maybe we can get away with only using points? 16969 if (group.uniforms[i].x !== undefined) 16970 { 16971 func += "\n cv = ud." + i + ".value;\n v = uv." + i + ";\n\n if(cv[0] !== v.x || cv[1] !== v.y)\n {\n cv[0] = v.x;\n cv[1] = v.y;\n gl.uniform2f(ud." + i + ".location, v.x, v.y);\n }\n"; 16972 } 16973 else 16974 { 16975 func += "\n cv = ud." + i + ".value;\n v = uv." + i + ";\n\n if(cv[0] !== v[0] || cv[1] !== v[1])\n {\n cv[0] = v[0];\n cv[1] = v[1];\n gl.uniform2f(ud." + i + ".location, v[0], v[1]);\n }\n \n"; 16976 } 16977 } 16978 else if (data.type === 'vec4' && data.size === 1) 16979 { 16980 // TODO - do we need both here? 16981 // maybe we can get away with only using points? 16982 if (group.uniforms[i].width !== undefined) 16983 { 16984 func += "\n cv = ud." + i + ".value;\n v = uv." + i + ";\n\n if(cv[0] !== v.x || cv[1] !== v.y || cv[2] !== v.width || cv[3] !== v.height)\n {\n cv[0] = v.x;\n cv[1] = v.y;\n cv[2] = v.width;\n cv[3] = v.height;\n gl.uniform4f(ud." + i + ".location, v.x, v.y, v.width, v.height)\n }\n"; 16985 } 16986 else 16987 { 16988 func += "\n cv = ud." + i + ".value;\n v = uv." + i + ";\n\n if(cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2] || cv[3] !== v[3])\n {\n cv[0] = v[0];\n cv[1] = v[1];\n cv[2] = v[2];\n cv[3] = v[3];\n\n gl.uniform4f(ud." + i + ".location, v[0], v[1], v[2], v[3])\n }\n \n"; 16989 } 16990 } 16991 else 16992 { 16993 var templateType = (data.size === 1) ? GLSL_TO_SINGLE_SETTERS_CACHED : GLSL_TO_ARRAY_SETTERS; 16994 16995 var template = templateType[data.type].replace('location', ("ud." + i + ".location")); 16996 16997 func += "\n cv = ud." + i + ".value;\n v = uv." + i + ";\n " + template + ";\n"; 16998 } 16999 } 17000 17001 return new Function('ud', 'uv', 'renderer', func); // eslint-disable-line no-new-func 17002 } 17003 17004 var context = null; 17005 17006 /** 17007 * returns a little WebGL context to use for program inspection. 17008 * 17009 * @static 17010 * @private 17011 * @returns {webGL-context} a gl context to test with 17012 */ 17013 function getTestContext() 17014 { 17015 if (!context) 17016 { 17017 var canvas = document.createElement('canvas'); 17018 17019 var gl; 17020 17021 if (settings.PREFER_ENV >= ENV.WEBGL2) 17022 { 17023 gl = canvas.getContext('webgl2', {}); 17024 } 17025 17026 if (!gl) 17027 { 17028 gl = canvas.getContext('webgl', {}) 17029 || canvas.getContext('experimental-webgl', {}); 17030 17031 if (!gl) 17032 { 17033 // fail, not able to get a context 17034 throw new Error('This browser does not support WebGL. Try using the canvas renderer'); 17035 } 17036 else 17037 { 17038 // for shader testing.. 17039 gl.getExtension('WEBGL_draw_buffers'); 17040 } 17041 } 17042 17043 context = gl; 17044 17045 return gl; 17046 } 17047 17048 return context; 17049 } 17050 17051 var fragTemplate = [ 17052 'precision mediump float;', 17053 'void main(void){', 17054 'float test = 0.1;', 17055 '%forloop%', 17056 'gl_FragColor = vec4(0.0);', 17057 '}' ].join('\n'); 17058 17059 function checkMaxIfStatementsInShader(maxIfs, gl) 17060 { 17061 if (maxIfs === 0) 17062 { 17063 throw new Error('Invalid value of `0` passed to `checkMaxIfStatementsInShader`'); 17064 } 17065 17066 var shader = gl.createShader(gl.FRAGMENT_SHADER); 17067 17068 while (true) // eslint-disable-line no-constant-condition 17069 { 17070 var fragmentSrc = fragTemplate.replace(/%forloop%/gi, generateIfTestSrc(maxIfs)); 17071 17072 gl.shaderSource(shader, fragmentSrc); 17073 gl.compileShader(shader); 17074 17075 if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) 17076 { 17077 maxIfs = (maxIfs / 2) | 0; 17078 } 17079 else 17080 { 17081 // valid! 17082 break; 17083 } 17084 } 17085
17086 return maxIfs; 17087 } 17088 17089 function generateIfTestSrc(maxIfs) 17090 { 17091 var src = ''; 17092 17093 for (var i = 0; i < maxIfs; ++i) 17094 { 17095 if (i > 0) 17096 { 17097 src += '\nelse '; 17098 } 17099 17100 if (i < maxIfs - 1) 17101 { 17102 src += "if(test == " + i + ".0){}"; 17103 } 17104 } 17105 17106 return src; 17107 } 17108 17109 // Cache the result to prevent running this over and over 17110 var unsafeEval; 17111 17112 /** 17113 * Not all platforms allow to generate function code (e.g., `new Function`). 17114 * this provides the platform-level detection. 17115 * 17116 * @private 17117 * @returns {boolean} 17118 */ 17119 function unsafeEvalSupported() 17120 { 17121 if (typeof unsafeEval === 'boolean') 17122 { 17123 return unsafeEval; 17124 } 17125 17126 try 17127 { 17128 /* eslint-disable no-new-func */ 17129 var func = new Function('param1', 'param2', 'param3', 'return param1[param2] === param3;'); 17130 /* eslint-enable no-new-func */ 17131 17132 unsafeEval = func({ a: 'b' }, 'a', 'b') === true; 17133 } 17134 catch (e) 17135 { 17136 unsafeEval = false; 17137 } 17138 17139 return unsafeEval; 17140 } 17141 17142 var defaultFragment = "varying vec2 vTextureCoord;\n\nuniform sampler2D uSampler;\n\nvoid main(void){\n gl_FragColor *= texture2D(uSampler, vTextureCoord);\n}"; 17143 17144 var defaultVertex = "attribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\n\nuniform mat3 projectionMatrix;\n\nvarying vec2 vTextureCoord;\n\nvoid main(void){\n gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0
17144)).xy, 0.0, 1.0);\n vTextureCoord = aTextureCoord;\n}\n"; 17145 17146 // import * as from '../systems/shader/shader'; 17147 17148 var UID$3 = 0; 17149 17150 var nameCache = {}; 17151 17152 /** 17153 * Helper class to create a shader program. 17154 * 17155 * @class 17156 * @memberof PIXI 17157 */ 17158 var Program = function Program(vertexSrc, fragmentSrc, name) 17159 { 17160 if ( name === void 0 ) { name = 'pixi-shader'; } 17161 17162 this.id = UID$3++; 17163 17164 /** 17165 * The vertex shader. 17166 * 17167 * @member {string} 17168 */ 17169 this.vertexSrc = vertexSrc || Program.defaultVertexSrc; 17170 17171 /** 17172 * The fragment shader. 17173 * 17174 * @member {string} 17175 */ 17176 this.fragmentSrc = fragmentSrc || Program.defaultFragmentSrc; 17177 17178 this.vertexSrc = this.vertexSrc.trim(); 17179 this.fragmentSrc = this.fragmentSrc.trim(); 17180 17181 if (this.vertexSrc.substring(0, 8) !== '#version') 17182 { 17183 name = name.replace(/\s+/g, '-'); 17184 17185 if (nameCache[name]) 17186 { 17187 nameCache[name]++; 17188 name += "-" + (nameCache[name]); 17189 } 17190 else 17191 { 17192 nameCache[name] = 1; 17193 } 17194 17195 this.vertexSrc = "#define SHADER_NAME " + name + "\n" + (this.vertexSrc); 17196 this.fragmentSrc = "#define SHADER_NAME " + name + "\n" + (this.fragmentSrc); 17197 17198 this.vertexSrc = setPrecision(this.vertexSrc, settings.PRECISION_VERTEX); 17199 this.fragmentSrc = setPrecision(this.fragmentSrc, settings.PRECISION_FRAGMENT); 17200 } 17201 17202 // currently this does not extract structs only default types 17203 this.extractData(this.vertexSrc, this.fragmentSrc); 17204 17205 // this is where we store shader references.. 17206 this.glPrograms = {}; 17207 17208 this.syncUniforms = null; 17209 }; 17210 17211 var staticAccessors$3 = { defaultVertexSrc: { configurable: true },defaultFragmentSrc: { configurable: true } }; 17212 17213 /** 17214 * Extracts the data for a buy creating a small test program 17215 * or reading the src directly. 17216 * @protected 17217 * 17218 * @param {string} [vertexSrc] - The source of the vertex shader. 17219 * @param {string} [fragmentSrc] - The source of the fragment shader. 17220 */ 17221 Program.prototype.extractData = function extractData (vertexSrc, fragmentSrc) 17222 { 17223 var gl = getTestContext(); 17224 17225 if (gl) 17226 { 17227 var program = compileProgram(gl, vertexSrc, fragmentSrc); 17228 17229 this.attributeData = this.getAttributeData(program, gl); 17230 this.uniformData = this.getUniformData(program, gl); 17231 17232 gl.deleteProgram(program); 17233 } 17234 else 17235 { 17236 this.uniformData = {}; 17237 this.attributeData = {}; 17238 } 17239 }; 17240 17241 /** 17242 * returns the attribute data from the program 17243 * @private 17244 * 17245 * @param {WebGLProgram} [program] - the WebGL program 17246 * @param {WebGLRenderingContext} [gl] - the WebGL context 17247 * 17248 * @returns {object} the attribute data for this program 17249 */ 17250 Program.prototype.getAttributeData = function getAttributeData (program, gl) 17251 { 17252 var attributes = {}; 17253 var attributesArray = []; 17254 17255 var totalAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES); 17256 17257 for (var i = 0; i < totalAttributes; i++) 17258 { 17259 var attribData = gl.getActiveAttrib(program, i); 17260 var type = mapType(gl, attribData.type); 17261 17262 /*eslint-disable */ 17263 var data = { 17264 type: type, 17265 name: attribData.name, 17266 size: mapSize(type), 17267 location: 0, 17268 }; 17269 /* eslint-enable */ 17270 17271 attributes[attribData.name] = data; 17272 attributesArray.push(data); 17273 } 17274 17275 attributesArray.sort(function (a, b) { return (a.name > b.name) ? 1 : -1; }); // eslint-disable-line no-confusing-arrow 17276 17277 for (var i$1 = 0; i$1 < attributesArray.length; i$1++) 17278 { 17279 attributesArray[i$1].location = i$1; 17280 } 17281 17282 return attributes; 17283 }; 17284 17285 /** 17286 * returns the uniform data from the program 17287 * @private 17288 * 17289 * @param {webGL-program} [program] - the webgl program 17290 * @param {context} [gl] - the WebGL context 17291 * 17292 * @returns {object} the uniform data for this program 17293 */ 17294 Program.prototype.getUniformData = function getUniformData (program, gl) 17295 { 17296 var uniforms = {}; 17297 17298 var totalUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); 17299 17300 // TODO expose this as a prop? 17301 // const maskRegex = new RegExp('^(projectionMatrix|uSampler|translationMatrix)$'); 17302 // const maskRegex = new RegExp('^(projectionMatrix|uSampler|translationMatrix)$'); 17303 17304 for (var i = 0; i < totalUniforms; i++) 17305 { 17306 var uniformData = gl.getActiveUniform(program, i); 17307 var name = uniformData.name.replace(/\[.*?\]/, ''); 17308 17309 var isArray = uniformData.name.match(/\[.*?\]/, ''); 17310 var type = mapType(gl, uniformData.type); 17311 17312 /*eslint-disable */ 17313 uniforms[name] = { 17314 type: type, 17315 size: uniformData.size, 17316 isArray:isArray, 17317 value: defaultValue(type, uniformData.size), 17318 }; 17319 /* eslint-enable */ 17320 } 17321 17322 return uniforms; 17323 }; 17324 17325 /** 17326 * The default vertex shader source 17327 * 17328 * @static 17329 * @constant 17330 * @member {string} 17331 */
17332 staticAccessors$3.defaultVertexSrc.get = function () 17333 { 17334 return defaultVertex; 17335 }; 17336 17337 /** 17338 * The default fragment shader source 17339 * 17340 * @static 17341 * @constant 17342 * @member {string} 17343 */ 17344 staticAccessors$3.defaultFragmentSrc.get = function () 17345 { 17346 return defaultFragment; 17347 }; 17348 17349 /** 17350 * A short hand function to create a program based of a vertex and fragment shader 17351 * this method will also check to see if there is a cached program. 17352 * 17353 * @param {string} [vertexSrc] - The source of the vertex shader. 17354 * @param {string} [fragmentSrc] - The source of the fragment shader. 17355 * @param {object} [uniforms] - Custom uniforms to use to augment the built-in ones. 17356 * 17357 * @returns {PIXI.Program} an shiny new Pixi shader! 17358 */ 17359 Program.from = function from (vertexSrc, fragmentSrc, name) 17360 { 17361 var key = vertexSrc + fragmentSrc; 17362 17363 var program = ProgramCache[key]; 17364 17365 if (!program) 17366 { 17367 ProgramCache[key] = program = new Program(vertexSrc, fragmentSrc, name); 17368 } 17369 17370 return program; 17371 }; 17372 17373 Object.defineProperties( Program, staticAccessors$3 ); 17374 17375 /** 17376 * A helper class for shaders 17377 * 17378 * @class 17379 * @memberof PIXI 17380 */ 17381 var Shader = function Shader(program, uniforms) 17382 { 17383 this.program = program; 17384 17385 // lets see whats been passed in 17386 // uniforms should be converted to a uniform group 17387 if (uniforms) 17388 { 17389 if (uniforms instanceof UniformGroup) 17390 { 17391 this.uniformGroup = uniforms; 17392 } 17393 else 17394 { 17395 this.uniformGroup = new UniformGroup(uniforms); 17396 } 17397 } 17398 else 17399 { 17400 this.uniformGroup = new UniformGroup({}); 17401 } 17402 17403 // time to build some getters and setters! 17404 // I guess down the line this could sort of generate an instruction list rather than use dirty ids? 17405 // does the trick for now though! 17406 for (var i in program.uniformData) 17407 { 17408 if (this.uniformGroup.uniforms[i] instanceof Array) 17409 { 17410 this.uniformGroup.uniforms[i] = new Float32Array(this.uniformGroup.uniforms[i]); 17411 } 17412 } 17413 }; 17414 17415 var prototypeAccessors$2$1 = { uniforms: { configurable: true } }; 17416 17417 // TODO move to shader system.. 17418 Shader.prototype.checkUniformExists = function checkUniformExists (name, group) 17419 { 17420 if (group.uniforms[name]) 17421 { 17422 return true; 17423 } 17424 17425 for (var i in group.uniforms) 17426 { 17427 var uniform = group.uniforms[i]; 17428 17429 if (uniform.group) 17430 { 17431 if (this.checkUniformExists(name, uniform)) 17432 { 17433 return true; 17434 } 17435 } 17436 } 17437 17438 return false; 17439 }; 17440 17441 Shader.prototype.destroy = function destroy () 17442 { 17443 // usage count on programs? 17444 // remove if not used! 17445 this.uniformGroup = null; 17446 }; 17447 17448 /** 17449 * Shader uniform values, shortcut for `uniformGroup.uniforms` 17450 * @readonly 17451 * @member {object} 17452 */ 17453 prototypeAccessors$2$1.uniforms.get = function () 17454 { 17455 return this.uniformGroup.uniforms; 17456 }; 17457 17458 /** 17459 * A short hand function to create a shader based of a vertex and fragment shader 17460 * 17461 * @param {string} [vertexSrc] - The source of the vertex shader. 17462 * @param {string} [fragmentSrc] - The source of the fragment shader. 17463 * @param {object} [uniforms] - Custom uniforms to use to augment the built-in ones. 17464 * 17465 * @returns {PIXI.Shader} an shiny new Pixi shader! 17466 */ 17467 Shader.from = function from (vertexSrc, fragmentSrc, uniforms) 17468 { 17469 var program = Program.from(vertexSrc, fragmentSrc); 17470 17471 return new Shader(program, uniforms); 17472 }; 17473 17474 Object.defineProperties( Shader.prototype, prototypeAccessors$2$1 ); 17475 17476 /* eslint-disable max-len */ 17477 17478 var BLEND = 0; 17479 var OFFSET = 1; 17480 var CULLING = 2; 17481 var DEPTH_TEST = 3; 17482 var WINDING = 4; 17483 17484 /** 17485 * This is a WebGL state, and is is passed The WebGL StateManager. 17486 * 17487 * Each mesh rendered may require WebGL to be in a different state. 17488 * For example you may want different blend mode or to enable polygon offsets 17489 * 17490 * @class 17491 * @memberof PIXI 17492 */ 17493 var State = function State() 17494 { 17495 this.data = 0; 17496 17497 this.blendMode = BLEND_MODES.NORMAL; 17498 this.polygonOffset = 0; 17499 17500 this.blend = true; 17501 // this.depthTest = true; 17502 }; 17503 17504 var prototypeAccessors$3$1 = { blend: { configurable: true },offsets: { configurable: true },culling: { configurable: true },depthTest: { configurable: true },clockwiseFrontFace: { configurable: true },blendMode: { configurable: true },polygonOffset: { configurable: true } }; 17505 17506 /** 17507 * Activates blending of the computed fragment color values 17508 * 17509 * @member {boolean} 17510 */ 17511 prototypeAccessors$3$1.blend.get = function () 17512 { 17513 return !!(this.data & (1 << BLEND)); 17514 }; 17515 17516 prototypeAccessors$3$1.blend.set = function (value) // eslint-disable-line require-jsdoc 17517 { 17518 if (!!(this.data & (1 << BLEND)) !== value) 17519 { 17520 this.data ^= (1 << BLEND); 17521 } 17522 }; 17523 17524 /**
17525 * Activates adding an offset to depth values of polygon's fragments 17526 * 17527 * @member {boolean} 17528 * @default false 17529 */ 17530 prototypeAccessors$3$1.offsets.get = function () 17531 { 17532 return !!(this.data & (1 << OFFSET)); 17533 }; 17534 17535 prototypeAccessors$3$1.offsets.set = function (value) // eslint-disable-line require-jsdoc 17536 { 17537 if (!!(this.data & (1 << OFFSET)) !== value) 17538 { 17539 this.data ^= (1 << OFFSET); 17540 } 17541 }; 17542 17543 /** 17544 * Activates culling of polygons. 17545 * 17546 * @member {boolean} 17547 * @default false 17548 */ 17549 prototypeAccessors$3$1.culling.get = function () 17550 { 17551 return !!(this.data & (1 << CULLING)); 17552 }; 17553 17554 prototypeAccessors$3$1.culling.set = function (value) // eslint-disable-line require-jsdoc 17555 { 17556 if (!!(this.data & (1 << CULLING)) !== value) 17557 { 17558 this.data ^= (1 << CULLING); 17559 } 17560 }; 17561 17562 /** 17563 * Activates depth comparisons and updates to the depth buffer. 17564 * 17565 * @member {boolean} 17566 * @default false 17567 */ 17568 prototypeAccessors$3$1.depthTest.get = function () 17569 { 17570 return !!(this.data & (1 << DEPTH_TEST)); 17571 }; 17572 17573 prototypeAccessors$3$1.depthTest.set = function (value) // eslint-disable-line require-jsdoc 17574 { 17575 if (!!(this.data & (1 << DEPTH_TEST)) !== value) 17576 { 17577 this.data ^= (1 << DEPTH_TEST); 17578 } 17579 }; 17580 17581 /** 17582 * Specifies whether or not front or back-facing polygons can be culled. 17583 * @member {boolean} 17584 * @default false 17585 */ 17586 prototypeAccessors$3$1.clockwiseFrontFace.get = function () 17587 { 17588 return !!(this.data & (1 << WINDING)); 17589 }; 17590 17591 prototypeAccessors$3$1.clockwiseFrontFace.set = function (value) // eslint-disable-line require-jsdoc 17592 { 17593 if (!!(this.data & (1 << WINDING)) !== value) 17594 { 17595 this.data ^= (1 << WINDING); 17596 } 17597 }; 17598 17599 /** 17600 * The blend mode to be applied when this state is set. Apply a value of `PIXI.BLEND_MODES.NORMAL` to reset the blend mode. 17601 * Setting this mode to anything other than NO_BLEND will automatically switch blending on. 17602 * 17603 * @member {boolean} 17604 * @default PIXI.BLEND_MODES.NORMAL 17605 * @see PIXI.BLEND_MODES 17606 */ 17607 prototypeAccessors$3$1.blendMode.get = function () 17608 { 17609 return this._blendMode; 17610 }; 17611 17612 prototypeAccessors$3$1.blendMode.set = function (value) // eslint-disable-line require-jsdoc 17613 { 17614 this.blend = (value !== BLEND_MODES.NONE); 17615 this._blendMode = value; 17616 }; 17617 17618 /** 17619 * The polygon offset. Setting this property to anything other than 0 will automatically enable polygon offset fill. 17620 * 17621 * @member {number} 17622 * @default 0 17623 */ 17624 prototypeAccessors$3$1.polygonOffset.get = function () 17625 { 17626 return this._polygonOffset; 17627 }; 17628 17629 prototypeAccessors$3$1.polygonOffset.set = function (value) // eslint-disable-line require-jsdoc 17630 { 17631 this.offsets = !!value; 17632 this._polygonOffset = value; 17633 }; 17634 17635 State.for2d = function for2d () 17636 { 17637 var state = new State(); 17638 17639 state.depthTest = false; 17640 state.blend = true; 17641 17642 return state; 17643 }; 17644 17645 Object.defineProperties( State.prototype, prototypeAccessors$3$1 ); 17646 17647 var defaultVertex$1 = "attribute vec2 aVertexPosition;\n\nuniform mat3 projectionMatrix;\n\nvarying vec2 vTextureCoord;\n\nuniform vec4 inputSize;\nuniform vec4 outputFrame;\n\nvec4 filterVertexPosition( void )\n{\n vec2 position = aVertexPosition * max(outputFrame.zw, vec2(0.)) + outputFrame.xy;\n\n return vec4((projectionMatrix * vec3(position, 1.0)).xy, 0.0, 1.0);\n}\n\nvec2 filterTextureCoord( void )\n{\n return aVertexPosition * (outputFrame.zw * inputSize.zw);\n}\n\nvoid main(void)\n{\n gl_Position = filterVertexPosition();\n vTextureCoord = filterTextureCoord();\n}\n"; 17648 17649 var defaultFragment$1 = "varying vec2 vTextureCoord;\n\nuniform sampler2D uSampler;\n\nvoid main(void){\n gl_FragColor = texture2D(uSampler, vTextureCoord);\n}\n"; 17650 17651 /** 17652 * Filter is a special type of WebGL shader that is applied to the screen. 17653 * 17654 * {@link http://pixijs.io/examples/#/filters/blur-filter.js Example} of the 17655 * {@link PIXI.filters.BlurFilter BlurFilter}. 17656 * 17657 * ### Usage 17658 * Filters can be applied to any DisplayObject or Container. 17659 * PixiJS' `FilterSystem` renders the container into temporary Framebuffer, 17660 * then filter renders it to the screen. 17661 * Multiple filters can be added to the `filters` array property and stacked on each other. 17662 * 17663 * ``` 17664 * const filter = new PIXI.Filter(myShaderVert, myShaderFrag, { myUniform: 0.5 }); 17665 * const container = new PIXI.Container(); 17666 * container.filters = [filter]; 17667 * ``` 17668 * 17669 * ### Previous Version Differences 17670 * 17671 * In PixiJS **v3**, a filter was always applied to _whole screen_. 17672 * 17673 * In PixiJS **v4**, a filter can be applied _only part of the screen_. 17674 * Developers had to create a set of uniforms to deal with coordinates. 17675 * 17676 * In PixiJS **v5** combines _both approaches_. 17677 * Developers can use normal coordinates of v3 and then allow filter to use partial Framebuffers, 17678 * bringing those extra uniforms into account. 17679 * 17680 * ### Built-in Uniforms 17681 * 17682 * PixiJS viewport uses screen (CSS) coordinates, `(0, 0, renderer.screen.width, renderer.screen.height)`, 17683 * and `projectionMatrix` uniform maps it to the gl viewport. 17684 * 17685 * **uSampler** 17686 * 17687 * The most important uniform is the input texture that container was rendered into. 17688 * _Important note: as with all Framebuffers in PixiJS, both input and output are 17689 * premultiplied by alpha._ 17690 * 17691 * By default, input Framebuffer space coordinates are passed to fragment shader with `vTextureCoord`. 17692 * Use it to sample the input. 17693 * 17694 * ``` 17695 * const fragment = ` 17696 * varying vec2 vTextureCoord; 17697 * uniform sampler2D uSampler; 17698 * void main(void) 17699 * { 17700 * gl_FragColor = texture2D(uSampler, vTextureCoord); 17701 * } 17702 * `; 17703 * 17704 * const myFilter = new PIXI.Filter(null, fragment); 17705 * ``` 17706 * 17707 * This filter is just one uniform less than {@link PIXI.filters.AlphaFilter AlphaFilter}. 17708 * 17709 * **outputFrame** 17710 * 17711 * The `outputFrame` holds the rectangle where filter is applied in screen (CSS) coordinates. 17712 * It's the same as `renderer.screen` for a fullscreen filter. 17713 * Only a part of `outputFrame.zw` size of temporary Framebuffer is used, 17714 * `(0, 0, outputFrame.width, outputFrame.height)`, 17715 * 17716 * Filters uses this quad to normalized (0-1) space, its passed into `aVertexPosition` attribute. 17717 * To calculate vertex position in screen space using normalized (0-1) space: 17718 * 17719 * ``` 17720 * vec4 filterVertexPosition( void ) 17721 * { 17722 * vec2 position = aVertexPosition * max(outputFrame.zw, vec2(0.)) + outputFrame.xy;
17723 * return vec4((projectionMatrix * vec3(position, 1.0)).xy, 0.0, 1.0); 17724 * } 17725 * ``` 17726 * 17727 * **inputSize** 17728 * 17729 * Temporary Framebuffer is different, it can be either the size of screen, either power-of-two. 17730 * The `inputSize.xy` are size of temporary Framebuffer that holds input. 17731 * The `inputSize.zw` is inverted, it's a shortcut to evade division inside the shader. 17732 * 17733 * Set `inputSize.xy = outputFrame.zw` for a fullscreen filter. 17734 * 17735 * To calculate input texture coordinate in 0-1 space, you have to map it to Framebuffer normalized space. 17736 * Multiply by `outputFrame.zw` to get pixel coordinate in part of Framebuffer. 17737 * Divide by `inputSize.xy` to get Framebuffer normalized space (input sampler space) 17738 * 17739 * ``` 17740 * vec2 filterTextureCoord( void ) 17741 * { 17742 * return aVertexPosition * (outputFrame.zw * inputSize.zw); // same as /inputSize.xy 17743 * } 17744 * ``` 17745 * **resolution** 17746 * 17747 * The `resolution` is the ratio of screen (CSS) pixels to real pixels. 17748 * 17749 * **inputPixel** 17750 * 17751 * `inputPixel.xy` is the size of framebuffer in real pixels, same as `inputSize.xy * resolution` 17752 * `inputPixel.zw` is inverted `inputPixel.xy`. 17753 * 17754 * It's handy for filters that use neighbour pixels, like {@link PIXI.filters.FXAAFilter FXAAFilter}. 17755 * 17756 * **inputClamp** 17757 * 17758 * If you try to get info from outside of used part of Framebuffer - you'll get undefined behaviour. 17759 * For displacements, coordinates has to be clamped. 17760 * 17761 * The `inputClamp.xy` is left-top pixel center, you may ignore it, because we use left-top part of Framebuffer 17762 * `inputClamp.zw` is bottom-right pixel center. 17763 * 17764 * ``` 17765 * vec4 color = texture2D(uSampler, clamp(modifigedTextureCoord, inputClamp.xy, inputClamp.zw)) 17766 * ``` 17767 * OR 17768 * ``` 17769 * vec4 color = texture2D(uSampler, min(modifigedTextureCoord, inputClamp.zw)) 17770 * ``` 17771 * 17772 * ### Additional Information 17773 * 17774 * Complete documentation on Filter usage is located in the 17775 * {@link https://github.com/pixijs/pixi.js/wiki/v5-Creating-filters Wiki}. 17776 * 17777 * Since PixiJS only had a handful of built-in filters, additional filters can be downloaded 17778 * {@link https://github.com/pixijs/pixi-filters here} from the PixiJS Filters repository. 17779 * 17780 * @class 17781 * @memberof PIXI 17782 * @extends PIXI.Shader 17783 */ 17784 var Filter = /*@__PURE__*/(function (Shader) { 17785 function Filter(vertexSrc, fragmentSrc, uniforms) 17786 { 17787 var program = Program.from(vertexSrc || Filter.defaultVertexSrc, 17788 fragmentSrc || Filter.defaultFragmentSrc); 17789 17790 Shader.call(this, program, uniforms); 17791 17792 /** 17793 * The padding of the filter. Some filters require extra space to breath such as a blur. 17794 * Increasing this will add extra width and height to the bounds of the object that the 17795 * filter is applied to. 17796 * 17797 * @member {number} 17798 */ 17799 this.padding = 0; 17800 17801 /** 17802 * The resolution of the filter. Setting this to be lower will lower the quality but 17803 * increase the performance of the filter. 17804 * 17805 * @member {number} 17806 */ 17807 this.resolution = settings.FILTER_RESOLUTION; 17808 17809 /** 17810 * If enabled is true the filter is applied, if false it will not. 17811 * 17812 * @member {boolean} 17813 */ 17814 this.enabled = true; 17815 17816 /** 17817 * If enabled, PixiJS will fit the filter area into boundaries for better performance. 17818 * Switch it off if it does not work for specific shader. 17819 * 17820 * @member {boolean} 17821 */ 17822 this.autoFit = true; 17823 17824 /** 17825 * Legacy filters use position and uvs from attributes 17826 * @member {boolean} 17827 * @readonly 17828 */ 17829 this.legacy = !!this.program.attributeData.aTextureCoord; 17830 17831 /** 17832 * The WebGL state the filter requires to render 17833 * @member {PIXI.State} 17834 */ 17835 this.state = new State(); 17836 } 17837 17838 if ( Shader ) { Filter.__proto__ = Shader; } 17839 Filter.prototype = Object.create( Shader && Shader.prototype ); 17840 Filter.prototype.constructor = Filter; 17841 17842 var prototypeAccessors = { blendMode: { configurable: true } }; 17843 var staticAccessors = { defaultVertexSrc: { configurable: true },defaultFragmentSrc: { configurable: true } }; 17844 17845 /** 17846 * Applies the filter 17847 * 17848 * @param {PIXI.systems.FilterSystem} filterManager - The renderer to retrieve the filter from 17849 * @param {PIXI.RenderTexture} input - The input render target. 17850 * @param {PIXI.RenderTexture} output - The target to output to. 17851 * @param {boolean} clear - Should the output be cleared before rendering to it 17852 * @param {object} [currentState] - It's current state of filter. 17853 * There are some useful properties in the currentState : 17854 * target, filters, sourceFrame, destinationFrame, renderTarget, resolution 17855 */ 17856 Filter.prototype.apply = function apply (filterManager, input, output, clear, currentState, derp) // eslint-disable-line no-unused-vars 17857 { 17858 // do as you please! 17859 17860 filterManager.applyFilter(this, input, output, clear, currentState, derp); 17861 17862 // or just do a regular render.. 17863 }; 17864 17865 /** 17866 * Sets the blendmode of the filter 17867 * 17868 * @member {number} 17869 * @default PIXI.BLEND_MODES.NORMAL 17870 */ 17871 prototypeAccessors.blendMode.get = function () 17872 { 17873 return this.state.blendMode; 17874 }; 17875 17876 prototypeAccessors.blendMode.set = function (value) // eslint-disable-line require-jsdoc 17877 { 17878 this.state.blendMode = value; 17879 }; 17880 17881 /** 17882 * The default vertex shader source 17883 * 17884 * @static 17885 * @type {string} 17886 * @constant 17887 */ 17888 staticAccessors.defaultVertexSrc.get = function () 17889 { 17890 return defaultVertex$1; 17891 }; 17892 17893 /** 17894 * The default fragment shader source 17895 * 17896 * @static 17897 * @type {string} 17898 * @constant 17899 */ 17900 staticAccessors.defaultFragmentSrc.get = function () 17901 { 17902 return defaultFragment$1; 17903 }; 17904 17905 Object.defineProperties( Filter.prototype, prototypeAccessors ); 17906 Object.defineProperties( Filter, staticAccessors ); 17907 17908 return Filter; 17909 }(Shader)); 17910 17911 /** 17912 * Used for caching shader IDs 17913 * 17914 * @static 17915 * @type {object} 17916 * @protected 17917 */ 17918 Filter.SOURCE_KEY_MAP = {}; 17919 17920 var vertex = "attribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\n\nuniform mat3 projectionMatrix;\nuniform mat3 otherMatrix;\n\nvarying vec2 vMaskCoord;\nvarying vec2 vTextureCoord;\n\nvoid main(void)\n{\n gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0
17920)).xy, 0.0, 1.0);\n\n vTextureCoord = aTextureCoord;\n vMaskCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy;\n}\n"; 17921 17922 var fragment = "varying vec2 vMaskCoord;\nvarying vec2 vTextureCoord;\n\nuniform sampler2D uSampler;\nuniform sampler2D mask;\nuniform float alpha;\nuniform float npmAlpha;\nuniform vec4 maskClamp;\n\nvoid main(void)\n{\n float clip = step(3.5,\n step(maskClamp.x, vMaskCoord.x) +\n step(maskClamp.y, vMaskCoord.y) +\n step(vMaskCoord.x, maskClamp.z) +\n step(vMaskCoord.y, maskClamp.w));\n\n vec4 original = texture2D(uSampler, vTextureCoord);\n vec4 masky = texture2D(mask, vMaskCoord);\n float alphaMul = 1.0 - npmAlpha * (1.0 - masky.a);\n\n original *= (alphaMul * masky.r * alpha * clip);\n\n gl_FragColor = original;\n}\n"; 17923 17924 var tempMat = new Matrix(); 17925 17926 /** 17927 * Class controls uv mapping from Texture normal space to BaseTexture normal space. 17928 * 17929 * Takes `trim` and `rotate` into account. May contain clamp settings for Meshes and TilingSprite. 17930 * 17931 * Can be used in Texture `uvMatrix` field, or separately, you can use different clamp settings on the same texture. 17932 * If you want to add support for texture region of certain feature or filter, that's what you're looking for. 17933 * 17934 * Takes track of Texture changes through `_lastTextureID` private field. 17935 * Use `update()` method call to track it from outside. 17936 * 17937 * @see PIXI.Texture 17938 * @see PIXI.Mesh 17939 * @see PIXI.TilingSprite 17940 * @class 17941 * @memberof PIXI 17942 */ 17943 var TextureMatrix = function TextureMatrix(texture, clampMargin) 17944 { 17945 this._texture = texture; 17946 17947 this.mapCoord = new Matrix(); 17948 17949 this.uClampFrame = new Float32Array(4); 17950 17951 this.uClampOffset = new Float32Array(2); 17952 17953 /** 17954 * Tracks Texture frame changes 17955 * @member {number} 17956 * @protected 17957 */ 17958 this._updateID = -1; 17959 17960 /** 17961 * Changes frame clamping 17962 * Works with TilingSprite and Mesh 17963 * Change to 1.5 if you texture has repeated right and bottom lines, that leads to smoother borders 17964 * 17965 * @default 0 17966 * @member {number} 17967 */ 17968 this.clampOffset = 0; 17969 17970 /** 17971 * Changes frame clamping 17972 * Works with TilingSprite and Mesh 17973 * Change to -0.5 to add a pixel to the edge, recommended for transparent trimmed textures in atlas 17974 * 17975 * @default 0.5 17976 * @member {number} 17977 */ 17978 this.clampMargin = (typeof clampMargin === 'undefined') ? 0.5 : clampMargin; 17979 17980 /** 17981 * If texture size is the same as baseTexture 17982 * @member {boolean} 17983 * @default false 17984 * @readonly 17985 */ 17986 this.isSimple = false; 17987 }; 17988 17989 var prototypeAccessors$4$1 = { texture: { configurable: true } }; 17990 17991 /** 17992 * texture property 17993 * @member {PIXI.Texture} 17994 */ 17995 prototypeAccessors$4$1.texture.get = function () 17996 { 17997 return this._texture; 17998 }; 17999 18000 prototypeAccessors$4$1.texture.set = function (value) // eslint-disable-line require-jsdoc 18001 { 18002 this._texture = value; 18003 this._updateID = -1; 18004 }; 18005 18006 /** 18007 * Multiplies uvs array to transform 18008 * @param {Float32Array} uvs mesh uvs 18009 * @param {Float32Array} [out=uvs] output 18010 * @returns {Float32Array} output 18011 */ 18012 TextureMatrix.prototype.multiplyUvs = function multiplyUvs (uvs, out) 18013 { 18014 if (out === undefined) 18015 { 18016 out = uvs; 18017 } 18018 18019 var mat = this.mapCoord; 18020 18021 for (var i = 0; i < uvs.length; i += 2) 18022 { 18023 var x = uvs[i]; 18024 var y = uvs[i + 1]; 18025 18026 out[i] = (x * mat.a) + (y * mat.c) + mat.tx; 18027 out[i + 1] = (x * mat.b) + (y * mat.d) + mat.ty; 18028 } 18029 18030 return out; 18031 }; 18032 18033 /** 18034 * updates matrices if texture was changed 18035 * @param {boolean} forceUpdate if true, matrices will be updated any case 18036 * @returns {boolean} whether or not it was updated 18037 */ 18038 TextureMatrix.prototype.update = function update (forceUpdate) 18039 { 18040 var tex = this._texture; 18041 18042 if (!tex || !tex.valid) 18043 { 18044 return false; 18045 } 18046 18047 if (!forceUpdate 18048 && this._updateID === tex._updateID) 18049 { 18050 return false; 18051 } 18052 18053 this._updateID = tex._updateID; 18054 18055 var uvs = tex._uvs; 18056 18057 this.mapCoord.set(uvs.x1 - uvs.x0, uvs.y1 - uvs.y0, uvs.x3 - uvs.x0, uvs.y3 - uvs.y0, uvs.x0, uvs.y0); 18058 18059 var orig = tex.orig; 18060 var trim = tex.trim; 18061 18062 if (trim) 18063 { 18064 tempMat.set(orig.width / trim.width, 0, 0, orig.height / trim.height, 18065 -trim.x / trim.width, -trim.y / trim.height); 18066 this.mapCoord.append(tempMat); 18067 } 18068 18069 var texBase = tex.baseTexture; 18070 var frame = this.uClampFrame; 18071 var margin = this.clampMargin / texBase.resolution; 18072 var offset = this.clampOffset; 18073 18074 frame[0] = (tex._frame.x + margin + offset) / texBase.width; 18075 frame[1] = (tex._frame.y + margin + offset) / texBase.height; 18076 frame[2] = (tex._frame.x + tex._frame.width - margin + offset) / texBase.width; 18077 frame[3] = (tex._frame.y + tex._frame.height - margin + offset) / texBase.height; 18078 this.uClampOffset[0] = offset / texBase.realWidth; 18079 this.uClampOffset[1] = offset / texBase.realHeight; 18080 18081 this.isSimple = tex._frame.width === texBase.width 18082 && tex._frame.height === texBase.height 18083 && tex.rotate === 0; 18084 18085 return true; 18086 }; 18087 18088 Object.defineProperties( TextureMatrix.prototype, prototypeAccessors$4$1 ); 18089 18090 /** 18091 * This handles a Sprite acting as a mask, as opposed to a Graphic. 18092 * 18093 * WebGL only. 18094 * 18095 * @class 18096 * @extends PIXI.Filter 18097 * @memberof PIXI 18098 */ 18099 var SpriteMaskFilter = /*@__PURE__*/(function (Filter) { 18100 function SpriteMaskFilter(sprite) 18101 { 18102 var maskMatrix = new Matrix(); 18103 18104 Filter.call(this, vertex, fragment); 18105 18106 sprite.renderable = false;
18107 18108 /** 18109 * Sprite mask 18110 * @member {PIXI.Sprite} 18111 */ 18112 this.maskSprite = sprite; 18113 18114 /** 18115 * Mask matrix 18116 * @member {PIXI.Matrix} 18117 */ 18118 this.maskMatrix = maskMatrix; 18119 } 18120 18121 if ( Filter ) { SpriteMaskFilter.__proto__ = Filter; } 18122 SpriteMaskFilter.prototype = Object.create( Filter && Filter.prototype ); 18123 SpriteMaskFilter.prototype.constructor = SpriteMaskFilter; 18124 18125 /** 18126 * Applies the filter 18127 * 18128 * @param {PIXI.systems.FilterSystem} filterManager - The renderer to retrieve the filter from 18129 * @param {PIXI.RenderTexture} input - The input render target. 18130 * @param {PIXI.RenderTexture} output - The target to output to. 18131 * @param {boolean} clear - Should the output be cleared before rendering to it. 18132 */ 18133 SpriteMaskFilter.prototype.apply = function apply (filterManager, input, output, clear) 18134 { 18135 var maskSprite = this.maskSprite; 18136 var tex = this.maskSprite.texture; 18137 18138 if (!tex.valid) 18139 { 18140 return; 18141 } 18142 if (!tex.transform) 18143 { 18144 // margin = 0.0, let it bleed a bit, shader code becomes easier 18145 // assuming that atlas textures were made with 1-pixel padding 18146 tex.transform = new TextureMatrix(tex, 0.0); 18147 } 18148 tex.transform.update(); 18149 18150 this.uniforms.npmAlpha = tex.baseTexture.premultiplyAlpha ? 0.0 : 1.0; 18151 this.uniforms.mask = tex; 18152 this.uniforms.otherMatrix = filterManager.calculateSpriteMatrix(this.maskMatrix, maskSprite) 18153 .prepend(tex.transform.mapCoord); 18154 this.uniforms.alpha = maskSprite.worldAlpha; 18155 this.uniforms.maskClamp = tex.transform.uClampFrame; 18156 18157 filterManager.applyFilter(this, input, output, clear); 18158 }; 18159 18160 return SpriteMaskFilter; 18161 }(Filter)); 18162 18163 /** 18164 * System plugin to the renderer to manage masks. 18165 * 18166 * @class 18167 * @extends PIXI.System 18168 * @memberof PIXI.systems 18169 */ 18170 var MaskSystem = /*@__PURE__*/(function (System) { 18171 function MaskSystem(renderer) 18172 { 18173 System.call(this, renderer); 18174 18175 // TODO - we don't need both! 18176 /** 18177 * `true` if current pushed masked is scissor 18178 * @member {boolean} 18179 * @readonly 18180 */ 18181 this.scissor = false; 18182 18183 /** 18184 * Mask data 18185 * @member {PIXI.Graphics} 18186 * @readonly 18187 */ 18188 this.scissorData = null; 18189 18190 /** 18191 * Target to mask 18192 * @member {PIXI.DisplayObject} 18193 * @readonly 18194 */ 18195 this.scissorRenderTarget = null; 18196 18197 /** 18198 * Enable scissor 18199 * @member {boolean} 18200 * @readonly 18201 */ 18202 this.enableScissor = false; 18203 18204 /** 18205 * Pool of used sprite mask filters 18206 * @member {PIXI.SpriteMaskFilter[]} 18207 * @readonly 18208 */ 18209 this.alphaMaskPool = []; 18210 18211 /** 18212 * Current index of alpha mask pool 18213 * @member {number} 18214 * @default 0 18215 * @readonly 18216 */ 18217 this.alphaMaskIndex = 0; 18218 } 18219 18220 if ( System ) { MaskSystem.__proto__ = System; } 18221 MaskSystem.prototype = Object.create( System && System.prototype ); 18222 MaskSystem.prototype.constructor = MaskSystem; 18223 18224 /** 18225 * Applies the Mask and adds it to the current filter stack. 18226 * 18227 * @param {PIXI.DisplayObject} target - Display Object to push the mask to 18228 * @param {PIXI.Sprite|PIXI.Graphics} maskData - The masking data. 18229 */ 18230 MaskSystem.prototype.push = function push (target, maskData) 18231 { 18232 // TODO the root check means scissor rect will not 18233 // be used on render textures more info here: 18234 // https://github.com/pixijs/pixi.js/pull/3545 18235 18236 if (maskData.isSprite) 18237 { 18238 this.pushSpriteMask(target, maskData); 18239 } 18240 else if (this.enableScissor 18241 && !this.scissor 18242 && this.renderer._activeRenderTarget.root 18243 && !this.renderer.stencil.stencilMaskStack.length
18244 && maskData.isFastRect()) 18245 { 18246 var matrix = maskData.worldTransform; 18247 18248 var rot = Math.atan2(matrix.b, matrix.a); 18249 18250 // use the nearest degree! 18251 rot = Math.round(rot * (180 / Math.PI)); 18252 18253 if (rot % 90) 18254 { 18255 this.pushStencilMask(maskData); 18256 } 18257 else 18258 { 18259 this.pushScissorMask(target, maskData); 18260 } 18261 } 18262 else 18263 { 18264 this.pushStencilMask(maskData); 18265 } 18266 }; 18267 18268 /** 18269 * Removes the last mask from the mask stack and doesn't return it. 18270 * 18271 * @param {PIXI.DisplayObject} target - Display Object to pop the mask from 18272 * @param {PIXI.Sprite|PIXI.Graphics} maskData - The masking data. 18273 */ 18274 MaskSystem.prototype.pop = function pop (target, maskData) 18275 { 18276 if (maskData.isSprite) 18277 { 18278 this.popSpriteMask(target, maskData); 18279 } 18280 else if (this.enableScissor && !this.renderer.stencil.stencilMaskStack.length) 18281 { 18282 this.popScissorMask(target, maskData); 18283 } 18284 else 18285 { 18286 this.popStencilMask(target, maskData); 18287 } 18288 }; 18289 18290 /** 18291 * Applies the Mask and adds it to the current filter stack. 18292 * 18293 * @param {PIXI.RenderTexture} target - Display Object to push the sprite mask to 18294 * @param {PIXI.Sprite} maskData - Sprite to be used as the mask 18295 */ 18296 MaskSystem.prototype.pushSpriteMask = function pushSpriteMask (target, maskData) 18297 { 18298 var alphaMaskFilter = this.alphaMaskPool[this.alphaMaskIndex]; 18299 18300 if (!alphaMaskFilter) 18301 { 18302 alphaMaskFilter = this.alphaMaskPool[this.alphaMaskIndex] = [new SpriteMaskFilter(maskData)]; 18303 } 18304 18305 alphaMaskFilter[0].resolution = this.renderer.resolution; 18306 alphaMaskFilter[0].maskSprite = maskData; 18307 18308 var stashFilterArea = target.filterArea; 18309 18310 target.filterArea = maskData.getBounds(true); 18311 this.renderer.filter.push(target, alphaMaskFilter); 18312 target.filterArea = stashFilterArea; 18313 18314 this.alphaMaskIndex++; 18315 }; 18316 18317 /** 18318 * Removes the last filter from the filter stack and doesn't return it. 18319 * 18320 */ 18321 MaskSystem.prototype.popSpriteMask = function popSpriteMask () 18322 { 18323 this.renderer.filter.pop(); 18324 this.alphaMaskIndex--; 18325 }; 18326 18327 /** 18328 * Applies the Mask and adds it to the current filter stack. 18329 * 18330 * @param {PIXI.Sprite|PIXI.Graphics} maskData - The masking data. 18331 */ 18332 MaskSystem.prototype.pushStencilMask = function pushStencilMask (maskData) 18333 { 18334 this.renderer.batch.flush(); 18335 this.renderer.stencil.pushStencil(maskData); 18336 }; 18337 18338 /** 18339 * Removes the last filter from the filter stack and doesn't return it. 18340 * 18341 */ 18342 MaskSystem.prototype.popStencilMask = function popStencilMask () 18343 { 18344 // this.renderer.currentRenderer.stop(); 18345 this.renderer.stencil.popStencil(); 18346 }; 18347 18348 /** 18349 * 18350 * @param {PIXI.DisplayObject} target - Display Object to push the mask to 18351 * @param {PIXI.Graphics} maskData - The masking data. 18352 */ 18353 MaskSystem.prototype.pushScissorMask = function pushScissorMask (target, maskData) 18354 { 18355 maskData.renderable = true; 18356 18357 var renderTarget = this.renderer._activeRenderTarget; 18358 18359 var bounds = maskData.getBounds(); 18360 18361 bounds.fit(renderTarget.size); 18362 maskData.renderable = false; 18363 18364 this.renderer.gl.enable(this.renderer.gl.SCISSOR_TEST); 18365 18366 var resolution = this.renderer.resolution; 18367 18368 this.renderer.gl.scissor( 18369 bounds.x * resolution, 18370 (renderTarget.root ? renderTarget.size.height - bounds.y - bounds.height : bounds.y) * resolution, 18371 bounds.width * resolution, 18372 bounds.height * resolution 18373 ); 18374 18375 this.scissorRenderTarget = renderTarget; 18376 this.scissorData = maskData; 18377 this.scissor = true; 18378 }; 18379 18380 /** 18381 * Pop scissor mask 18382 * 18383 */ 18384 MaskSystem.prototype.popScissorMask = function popScissorMask () 18385 { 18386 this.scissorRenderTarget = null; 18387 this.scissorData = null; 18388 this.scissor = false;
18389 18390 // must be scissor! 18391 var ref = this.renderer; 18392 var gl = ref.gl; 18393 18394 gl.disable(gl.SCISSOR_TEST); 18395 }; 18396 18397 return MaskSystem; 18398 }(System)); 18399 18400 /** 18401 * System plugin to the renderer to manage stencils (used for masks). 18402 * 18403 * @class 18404 * @extends PIXI.System 18405 * @memberof PIXI.systems 18406 */ 18407 var StencilSystem = /*@__PURE__*/(function (System) { 18408 function StencilSystem(renderer) 18409 { 18410 System.call(this, renderer); 18411 18412 /** 18413 * The mask stack 18414 * @member {PIXI.Graphics[]} 18415 */ 18416 this.stencilMaskStack = []; 18417 } 18418 18419 if ( System ) { StencilSystem.__proto__ = System; } 18420 StencilSystem.prototype = Object.create( System && System.prototype ); 18421 StencilSystem.prototype.constructor = StencilSystem; 18422 18423 /** 18424 * Changes the mask stack that is used by this System. 18425 * 18426 * @param {PIXI.Graphics[]} stencilMaskStack - The mask stack 18427 */ 18428 StencilSystem.prototype.setMaskStack = function setMaskStack (stencilMaskStack) 18429 { 18430 var gl = this.renderer.gl; 18431 18432 if (stencilMaskStack.length !== this.stencilMaskStack.length) 18433 { 18434 if (stencilMaskStack.length === 0) 18435 { 18436 gl.disable(gl.STENCIL_TEST); 18437 } 18438 else 18439 { 18440 gl.enable(gl.STENCIL_TEST); 18441 } 18442 } 18443 18444 this.stencilMaskStack = stencilMaskStack; 18445 }; 18446 18447 /** 18448 * Applies the Mask and adds it to the current stencil stack. @alvin 18449 * 18450 * @param {PIXI.Graphics} graphics - The mask 18451 */ 18452 StencilSystem.prototype.pushStencil = function pushStencil (graphics) 18453 { 18454 var gl = this.renderer.gl; 18455 var prevMaskCount = this.stencilMaskStack.length; 18456 18457 if (prevMaskCount === 0) 18458 { 18459 gl.enable(gl.STENCIL_TEST); 18460 } 18461 18462 this.stencilMaskStack.push(graphics); 18463 18464 // Increment the reference stencil value where the new mask overlaps with the old ones. 18465 gl.colorMask(false, false, false, false); 18466 gl.stencilFunc(gl.EQUAL, prevMaskCount, this._getBitwiseMask()); 18467 gl.stencilOp(gl.KEEP, gl.KEEP, gl.INCR); 18468 18469 graphics.renderable = true; 18470 graphics.render(this.renderer); 18471 this.renderer.batch.flush(); 18472 graphics.renderable = false; 18473 18474 this._useCurrent(); 18475 }; 18476 18477 /** 18478 * Removes the last mask from the stencil stack. @alvin 18479 */ 18480 StencilSystem.prototype.popStencil = function popStencil () 18481 { 18482 var gl = this.renderer.gl; 18483 var graphics = this.stencilMaskStack.pop(); 18484 18485 if (this.stencilMaskStack.length === 0) 18486 { 18487 // the stack is empty! 18488 gl.disable(gl.STENCIL_TEST); 18489 gl.clear(gl.STENCIL_BUFFER_BIT); 18490 gl.clearStencil(0); 18491 } 18492 else 18493 { 18494 // Decrement the reference stencil value where the popped mask overlaps with the other ones 18495 gl.colorMask(false, false, false, false); 18496 gl.stencilOp(gl.KEEP, gl.KEEP, gl.DECR); 18497 18498 graphics.renderable = true; 18499 graphics.render(this.renderer); 18500 this.renderer.batch.flush(); 18501 graphics.renderable = false; 18502 18503 this._useCurrent(); 18504 } 18505 }; 18506 18507 /** 18508 * Setup renderer to use the current stencil data. 18509 * @private 18510 */ 18511 StencilSystem.prototype._useCurrent = function _useCurrent () 18512 { 18513 var gl = this.renderer.gl; 18514 18515 gl.colorMask(true, true, true, true); 18516 gl.stencilFunc(gl.EQUAL, this.stencilMaskStack.length, this._getBitwiseMask()); 18517 gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP); 18518 }; 18519 18520 /** 18521 * Fill 1s equal to the number of acitve stencil masks. 18522 * @private 18523 * @return {number} The bitwise mask. 18524 */ 18525 StencilSystem.prototype._getBitwiseMask = function _getBitwiseMask () 18526 { 18527 return (1 << this.stencilMaskStack.length) - 1; 18528 }; 18529 18530 /** 18531 * Destroys the mask stack. 18532 * 18533 */ 18534 StencilSystem.prototype.destroy = function destroy () 18535 { 18536 System.prototype.destroy.call(this, this); 18537 18538 this.stencilMaskStack = null; 18539 }; 18540 18541 return StencilSystem; 18542 }(System)); 18543 18544 /** 18545 * System plugin to the renderer to manage the projection matrix. 18546 * 18547 * @class 18548 * @extends PIXI.System 18549 * @memberof PIXI.systems 18550 */ 18551 18552 var ProjectionSystem = /*@__PURE__*/(function (System) { 18553 function ProjectionSystem(renderer) 18554 { 18555 System.call(this, renderer); 18556 18557 /** 18558 * Destination frame 18559 * @member {PIXI.Rectangle} 18560 * @readonly 18561 */ 18562 this.destinationFrame = null; 18563 18564 /** 18565 * Source frame 18566 * @member {PIXI.Rectangle} 18567 * @readonly 18568 */ 18569 this.sourceFrame = null; 18570 18571 /** 18572 * Default destination frame 18573 * @member {PIXI.Rectangle} 18574 * @readonly 18575 */ 18576 this.defaultFrame = null; 18577 18578 /** 18579 * Project matrix 18580 * @member {PIXI.Matrix} 18581 * @readonly 18582 */ 18583 this.projectionMatrix = new Matrix(); 18584 18585 /** 18586 * A transform that will be appended to the projection matrix 18587 * if null, nothing will be applied 18588 * @member {PIXI.Matrix} 18589 */ 18590 this.transform = null; 18591 } 18592 18593 if ( System ) { ProjectionSystem.__proto__ = System; } 18594 ProjectionSystem.prototype = Object.create( System && System.prototype ); 18595 ProjectionSystem.prototype.constructor = ProjectionSystem; 18596 18597 /** 18598 * Updates the projection matrix based on a projection frame (which is a rectangle) 18599 * 18600 * @param {PIXI.Rectangle} destinationFrame - The destination frame. 18601 * @param {PIXI.Rectangle} sourceFrame - The source frame. 18602 * @param {Number} resolution - Resolution 18603 * @param {boolean} root - If is root 18604 */ 18605 ProjectionSystem.prototype.update = function update (destinationFrame, sourceFrame, resolution, root) 18606 { 18607 this.destinationFrame = destinationFrame || this.destinationFrame || this.defaultFrame; 18608 this.sourceFrame = sourceFrame || this.sourceFrame || destinationFrame; 18609 18610 this.calculateProjection(this.destinationFrame, this.sourceFrame, resolution, root); 18611 18612 if (this.transform) 18613 { 18614 this.projectionMatrix.append(this.transform); 18615 } 18616 18617 var renderer = this.renderer; 18618 18619 renderer.globalUniforms.uniforms.projectionMatrix = this.projectionMatrix; 18620 renderer.globalUniforms.update(); 18621 18622 // this will work for now 18623 // but would be sweet to stick and even on the global uniforms.. 18624 if (renderer.shader.shader) 18625 { 18626 renderer.shader.syncUniformGroup(renderer.shader.shader.uniforms.globals); 18627 } 18628 }; 18629 18630 /** 18631 * Updates the projection matrix based on a projection frame (which is a rectangle) 18632 * 18633 * @param {PIXI.Rectangle} destinationFrame - The destination frame. 18634 * @param {PIXI.Rectangle} sourceFrame - The source frame. 18635 * @param {Number} resolution - Resolution 18636 * @param {boolean} root - If is root 18637 */ 18638 ProjectionSystem.prototype.calculateProjection = function calculateProjection (destinationFrame, sourceFrame, resolution, root) 18639 { 18640 var pm = this.projectionMatrix; 18641 18642 // I don't think we will need this line.. 18643 // pm.identity(); 18644 18645 if (!root) 18646 { 18647 pm.a = (1 / destinationFrame.width * 2) * resolution; 18648 pm.d = (1 / destinationFrame.height * 2) * resolution; 18649 18650 pm.tx = -1 - (sourceFrame.x * pm.a); 18651 pm.ty = -1 - (sourceFrame.y * pm.d); 18652 } 18653 else 18654 { 18655 pm.a = (1 / destinationFrame.width * 2) * resolution; 18656 pm.d = (-1 / destinationFrame.height * 2) * resolution; 18657 18658 pm.tx = -1 - (sourceFrame.x * pm.a); 18659 pm.ty = 1 - (sourceFrame.y * pm.d); 18660 } 18661 }; 18662 18663 /** 18664 * Sets the transform of the active render target to the given matrix 18665 * 18666 * @param {PIXI.Matrix} matrix - The transformation matrix 18667 */ 18668 ProjectionSystem.prototype.setTransform = function setTransform ()/
18668/ matrix) 18669 { 18670 // this._activeRenderTarget.transform = matrix; 18671 }; 18672 18673 return ProjectionSystem; 18674 }(System)); 18675 18676 var tempRect = new Rectangle(); 18677 18678 /** 18679 * System plugin to the renderer to manage render textures. 18680 * 18681 * Should be added after FramebufferSystem 18682 * 18683 * @class 18684 * @extends PIXI.System 18685 * @memberof PIXI.systems 18686 */ 18687 18688 var RenderTextureSystem = /*@__PURE__*/(function (System) { 18689 function RenderTextureSystem(renderer) 18690 { 18691 System.call(this, renderer); 18692 18693 /** 18694 * The clear background color as rgba 18695 * @member {number[]} 18696 */ 18697 this.clearColor = renderer._backgroundColorRgba; 18698 18699 // TODO move this property somewhere else! 18700 /** 18701 * List of masks for the StencilSystem 18702 * @member {PIXI.Graphics[]} 18703 * @readonly 18704 */ 18705 this.defaultMaskStack = []; 18706 18707 // empty render texture? 18708 /** 18709 * Render texture 18710 * @member {PIXI.RenderTexture} 18711 * @readonly 18712 */ 18713 this.current = null; 18714 18715 /** 18716 * Source frame 18717 * @member {PIXI.Rectangle} 18718 * @readonly 18719 */ 18720 this.sourceFrame = new Rectangle(); 18721 18722 /** 18723 * Destination frame 18724 * @member {PIXI.Rectangle} 18725 * @readonly 18726 */ 18727 this.destinationFrame = new Rectangle(); 18728 } 18729 18730 if ( System ) { RenderTextureSystem.__proto__ = System; } 18731 RenderTextureSystem.prototype = Object.create( System && System.prototype ); 18732 RenderTextureSystem.prototype.constructor = RenderTextureSystem; 18733 18734 /** 18735 * Bind the current render texture 18736 * @param {PIXI.RenderTexture} renderTexture 18737 * @param {PIXI.Rectangle} sourceFrame 18738 * @param {PIXI.Rectangle} destinationFrame 18739 */ 18740 RenderTextureSystem.prototype.bind = function bind (renderTexture, sourceFrame, destinationFrame) 18741 { 18742 if ( renderTexture === void 0 ) { renderTexture = null; } 18743 18744 this.current = renderTexture; 18745 18746 var renderer = this.renderer; 18747 18748 var resolution; 18749 18750 if (renderTexture) 18751 { 18752 var baseTexture = renderTexture.baseTexture; 18753 18754 resolution = baseTexture.resolution; 18755 18756 if (!destinationFrame) 18757 { 18758 tempRect.width = baseTexture.realWidth; 18759 tempRect.height = baseTexture.realHeight; 18760 18761 destinationFrame = tempRect; 18762 } 18763 18764 if (!sourceFrame) 18765 { 18766 sourceFrame = destinationFrame; 18767 } 18768 18769 this.renderer.framebuffer.bind(baseTexture.framebuffer, destinationFrame); 18770 18771 this.renderer.projection.update(destinationFrame, sourceFrame, resolution, false); 18772 this.renderer.stencil.setMaskStack(baseTexture.stencilMaskStack); 18773 } 18774 else 18775 { 18776 resolution = this.renderer.resolution; 18777 18778 // TODO these validation checks happen deeper down.. 18779 // thing they can be avoided.. 18780 if (!destinationFrame) 18781 { 18782 tempRect.width = renderer.width; 18783 tempRect.height = renderer.height; 18784 18785 destinationFrame = tempRect; 18786 } 18787 18788 if (!sourceFrame) 18789 { 18790 sourceFrame = destinationFrame; 18791 } 18792 18793 renderer.framebuffer.bind(null, destinationFrame); 18794 18795 // TODO store this.. 18796 this.renderer.projection.update(destinationFrame, sourceFrame, resolution, true); 18797 this.renderer.stencil.setMaskStack(this.defaultMaskStack); 18798 } 18799 18800 this.sourceFrame.copyFrom(sourceFrame); 18801 18802 this.destinationFrame.x = destinationFrame.x / resolution; 18803 this.destinationFrame.y = destinationFrame.y / resolution; 18804 18805 this.destinationFrame.width = destinationFrame.width / resolution; 18806 this.destinationFrame.height = destinationFrame.height / resolution; 18807 }; 18808 18809 /** 18810 * Erases the render texture and fills the drawing area with a colour 18811 * 18812 * @param {number[]} [clearColor] - The color as rgba, default to use the renderer backgroundColor 18813 * @return {PIXI.Renderer} Returns itself. 18814 */ 18815 RenderTextureSystem.prototype.clear = function clear (clearColor) 18816 { 18817 if (this.current) 18818 { 18819 clearColor = clearColor || this.current.baseTexture.clearColor; 18820 } 18821 else 18822 { 18823 clearColor = clearColor || this.clearColor; 18824 } 18825 18826 this.renderer.framebuffer.clear(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); 18827 }; 18828
18829 RenderTextureSystem.prototype.resize = function resize ()// screenWidth, screenHeight) 18830 { 18831 // resize the root only! 18832 this.bind(null); 18833 }; 18834 18835 /** 18836 * Resets renderTexture state 18837 */ 18838 RenderTextureSystem.prototype.reset = function reset () 18839 { 18840 this.bind(null); 18841 }; 18842 18843 return RenderTextureSystem; 18844 }(System)); 18845 18846 /** 18847 * Helper class to create a WebGL Program 18848 * 18849 * @class 18850 * @memberof PIXI 18851 */ 18852 var GLProgram = function GLProgram(program, uniformData) 18853 { 18854 /** 18855 * The shader program 18856 * 18857 * @member {WebGLProgram} 18858 */ 18859 this.program = program; 18860 18861 /** 18862 * holds the uniform data which contains uniform locations 18863 * and current uniform values used for caching and preventing unneeded GPU commands 18864 * @member {Object} 18865 */ 18866 this.uniformData = uniformData; 18867 18868 /** 18869 * uniformGroups holds the various upload functions for the shader. Each uniform group 18870 * and program have a unique upload function generated. 18871 * @member {Object} 18872 */ 18873 this.uniformGroups = {}; 18874 }; 18875 18876 /** 18877 * Destroys this program 18878 */ 18879 GLProgram.prototype.destroy = function destroy () 18880 { 18881 this.uniformData = null; 18882 this.uniformGroups = null; 18883 this.program = null; 18884 }; 18885 18886 var UID$4 = 0; 18887 18888 /** 18889 * System plugin to the renderer to manage shaders. 18890 * 18891 * @class 18892 * @memberof PIXI.systems 18893 * @extends PIXI.System 18894 */ 18895 var ShaderSystem = /*@__PURE__*/(function (System) { 18896 function ShaderSystem(renderer) 18897 { 18898 System.call(this, renderer); 18899 18900 // Validation check that this environment support `new Function` 18901 this.systemCheck(); 18902 18903 /** 18904 * The current WebGL rendering context 18905 * 18906 * @member {WebGLRenderingContext} 18907 */ 18908 this.gl = null; 18909 18910 this.shader = null; 18911 this.program = null; 18912 18913 /** 18914 * Cache to holds the generated functions. Stored against UniformObjects unique signature 18915 * @type {Object} 18916 * @private 18917 */ 18918 this.cache = {}; 18919 18920 this.id = UID$4++; 18921 } 18922 18923 if ( System ) { ShaderSystem.__proto__ = System; } 18924 ShaderSystem.prototype = Object.create( System && System.prototype ); 18925 ShaderSystem.prototype.constructor = ShaderSystem; 18926 18927 /** 18928 * Overrideable function by `@pixi/unsafe-eval` to silence 18929 * throwing an error if platform doesn't support unsafe-evals. 18930 * 18931 * @private 18932 */ 18933 ShaderSystem.prototype.systemCheck = function systemCheck () 18934 { 18935 if (!unsafeEvalSupported()) 18936 { 18937 throw new Error('Current environment does not allow unsafe-eval, ' 18938 + 'please use @pixi/unsafe-eval module to enable support.'); 18939 } 18940 }; 18941 18942 ShaderSystem.prototype.contextChange = function contextChange (gl) 18943 { 18944 this.gl = gl; 18945 }; 18946 18947 /** 18948 * Changes the current shader to the one given in parameter 18949 * 18950 * @param {PIXI.Shader} shader - the new shader 18951 * @param {boolean} dontSync - false if the shader should automatically sync its uniforms. 18952 * @returns {PIXI.GLProgram} the glProgram that belongs to the shader. 18953 */ 18954 ShaderSystem.prototype.bind = function bind (shader, dontSync) 18955 { 18956 shader.uniforms.globals = this.renderer.globalUniforms; 18957 18958 var program = shader.program; 18959 var glProgram = program.glPrograms[this.renderer.CONTEXT_UID] || this.generateShader(shader); 18960 18961 this.shader = shader; 18962 18963 // TODO - some current Pixi plugins bypass this.. so it not safe to use yet.. 18964 if (this.program !== program) 18965 { 18966 this.program = program; 18967 this.gl.useProgram(glProgram.program); 18968 } 18969 18970 if (!dontSync) 18971 { 18972 this.syncUniformGroup(shader.uniformGroup); 18973 } 18974 18975 return glProgram; 18976 }; 18977 18978 /** 18979 * Uploads the uniforms values to the currently bound shader. 18980 * 18981 * @param {object} uniforms - the uniforms values that be applied to the current shader 18982 */ 18983 ShaderSystem.prototype.setUniforms = function setUniforms (uniforms) 18984 { 18985 var shader = this.shader.program; 18986 var glProgram = shader.glPrograms[this.renderer.CONTEXT_UID]; 18987 18988 shader.syncUniforms(glProgram.uniformData, uniforms, this.renderer); 18989 }; 18990 18991 ShaderSystem.prototype.syncUniformGroup = function syncUniformGroup (group) 18992 { 18993 var glProgram = this.getglProgram(); 18994 18995 if (!group.static || group.dirtyId !== glProgram.uniformGroups[group.id]) 18996 { 18997 glProgram.uniformGroups[group.id] = group.dirtyId; 18998 18999 this.syncUniforms(group, glProgram); 19000 } 19001 }; 19002 19003 /** 19004 * Overrideable by the @pixi/unsafe-eval package to use static 19005 * syncUnforms instead. 19006 * 19007 * @private 19008 */ 19009 ShaderSystem.prototype.syncUniforms = function syncUniforms (group, glProgram) 19010 { 19011 var syncFunc = group.syncUniforms[this.shader.program.id] || this.createSyncGroups(group); 19012 19013 syncFunc(glProgram.uniformData, group.uniforms, this.renderer); 19014 }; 19015 19016 ShaderSystem.prototype.createSyncGroups = function createSyncGroups (group) 19017 {
19018 var id = this.getSignature(group, this.shader.program.uniformData); 19019 19020 if (!this.cache[id]) 19021 { 19022 this.cache[id] = generateUniformsSync(group, this.shader.program.uniformData); 19023 } 19024 19025 group.syncUniforms[this.shader.program.id] = this.cache[id]; 19026 19027 return group.syncUniforms[this.shader.program.id]; 19028 }; 19029 19030 /** 19031 * Takes a uniform group and data and generates a unique signature for them. 19032 * 19033 * @param {PIXI.UniformGroup} group the uniform group to get signature of 19034 * @param {Object} uniformData uniform information generated by the shader 19035 * @returns {String} Unique signature of the uniform group 19036 * @private 19037 */ 19038 ShaderSystem.prototype.getSignature = function getSignature (group, uniformData) 19039 { 19040 var uniforms = group.uniforms; 19041 19042 var strings = []; 19043 19044 for (var i in uniforms) 19045 { 19046 strings.push(i); 19047 19048 if (uniformData[i]) 19049 { 19050 strings.push(uniformData[i].type); 19051 } 19052 } 19053 19054 return strings.join('-'); 19055 }; 19056 19057 /** 19058 * Returns the underlying GLShade rof the currently bound shader. 19059 * This can be handy for when you to have a little more control over the setting of your uniforms. 19060 * 19061 * @return {PIXI.GLProgram} the glProgram for the currently bound Shader for this context 19062 */ 19063 ShaderSystem.prototype.getglProgram = function getglProgram () 19064 { 19065 if (this.shader) 19066 { 19067 return this.shader.program.glPrograms[this.renderer.CONTEXT_UID]; 19068 } 19069 19070 return null; 19071 }; 19072 19073 /** 19074 * Generates a glProgram version of the Shader provided. 19075 * 19076 * @private 19077 * @param {PIXI.Shader} shader the shader that the glProgram will be based on. 19078 * @return {PIXI.GLProgram} A shiny new glProgram! 19079 */ 19080 ShaderSystem.prototype.generateShader = function generateShader (shader) 19081 { 19082 var gl = this.gl; 19083 19084 var program = shader.program; 19085 19086 var attribMap = {}; 19087 19088 for (var i in program.attributeData) 19089 { 19090 attribMap[i] = program.attributeData[i].location; 19091 } 19092 19093 var shaderProgram = compileProgram(gl, program.vertexSrc, program.fragmentSrc, attribMap); 19094 var uniformData = {}; 19095 19096 for (var i$1 in program.uniformData) 19097 { 19098 var data = program.uniformData[i$1]; 19099 19100 uniformData[i$1] = { 19101 location: gl.getUniformLocation(shaderProgram, i$1), 19102 value: defaultValue(data.type, data.size), 19103 }; 19104 } 19105 19106 var glProgram = new GLProgram(shaderProgram, uniformData); 19107 19108 program.glPrograms[this.renderer.CONTEXT_UID] = glProgram; 19109 19110 return glProgram; 19111 }; 19112 19113 /** 19114 * Resets ShaderSystem state, does not affect WebGL state 19115 */ 19116 ShaderSystem.prototype.reset = function reset () 19117 { 19118 this.program = null; 19119 this.shader = null; 19120 }; 19121 19122 /** 19123 * Destroys this System and removes all its textures 19124 */ 19125 ShaderSystem.prototype.destroy = function destroy () 19126 { 19127 // TODO implement destroy method for ShaderSystem 19128 this.destroyed = true; 19129 }; 19130 19131 return ShaderSystem; 19132 }(System)); 19133 19134 /** 19135 * Maps gl blend combinations to WebGL. 19136 * 19137 * @memberof PIXI 19138 * @function mapWebGLBlendModesToPixi 19139 * @private 19140 * @param {WebGLRenderingContext} gl - The rendering context. 19141 * @param {number[][]} [array=[]] - The array to output into. 19142 * @return {number[][]} Mapped modes. 19143 */ 19144 function mapWebGLBlendModesToPixi(gl, array) 19145 { 19146 if ( array === void 0 ) { array = []; } 19147 19148 // TODO - premultiply alpha would be different. 19149 // add a boolean for that! 19150 array[BLEND_MODES.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; 19151 array[BLEND_MODES.ADD] = [gl.ONE, gl.DST_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; 19152 array[BLEND_MODES.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; 19153 array[BLEND_MODES.SCREEN] = [gl.ONE, gl.ONE_MINUS_SRC_COLOR, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; 19154 array[BLEND_MODES.OVERLAY] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; 19155 array[BLEND_MODES.DARKEN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; 19156 array[BLEND_MODES.LIGHTEN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; 19157 array[BLEND_MODES.COLOR_DODGE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; 19158 array[BLEND_MODES.COLOR_BURN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; 19159 array[BLEND_MODES.HARD_LIGHT] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; 19160 array[BLEND_MODES.SOFT_LIGHT] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; 19161 array[BLEND_MODES.DIFFERENCE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; 19162 array[BLEND_MODES.EXCLUSION] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; 19163 array[BLEND_MODES.HUE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; 19164 array[BLEND_MODES.SATURATION] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; 19165 array[BLEND_MODES.COLOR] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; 19166 array[BLEND_MODES.LUMINOSITY] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; 19167 array[BLEND_MODES.NONE] = [0, 0]; 19168 19169 // not-premultiplied blend modes 19170 array[BLEND_MODES.NORMAL_NPM] = [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; 19171 array[BLEND_MODES.ADD_NPM] = [gl.SRC_ALPHA, gl.DST_ALPHA, gl.ONE, gl.DST_ALPHA]; 19172 array[BLEND_MODES.SCREEN_NPM] = [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_COLOR, gl.ONE, gl.ONE_MINUS_SRC_COLOR]; 19173 19174 // composite operations 19175 array[BLEND_MODES.SRC_IN] = [gl.DST_ALPHA, gl.ZERO]; 19176 array[BLEND_MODES.SRC_OUT] = [gl.ONE_MINUS_DST_ALPHA, gl.ZERO]; 19177 array[BLEND_MODES.SRC_ATOP] = [gl.DST_ALPHA, gl.ONE_MINUS_SRC_ALPHA]; 19178 array[BLEND_MODES.DST_OVER] = [gl.ONE_MINUS_DST_ALPHA, gl.ONE]; 19179 array[BLEND_MODES.DST_IN] = [gl.ZERO, gl.SRC_ALPHA]; 19180 array[BLEND_MODES.DST_OUT] = [gl.ZERO, gl.ONE_MINUS_SRC_ALPHA]; 19181 array[BLEND_MODES.DST_ATOP] = [gl.ONE_MINUS_DST_ALPHA, gl.SRC_ALPHA]; 19182 19183 // SUBTRACT from flash 19184 array[BLEND_MODES.SUBTRACT] = [gl.ONE, gl.ONE, gl.ONE, gl.ONE, gl.FUNC_REVERSE_SUBTRACT, gl.FUNC_ADD]; 19185 19186 return array; 19187 } 19188 19189 var BLEND$1 = 0; 19190 var OFFSET$1 = 1;
19191 var CULLING$1 = 2; 19192 var DEPTH_TEST$1 = 3; 19193 var WINDING$1 = 4; 19194 19195 /** 19196 * System plugin to the renderer to manage WebGL state machines. 19197 * 19198 * @class 19199 * @extends PIXI.System 19200 * @memberof PIXI.systems 19201 */ 19202 var StateSystem = /*@__PURE__*/(function (System) { 19203 function StateSystem(renderer) 19204 { 19205 System.call(this, renderer); 19206 19207 /** 19208 * GL context 19209 * @member {WebGLRenderingContext} 19210 * @readonly 19211 */ 19212 this.gl = null; 19213 19214 /** 19215 * State ID 19216 * @member {number} 19217 * @readonly 19218 */ 19219 this.stateId = 0; 19220 19221 /** 19222 * Polygon offset 19223 * @member {number} 19224 * @readonly 19225 */ 19226 this.polygonOffset = 0; 19227 19228 /** 19229 * Blend mode 19230 * @member {number} 19231 * @default PIXI.BLEND_MODES.NONE 19232 * @readonly 19233 */ 19234 this.blendMode = BLEND_MODES.NONE; 19235 19236 /** 19237 * Whether current blend equation is different 19238 * @member {boolean} 19239 * @protected 19240 */ 19241 this._blendEq = false; 19242 19243 /** 19244 * Collection of calls 19245 * @member {function[]} 19246 * @readonly 19247 */ 19248 this.map = []; 19249 19250 // map functions for when we set state.. 19251 this.map[BLEND$1] = this.setBlend; 19252 this.map[OFFSET$1] = this.setOffset; 19253 this.map[CULLING$1] = this.setCullFace; 19254 this.map[DEPTH_TEST$1] = this.setDepthTest; 19255 this.map[WINDING$1] = this.setFrontFace; 19256 19257 /** 19258 * Collection of check calls 19259 * @member {function[]} 19260 * @readonly 19261 */ 19262 this.checks = []; 19263 19264 /** 19265 * Default WebGL State 19266 * @member {PIXI.State} 19267 * @readonly 19268 */ 19269 this.defaultState = new State(); 19270 this.defaultState.blend = true; 19271 this.defaultState.depth = true; 19272 } 19273 19274 if ( System ) { StateSystem.__proto__ = System; } 19275 StateSystem.prototype = Object.create( System && System.prototype ); 19276 StateSystem.prototype.constructor = StateSystem; 19277 19278 StateSystem.prototype.contextChange = function contextChange (gl) 19279 { 19280 this.gl = gl; 19281 19282 this.blendModes = mapWebGLBlendModesToPixi(gl); 19283 19284 this.setState(this.defaultState); 19285 19286 this.reset(); 19287 }; 19288 19289 /** 19290 * Sets the current state 19291 * 19292 * @param {*} state - The state to set. 19293 */ 19294 StateSystem.prototype.setState = function setState (state) 19295 { 19296 state = state || this.defaultState; 19297 19298 // TODO maybe to an object check? ( this.state === state )? 19299 if (this.stateId !== state.data) 19300 { 19301 var diff = this.stateId ^ state.data; 19302 var i = 0; 19303 19304 // order from least to most common 19305 while (diff) 19306 { 19307 if (diff & 1) 19308 { 19309 // state change! 19310 this.map[i].call(this, !!(state.data & (1 << i))); 19311 } 19312 19313 diff = diff >> 1; 19314 i++; 19315 } 19316 19317 this.stateId = state.data; 19318 } 19319 19320 // based on the above settings we check for specific modes.. 19321 // for example if blend is active we check and set the blend modes 19322 // or of polygon offset is active we check the poly depth. 19323 for (var i$1 = 0; i$1 < this.checks.length; i$1++) 19324 { 19325 this.checks[i$1](this, state); 19326 } 19327 }; 19328 19329 /** 19330 * Sets the state, when previous state is unknown 19331 * 19332 * @param {*} state - The state to set 19333 */ 19334 StateSystem.prototype.forceState = function forceState (state) 19335 { 19336 state = state || this.defaultState; 19337 for (var i = 0; i < this.map.length; i++) 19338 { 19339 this.map[i].call(this, !!(state.data & (1 << i))); 19340 } 19341 for (var i$1 = 0; i$1 < this.checks.length; i$1++) 19342 { 19343 this.checks[i$1](this, state); 19344 } 19345 19346 this.stateId = state.data; 19347 }; 19348 19349 /** 19350 * Enables or disabled blending. 19351 * 19352 * @param {boolean} value - Turn on or off webgl blending. 19353 */ 19354 StateSystem.prototype.setBlend = function setBlend (value) 19355 { 19356 this.updateCheck(StateSystem.checkBlendMode, value); 19357 19358 this.gl[value ? 'enable' : 'disable'](this.gl.BLEND); 19359 }; 19360 19361 /**
19362 * Enables or disable polygon offset fill 19363 * 19364 * @param {boolean} value - Turn on or off webgl polygon offset testing. 19365 */ 19366 StateSystem.prototype.setOffset = function setOffset (value) 19367 { 19368 this.gl[value ? 'enable' : 'disable'](this.gl.POLYGON_OFFSET_FILL); 19369 }; 19370 19371 /** 19372 * Sets whether to enable or disable depth test. 19373 * 19374 * @param {boolean} value - Turn on or off webgl depth testing. 19375 */ 19376 StateSystem.prototype.setDepthTest = function setDepthTest (value) 19377 { 19378 this.gl[value ? 'enable' : 'disable'](this.gl.DEPTH_TEST); 19379 }; 19380 19381 /** 19382 * Sets whether to enable or disable cull face. 19383 * 19384 * @param {boolean} value - Turn on or off webgl cull face. 19385 */ 19386 StateSystem.prototype.setCullFace = function setCullFace (value) 19387 { 19388 this.gl[value ? 'enable' : 'disable'](this.gl.CULL_FACE); 19389 }; 19390 19391 /** 19392 * Sets the gl front face. 19393 * 19394 * @param {boolean} value - true is clockwise and false is counter-clockwise 19395 */ 19396 StateSystem.prototype.setFrontFace = function setFrontFace (value) 19397 { 19398 this.gl.frontFace(this.gl[value ? 'CW' : 'CCW']); 19399 }; 19400 19401 /** 19402 * Sets the blend mode. 19403 * 19404 * @param {number} value - The blend mode to set to. 19405 */ 19406 StateSystem.prototype.setBlendMode = function setBlendMode (value) 19407 { 19408 if (value === this.blendMode) 19409 { 19410 return; 19411 } 19412 19413 this.blendMode = value; 19414 19415 var mode = this.blendModes[value]; 19416 var gl = this.gl; 19417 19418 if (mode.length === 2) 19419 { 19420 gl.blendFunc(mode[0], mode[1]); 19421 } 19422 else 19423 { 19424 gl.blendFuncSeparate(mode[0], mode[1], mode[2], mode[3]); 19425 } 19426 if (mode.length === 6) 19427 { 19428 this._blendEq = true; 19429 gl.blendEquationSeparate(mode[4], mode[5]); 19430 } 19431 else if (this._blendEq) 19432 { 19433 this._blendEq = false; 19434 gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD); 19435 } 19436 }; 19437 19438 /** 19439 * Sets the polygon offset. 19440 * 19441 * @param {number} value - the polygon offset 19442 * @param {number} scale - the polygon offset scale 19443 */ 19444 StateSystem.prototype.setPolygonOffset = function setPolygonOffset (value, scale) 19445 { 19446 this.gl.polygonOffset(value, scale); 19447 }; 19448 19449 // used 19450 /** 19451 * Resets all the logic and disables the vaos 19452 */ 19453 StateSystem.prototype.reset = function reset () 19454 { 19455 this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, false); 19456 19457 this.forceState(0); 19458 19459 this._blendEq = true; 19460 this.blendMode = -1; 19461 this.setBlendMode(0); 19462 }; 19463 19464 /** 19465 * checks to see which updates should be checked based on which settings have been activated. 19466 * For example, if blend is enabled then we should check the blend modes each time the state is changed 19467 * or if polygon fill is activated then we need to check if the polygon offset changes. 19468 * The idea is that we only check what we have too. 19469 * 19470 * @param {Function} func the checking function to add or remove 19471 * @param {boolean} value should the check function be added or removed. 19472 */ 19473 StateSystem.prototype.updateCheck = function updateCheck (func, value) 19474 { 19475 var index = this.checks.indexOf(func); 19476 19477 if (value && index === -1) 19478 { 19479 this.checks.push(func); 19480 } 19481 else if (!value && index !== -1) 19482 { 19483 this.checks.splice(index, 1); 19484 } 19485 }; 19486 19487 /** 19488 * A private little wrapper function that we call to check the blend mode. 19489 * 19490 * @static 19491 * @private 19492 * @param {PIXI.StateSystem} System the System to perform the state check on 19493 * @param {PIXI.State} state the state that the blendMode will pulled from 19494 */ 19495 StateSystem.checkBlendMode = function checkBlendMode (system, state) 19496 { 19497 system.setBlendMode(state.blendMode); 19498 }; 19499 19500 return StateSystem; 19501 }(System)); 19502 19503 /** 19504 * System plugin to the renderer to manage texture garbage collection on the GPU, 19505 * ensuring that it does not get clogged up with textures that are no longer being used. 19506 * 19507 * @class 19508 * @memberof PIXI.systems 19509 * @extends PIXI.System 19510 */ 19511 var TextureGCSystem = /*@__PURE__*/(function (System) { 19512 function TextureGCSystem(renderer) 19513 { 19514 System.call(this, renderer); 19515 19516 /** 19517 * Count 19518 * @member {number} 19519 * @readonly 19520 */ 19521 this.count = 0; 19522 19523 /** 19524 * Check count 19525 * @member {number} 19526 * @readonly 19527 */ 19528 this.checkCount = 0; 19529 19530 /** 19531 * Maximum idle time, in seconds 19532 * @member {number} 19533 * @see PIXI.settings.GC_MAX_IDLE 19534 */ 19535 this.maxIdle = settings.GC_MAX_IDLE; 19536 19537 /** 19538 * Maximum number of itesm to check 19539 * @member {number} 19540 * @see PIXI.settings.GC_MAX_CHECK_COUNT 19541 */ 19542 this.checkCountMax = settings.GC_MAX_CHECK_COUNT; 19543 19544 /** 19545 * Current garabage collection mode 19546 * @member {PIXI.GC_MODES} 19547 * @see PIXI.settings.GC_MODE 19548 */ 19549 this.mode = settings.GC_MODE; 19550 } 19551 19552 if ( System ) { TextureGCSystem.__proto__ = System; } 19553 TextureGCSystem.prototype = Object.create( System && System.prototype ); 19554 TextureGCSystem.prototype.constructor = TextureGCSystem; 19555 19556 /** 19557 * Checks to see when the last time a texture was used 19558 * if the texture has not been used for a specified amount of time it will be removed from the GPU 19559 */ 19560 TextureGCSystem.prototype.postrender = function postrender () 19561 { 19562 this.count++; 19563 19564 if (this.mode === GC_MODES.MANUAL) 19565 { 19566 return; 19567 } 19568 19569 this.checkCount++; 19570 19571 if (this.checkCount > this.checkCountMax) 19572 { 19573 this.checkCount = 0; 19574 19575 this.run(); 19576 } 19577 }; 19578 19579 /** 19580 * Checks to see when the last time a texture was used 19581 * if the texture has not been used for a specified amount of time it will be removed from the GPU 19582 */ 19583 TextureGCSystem.prototype.run = function run () 19584 { 19585 var tm = this.renderer.texture; 19586 var managedTextures = tm.managedTextures; 19587 var wasRemoved = false;
19588 19589 for (var i = 0; i < managedTextures.length; i++) 19590 { 19591 var texture = managedTextures[i]; 19592 19593 // only supports non generated textures at the moment! 19594 if (!texture.framebuffer && this.count - texture.touched > this.maxIdle) 19595 { 19596 tm.destroyTexture(texture, true); 19597 managedTextures[i] = null; 19598 wasRemoved = true; 19599 } 19600 } 19601 19602 if (wasRemoved) 19603 { 19604 var j = 0; 19605 19606 for (var i$1 = 0; i$1 < managedTextures.length; i$1++) 19607 { 19608 if (managedTextures[i$1] !== null) 19609 { 19610 managedTextures[j++] = managedTextures[i$1]; 19611 } 19612 } 19613 19614 managedTextures.length = j; 19615 } 19616 }; 19617 19618 /** 19619 * Removes all the textures within the specified displayObject and its children from the GPU 19620 * 19621 * @param {PIXI.DisplayObject} displayObject - the displayObject to remove the textures from. 19622 */ 19623 TextureGCSystem.prototype.unload = function unload (displayObject) 19624 { 19625 var tm = this.renderer.textureSystem; 19626 19627 // only destroy non generated textures 19628 if (displayObject._texture && displayObject._texture._glRenderTargets) 19629 { 19630 tm.destroyTexture(displayObject._texture); 19631 } 19632 19633 for (var i = displayObject.children.length - 1; i >= 0; i--) 19634 { 19635 this.unload(displayObject.children[i]); 19636 } 19637 }; 19638 19639 return TextureGCSystem; 19640 }(System)); 19641 19642 /** 19643 * Internal texture for WebGL context 19644 * @class 19645 * @memberof PIXI 19646 */ 19647 var GLTexture = function GLTexture(texture) 19648 { 19649 /** 19650 * The WebGL texture 19651 * @member {WebGLTexture} 19652 */ 19653 this.texture = texture; 19654 19655 this.width = -1; 19656 this.height = -1; 19657 19658 /** 19659 * Texture contents dirty flag 19660 * @member {number} 19661 */ 19662 this.dirtyId = -1; 19663 19664 /** 19665 * Texture style dirty flag 19666 * @member {number} 19667 */ 19668 this.dirtyStyleId = -1; 19669 19670 /** 19671 * Whether mip levels has to be generated 19672 * @member {boolean} 19673 */ 19674 this.mipmap = false; 19675 19676 /** 19677 * WrapMode copied from baseTexture 19678 * @member {number} 19679 */ 19680 this.wrapMode = 33071; 19681 }; 19682 19683 /** 19684 * System plugin to the renderer to manage textures. 19685 * 19686 * @class 19687 * @extends PIXI.System 19688 * @memberof PIXI.systems 19689 */ 19690 var TextureSystem = /*@__PURE__*/(function (System) { 19691 function TextureSystem(renderer) 19692 { 19693 System.call(this, renderer); 19694 19695 // TODO set to max textures... 19696 /** 19697 * Bound textures 19698 * @member {PIXI.BaseTexture[]} 19699 * @readonly 19700 */ 19701 this.boundTextures = []; 19702 /** 19703 * Current location 19704 * @member {number} 19705 * @readonly 19706 */ 19707 this.currentLocation = -1; 19708 19709 /** 19710 * List of managed textures 19711 * @member {PIXI.BaseTexture[]} 19712 * @readonly 19713 */ 19714 this.managedTextures = []; 19715 19716 /** 19717 * Did someone temper with textures state? We'll overwrite them when we need to unbind something. 19718 * @member {boolean} 19719 * @private 19720 */ 19721 this._unknownBoundTextures = false; 19722 19723 /** 19724 * BaseTexture value that shows that we don't know what is bound 19725 * @member {PIXI.BaseTexture} 19726 * @readonly 19727 */ 19728 this.unknownTexture = new BaseTexture(); 19729 } 19730 19731 if ( System ) { TextureSystem.__proto__ = System; } 19732 TextureSystem.prototype = Object.create( System && System.prototype ); 19733 TextureSystem.prototype.constructor = TextureSystem; 19734 19735 /** 19736 * Sets up the renderer context and necessary buffers. 19737 */ 19738 TextureSystem.prototype.contextChange = function contextChange () 19739 { 19740 var gl = this.gl = this.renderer.gl; 19741 19742 this.CONTEXT_UID = this.renderer.CONTEXT_UID; 19743 19744 this.webGLVersion = this.renderer.context.webGLVersion; 19745 19746 var maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); 19747 19748 this.boundTextures.length = maxTextures; 19749 19750 for (var i = 0; i < maxTextures; i++) 19751 { 19752 this.boundTextures[i] = null; 19753 } 19754 19755 // TODO move this.. to a nice make empty textures class.. 19756 this.emptyTextures = {}; 19757 19758 var emptyTexture2D = new GLTexture(gl.createTexture()); 19759 19760 gl.bindTexture(gl.TEXTURE_2D, emptyTexture2D.texture); 19761 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(4)); 19762 19763 this.emptyTextures[gl.TEXTURE_2D] = emptyTexture2D; 19764 this.emptyTextures[gl.TEXTURE_CUBE_MAP] = new GLTexture(gl.createTexture()); 19765 19766 gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.emptyTextures[gl.TEXTURE_CUBE_MAP].texture); 19767 19768 for (var i$1 = 0; i$1 < 6; i$1++) 19769 { 19770 gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + i$1, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); 19771 } 19772 19773 gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 19774 gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 19775 19776 for (var i$2 = 0; i$2 < this.boundTextures.length; i$2++) 19777 { 19778 this.bind(null, i$2); 19779 } 19780 }; 19781 19782 /** 19783 * Bind a texture to a specific location 19784 * 19785 * If you want to unbind something, please use `unbind(texture)` instead of `bind(null, textureLocation)` 19786 * 19787 * @param {PIXI.Texture|PIXI.BaseTexture} texture - Texture to bind 19788 * @param {number} [location=0] - Location to bind at 19789 */ 19790 TextureSystem.prototype.bind = function bind (texture, location) 19791 { 19792 if ( location === void 0 ) { location = 0; } 19793 19794 var ref = this; 19795 var gl = ref.gl; 19796 19797 if (texture) 19798 { 19799 texture = texture.baseTexture || texture; 19800 19801 if (texture.valid) 19802 { 19803 texture.touched = this.renderer.textureGC.count; 19804 19805 var glTexture = texture._glTextures[this.CONTEXT_UID] || this.initTexture(texture); 19806 19807 if (this.currentLocation !== location) 19808 { 19809 this.currentLocation = location; 19810 gl.activeTexture(gl.TEXTURE0 + location); 19811 } 19812 19813 if (this.boundTextures[location] !== texture) 19814 { 19815 gl.bindTexture(texture.target, glTexture.texture); 19816 } 19817 19818 if (glTexture.dirtyId !== texture.dirtyId) 19819 { 19820 this.updateTexture(texture); 19821 } 19822 19823 this.boundTextures[location] = texture; 19824 } 19825 } 19826 else 19827 { 19828 if (this.currentLocation !== location) 19829 { 19830 this.currentLocation = location; 19831 gl.activeTexture(gl.TEXTURE0 + location); 19832 } 19833 19834 gl.bindTexture(gl.TEXTURE_2D, this.emptyTextures[gl.TEXTURE_2D].texture); 19835 this.boundTextures[location] = null; 19836 } 19837 }; 19838 19839 /** 19840 * Resets texture location and bound textures 19841 * 19842 * Actual `bind(null, i)` calls will be performed at next `unbind()` call 19843 */ 19844 TextureSystem.prototype.reset = function reset () 19845 { 19846 this._unknownBoundTextures = true; 19847 this.currentLocation = -1; 19848 19849 for (var i = 0; i < this.boundTextures.length; i++) 19850 { 19851 this.boundTextures[i] = this.unknownTexture; 19852 } 19853 }; 19854 19855 /** 19856 * Unbind a texture 19857 * @param {PIXI.Texture|PIXI.BaseTexture} texture - Texture to bind 19858 */ 19859 TextureSystem.prototype.unbind = function unbind (texture) 19860 { 19861 var ref = this; 19862 var gl = ref.gl; 19863 var boundTextures = ref.boundTextures; 19864 19865 if (this._unknownBoundTextures) 19866 { 19867 this._unknownBoundTextures = false;
19868 // someone changed webGL state, 19869 // we have to be sure that our texture does not appear in multi-texture renderer samplers 19870 for (var i = 0; i < boundTextures.length; i++) 19871 { 19872 if (boundTextures[i] === this.unknownTexture) 19873 { 19874 this.bind(null, i); 19875 } 19876 } 19877 } 19878 19879 for (var i$1 = 0; i$1 < boundTextures.length; i$1++) 19880 { 19881 if (boundTextures[i$1] === texture) 19882 { 19883 if (this.currentLocation !== i$1) 19884 { 19885 gl.activeTexture(gl.TEXTURE0 + i$1); 19886 this.currentLocation = i$1; 19887 } 19888 19889 gl.bindTexture(gl.TEXTURE_2D, this.emptyTextures[texture.target].texture); 19890 boundTextures[i$1] = null; 19891 } 19892 } 19893 }; 19894 19895 /** 19896 * Initialize a texture 19897 * 19898 * @private 19899 * @param {PIXI.BaseTexture} texture - Texture to initialize 19900 */ 19901 TextureSystem.prototype.initTexture = function initTexture (texture) 19902 { 19903 var glTexture = new GLTexture(this.gl.createTexture()); 19904 19905 // guarantee an update.. 19906 glTexture.dirtyId = -1; 19907 19908 texture._glTextures[this.CONTEXT_UID] = glTexture; 19909 19910 this.managedTextures.push(texture); 19911 texture.on('dispose', this.destroyTexture, this); 19912 19913 return glTexture; 19914 }; 19915 19916 /** 19917 * Update a texture 19918 * 19919 * @private 19920 * @param {PIXI.BaseTexture} texture - Texture to initialize 19921 */ 19922 TextureSystem.prototype.updateTexture = function updateTexture (texture) 19923 { 19924 var glTexture = texture._glTextures[this.CONTEXT_UID]; 19925 var renderer = this.renderer; 19926 19927 if (texture.resource && texture.resource.upload(renderer, texture, glTexture)) 19928 { ; } 19929 else 19930 { 19931 // default, renderTexture-like logic 19932 var width = texture.realWidth; 19933 var height = texture.realHeight; 19934 var gl = renderer.gl; 19935 19936 if (glTexture.width !== width 19937 || glTexture.height !== height 19938 || glTexture.dirtyId < 0) 19939 { 19940 glTexture.width = width; 19941 glTexture.height = height; 19942 19943 gl.texImage2D(texture.target, 0, 19944 texture.format, 19945 width, 19946 height, 19947 0, 19948 texture.format, 19949 texture.type, 19950 null); 19951 } 19952 } 19953 19954 // lets only update what changes.. 19955 if (texture.dirtyStyleId !== glTexture.dirtyStyleId) 19956 { 19957 this.updateTextureStyle(texture); 19958 } 19959 glTexture.dirtyId = texture.dirtyId; 19960 }; 19961 19962 /** 19963 * Deletes the texture from WebGL 19964 * 19965 * @private 19966 * @param {PIXI.BaseTexture|PIXI.Texture} texture - the texture to destroy 19967 * @param {boolean} [skipRemove=false] - Whether to skip removing the texture from the TextureManager. 19968 */ 19969 TextureSystem.prototype.destroyTexture = function destroyTexture (texture, skipRemove) 19970 { 19971 var ref = this; 19972 var gl = ref.gl; 19973 19974 texture = texture.baseTexture || texture; 19975 19976 if (texture._glTextures[this.renderer.CONTEXT_UID]) 19977 { 19978 this.unbind(texture); 19979 19980 gl.deleteTexture(texture._glTextures[this.renderer.CONTEXT_UID].texture); 19981 texture.off('dispose', this.destroyTexture, this); 19982 19983 delete texture._glTextures[this.renderer.CONTEXT_UID]; 19984 19985 if (!skipRemove) 19986 { 19987 var i = this.managedTextures.indexOf(texture); 19988 19989 if (i !== -1) 19990 { 19991 removeItems(this.managedTextures, i, 1); 19992 } 19993 } 19994 } 19995 }; 19996 19997 /** 19998 * Update texture style such as mipmap flag 19999 * 20000 * @private 20001 * @param {PIXI.BaseTexture} texture - Texture to update 20002 */ 20003 TextureSystem.prototype.updateTextureStyle = function updateTextureStyle (texture) 20004 { 20005 var glTexture = texture._glTextures[this.CONTEXT_UID]; 20006 20007 if (!glTexture) 20008 { 20009 return; 20010 } 20011 20012 if ((texture.mipmap === MIPMAP_MODES.POW2 || this.webGLVersion !== 2) && !texture.isPowerOfTwo) 20013 { 20014 glTexture.mipmap = 0; 20015 glTexture.wrapMode = WRAP_MODES.CLAMP; 20016 } 20017 else 20018 { 20019 glTexture.mipmap = texture.mipmap >= 1; 20020 glTexture.wrapMode = texture.wrapMode; 20021 } 20022 20023 if (texture.resource && texture.resource.style(this.renderer, texture, glTexture)) 20024 { ; } 20025 else 20026 { 20027 this.setStyle(texture, glTexture); 20028 } 20029 20030 glTexture.dirtyStyleId = texture.dirtyStyleId; 20031 }; 20032 20033 /** 20034 * Set style for texture 20035 * 20036 * @private 20037 * @param {PIXI.BaseTexture} texture - Texture to update 20038 * @param {glTexture} glTexture 20039 */ 20040 TextureSystem.prototype.setStyle = function setStyle (texture, glTexture) 20041 { 20042 var gl = this.gl; 20043 20044 if (glTexture.mipmap) 20045 { 20046 gl.generateMipmap(texture.target); 20047 } 20048 20049 gl.texParameteri(texture.target, gl.TEXTURE_WRAP_S, glTexture.wrapMode); 20050 gl.texParameteri(texture.target, gl.TEXTURE_WRAP_T, glTexture.wrapMode); 20051 20052 if (glTexture.mipmap) 20053 { 20054 /* eslint-disable max-len */ 20055 gl.texParameteri(texture.target, gl.TEXTURE_MIN_FILTER, texture.scaleMode ? gl.LINEAR_MIPMAP_LINEAR
20055: gl.NEAREST_MIPMAP_NEAREST); 20056 /* eslint-disable max-len */ 20057 } 20058 else 20059 { 20060 gl.texParameteri(texture.target, gl.TEXTURE_MIN_FILTER, texture.scaleMode ? gl.LINEAR : gl.NEAREST); 20061 } 20062 20063 gl.texParameteri(texture.target, gl.TEXTURE_MAG_FILTER, texture.scaleMode ? gl.LINEAR : gl.NEAREST); 20064 }; 20065 20066 return TextureSystem; 20067 }(System)); 20068 20069 /** 20070 * Systems are individual components to the Renderer pipeline. 20071 * @namespace PIXI.systems 20072 */ 20073 20074 var systems = ({ 20075 FilterSystem: FilterSystem, 20076 BatchSystem: BatchSystem, 20077 ContextSystem: ContextSystem, 20078 FramebufferSystem: FramebufferSystem, 20079 GeometrySystem: GeometrySystem, 20080 MaskSystem: MaskSystem, 20081 StencilSystem: StencilSystem, 20082 ProjectionSystem: ProjectionSystem, 20083 RenderTextureSystem: RenderTextureSystem, 20084 ShaderSystem: ShaderSystem, 20085 StateSystem: StateSystem, 20086 TextureGCSystem: TextureGCSystem, 20087 TextureSystem: TextureSystem 20088 }); 20089 20090 var tempMatrix = new Matrix(); 20091 20092 /** 20093 * The AbstractRenderer is the base for a PixiJS Renderer. It is extended by the {@link PIXI.CanvasRenderer} 20094 * and {@link PIXI.Renderer} which can be used for rendering a PixiJS scene. 20095 * 20096 * @abstract 20097 * @class 20098 * @extends PIXI.utils.EventEmitter 20099 * @memberof PIXI 20100 */ 20101 var AbstractRenderer = /*@__PURE__*/(function (EventEmitter) { 20102 function AbstractRenderer(system, options) 20103 { 20104 EventEmitter.call(this); 20105 20106 // Add the default render options 20107 options = Object.assign({}, settings.RENDER_OPTIONS, options); 20108 20109 // Deprecation notice for renderer roundPixels option 20110 if (options.roundPixels) 20111 { 20112 settings.ROUND_PIXELS = options.roundPixels; 20113 deprecation('5.0.0', 'Renderer roundPixels option is deprecated, please use PIXI.settings.ROUND_PIXELS', 2); 20114 } 20115 20116 /** 20117 * The supplied constructor options. 20118 * 20119 * @member {Object} 20120 * @readOnly 20121 */ 20122 this.options = options; 20123 20124 /** 20125 * The type of the renderer. 20126 * 20127 * @member {number} 20128 * @default PIXI.RENDERER_TYPE.UNKNOWN 20129 * @see PIXI.RENDERER_TYPE 20130 */ 20131 this.type = RENDERER_TYPE.UNKNOWN; 20132 20133 /** 20134 * Measurements of the screen. (0, 0, screenWidth, screenHeight). 20135 * 20136 * Its safe to use as filterArea or hitArea for the whole stage. 20137 * 20138 * @member {PIXI.Rectangle} 20139 */ 20140 this.screen = new Rectangle(0, 0, options.width, options.height); 20141 20142 /** 20143 * The canvas element that everything is drawn to. 20144 * 20145 * @member {HTMLCanvasElement} 20146 */ 20147 this.view = options.view || document.createElement('canvas'); 20148 20149 /** 20150 * The resolution / device pixel ratio of the renderer. 20151 * 20152 * @member {number} 20153 * @default 1 20154 */ 20155 this.resolution = options.resolution || settings.RESOLUTION; 20156 20157 /** 20158 * Whether the render view is transparent. 20159 * 20160 * @member {boolean} 20161 */ 20162 this.transparent = options.transparent; 20163 20164 /** 20165 * Whether CSS dimensions of canvas view should be resized to screen dimensions automatically. 20166 * 20167 * @member {boolean} 20168 */ 20169 this.autoDensity = options.autoDensity || options.autoResize || false; 20170 // autoResize is deprecated, provides fallback support 20171 20172 /** 20173 * The value of the preserveDrawingBuffer flag affects whether or not the contents of 20174 * the stencil buffer is retained after rendering. 20175 * 20176 * @member {boolean} 20177 */ 20178 this.preserveDrawingBuffer = options.preserveDrawingBuffer; 20179 20180 /** 20181 * This sets if the CanvasRenderer will clear the canvas or not before the new render pass. 20182 * If the scene is NOT transparent PixiJS will use a canvas sized fillRect operation every 20183 * frame to set the canvas background color. If the scene is transparent PixiJS will use clearRect 20184 * to clear the canvas every frame. Disable this by setting this to fal
20184se. For example, if 20185 * your game has a canvas filling background image you often don't need this set. 20186 * 20187 * @member {boolean} 20188 * @default 20189 */ 20190 this.clearBeforeRender = options.clearBeforeRender; 20191 20192 /** 20193 * The background color as a number. 20194 * 20195 * @member {number} 20196 * @protected 20197 */ 20198 this._backgroundColor = 0x000000; 20199 20200 /** 20201 * The background color as an [R, G, B] array. 20202 * 20203 * @member {number[]} 20204 * @protected 20205 */ 20206 this._backgroundColorRgba = [0, 0, 0, 0]; 20207 20208 /** 20209 * The background color as a string. 20210 * 20211 * @member {string} 20212 * @protected 20213 */ 20214 this._backgroundColorString = '#000000'; 20215 20216 this.backgroundColor = options.backgroundColor || this._backgroundColor; // run bg color setter 20217 20218 /** 20219 * This temporary display object used as the parent of the currently being rendered item. 20220 * 20221 * @member {PIXI.DisplayObject} 20222 * @protected 20223 */ 20224 this._tempDisplayObjectParent = new Container(); 20225 20226 /** 20227 * The last root object that the renderer tried to render. 20228 * 20229 * @member {PIXI.DisplayObject} 20230 * @protected 20231 */ 20232 this._lastObjectRendered = this._tempDisplayObjectParent; 20233 20234 /** 20235 * Collection of plugins. 20236 * @readonly 20237 * @member {object} 20238 */ 20239 this.plugins = {}; 20240 } 20241 20242 if ( EventEmitter ) { AbstractRenderer.__proto__ = EventEmitter; } 20243 AbstractRenderer.prototype = Object.create( EventEmitter && EventEmitter.prototype ); 20244 AbstractRenderer.prototype.constructor = AbstractRenderer; 20245 20246 var prototypeAccessors = { width: { configurable: true },height: { configurable: true },backgroundColor: { configurable: true } }; 20247 20248 /** 20249 * Initialize the plugins. 20250 * 20251 * @protected 20252 * @param {object} staticMap - The dictionary of statically saved plugins. 20253 */ 20254 AbstractRenderer.prototype.initPlugins = function initPlugins (staticMap) 20255 { 20256 for (var o in staticMap) 20257 { 20258 this.plugins[o] = new (staticMap[o])(this); 20259 } 20260 }; 20261 20262 /** 20263 * Same as view.width, actual number of pixels in the canvas by horizontal. 20264 * 20265 * @member {number} 20266 * @readonly 20267 * @default 800 20268 */ 20269 prototypeAccessors.width.get = function () 20270 { 20271 return this.view.width; 20272 }; 20273 20274 /** 20275 * Same as view.height, actual number of pixels in the canvas by vertical. 20276 * 20277 * @member {number} 20278 * @readonly 20279 * @default 600 20280 */ 20281 prototypeAccessors.height.get = function () 20282 { 20283 return this.view.height; 20284 }; 20285 20286 /** 20287 * Resizes the screen and canvas to the specified width and height. 20288 * Canvas dimensions are multiplied by resolution. 20289 * 20290 * @param {number} screenWidth - The new width of the screen. 20291 * @param {number} screenHeight - The new height of the screen. 20292 */ 20293 AbstractRenderer.prototype.resize = function resize (screenWidth, screenHeight) 20294 { 20295 this.screen.width = screenWidth; 20296 this.screen.height = screenHeight; 20297 20298 this.view.width = screenWidth * this.resolution; 20299 this.view.height = screenHeight * this.resolution; 20300 20301 if (this.autoDensity) 20302 { 20303 this.view.style.width = screenWidth + "px"; 20304 this.view.style.height = screenHeight + "px"; 20305 } 20306 }; 20307 20308 /** 20309 * Useful function that returns a texture of the display object that can then be used to create sprites 20310 * This can be quite useful if your displayObject is complicated and needs to be reused multiple times. 20311 * 20312 * @param {PIXI.DisplayObject} displayObject - The displayObject the object will be generated from. 20313 * @param {number} scaleMode - Should be one of the scaleMode consts. 20314 * @param {number} resolution - The resolution / device pixel ratio of the texture being generated. 20315 * @param {PIXI.Rectangle}
20315 [region] - The region of the displayObject, that shall be rendered, 20316 * if no region is specified, defaults to the local bounds of the displayObject. 20317 * @return {PIXI.Texture} A texture of the graphics object. 20318 */ 20319 AbstractRenderer.prototype.generateTexture = function generateTexture (displayObject, scaleMode, resolution, region) 20320 { 20321 region = region || displayObject.getLocalBounds(); 20322 20323 // minimum texture size is 1x1, 0x0 will throw an error 20324 if (region.width === 0) { region.width = 1; } 20325 if (region.height === 0) { region.height = 1; } 20326 20327 var renderTexture = RenderTexture.create(region.width | 0, region.height | 0, scaleMode, resolution); 20328 20329 tempMatrix.tx = -region.x; 20330 tempMatrix.ty = -region.y; 20331 20332 this.render(displayObject, renderTexture, false, tempMatrix, !!displayObject.parent); 20333 20334 return renderTexture; 20335 }; 20336 20337 /** 20338 * Removes everything from the renderer and optionally removes the Canvas DOM element. 20339 * 20340 * @param {boolean} [removeView=false] - Removes the Canvas element from the DOM. 20341 */ 20342 AbstractRenderer.prototype.destroy = function destroy (removeView) 20343 { 20344 for (var o in this.plugins) 20345 { 20346 this.plugins[o].destroy(); 20347 this.plugins[o] = null; 20348 } 20349 20350 if (removeView && this.view.parentNode) 20351 { 20352 this.view.parentNode.removeChild(this.view); 20353 } 20354 20355 this.plugins = null; 20356 20357 this.type = RENDERER_TYPE.UNKNOWN; 20358 20359 this.view = null; 20360 20361 this.screen = null; 20362 20363 this.resolution = 0; 20364 20365 this.transparent = false; 20366 20367 this.autoDensity = false; 20368 20369 this.blendModes = null; 20370 20371 this.options = null; 20372 20373 this.preserveDrawingBuffer = false; 20374 this.clearBeforeRender = false;
20375 20376 this._backgroundColor = 0; 20377 this._backgroundColorRgba = null; 20378 this._backgroundColorString = null; 20379 20380 this._tempDisplayObjectParent = null; 20381 this._lastObjectRendered = null; 20382 }; 20383 20384 /** 20385 * The background color to fill if not transparent 20386 * 20387 * @member {number} 20388 */ 20389 prototypeAccessors.backgroundColor.get = function () 20390 { 20391 return this._backgroundColor; 20392 }; 20393 20394 prototypeAccessors.backgroundColor.set = function (value) // eslint-disable-line require-jsdoc 20395 { 20396 this._backgroundColor = value; 20397 this._backgroundColorString = hex2string(value); 20398 hex2rgb(value, this._backgroundColorRgba); 20399 }; 20400 20401 Object.defineProperties( AbstractRenderer.prototype, prototypeAccessors ); 20402 20403 return AbstractRenderer; 20404 }(eventemitter3)); 20405 20406 /** 20407 * The Renderer draws the scene and all its content onto a WebGL enabled canvas. 20408 * 20409 * This renderer should be used for browsers that support WebGL. 20410 * 20411 * This renderer works by automatically managing WebGLBatchesm, so no need for Sprite Batches or Sprite Clouds. 20412 * Don't forget to add the view to your DOM or you will not see anything! 20413 * 20414 * @class 20415 * @memberof PIXI 20416 * @extends PIXI.AbstractRenderer 20417 */ 20418 var Renderer = /*@__PURE__*/(function (AbstractRenderer) {
20419 function Renderer(options) 20420 { 20421 if ( options === void 0 ) { options = {}; } 20422 20423 AbstractRenderer.call(this, 'WebGL', options); 20424 20425 // the options will have been modified here in the super constructor with pixi's default settings.. 20426 options = this.options; 20427 20428 /** 20429 * The type of this renderer as a standardized const 20430 * 20431 * @member {number} 20432 * @see PIXI.RENDERER_TYPE 20433 */ 20434 this.type = RENDERER_TYPE.WEBGL; 20435 20436 // this will be set by the contextSystem (this.context) 20437 this.gl = null; 20438 this.CONTEXT_UID = 0; 20439 20440 // TODO legacy! 20441 20442 /** 20443 * Internal signal instances of **runner**, these 20444 * are assigned to each system created. 20445 * @see PIXI.Runner 20446 * @name PIXI.Renderer#runners 20447 * @private 20448 * @type {object} 20449 * @readonly 20450 * @property {PIXI.Runner} destroy - Destroy runner 20451 * @property {PIXI.Runner} contextChange - Context change runner 20452 * @property {PIXI.Runner} reset - Reset runner 20453 * @property {PIXI.Runner} update - Update runner 20454 * @property {PIXI.Runner} postrender - Post-render runner 20455 * @property {PIXI.Runner} prerender - Pre-render runner 20456 * @property {PIXI.Runner} resize - Resize runner 20457 */ 20458 this.runners = { 20459 destroy: new Runner('destroy'), 20460 contextChange: new Runner('contextChange', 1), 20461 reset: new Runner('reset'), 20462 update: new Runner('update'), 20463 postrender: new Runner('postrender'), 20464 prerender: new Runner('prerender'), 20465 resize: new Runner('resize', 2), 20466 }; 20467 20468 /** 20469 * Global uniforms 20470 * @member {PIXI.UniformGroup} 20471 */ 20472 this.globalUniforms = new UniformGroup({ 20473 projectionMatrix: new Matrix(), 20474 }, true); 20475 20476 /** 20477 * Mask system instance 20478 * @member {PIXI.systems.MaskSystem} mask 20479 * @memberof PIXI.Renderer# 20480 * @readonly 20481 */ 20482 this.addSystem(MaskSystem, 'mask') 20483 /** 20484 * Context system instance 20485 * @member {PIXI.systems.ContextSystem} context 20486 * @memberof PIXI.Renderer# 20487 * @readonly 20488 */ 20489 .addSystem(ContextSystem, 'context') 20490 /** 20491 * State system instance 20492 * @member {PIXI.systems.StateSystem} state 20493 * @memberof PIXI.Renderer# 20494 * @readonly 20495 */ 20496 .addSystem(StateSystem, 'state') 20497 /** 20498 * Shader system instance 20499 * @member {PIXI.systems.ShaderSystem} shader 20500 * @memberof PIXI.Renderer# 20501 * @readonly 20502 */ 20503 .addSystem(ShaderSystem, 'shader') 20504 /** 20505 * Texture system instance 20506 * @member {PIXI.systems.TextureSystem} texture 20507 * @memberof PIXI.Renderer# 20508 * @readonly 20509 */ 20510 .addSystem(TextureSystem, 'texture') 20511 /** 20512 * Geometry system instance 20513 * @member {PIXI.systems.GeometrySystem} geometry 20514 * @memberof PIXI.Renderer# 20515 * @readonly 20516 */ 20517 .addSystem(GeometrySystem, 'geometry') 20518 /** 20519 * Framebuffer system instance 20520 * @member {PIXI.systems.FramebufferSystem} framebuffer 20521 * @memberof PIXI.Renderer# 20522 * @readonly 20523 */ 20524 .addSystem(FramebufferSystem, 'framebuffer') 20525 /** 20526 * Stencil system instance 20527 * @member {PIXI.systems.StencilSystem} stencil 20528 * @memberof PIXI.Renderer# 20529 * @readonly 20530 */ 20531 .addSystem(StencilSystem, 'stencil') 20532 /** 20533 * Projection system instance 20534 * @member {PIXI.systems.ProjectionSystem} projection 20535 * @memberof PIXI.Renderer# 20536 * @readonly 20537 */ 20538 .addSystem(ProjectionSystem, 'projection') 20539 /** 20540 * Texture garbage collector system instance 20541 * @member {PIXI.systems.TextureGCSystem} textureGC 20542 * @memberof PIXI.Renderer# 20543 * @readonly 20544 */ 20545 .addSystem(TextureGCSystem, 'textureGC') 20546 /** 20547 * Filter system instance 20548 * @member {PIXI.systems.FilterSystem} filter 20549 * @memberof PIXI.Renderer# 20550 * @readonly 20551 */ 20552 .addSystem(FilterSystem, 'filter') 20553 /**
20554 * RenderTexture system instance 20555 * @member {PIXI.systems.RenderTextureSystem} renderTexture 20556 * @memberof PIXI.Renderer# 20557 * @readonly 20558 */ 20559 .addSystem(RenderTextureSystem, 'renderTexture') 20560 20561 /** 20562 * Batch system instance 20563 * @member {PIXI.systems.BatchSystem} batch 20564 * @memberof PIXI.Renderer# 20565 * @readonly 20566 */ 20567 .addSystem(BatchSystem, 'batch'); 20568 20569 this.initPlugins(Renderer.__plugins); 20570 20571 /** 20572 * The options passed in to create a new WebGL context. 20573 */ 20574 if (options.context) 20575 { 20576 this.context.initFromContext(options.context); 20577 } 20578 else 20579 { 20580 this.context.initFromOptions({ 20581 alpha: this.transparent, 20582 antialias: options.antialias, 20583 premultipliedAlpha: this.transparent && this.transparent !== 'notMultiplied', 20584 stencil: true, 20585 preserveDrawingBuffer: options.preserveDrawingBuffer, 20586 powerPreference: this.options.powerPreference, 20587 }); 20588 } 20589 20590 /** 20591 * Flag if we are rendering to the screen vs renderTexture 20592 * @member {boolean} 20593 * @readonly 20594 * @default true 20595 */ 20596 this.renderingToScreen = true; 20597 20598 sayHello(this.context.webGLVersion === 2 ? 'WebGL 2' : 'WebGL 1'); 20599 20600 this.resize(this.options.width, this.options.height); 20601 } 20602 20603 if ( AbstractRenderer ) { Renderer.__proto__ = AbstractRenderer; } 20604 Renderer.prototype = Object.create( AbstractRenderer && AbstractRenderer.prototype ); 20605 Renderer.prototype.constructor = Renderer; 20606 20607 /** 20608 * Add a new system to the renderer. 20609 * @param {Function} ClassRef - Class reference 20610 * @param {string} [name] - Property name for system, if not specified 20611 * will use a static `name` property on the class itself. This 20612 * name will be assigned as s property on the Renderer so make 20613 * sure it doesn't collide with properties on Renderer. 20614 * @return {PIXI.Renderer} Return instance of renderer 20615 */ 20616 Renderer.create = function create (options) 20617 { 20618 if (isWebGLSupported()) 20619 { 20620 return new Renderer(options); 20621 } 20622 20623 throw new Error('WebGL unsupported in this browser, use "pixi.js-legacy" for fallback canvas2d support.'); 20624 }; 20625 20626 Renderer.prototype.addSystem = function addSystem (ClassRef, name) 20627 { 20628 if (!name) 20629 { 20630 name = ClassRef.name; 20631 } 20632 20633 var system = new ClassRef(this); 20634 20635 if (this[name]) 20636 { 20637 throw new Error(("Whoops! The name \"" + name + "\" is already in use")); 20638 } 20639 20640 this[name] = system; 20641 20642 for (var i in this.runners) 20643 { 20644 this.runners[i].add(system); 20645 } 20646 20647 /** 20648 * Fired after rendering finishes. 20649 * 20650 * @event PIXI.Renderer#postrender 20651 */ 20652 20653 /** 20654 * Fired before rendering starts. 20655 * 20656 * @event PIXI.Renderer#prerender 20657 */ 20658 20659 /** 20660 * Fired when the WebGL context is set. 20661 * 20662 * @event PIXI.Renderer#context 20663 * @param {WebGLRenderingContext} gl - WebGL context. 20664 */ 20665 20666 return this; 20667 }; 20668 20669 /**
20670 * Renders the object to its WebGL view 20671 * 20672 * @param {PIXI.DisplayObject} displayObject - The object to be rendered. 20673 * @param {PIXI.RenderTexture} [renderTexture] - The render texture to render to. 20674 * @param {boolean} [clear=true] - Should the canvas be cleared before the new render. 20675 * @param {PIXI.Matrix} [transform] - A transform to apply to the render texture before rendering. 20676 * @param {boolean} [skipUpdateTransform=false] - Should we skip the update transform pass? 20677 */ 20678 Renderer.prototype.render = function render (displayObject, renderTexture, clear, transform, skipUpdateTransform) 20679 { 20680 // can be handy to know! 20681 this.renderingToScreen = !renderTexture; 20682 20683 this.runners.prerender.run(); 20684 this.emit('prerender'); 20685 20686 // no point rendering if our context has been blown up! 20687 if (this.context.isLost) 20688 { 20689 return; 20690 } 20691 20692 if (!renderTexture) 20693 { 20694 this._lastObjectRendered = displayObject; 20695 } 20696 20697 if (!skipUpdateTransform) 20698 { 20699 // update the scene graph 20700 var cacheParent = displayObject.parent; 20701 20702 displayObject.parent = this._tempDisplayObjectParent; 20703 displayObject.updateTransform(); 20704 displayObject.parent = cacheParent; 20705 // displayObject.hitArea = //TODO add a temp hit area 20706 } 20707 20708 this.renderTexture.bind(renderTexture); 20709 this.batch.currentRenderer.start(); 20710 20711 if (clear !== undefined ? clear : this.clearBeforeRender) 20712 { 20713 this.renderTexture.clear(); 20714 } 20715 20716 displayObject.render(this); 20717 20718 // apply transform.. 20719 this.batch.currentRenderer.flush(); 20720 20721 if (renderTexture) 20722 { 20723 renderTexture.baseTexture.update(); 20724 } 20725 20726 this.runners.postrender.run(); 20727 20728 this.emit('postrender'); 20729 }; 20730 20731 /** 20732 * Resizes the WebGL view to the specified width and height. 20733 * 20734 * @param {number} screenWidth - The new width of the screen. 20735 * @param {number} screenHeight - The new height of the screen. 20736 */ 20737 Renderer.prototype.resize = function resize (screenWidth, screenHeight) 20738 { 20739 AbstractRenderer.prototype.resize.call(this, screenWidth, screenHeight); 20740 20741 this.runners.resize.run(screenWidth, screenHeight); 20742 }; 20743 20744 /** 20745 * Resets the WebGL state so you can render things however you fancy! 20746 * 20747 * @return {PIXI.Renderer} Returns itself. 20748 */ 20749 Renderer.prototype.reset = function reset () 20750 { 20751 this.runners.reset.run(); 20752 20753 return this; 20754 }; 20755 20756 /** 20757 * Clear the frame buffer 20758 */ 20759 Renderer.prototype.clear = function clear () 20760 { 20761 this.framebuffer.bind(); 20762 this.framebuffer.clear(); 20763 }; 20764 20765 /** 20766 * Removes everything from the renderer (event listeners, spritebatch, etc...) 20767 * 20768 * @param {boolean} [removeView=false] - Removes the Canvas element from the DOM. 20769 * See: https://github.com/pixijs/pixi.js/issues/2233 20770 */ 20771 Renderer.prototype.destroy = function destroy (removeView) 20772 { 20773 this.runners.destroy.run(); 20774 20775 // call base destroy 20776 AbstractRenderer.prototype.destroy.call(this, removeView); 20777 20778 // TODO nullify all the managers.. 20779 this.gl = null; 20780 }; 20781 20782 /** 20783 * Collection of installed plugins. These are included by default in PIXI, but can be excluded 20784 * by creating a custom build. Consult the README for more information about creating custom 20785 * builds and excluding plugins. 20786 * @name PIXI.Renderer#plugins 20787 * @type {object} 20788 * @readonly 20789 * @property {PIXI.accessibility.AccessibilityManager} accessibility Support tabbing interactive elements. 20790 * @property {PIXI.extract.Extract} extract Extract image data from renderer. 20791 * @property {PIXI.interaction.InteractionManager} interaction Handles mouse, touch and pointer events. 20792 * @property {PIXI.prepare.Prepare} prepare Pre-render display objects. 20793 */ 20794 20795 /** 20796 * Adds a plugin to the renderer. 20797 * 20798 * @method 20799 * @param {string} pluginName - The name of the plugin. 20800 * @param {Function} ctor - The constructor function or class for the plugin. 20801 */ 20802 Renderer.registerPlugin = function registerPlugin (pluginName, ctor) 20803 { 20804 Renderer.__plugins = Renderer.__plugins || {}; 20805 Renderer.__plugins[pluginName] = ctor; 20806 }; 20807 20808 return Renderer; 20809 }(AbstractRenderer)); 20810 20811 /** 20812 * This helper function will automatically detect which renderer you should be using. 20813 * WebGL is the preferred renderer as it is a lot faster. If WebGL is not supported by 20814 * the browser then this function will return a canvas renderer 20815 * 20816 * @memberof PIXI 20817 * @function autoDetectRenderer 20818 * @param {object} [options] - The optional renderer parameters 20819 * @param {number} [options.width=800] - the width of the renderers view 20820 * @param {number} [options.height=600] - the height of the renderers view 20821 * @param {HTMLCanvasElement} [options.view] - the canvas to use as a view, optional 20822 * @param {boolean} [options.transparent=false] - If the render view is transparent, default false 20823 * @param {boolean} [options.autoDensity=false] - Resizes renderer view in CSS pixels to allow for 20824 * resolutions other than 1 20825 * @param {boolean} [options.antialias=false] - sets antialias 20826 * @param {boolean} [options.preserveDrawingBuffer=false] - enables drawing buffer preservation, enable this if you 20827 * need to call toDataUrl on the webgl context 20828 * @param {number} [options.backgroundColor=0x000000] - The background color of the rendered area 20829 * (shown if not transparent). 20830 * @param {boolean} [options.clearBeforeRender=true] - This sets if the renderer will clear the canvas or 20831 * not before the new render pass. 20832 * @param {number} [options.resolution=1] - The resolution / device pixel ratio of the renderer, retina would be 2 20833 * @param {boolean} [options.forceCanvas=false] - prevents selection of WebGL renderer, even if such is present, this 20834 * option only is available when using **pixi.js-legacy** or **@pixi/canvas-renderer** modules, otherwise 20835 * it is ignored. 20836 * @param {boolean} [options.forceFXAA=false] - forces FXAA antialiasing to be used over native.
20837 * FXAA is faster, but may not always look as great **webgl only** 20838 * @param {string} [options.powerPreference] - Parameter passed to webgl context, set to "high-performance" 20839 * for devices with dual graphics card **webgl only** 20840 * @return {PIXI.Renderer|PIXI.CanvasRenderer} Returns WebGL renderer if available, otherwise CanvasRenderer 20841 */ 20842 function autoDetectRenderer(options) 20843 { 20844 return Renderer.create(options); 20845 } 20846 20847 var _default = "attribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\n\nuniform mat3 projectionMatrix;\n\nvarying vec2 vTextureCoord;\n\nvoid main(void)\n{\n gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\n vTextureCoord = aTextureCoord;\n}"; 20848 20849 var defaultFilter = "attribute vec2 aVertexPosition;\n\nuniform mat3 projectionMatrix;\n\nvarying vec2 vTextureCoord;\n\nuniform vec4 inputSize;\nuniform vec4 outputFrame;\n\nvec4 filterVertexPosition( void )\n{\n vec2 position = aVertexPosition * max(outputFrame.zw, vec2(0.)) + outputFrame.xy;\n\n return vec4((projectionMatrix * vec3(position, 1.0)).xy, 0.0, 1.0);\n}\n\nvec2 filterTextureCoord( void )\n{\n return aVertexPosition * (outputFrame.zw * inputSize.zw);\n}\n\nvoid main(void)\n{\n gl_Position = filterVertexPosition();\n vTextureCoord = filterTextureCoord();\n}\n"; 20850 20851 /** 20852 * A Texture that depends on six other resources. 20853 * 20854 * @class 20855 * @extends PIXI.BaseTexture 20856 * @memberof PIXI 20857 */ 20858 var CubeTexture = /*@__PURE__*/(function (BaseTexture) { 20859 function CubeTexture () { 20860 BaseTexture.apply(this, arguments); 20861 } 20862 20863 if ( BaseTexture ) { CubeTexture.__proto__ = BaseTexture; } 20864 CubeTexture.prototype = Object.create( BaseTexture && BaseTexture.prototype ); 20865 CubeTexture.prototype.constructor = CubeTexture; 20866 20867 CubeTexture.from = function from (resources, options) 20868 { 20869 return new CubeTexture(new CubeResource(resources, options)); 20870 }; 20871 20872 return CubeTexture; 20873 }(BaseTexture)); 20874 20875 /** 20876 * Geometry used to batch standard PIXI content (e.g. Mesh, Sprite, Graphics objects). 20877 * 20878 * @class 20879 * @memberof PIXI 20880 */ 20881 var BatchGeometry = /*@__PURE__*/(function (Geometry) { 20882 function BatchGeometry(_static) 20883 { 20884 if ( _static === void 0 ) { _static = false; } 20885 20886 Geometry.call(this); 20887 20888 /** 20889 * Buffer used for position, color, texture IDs 20890 * 20891 * @member {PIXI.Buffer} 20892 * @protected 20893 */ 20894 this._buffer = new Buffer(null, _static, false); 20895 20896 /** 20897 * Index buffer data 20898 * 20899 * @member {PIXI.Buffer} 20900 * @protected 20901 */ 20902 this._indexBuffer = new Buffer(null, _static, true); 20903 20904 this.addAttribute('aVertexPosition', this._buffer, 2, false, TYPES.FLOAT) 20905 .addAttribute('aTextureCoord', this._buffer, 2, false, TYPES.FLOAT) 20906 .addAttribute('aColor', this._buffer, 4, true, TYPES.UNSIGNED_BYTE) 20907 .addAttribute('aTextureId', this._buffer, 1, true, TYPES.FLOAT) 20908 .addIndex(this._indexBuffer); 20909 } 20910 20911 if ( Geometry ) { BatchGeometry.__proto__ = Geometry; } 20912 BatchGeometry.prototype = Object.create( Geometry && Geometry.prototype ); 20913 BatchGeometry.prototype.constructor = BatchGeometry; 20914 20915 return BatchGeometry; 20916 }(Geometry)); 20917 20918 /** 20919 * Used by the batcher to draw batches. 20920 * Each one of these contains all information required to draw a bound geometry. 20921 * 20922 * @class 20923 * @memberof PIXI 20924 */ 20925 var BatchDrawCall = function BatchDrawCall() 20926 { 20927 this.textures = []; 20928 this.ids = []; 20929 this.blend = 0; 20930 this.textureCount = 0; 20931 this.start = 0; 20932 this.size = 0; 20933 this.type = 4; 20934 }; 20935 20936 /** 20937 * Used by the BatchRenderer 20938 * 20939 * @class 20940 * @memberof PIXI 20941 */ 20942 var BatchBuffer = function BatchBuffer(size) 20943 { 20944 this.vertices = new ArrayBuffer(size); 20945 20946 /** 20947 * View on the vertices as a Float32Array for positions 20948 * 20949 * @member {Float32Array} 20950 */ 20951 this.float32View = new Float32Array(this.vertices); 20952 20953 /** 20954 * View on the vertices as a Uint32Array for uvs 20955 * 20956 * @member {Float32Array} 20957 */ 20958 this.uint32View = new Uint32Array(this.vertices); 20959 }; 20960 20961 /** 20962 * Destroys the buffer. 20963 * 20964 */ 20965 BatchBuffer.prototype.destroy = function destroy () 20966 { 20967 this.vertices = null; 20968 this.float32View = null; 20969 this.uint32View = null; 20970 }; 20971 20972 var vertex$1 = "precision highp float;\nattribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\nattribute vec4 aColor;\nattribute float aTextureId;\n\nuniform mat3 projectionMatrix;\nuniform mat3 translationMatrix;\nuniform vec4 tint;\n\nvarying vec2 vTextureCoord;\nvarying vec4 vColor;\nvarying float vTextureId;\n\nvoid main(void){\n gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0
20972)).xy, 0.0, 1.0);\n\n vTextureCoord = aTextureCoord;\n vTextureId = aTextureId;\n vColor = aColor * tint;\n}\n"; 20973 20974 var fragTemplate$1 = [ 20975 'varying vec2 vTextureCoord;', 20976 'varying vec4 vColor;', 20977 'varying float vTextureId;', 20978 'uniform sampler2D uSamplers[%count%];', 20979 20980 'void main(void){', 20981 'vec4 color;', 20982 '%forloop%', 20983 'gl_FragColor = color * vColor;', 20984 '}' ].join('\n'); 20985 20986 var defaultGroupCache = {}; 20987 var programCache = {}; 20988 20989 function generateMultiTextureShader(gl, maxTextures) 20990 { 20991 if (!programCache[maxTextures]) 20992 { 20993 var sampleValues = new Int32Array(maxTextures); 20994 20995 for (var i = 0; i < maxTextures; i++) 20996 { 20997 sampleValues[i] = i; 20998 } 20999 21000 defaultGroupCache[maxTextures] = UniformGroup.from({ uSamplers: sampleValues }, true); 21001 21002 var fragmentSrc = fragTemplate$1; 21003 21004 fragmentSrc = fragmentSrc.replace(/%count%/gi, maxTextures); 21005 fragmentSrc = fragmentSrc.replace(/%forloop%/gi, generateSampleSrc(maxTextures)); 21006 21007 programCache[maxTextures] = new Program(vertex$1, fragmentSrc); 21008 } 21009 21010 var uniforms = { 21011 tint: new Float32Array([1, 1, 1, 1]), 21012 translationMatrix: new Matrix(), 21013 default: defaultGroupCache[maxTextures], 21014 }; 21015 21016 var shader = new Shader(programCache[maxTextures], uniforms); 21017 21018 return shader; 21019 } 21020 21021 function generateSampleSrc(maxTextures) 21022 { 21023 var src = ''; 21024 21025 src += '\n'; 21026 src += '\n'; 21027 21028 for (var i = 0; i < maxTextures; i++) 21029 { 21030 if (i > 0) 21031 { 21032 src += '\nelse '; 21033 } 21034 21035 if (i < maxTextures - 1) 21036 { 21037 src += "if(vTextureId < " + i + ".5)"; 21038 } 21039 21040 src += '\n{'; 21041 src += "\n\tcolor = texture2D(uSamplers[" + i + "], vTextureCoord);"; 21042 src += '\n}'; 21043 } 21044 21045 src += '\n'; 21046 src += '\n'; 21047 21048 return src; 21049 } 21050 21051 var TICK = 0; 21052 21053 /** 21054 * Renderer dedicated to drawing and batching sprites. 21055 * 21056 * @class 21057 * @protected 21058 * @memberof PIXI 21059 * @extends PIXI.ObjectRenderer 21060 */ 21061 var BatchRenderer = /*@__PURE__*/(function (ObjectRenderer) { 21062 function BatchRenderer(renderer) 21063 { 21064 ObjectRenderer.call(this, renderer); 21065 21066 /** 21067 * Number of values sent in the vertex buffer. 21068 * aVertexPosition(2), aTextureCoord(1), aColor(1), aTextureId(1) = 5 21069 * 21070 * @member {number} 21071 */ 21072 this.vertSize = 6; 21073 21074 /** 21075 * The size of the vertex information in bytes. 21076 * 21077 * @member {number} 21078 */ 21079 this.vertByteSize = this.vertSize * 4; 21080 21081 /** 21082 * The number of images in the SpriteRenderer before it flushes. 21083 * 21084 * @member {number} 21085 */ 21086 this.size = 2000 * 4;// settings.SPRITE_BATCH_SIZE; // 2000 is a nice balance between mobile / desktop 21087 21088 this.currentSize = 0; 21089 this.currentIndexSize = 0; 21090 21091 // the total number of bytes in our batch 21092 // let numVerts = this.size * 4 * this.vertByteSize; 21093 21094 this.attributeBuffers = {}; 21095 this.aBuffers = {}; 21096 this.iBuffers = {}; 21097 21098 // this.defualtSpriteIndexBuffer = new Buffer(createIndicesForQuads(this.size), true, true); 21099 21100 /** 21101 * Holds the defualt indices of the geometry (quads) to draw 21102 * 21103 * @member {Uint16Array} 21104 */ 21105 // const indicies = createIndicesForQuads(this.size); 21106 21107 // this.defaultQuadIndexBuffer = new Buffer(indicies, true, true); 21108 21109 this.onlySprites = false; 21110 21111 /** 21112 * The default shaders that is used if a sprite doesn't have a more specific one. 21113 * there is a shader for each number of textures that can be rendered. 21114 * These shaders will also be generated on the fly as required. 21115 * @member {PIXI.Shader[]} 21116 */ 21117 this.shader = null; 21118 21119 this.currentIndex = 0; 21120 this.groups = []; 21121 21122 for (var k = 0; k < this.size / 4; k++) 21123 { 21124 this.groups[k] = new BatchDrawCall(); 21125 } 21126 21127 this.elements = []; 21128 21129 this.vaos = []; 21130 21131 this.vaoMax = 2; 21132 this.vertexCount = 0; 21133 21134 this.renderer.on('prerender', this.onPrerender, this); 21135 this.state = State.for2d(); 21136 } 21137 21138 if ( ObjectRenderer ) { BatchRenderer.__proto__ = ObjectRenderer; } 21139 BatchRenderer.prototype = Object.create( ObjectRenderer && ObjectRenderer.prototype ); 21140 BatchRenderer.prototype.constructor = BatchRenderer; 21141 21142 /** 21143 * Sets up the renderer context and necessary buffers. 21144 */ 21145 BatchRenderer.prototype.contextChange = function contextChange () 21146 { 21147 var gl = this.renderer.gl; 21148 21149 if (settings.PREFER_ENV === ENV.WEBGL_LEGACY) 21150 { 21151 this.MAX_TEXTURES = 1; 21152 } 21153 else 21154 { 21155 // step 1: first check max textures the GPU can handle. 21156 this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), settings.SPRITE_MAX_TEXTURES); 21157 21158 // step 2: check the maximum number of if statements the shader can have too.. 21159 this.MAX_TEXTURES = checkMaxIfStatementsInShader(this.MAX_TEXTURES, gl); 21160 } 21161 21162 // generate generateMultiTextureProgram, may be a better move? 21163 this.shader = generateMultiTextureShader(gl, this.MAX_TEXTURES); 21164 21165 // we use the second shader as the first one depending on your browser may omit aTextureId 21166 // as it is not used by the shader so is optimized out. 21167 for (var i = 0; i < this.vaoMax; i++) 21168 { 21169 /* eslint-disable max-len */ 21170 this.vaos[i] = new BatchGeometry(); 21171 } 21172 }; 21173 21174 /** 21175 * Called before the renderer starts rendering. 21176 * 21177 */ 21178 BatchRenderer.prototype.onPrerender = function onPrerender () 21179 { 21180 this.vertexCount = 0; 21181 }; 21182 21183 /**
21184 * Renders the sprite object. 21185 * 21186 * @param {PIXI.Sprite} sprite - the sprite to render when using this spritebatch 21187 */ 21188 BatchRenderer.prototype.render = function render (element) 21189 { 21190 if (!element._texture.valid) 21191 { 21192 return; 21193 } 21194 21195 if (this.currentSize + (element.vertexData.length / 2) > this.size) 21196 { 21197 this.flush(); 21198 } 21199 21200 this.elements[this.currentIndex++] = element; 21201 21202 this.currentSize += element.vertexData.length / 2; 21203 this.currentIndexSize += element.indices.length; 21204 }; 21205 21206 BatchRenderer.prototype.getIndexBuffer = function getIndexBuffer (size) 21207 { 21208 // 12 indices is enough for 2 quads 21209 var roundedP2 = nextPow2(Math.ceil(size / 12)); 21210 var roundedSizeIndex = log2(roundedP2); 21211 var roundedSize = roundedP2 * 12; 21212 21213 if (this.iBuffers.length <= roundedSizeIndex) 21214 { 21215 this.iBuffers.length = roundedSizeIndex + 1; 21216 } 21217 21218 var buffer = this.iBuffers[roundedSizeIndex]; 21219 21220 if (!buffer) 21221 { 21222 this.iBuffers[roundedSizeIndex] = buffer = new Uint16Array(roundedSize); 21223 } 21224 21225 return buffer; 21226 }; 21227 21228 BatchRenderer.prototype.getAttributeBuffer = function getAttributeBuffer (size) 21229 { 21230 // 8 vertices is enough for 2 quads 21231 var roundedP2 = nextPow2(Math.ceil(size / 8)); 21232 var roundedSizeIndex = log2(roundedP2); 21233 var roundedSize = roundedP2 * 8; 21234 21235 if (this.aBuffers.length <= roundedSizeIndex) 21236 { 21237 this.iBuffers.length = roundedSizeIndex + 1; 21238 } 21239 21240 var buffer = this.aBuffers[roundedSize]; 21241 21242 if (!buffer) 21243 { 21244 this.aBuffers[roundedSize] = buffer = new BatchBuffer(roundedSize * this.vertByteSize); 21245 } 21246 21247 return buffer; 21248 }; 21249 21250 /**
21251 * Renders the content and empties the current batch. 21252 * 21253 */ 21254 BatchRenderer.prototype.flush = function flush () 21255 { 21256 if (this.currentSize === 0) 21257 { 21258 return; 21259 } 21260 21261 var gl = this.renderer.gl; 21262 var MAX_TEXTURES = this.MAX_TEXTURES; 21263 21264 var buffer = this.getAttributeBuffer(this.currentSize); 21265 var indexBuffer = this.getIndexBuffer(this.currentIndexSize); 21266 21267 var elements = this.elements; 21268 var groups = this.groups; 21269 21270 var float32View = buffer.float32View; 21271 var uint32View = buffer.uint32View; 21272 21273 var touch = this.renderer.textureGC.count; 21274 21275 var index = 0; 21276 var indexCount = 0; 21277 var nextTexture; 21278 var currentTexture; 21279 var groupCount = 0; 21280 21281 var textureCount = 0; 21282 var currentGroup = groups[0]; 21283 21284 var blendMode = -1;// premultiplyBlendMode[elements[0]._texture.baseTexture.premultiplyAlpha ? 0 : ][elements[0].blendMode]; 21285 21286 currentGroup.textureCount = 0; 21287 currentGroup.start = 0; 21288 currentGroup.blend = blendMode; 21289 21290 TICK++; 21291 21292 var i; 21293 21294 for (i = 0; i < this.currentIndex; ++i) 21295 { 21296 // upload the sprite elements... 21297 // they have all ready been calculated so we just need to push them into the buffer. 21298 21299 var sprite = elements[i]; 21300 21301 elements[i] = null; 21302 21303 nextTexture = sprite._texture.baseTexture; 21304 21305 var spriteBlendMode = premultiplyBlendMode[nextTexture.premultiplyAlpha ? 1 : 0][sprite.blendMode]; 21306 21307 if (blendMode !== spriteBlendMode) 21308 { 21309 blendMode = spriteBlendMode; 21310 21311 // force the batch to break! 21312 currentTexture = null; 21313 textureCount = MAX_TEXTURES; 21314 TICK++; 21315 } 21316 21317 if (currentTexture !== nextTexture) 21318 { 21319 currentTexture = nextTexture; 21320 21321 if (nextTexture._enabled !== TICK) 21322 { 21323 if (textureCount === MAX_TEXTURES) 21324 { 21325 TICK++; 21326 21327 textureCount = 0; 21328 21329 currentGroup.size = indexCount - currentGroup.start; 21330 21331 currentGroup = groups[groupCount++]; 21332 currentGroup.textureCount = 0; 21333 currentGroup.blend = blendMode; 21334 currentGroup.start = indexCount; 21335 } 21336 21337 nextTexture.touched = touch; 21338 nextTexture._enabled = TICK; 21339 nextTexture._id = textureCount; 21340 21341 currentGroup.textures[currentGroup.textureCount++] = nextTexture; 21342 textureCount++; 21343 } 21344 } 21345 21346 this.packGeometry(sprite, float32View, uint32View, indexBuffer, index, indexCount);// argb, nextTexture._id, float32View, uint32View, indexBuffer, index, indexCount); 21347 21348 // push a graphics.. 21349 index += (sprite.vertexData.length / 2) * this.vertSize; 21350 indexCount += sprite.indices.length; 21351 } 21352 21353 currentGroup.size = indexCount - currentGroup.start; 21354 21355 // this.indexBuffer.update(); 21356 21357 if (!settings.CAN_UPLOAD_SAME_BUFFER) 21358 { 21359 // this is still needed for IOS performance.. 21360 // it really does not like uploading to the same buffer in a single frame! 21361 if (this.vaoMax <= this.vertexCount) 21362 { 21363 this.vaoMax++; 21364 /* eslint-disable max-len */ 21365 this.vaos[this.vertexCount] = new BatchGeometry(); 21366 } 21367 21368 this.vaos[this.vertexCount]._buffer.update(buffer.vertices, 0); 21369 this.vaos[this.vertexCount]._indexBuffer.update(indexBuffer, 0); 21370 21371 // this.vertexBuffers[this.vertexCount].update(buffer.vertices, 0); 21372 this.renderer.geometry.bind(this.vaos[this.vertexCount]); 21373 21374 this.renderer.geometry.updateBuffers(); 21375 21376 this.vertexCount++; 21377 } 21378 else 21379 { 21380 // lets use the faster option, always use buffer number 0 21381 this.vaos[this.vertexCount]._buffer.update(buffer.vertices, 0); 21382 this.vaos[this.vertexCount]._indexBuffer.update(indexBuffer, 0); 21383 21384 // if (true)// this.spriteOnly) 21385 // { 21386 // this.vaos[this.vertexCount].indexBuffer = this.defualtSpriteIndexBuffer; 21387 // this.vaos[this.vertexCount].buffers[1] = this.defualtSpriteIndexBuffer; 21388 // } 21389 21390 this.renderer.geometry.updateBuffers(); 21391 } 21392 21393 // this.renderer.state.set(this.state); 21394 21395 var textureSystem = this.renderer.texture; 21396 var stateSystem = this.renderer.state; 21397 // e.log(groupCount); 21398 // / render the groups.. 21399 21400 for (i = 0; i < groupCount; i++) 21401 { 21402 var group = groups[i]; 21403 var groupTextureCount = group.textureCount; 21404 21405 for (var j = 0; j < groupTextureCount; j++) 21406 { 21407 textureSystem.bind(group.textures[j], j); 21408 group.textures[j] = null; 21409 } 21410 21411 // this.state.blendMode = group.blend; 21412 // this.state.blend = true; 21413 21414 // this.renderer.state.setState(this.state); 21415 // set the blend mode.. 21416 stateSystem.setBlendMode(group.blend); 21417 21418 gl.drawElements(group.type, group.size, gl.UNSIGNED_SHORT, group.start * 2); 21419 } 21420 21421 // reset elements for the next flush 21422 this.currentIndex = 0; 21423 this.currentSize = 0; 21424 this.currentIndexSize = 0; 21425 }; 21426 21427 BatchRenderer.prototype.packGeometry = function packGeometry (element, float32View, uint32View, indexBuffer, index, indexCount) 21428 { 21429 var p = index / this.vertSize;// float32View.length / 6 / 2; 21430 var uvs = element.uvs; 21431 var indicies = element.indices;// geometry.getIndex().data;// indicies; 21432 var vertexData = element.vertexData; 21433 var textureId = element._texture.baseTexture._id; 21434 21435 var alpha = Math.min(element.worldAlpha, 1.0); 21436 21437 var argb = alpha < 1.0 && element._texture.baseTexture.premultiplyAlpha ? premultiplyTint(element._tintRGB, alpha) 21438 : element._tintRGB + (alpha * 255 << 24); 21439 21440 // lets not worry about tint! for now.. 21441 for (var i = 0; i < vertexData.length; i += 2) 21442 { 21443 float32View[index++] = vertexData[i]; 21444 float32View[index++] = vertexData[i + 1]; 21445 float32View[index++] = uvs[i]; 21446 float32View[index++] = uvs[i + 1]; 21447 uint32View[index++] = argb; 21448 float32View[index++] = textureId; 21449 } 21450 21451 for (var i$1 = 0; i$1 < indicies.length; i$1++) 21452 { 21453 indexBuffer[indexCount++] = p + indicies[i$1]; 21454 } 21455 }; 21456 /* 21457 renderQuad(vertexData, uvs, argb, textureId, float32View, uint32View, indexBuffer, index, indexCount) 21458 { 21459 const p = index / 6; 21460 21461 float32View[index++] = vertexData[0]; 21462 float32View[index++] = vertexData[1]; 21463 float32View[index++] = uvs.x0; 21464 float32View[index++] = uvs.y0; 21465 uint32View[index++] = argb; 21466 float32View[index++] = textureId; 21467 21468 float32View[index++] = vertexData[2]; 21469 float32View[index++] = vertexData[3]; 21470 float32View[index++] = uvs.x1; 21471 float32View[index++] = uvs.y1; 21472 uint32View[index++] = argb; 21473 float32View[index++] = textureId; 21474 21475 float32View[index++] = vertexData[4]; 21476 float32View[index++] = vertexData[5]; 21477 float32View[index++] = uvs.x2; 21478 float32View[index++] = uvs.y2; 21479 uint32View[index++] = argb; 21480 float32View[index++] = textureId; 21481 21482 float32View[index++] = vertexData[6]; 21483 float32View[index++] = vertexData[7]; 21484 float32View[index++] = uvs.x3; 21485 float32View[index++] = uvs.y3; 21486 uint32View[index++] = argb; 21487 float32View[index++] = textureId; 21488 21489 indexBuffer[indexCount++] = p + 0; 21490 indexBuffer[indexCount++] = p + 1; 21491 indexBuffer[indexCount++] = p + 2; 21492 indexBuffer[indexCount++] = p + 0; 21493 indexBuffer[indexCount++] = p + 2; 21494 indexBuffer[indexCount++] = p + 3; 21495 } 21496 */ 21497 /** 21498 * Starts a new sprite batch. 21499 */ 21500 BatchRenderer.prototype.start = function start () 21501 { 21502 this.renderer.state.setState(this.state); 21503 21504 this.renderer.shader.bind(this.shader); 21505 21506 if (settings.CAN_UPLOAD_SAME_BUFFER) 21507 { 21508 // bind buffer #0, we don't need others 21509 this.renderer.geometry.bind(this.vaos[this.vertexCount]); 21510 } 21511 }; 21512 21513 /** 21514 * Stops and flushes the current batch. 21515 * 21516 */ 21517 BatchRenderer.prototype.stop = function stop () 21518 { 21519 this.flush(); 21520 }; 21521 21522 /** 21523 * Destroys the SpriteRenderer. 21524 * 21525 */ 21526 BatchRenderer.prototype.destroy = function destroy () 21527 { 21528 for (var i = 0; i < this.vaoMax; i++) 21529 { 21530 // if (this.vertexBuffers[i]) 21531 // { 21532 // this.vertexBuffers[i].destroy(); 21533 // } 21534 if (this.vaos[i]) 21535 { 21536 this.vaos[i].destroy(); 21537 } 21538 } 21539 21540 if (this.indexBuffer) 21541 { 21542 this.indexBuffer.destroy(); 21543 } 21544 21545 this.renderer.off('prerender', this.onPrerender, this); 21546 21547 if (this.shader) 21548 { 21549 this.shader.destroy(); 21550 this.shader = null; 21551 } 21552 21553 // this.vertexBuffers = null; 21554 this.vaos = null; 21555 this.indexBuffer = null; 21556 this.indices = null; 21557 this.sprites = null; 21558 21559 // for (let i = 0; i < this.buffers.length; ++i) 21560 // { 21561 // this.buffers[i].destroy(); 21562 // } 21563 21564 ObjectRenderer.prototype.destroy.call(this); 21565 }; 21566 21567 return BatchRenderer; 21568 }(ObjectRenderer)); 21569 21570 /*! 21571 * @pixi/extract - v5.0.0-rc.3 21572 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 21573 * 21574 * @pixi/extract is licensed under the MIT License. 21575 * http://www.opensource.org/licenses/mit-license 21576 */ 21577 21578 var TEMP_RECT = new Rectangle(); 21579 var BYTES_PER_PIXEL = 4; 21580 21581 /** 21582 * The extract manager provides functionality to export content from the renderers. 21583 * 21584 * An instance of this class is automatically created by default, and can be found at `renderer.plugins.extract` 21585 * 21586 * @class 21587 * @memberof PIXI.extract 21588 */ 21589 var Extract = function Extract(renderer) 21590 { 21591 this.renderer = renderer; 21592 /** 21593 * Collection of methods for extracting data (image, pixels, etc.) from a display object or render texture 21594 * 21595 * @member {PIXI.extract.Extract} extract 21596 * @memberof PIXI.Renderer# 21597 * @see PIXI.extract.Extract 21598 */ 21599 renderer.extract = this; 21600 }; 21601 21602 /** 21603 * Will return a HTML Image of the target 21604 * 21605 * @param {PIXI.DisplayObject|PIXI.RenderTexture} target - A displayObject or renderTexture 21606 * to convert. If left empty will use the main renderer 21607 * @return {HTMLImageElement} HTML Image of the target 21608 */ 21609 Extract.prototype.image = function image (target) 21610 { 21611 var image = new Image(); 21612 21613 image.src = this.base64(target); 21614 21615 return image; 21616 }; 21617 21618 /** 21619 * Will return a a base64 encoded string of this target. It works by calling 21620 * `Extract.getCanvas` and then running toDataURL on that. 21621 * 21622 * @param {PIXI.DisplayObject|PIXI.RenderTexture} target - A displayObject or renderTexture 21623 * to convert. If left empty will use the main renderer 21624 * @return {string} A base64 encoded string of the texture. 21625 */ 21626 Extract.prototype.base64 = function base64 (target) 21627 { 21628 return this.canvas(target).toDataURL(); 21629 }; 21630 21631 /** 21632 * Creates a Canvas element, renders this target to it and then returns it. 21633 * 21634 * @param {PIXI.DisplayObject|PIXI.RenderTexture} target - A displayObject or renderTexture 21635 * to convert. If left empty will use the main renderer 21636 * @return {HTMLCanvasElement} A Canvas element with the texture rendered on. 21637 */ 21638 Extract.prototype.canvas = function canvas (target) 21639 { 21640 var renderer = this.renderer; 21641 var resolution; 21642 var frame; 21643 var flipY = false;
21644 var renderTexture; 21645 var generated = false; 21646 21647 if (target) 21648 { 21649 if (target instanceof RenderTexture) 21650 { 21651 renderTexture = target; 21652 } 21653 else 21654 { 21655 renderTexture = this.renderer.generateTexture(target); 21656 generated = true; 21657 } 21658 } 21659 21660 if (renderTexture) 21661 { 21662 resolution = renderTexture.baseTexture.resolution; 21663 frame = renderTexture.frame; 21664 flipY = false; 21665 renderer.renderTexture.bind(renderTexture); 21666 } 21667 else 21668 { 21669 resolution = this.renderer.resolution; 21670 21671 flipY = true; 21672 21673 frame = TEMP_RECT; 21674 frame.width = this.renderer.width; 21675 frame.height = this.renderer.height; 21676 21677 renderer.renderTexture.bind(null); 21678 } 21679 21680 var width = frame.width * resolution; 21681 var height = frame.height * resolution; 21682 21683 var canvasBuffer = new CanvasRenderTarget(width, height, 1); 21684 21685 var webglPixels = new Uint8Array(BYTES_PER_PIXEL * width * height); 21686 21687 // read pixels to the array 21688 var gl = renderer.gl; 21689 21690 gl.readPixels( 21691 frame.x * resolution, 21692 frame.y * resolution, 21693 width, 21694 height, 21695 gl.RGBA, 21696 gl.UNSIGNED_BYTE, 21697 webglPixels 21698 ); 21699 21700 // add the pixels to the canvas 21701 var canvasData = canvasBuffer.context.getImageData(0, 0, width, height); 21702 21703 canvasData.data.set(webglPixels); 21704 21705 canvasBuffer.context.putImageData(canvasData, 0, 0); 21706 21707 // pulling pixels 21708 if (flipY) 21709 { 21710 canvasBuffer.context.scale(1, -1); 21711 canvasBuffer.context.drawImage(canvasBuffer.canvas, 0, -height); 21712 } 21713 21714 if (generated) 21715 { 21716 renderTexture.destroy(true); 21717 } 21718 21719 // send the canvas back.. 21720 return canvasBuffer.canvas; 21721 }; 21722 21723 /** 21724 * Will return a one-dimensional array containing the pixel data of the entire texture in RGBA 21725 * order, with integer values between 0 and 255 (included). 21726 * 21727 * @param {PIXI.DisplayObject|PIXI.RenderTexture} target - A displayObject or renderTexture 21728 * to convert. If left empty will use the main renderer 21729 * @return {Uint8ClampedArray} One-dimensional array containing the pixel data of the entire texture 21730 */ 21731 Extract.prototype.pixels = function pixels (target) 21732 { 21733 var renderer = this.renderer; 21734 var resolution; 21735 var frame; 21736 var renderTexture; 21737 var generated = false; 21738 21739 if (target) 21740 { 21741 if (target instanceof RenderTexture) 21742 { 21743 renderTexture = target; 21744 } 21745 else 21746 { 21747 renderTexture = this.renderer.generateTexture(target); 21748 generated = true; 21749 } 21750 } 21751 21752 if (renderTexture) 21753 { 21754 resolution = renderTexture.baseTexture.resolution; 21755 frame = renderTexture.frame; 21756 21757 // bind the buffer 21758 renderer.renderTexture.bind(renderTexture); 21759 } 21760 else 21761 { 21762 resolution = renderer.resolution; 21763 21764 frame = TEMP_RECT; 21765 frame.width = renderer.width; 21766 frame.height = renderer.height; 21767 21768 renderer.renderTexture.bind(null); 21769 } 21770 21771 var width = frame.width * resolution; 21772 var height = frame.height * resolution; 21773 21774 var webglPixels = new Uint8Array(BYTES_PER_PIXEL * width * height); 21775 21776 // read pixels to the array 21777 var gl = renderer.gl; 21778 21779 gl.readPixels( 21780 frame.x * resolution, 21781 frame.y * resolution, 21782 width, 21783 height, 21784 gl.RGBA, 21785 gl.UNSIGNED_BYTE, 21786 webglPixels 21787 ); 21788 21789 if (generated) 21790 { 21791 renderTexture.destroy(true); 21792 } 21793 21794 return webglPixels; 21795 }; 21796 21797 /** 21798 * Destroys the extract 21799 * 21800 */ 21801 Extract.prototype.destroy = function destroy () 21802 { 21803 this.renderer.extract = null; 21804 this.renderer = null; 21805 }; 21806 21807 var extract = ({ 21808 Extract: Extract 21809 }); 21810 21811 /*! 21812 * @pixi/interaction - v5.0.0-rc.3 21813 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 21814 * 21815 * @pixi/interaction is licensed under the MIT License. 21816 * http://www.opensource.org/licenses/mit-license 21817 */ 21818 21819 /** 21820 * Holds all information related to an Interaction event 21821 * 21822 * @class 21823 * @memberof PIXI.interaction 21824 */ 21825 var InteractionData = function InteractionData() 21826 { 21827 /** 21828 * This point stores the global coords of where the touch/mouse event happened 21829 * 21830 * @member {PIXI.Point} 21831 */ 21832 this.global = new Point(); 21833 21834 /** 21835 * The target Sprite that was interacted with 21836 * 21837 * @member {PIXI.Sprite} 21838 */ 21839 this.target = null; 21840 21841 /** 21842 * When passed to an event handler, this will be the original DOM Event that was captured 21843 * 21844 * @see https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent 21845 * @see https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent 21846 * @see https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent 21847 * @member {MouseEvent|TouchEvent|PointerEvent} 21848 */ 21849 this.originalEvent = null; 21850 21851 /** 21852 * Unique identifier for this interaction 21853 * 21854 * @member {number} 21855 */ 21856 this.identifier = null; 21857 21858 /** 21859 * Indicates whether or not the pointer device that created the event is the primary pointer. 21860 * @see https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/isPrimary 21861 * @type {Boolean} 21862 */ 21863 this.isPrimary = false;
21864 21865 /** 21866 * Indicates which button was pressed on the mouse or pointer device to trigger the event. 21867 * @see https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button 21868 * @type {number} 21869 */ 21870 this.button = 0; 21871 21872 /** 21873 * Indicates which buttons are pressed on the mouse or pointer device when the event is triggered. 21874 * @see https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons 21875 * @type {number} 21876 */ 21877 this.buttons = 0; 21878 21879 /** 21880 * The width of the pointer's contact along the x-axis, measured in CSS pixels. 21881 * radiusX of TouchEvents will be represented by this value. 21882 * @see https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/width 21883 * @type {number} 21884 */ 21885 this.width = 0; 21886 21887 /** 21888 * The height of the pointer's contact along the y-axis, measured in CSS pixels. 21889 * radiusY of TouchEvents will be represented by this value. 21890 * @see https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/height 21891 * @type {number} 21892 */ 21893 this.height = 0; 21894 21895 /** 21896 * The angle, in degrees, between the pointer device and the screen. 21897 * @see https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/tiltX 21898 * @type {number} 21899 */ 21900 this.tiltX = 0; 21901 21902 /** 21903 * The angle, in degrees, between the pointer device and the screen. 21904 * @see https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/tiltY 21905 * @type {number} 21906 */ 21907 this.tiltY = 0; 21908 21909 /** 21910 * The type of pointer that triggered the event. 21911 * @see https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/pointerType 21912 * @type {string} 21913 */ 21914 this.pointerType = null; 21915 21916 /** 21917 * Pressure applied by the pointing device during the event. A Touch's force property 21918 * will be represented by this value. 21919 * @see https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/pressure 21920 * @type {number} 21921 */ 21922 this.pressure = 0; 21923 21924 /** 21925 * From TouchEvents (not PointerEvents triggered by touches), the rotationAngle of the Touch. 21926 * @see https://developer.mozilla.org/en-US/docs/Web/API/Touch/rotationAngle 21927 * @type {number} 21928 */ 21929 this.rotationAngle = 0; 21930 21931 /** 21932 * Twist of a stylus pointer. 21933 * @see https://w3c.github.io/pointerevents/#pointerevent-interface 21934 * @type {number} 21935 */ 21936 this.twist = 0; 21937 21938 /** 21939 * Barrel pressure on a stylus pointer. 21940 * @see https://w3c.github.io/pointerevents/#pointerevent-interface 21941 * @type {number} 21942 */ 21943 this.tangentialPressure = 0; 21944 }; 21945 21946 var prototypeAccessors$6 = { pointerId: { configurable: true } }; 21947 21948 /** 21949 * The unique identifier of the pointer. It will be the same as `identifier`. 21950 * @readonly 21951 * @member {number} 21952 * @see https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/pointerId 21953 */ 21954 prototypeAccessors$6.pointerId.get = function () 21955 { 21956 return this.identifier; 21957 }; 21958 21959 /** 21960 * This will return the local coordinates of the specified displayObject for this InteractionData 21961 * 21962 * @param {PIXI.DisplayObject} displayObject - The DisplayObject that you would like the local 21963 * coords off 21964 * @param {PIXI.Point} [point] - A Point object in which to store the value, optional (otherwise 21965 * will create a new point) 21966 * @param {PIXI.Point} [globalPos] - A Point object containing your custom global coords, optional 21967 * (otherwise will use the current global coords) 21968 * @return {PIXI.Point} A point containing the coordinates of the InteractionData position relative 21969 * to the DisplayObject 21970 */ 21971 InteractionData.prototype.getLocalPosition = function getLocalPosition (displayObject, point, globalPos) 21972 { 21973 return displayObject.worldTransform.applyInverse(globalPos || this.global, point); 21974 }; 21975 21976 /** 21977 * Copies properties from normalized event data. 21978 * 21979 * @param {Touch|MouseEvent|PointerEvent} event The normalized event data 21980 */ 21981 InteractionData.prototype.copyEvent = function copyEvent (event) 21982 { 21983 // isPrimary should only change on touchstart/pointerdown, so we don't want to overwrite 21984 // it with "false" on later events when our shim for it on touch events might not be 21985 // accurate 21986 if (event.isPrimary) 21987 { 21988 this.isPrimary = true; 21989 } 21990 this.button = event.button; 21991 // event.buttons is not available in all browsers (ie. Safari), but it does have a non-standard 21992 // event.which property instead, which conveys the same information. 21993 this.buttons = Number.isInteger(event.buttons) ? event.buttons : event.which; 21994 this.width = event.width; 21995 this.height = event.height; 21996 this.tiltX = event.tiltX; 21997 this.tiltY = event.tiltY; 21998 this.pointerType = event.pointerType; 21999 this.pressure = event.pressure; 22000 this.rotationAngle = event.rotationAngle; 22001 this.twist = event.twist || 0; 22002 this.tangentialPressure = event.tangentialPressure || 0; 22003 }; 22004 22005 /** 22006 * Resets the data for pooling. 22007 */ 22008 InteractionData.prototype.reset = function reset () 22009 { 22010 // isPrimary is the only property that we really need to reset - everything else is
22011 // guaranteed to be overwritten 22012 this.isPrimary = false; 22013 }; 22014 22015 Object.defineProperties( InteractionData.prototype, prototypeAccessors$6 ); 22016 22017 /** 22018 * Event class that mimics native DOM events. 22019 * 22020 * @class 22021 * @memberof PIXI.interaction 22022 */ 22023 var InteractionEvent = function InteractionEvent() 22024 { 22025 /** 22026 * Whether this event will continue propagating in the tree 22027 * 22028 * @member {boolean} 22029 */ 22030 this.stopped = false; 22031 22032 /** 22033 * The object which caused this event to be dispatched. 22034 * For listener callback see {@link PIXI.interaction.InteractionEvent.currentTarget}. 22035 * 22036 * @member {PIXI.DisplayObject} 22037 */ 22038 this.target = null; 22039 22040 /** 22041 * The object whose event listener’s callback is currently being invoked. 22042 * 22043 * @member {PIXI.DisplayObject} 22044 */ 22045 this.currentTarget = null; 22046 22047 /** 22048 * Type of the event 22049 * 22050 * @member {string} 22051 */ 22052 this.type = null; 22053 22054 /** 22055 * InteractionData related to this event 22056 * 22057 * @member {PIXI.interaction.InteractionData} 22058 */ 22059 this.data = null; 22060 }; 22061 22062 /** 22063 * Prevents event from reaching any objects other than the current object. 22064 * 22065 */ 22066 InteractionEvent.prototype.stopPropagation = function stopPropagation () 22067 { 22068 this.stopped = true; 22069 }; 22070 22071 /** 22072 * Resets the event. 22073 */ 22074 InteractionEvent.prototype.reset = function reset () 22075 { 22076 this.stopped = false; 22077 this.currentTarget = null; 22078 this.target = null; 22079 }; 22080 22081 /** 22082 * DisplayObjects with the {@link PIXI.interaction.interactiveTarget} mixin use this class to track interactions 22083 * 22084 * @class 22085 * @private 22086 * @memberof PIXI.interaction 22087 */ 22088 var InteractionTrackingData = function InteractionTrackingData(pointerId) 22089 { 22090 this._pointerId = pointerId; 22091 this._flags = InteractionTrackingData.FLAGS.NONE; 22092 }; 22093 22094 var prototypeAccessors$1$3 = { pointerId: { configurable: true },flags: { configurable: true },none: { configurable: true },over: { configurable: true },rightDown: { configurable: true },leftDown: { configurable: true } }; 22095 22096 /** 22097 * 22098 * @private 22099 * @param {number} flag - The interaction flag to set 22100 * @param {boolean} yn - Should the flag be set or unset 22101 */ 22102 InteractionTrackingData.prototype._doSet = function _doSet (flag, yn) 22103 { 22104 if (yn) 22105 { 22106 this._flags = this._flags | flag; 22107 } 22108 else 22109 { 22110 this._flags = this._flags & (~flag); 22111 } 22112 }; 22113 22114 /** 22115 * Unique pointer id of the event 22116 * 22117 * @readonly 22118 * @private 22119 * @member {number} 22120 */ 22121 prototypeAccessors$1$3.pointerId.get = function () 22122 { 22123 return this._pointerId; 22124 }; 22125 22126 /** 22127 * State of the tracking data, expressed as bit flags 22128 * 22129 * @private 22130 * @member {number} 22131 */ 22132 prototypeAccessors$1$3.flags.get = function () 22133 { 22134 return this._flags; 22135 }; 22136 22137 prototypeAccessors$1$3.flags.set = function (flags) // eslint-disable-line require-jsdoc 22138 { 22139 this._flags = flags; 22140 }; 22141 22142 /** 22143 * Is the tracked event inactive (not over or down)? 22144 * 22145 * @private 22146 * @member {number} 22147 */ 22148 prototypeAccessors$1$3.none.get = function () 22149 { 22150 return this._flags === this.constructor.FLAGS.NONE; 22151 }; 22152 22153 /** 22154 * Is the tracked event over the DisplayObject? 22155 * 22156 * @private 22157 * @member {boolean} 22158 */ 22159 prototypeAccessors$1$3.over.get = function () 22160 { 22161 return (this._flags & this.constructor.FLAGS.OVER) !== 0; 22162 }; 22163 22164 prototypeAccessors$1$3.over.set = function (yn) // eslint-disable-line require-jsdoc 22165 { 22166 this._doSet(this.constructor.FLAGS.OVER, yn); 22167 }; 22168 22169 /** 22170 * Did the right mouse button come down in the DisplayObject? 22171 * 22172 * @private 22173 * @member {boolean} 22174 */ 22175 prototypeAccessors$1$3.rightDown.get = function () 22176 { 22177 return (this._flags & this.constructor.FLAGS.RIGHT_DOWN) !== 0; 22178 }; 22179 22180 prototypeAccessors$1$3.rightDown.set = function (yn) // eslint-disable-line require-jsdoc 22181 { 22182 this._doSet(this.constructor.FLAGS.RIGHT_DOWN, yn); 22183 }; 22184 22185 /** 22186 * Did the left mouse button come down in the DisplayObject? 22187 * 22188 * @private 22189 * @member {boolean} 22190 */ 22191 prototypeAccessors$1$3.leftDown.get = function () 22192 { 22193 return (this._flags & this.constructor.FLAGS.LEFT_DOWN) !== 0; 22194 }; 22195 22196 prototypeAccessors$1$3.leftDown.set = function (yn) // eslint-disable-line require-jsdoc 22197 { 22198 this._doSet(this.constructor.FLAGS.LEFT_DOWN, yn); 22199 }; 22200 22201 Object.defineProperties( InteractionTrackingData.prototype, prototypeAccessors$1$3 ); 22202 22203 InteractionTrackingData.FLAGS = Object.freeze({ 22204 NONE: 0, 22205 OVER: 1 << 0, 22206 LEFT_DOWN: 1 << 1, 22207 RIGHT_DOWN: 1 << 2, 22208 }); 22209 22210 /** 22211 * Default property values of interactive objects 22212 * Used by {@link PIXI.interaction.InteractionManager} to automatically give all DisplayObjects these properties 22213 * 22214 * @private 22215 * @name interactiveTarget 22216 * @type {Object} 22217 * @memberof PIXI.interaction 22218 * @example 22219 * function MyObject() {} 22220 * 22221 * Object.assign( 22222 * DisplayObject.prototype, 22223 * PIXI.interaction.interactiveTarget 22224 * ); 22225 */ 22226 var interactiveTarget = { 22227 22228 /** 22229 * Enable interaction events for the DisplayObject. Touch, pointer and mouse 22230 * events will not be emitted unless `interactive` is set to `true`. 22231 * 22232 * @example 22233 * const sprite = new PIXI.Sprite(texture); 22234 * sprite.interactive = true; 22235 * sprite.on('tap', (event) => { 22236 * //handle event 22237 * }); 22238 * @member {boolean} 22239 * @memberof PIXI.DisplayObject# 22240 */ 22241 interactive: false, 22242 22243 /** 22244 * Determines if the children to the displayObject can be clicked/touched
22245 * Setting this to false allows PixiJS to bypass a recursive `hitTest` function 22246 * 22247 * @member {boolean} 22248 * @memberof PIXI.Container# 22249 */ 22250 interactiveChildren: true, 22251 22252 /** 22253 * Interaction shape. Children will be hit first, then this shape will be checked. 22254 * Setting this will cause this shape to be checked in hit tests rather than the displayObject's bounds. 22255 * 22256 * @example 22257 * const sprite = new PIXI.Sprite(texture); 22258 * sprite.interactive = true; 22259 * sprite.hitArea = new PIXI.Rectangle(0, 0, 100, 100); 22260 * @member {PIXI.Rectangle|PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.RoundedRectangle} 22261 * @memberof PIXI.DisplayObject# 22262 */ 22263 hitArea: null, 22264 22265 /** 22266 * If enabled, the mouse cursor use the pointer behavior when hovered over the displayObject if it is interactive 22267 * Setting this changes the 'cursor' property to `'pointer'`. 22268 * 22269 * @example 22270 * const sprite = new PIXI.Sprite(texture); 22271 * sprite.interactive = true; 22272 * sprite.buttonMode = true; 22273 * @member {boolean} 22274 * @memberof PIXI.DisplayObject# 22275 */ 22276 get buttonMode() 22277 { 22278 return this.cursor === 'pointer'; 22279 }, 22280 set buttonMode(value) 22281 { 22282 if (value) 22283 { 22284 this.cursor = 'pointer'; 22285 } 22286 else if (this.cursor === 'pointer') 22287 { 22288 this.cursor = null; 22289 } 22290 }, 22291 22292 /**
22293 * This defines what cursor mode is used when the mouse cursor 22294 * is hovered over the displayObject. 22295 * 22296 * @example 22297 * const sprite = new PIXI.Sprite(texture); 22298 * sprite.interactive = true; 22299 * sprite.cursor = 'wait'; 22300 * @see https://developer.mozilla.org/en/docs/Web/CSS/cursor 22301 * 22302 * @member {string} 22303 * @memberof PIXI.DisplayObject# 22304 */ 22305 cursor: null, 22306 22307 /** 22308 * Internal set of all active pointers, by identifier 22309 * 22310 * @member {Map<number, InteractionTrackingData>} 22311 * @memberof PIXI.DisplayObject# 22312 * @private 22313 */ 22314 get trackedPointers() 22315 { 22316 if (this._trackedPointers === undefined) { this._trackedPointers = {}; } 22317 22318 return this._trackedPointers; 22319 }, 22320 22321 /** 22322 * Map of all tracked pointers, by identifier. Use trackedPointers to access. 22323 * 22324 * @private 22325 * @type {Map<number, InteractionTrackingData>} 22326 */ 22327 _trackedPointers: undefined, 22328 }; 22329 22330 // Mix interactiveTarget into DisplayObject.prototype, 22331 // after deprecation has been handled 22332 DisplayObject.mixin(interactiveTarget); 22333 22334 var MOUSE_POINTER_ID = 1; 22335 22336 // helpers for hitTest() - only used inside hitTest() 22337 var hitTestEvent = { 22338 target: null, 22339 data: { 22340 global: null, 22341 }, 22342 }; 22343 22344 /** 22345 * The interaction manager deals with mouse, touch and pointer events. 22346 * 22347 * Any DisplayObject can be interactive if its `interactive` property is set to true. 22348 * 22349 * This manager also supports multitouch. 22350 * 22351 * An instance of this class is automatically created by default, and can be found at `renderer.plugins.interaction` 22352 * 22353 * @class 22354 * @extends PIXI.utils.EventEmitter 22355 * @memberof PIXI.interaction 22356 */ 22357 var InteractionManager = /*@__PURE__*/(function (EventEmitter) { 22358 function InteractionManager(renderer, options) 22359 { 22360 EventEmitter.call(this); 22361 22362 options = options || {}; 22363 22364 /** 22365 * The renderer this interaction manager works for. 22366 * 22367 * @member {PIXI.AbstractRenderer} 22368 */ 22369 this.renderer = renderer; 22370 22371 /** 22372 * Should default browser actions automatically be prevented. 22373 * Does not apply to pointer events for backwards compatibility 22374 * preventDefault on pointer events stops mouse events from firing 22375 * Thus, for every pointer event, there will always be either a mouse of touch event alongside it. 22376 * 22377 * @member {boolean} 22378 * @default true 22379 */ 22380 this.autoPreventDefault = options.autoPreventDefault !== undefined ? options.autoPreventDefault : true; 22381 22382 /** 22383 * Frequency in milliseconds that the mousemove, mouseover & mouseout interaction events will be checked. 22384 * 22385 * @member {number} 22386 * @default 10 22387 */ 22388 this.interactionFrequency = options.interactionFrequency || 10; 22389 22390 /** 22391 * The mouse data 22392 * 22393 * @member {PIXI.interaction.InteractionData} 22394 */ 22395 this.mouse = new InteractionData(); 22396 this.mouse.identifier = MOUSE_POINTER_ID; 22397 22398 // setting the mouse to start off far off screen will mean that mouse over does 22399 // not get called before we even move the mouse. 22400 this.mouse.global.set(-999999); 22401 22402 /** 22403 * Actively tracked InteractionData 22404 * 22405 * @private 22406 * @member {Object.<number,PIXI.interaction.InteractionData>} 22407 */ 22408 this.activeInteractionData = {}; 22409 this.activeInteractionData[MOUSE_POINTER_ID] = this.mouse; 22410 22411 /** 22412 * Pool of unused InteractionData 22413 * 22414 * @private 22415 * @member {PIXI.interaction.InteractionData[]} 22416 */ 22417 this.interactionDataPool = []; 22418 22419 /** 22420 * An event data object to handle all the event tracking/dispatching 22421 * 22422 * @member {object} 22423 */ 22424 this.eventData = new InteractionEvent(); 22425 22426 /** 22427 * The DOM element to bind to. 22428 * 22429 * @protected 22430 * @member {HTMLElement} 22431 */ 22432 this.interactionDOMElement = null; 22433 22434 /** 22435 * This property determines if mousemove and touchmove events are fired only when the cursor 22436 * is over the object. 22437 * Setting to true will make things work more in line with how the DOM ver
22437sion works. 22438 * Setting to false can make things easier for things like dragging 22439 * It is currently set to false as this is how PixiJS used to work. This will be set to true in 22440 * future versions of pixi. 22441 * 22442 * @member {boolean} 22443 * @default false 22444 */ 22445 this.moveWhenInside = false; 22446 22447 /** 22448 * Have events been attached to the dom element? 22449 * 22450 * @protected 22451 * @member {boolean} 22452 */ 22453 this.eventsAdded = false; 22454 22455 /** 22456 * Is the mouse hovering over the renderer? 22457 * 22458 * @protected 22459 * @member {boolean} 22460 */ 22461 this.mouseOverRenderer = false; 22462 22463 /** 22464 * Does the device support touch events 22465 * https://www.w3.org/TR/touch-events/ 22466 * 22467 * @readonly 22468 * @member {boolean} 22469 */ 22470 this.supportsTouchEvents = 'ontouchstart' in window; 22471 22472 /** 22473 * Does the device support pointer events 22474 * https://www.w3.org/Submission/pointer-events/ 22475 * 22476 * @readonly 22477 * @member {boolean} 22478 */ 22479 this.supportsPointerEvents = !!window.PointerEvent; 22480 22481 // this will make it so that you don't have to call bind all the time 22482 22483 /** 22484 * @private 22485 * @member {Function} 22486 */ 22487 this.onPointerUp = this.onPointerUp.bind(this); 22488 this.processPointerUp = this.processPointerUp.bind(this); 22489 22490 /** 22491 * @private 22492 * @member {Function} 22493 */ 22494 this.onPointerCancel = this.onPointerCancel.bind(this); 22495 this.processPointerCancel = this.processPointerCancel.bind(this); 22496 22497 /** 22498 * @private 22499 * @member {Function} 22500 */ 22501 this.onPointerDown = this.onPointerDown.bind(this); 22502 this.processPointerDown = this.processPointerDown.bind(this); 22503 22504 /** 22505 * @private 22506 * @member {Function} 22507 */ 22508 this.onPointerMove = this.onPointerMove.bind(this); 22509 this.processPointerMove = this.processPointerMove.bind(this); 22510 22511 /** 22512 * @private 22513 * @member {Function} 22514 */ 22515 this.onPointerOut = this.onPointerOut.bind(this); 22516 this.processPointerOverOut = this.processPointerOverOut.bind(this); 22517 22518 /** 22519 * @private 22520 * @member {Function} 22521 */ 22522 this.onPointerOver = this.onPointerOver.bind(this); 22523 22524 /** 22525 * Dictionary of how different cursor modes are handled. Strings are handled as CSS cursor 22526 * values, objects are handled as dictionaries of CSS values for interactionDOMElement, 22527 * and functions are called instead of changing the CSS. 22528 * Default CSS cursor values are provided for 'default' and 'pointer' modes. 22529 * @member {Object.<string, Object>} 22530 */ 22531 this.cursorStyles = { 22532 default: 'inherit', 22533 pointer: 'pointer', 22534 }; 22535 22536 /** 22537 * The mode of the cursor that is being used. 22538 * The value of this is a key from the cursorStyles dictionary. 22539 * 22540 * @member {string} 22541 */ 22542 this.currentCursorMode = null; 22543 22544 /** 22545 * Internal cached let. 22546 * 22547 * @private 22548 * @member {string} 22549 */ 22550 this.cursor = null; 22551 22552 /** 22553 * Internal cached let. 22554 * 22555 * @private 22556 * @member {PIXI.Point} 22557 */ 22558 this._tempPoint = new Point(); 22559 22560 /** 22561 * The current resolution / device pixel ratio. 22562 * 22563 * @member {number} 22564 * @default 1 22565 */ 22566 this.resolution = 1; 22567 22568 /** 22569 * Fired when a pointer device button (usually a mouse left-button) is pressed on the display 22570 * object. 22571 * 22572 * @event PIXI.interaction.InteractionManager#mousedown 22573 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22574 */ 22575 22576 /** 22577 * Fired when a pointer device secondary button (usually a mouse right-button) is pressed 22578 * on the display object. 22579 * 22580 * @event PIXI.interaction.InteractionManager#rightdown 22581 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22582 */ 22583 22584 /** 22585 * Fired when a pointer device button (usually a mouse left-button) is released over the display 22586 * object. 22587 * 22588 * @event PIXI.interaction.InteractionManager#mouseup 22589 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22590 */ 22591 22592 /** 22593 * Fired when a pointer device secondary button (usually a mouse right-button) is released 22594 * over the display object. 22595 * 22596 * @event PIXI.interaction.InteractionManager#rightup 22597 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22598 */ 22599 22600 /** 22601 * Fired when a pointer device button (usually a mouse left-button) is pressed and released on 22602 * the display object. 22603 * 22604 * @event PIXI.interaction.InteractionManager#click 22605 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22606 */ 22607 22608 /** 22609 * Fired when a pointer device secondary button (usually a mouse right-button) is pressed 22610 * and released on the display object. 22611 * 22612 * @event PIXI.interaction.InteractionManager#rightclick 22613 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22614 */ 22615 22616 /** 22617 * Fired when a pointer device button (usually a mouse left-button) is released outside the 22618 * display object that initially registered a 22619 * [mousedown]{@link PIXI.interaction.InteractionManager#event:mousedown}. 22620 * 22621 * @event PIXI.interaction.InteractionManager#mouseupoutside 22622 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22623 */ 22624 22625 /** 22626 * Fired when a pointer device secondary button (usually a mouse right-button) is released 22627 * outside the display object that initially registered a 22628 * [rightdown]{@link PIXI.interaction.InteractionManager#event:rightdown}. 22629 * 22630 * @event PIXI.interaction.InteractionManager#rightupoutside 22631 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22632 */ 22633 22634 /** 22635 * Fired when a pointer device (usually a mouse) is moved while over the display object 22636 * 22637 * @event PIXI.interaction.InteractionManager#mousemove 22638 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22639 */ 22640 22641 /** 22642 * Fired when a pointer device (usually a mouse) is moved onto the display object 22643 * 22644 * @event PIXI.interaction.InteractionManager#mouseover 22645 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22646 */ 22647 22648 /** 22649 * Fired when a pointer device (usually a mouse) is moved off the display object 22650 * 22651 * @event PIXI.interaction.InteractionManager#mouseout 22652 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22653 */ 22654 22655 /** 22656 * Fired when a pointer device button is pressed on the display object. 22657 * 22658 * @event PIXI.interaction.InteractionManager#pointerdown 22659 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22660 */ 22661 22662 /** 22663 * Fired when a pointer device button is released over the display object.
22664 * Not always fired when some buttons are held down while others are released. In those cases, 22665 * use [mousedown]{@link PIXI.interaction.InteractionManager#event:mousedown} and 22666 * [mouseup]{@link PIXI.interaction.InteractionManager#event:mouseup} instead. 22667 * 22668 * @event PIXI.interaction.InteractionManager#pointerup 22669 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22670 */ 22671 22672 /** 22673 * Fired when the operating system cancels a pointer event 22674 * 22675 * @event PIXI.interaction.InteractionManager#pointercancel 22676 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22677 */ 22678 22679 /** 22680 * Fired when a pointer device button is pressed and released on the display object. 22681 * 22682 * @event PIXI.interaction.InteractionManager#pointertap 22683 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22684 */ 22685 22686 /** 22687 * Fired when a pointer device button is released outside the display object that initially 22688 * registered a [pointerdown]{@link PIXI.interaction.InteractionManager#event:pointerdown}. 22689 * 22690 * @event PIXI.interaction.InteractionManager#pointerupoutside 22691 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22692 */ 22693 22694 /** 22695 * Fired when a pointer device is moved while over the display object 22696 * 22697 * @event PIXI.interaction.InteractionManager#pointermove 22698 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22699 */ 22700 22701 /** 22702 * Fired when a pointer device is moved onto the display object 22703 * 22704 * @event PIXI.interaction.InteractionManager#pointerover 22705 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22706 */ 22707 22708 /** 22709 * Fired when a pointer device is moved off the display object 22710 * 22711 * @event PIXI.interaction.InteractionManager#pointerout 22712 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22713 */ 22714 22715 /** 22716 * Fired when a touch point is placed on the display object. 22717 * 22718 * @event PIXI.interaction.InteractionManager#touchstart 22719 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22720 */ 22721 22722 /** 22723 * Fired when a touch point is removed from the display object. 22724 * 22725 * @event PIXI.interaction.InteractionManager#touchend 22726 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22727 */ 22728 22729 /** 22730 * Fired when the operating system cancels a touch 22731 * 22732 * @event PIXI.interaction.InteractionManager#touchcancel 22733 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22734 */ 22735 22736 /** 22737 * Fired when a touch point is placed and removed from the display object. 22738 * 22739 * @event PIXI.interaction.InteractionManager#tap 22740 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22741 */ 22742 22743 /** 22744 * Fired when a touch point is removed outside of the display object that initially 22745 * registered a [touchstart]{@link PIXI.interaction.InteractionManager#event:touchstart}. 22746 * 22747 * @event PIXI.interaction.InteractionManager#touchendoutside 22748 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22749 */ 22750 22751 /** 22752 * Fired when a touch point is moved along the display object. 22753 * 22754 * @event PIXI.interaction.InteractionManager#touchmove 22755 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22756 */ 22757 22758 /** 22759 * Fired when a pointer device button (usually a mouse left-button) is pressed on the display. 22760 * object. DisplayObject's `interactive` property must be set to `true` to fire event. 22761 * 22762 * @event PIXI.DisplayObject#mousedown 22763 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22764 */ 22765 22766 /** 22767 * Fired when a pointer device secondary button (usually a mouse right-button) is pressed 22768 * on the display object. DisplayObject's `interactive` property must be set to `true` to fire event. 22769 * 22770 * @event PIXI.DisplayObject#rightdown 22771 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22772 */ 22773 22774 /** 22775 * Fired when a pointer device button (usually a mouse left-button) is released over the display 22776 * object. DisplayObject's `interactive` property must be set to `true` to fire event. 22777 * 22778 * @event PIXI.DisplayObject#mouseup 22779 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22780 */ 22781 22782 /** 22783 * Fired when a pointer device secondary button (usually a mouse right-button) is released 22784 * over the display object. DisplayObject's `interactive` property must be set to `true` to fire event. 22785 * 22786 * @event PIXI.DisplayObject#rightup 22787 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22788 */ 22789 22790 /** 22791 * Fired when a pointer device button (usually a mouse left-button) is pressed and released on 22792 * the display object. DisplayObject's `interactive` property must be set to `true` to fire event. 22793 * 22794 * @event PIXI.DisplayObject#click 22795 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22796 */ 22797 22798 /** 22799 * Fired when a pointer device secondary button (usually a mouse right-button) is pressed 22800 * and released on the display object. DisplayObject's `interactive` property must be set to `true` to fire event. 22801 * 22802 * @event PIXI.DisplayObject#rightclick 22803 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22804 */ 22805 22806 /** 22807 * Fired when a pointer device button (usually a mouse left-button) is released outside the 22808 * display object that initially registered a 22809 * [mousedown]{@link PIXI.DisplayObject#event:mousedown}.
22810 * DisplayObject's `interactive` property must be set to `true` to fire event. 22811 * 22812 * @event PIXI.DisplayObject#mouseupoutside 22813 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22814 */ 22815 22816 /** 22817 * Fired when a pointer device secondary button (usually a mouse right-button) is released 22818 * outside the display object that initially registered a 22819 * [rightdown]{@link PIXI.DisplayObject#event:rightdown}. 22820 * DisplayObject's `interactive` property must be set to `true` to fire event. 22821 * 22822 * @event PIXI.DisplayObject#rightupoutside 22823 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22824 */ 22825 22826 /** 22827 * Fired when a pointer device (usually a mouse) is moved while over the display object. 22828 * DisplayObject's `interactive` property must be set to `true` to fire event. 22829 * 22830 * @event PIXI.DisplayObject#mousemove 22831 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22832 */ 22833 22834 /** 22835 * Fired when a pointer device (usually a mouse) is moved onto the display object. 22836 * DisplayObject's `interactive` property must be set to `true` to fire event. 22837 * 22838 * @event PIXI.DisplayObject#mouseover 22839 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22840 */ 22841 22842 /** 22843 * Fired when a pointer device (usually a mouse) is moved off the display object. 22844 * DisplayObject's `interactive` property must be set to `true` to fire event. 22845 * 22846 * @event PIXI.DisplayObject#mouseout 22847 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22848 */ 22849 22850 /** 22851 * Fired when a pointer device button is pressed on the display object. 22852 * DisplayObject's `interactive` property must be set to `true` to fire event. 22853 * 22854 * @event PIXI.DisplayObject#pointerdown 22855 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22856 */ 22857 22858 /** 22859 * Fired when a pointer device button is released over the display object. 22860 * DisplayObject's `interactive` property must be set to `true` to fire event. 22861 * 22862 * @event PIXI.DisplayObject#pointerup 22863 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22864 */ 22865 22866 /** 22867 * Fired when the operating system cancels a pointer event. 22868 * DisplayObject's `interactive` property must be set to `true` to fire event. 22869 * 22870 * @event PIXI.DisplayObject#pointercancel 22871 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22872 */ 22873 22874 /** 22875 * Fired when a pointer device button is pressed and released on the display object. 22876 * DisplayObject's `interactive` property must be set to `true` to fire event. 22877 * 22878 * @event PIXI.DisplayObject#pointertap 22879 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22880 */ 22881 22882 /** 22883 * Fired when a pointer device button is released outside the display object that initially 22884 * registered a [pointerdown]{@link PIXI.DisplayObject#event:pointerdown}. 22885 * DisplayObject's `interactive` property must be set to `true` to fire event. 22886 * 22887 * @event PIXI.DisplayObject#pointerupoutside 22888 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22889 */ 22890 22891 /** 22892 * Fired when a pointer device is moved while over the display object. 22893 * DisplayObject's `interactive` property must be set to `true` to fire event. 22894 * 22895 * @event PIXI.DisplayObject#pointermove 22896 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22897 */ 22898 22899 /** 22900 * Fired when a pointer device is moved onto the display object. 22901 * DisplayObject's `interactive` property must be set to `true` to fire event. 22902 * 22903 * @event PIXI.DisplayObject#pointerover 22904 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22905 */ 22906 22907 /** 22908 * Fired when a pointer device is moved off the display object.
22909 * DisplayObject's `interactive` property must be set to `true` to fire event. 22910 * 22911 * @event PIXI.DisplayObject#pointerout 22912 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22913 */ 22914 22915 /** 22916 * Fired when a touch point is placed on the display object. 22917 * DisplayObject's `interactive` property must be set to `true` to fire event. 22918 * 22919 * @event PIXI.DisplayObject#touchstart 22920 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22921 */ 22922 22923 /** 22924 * Fired when a touch point is removed from the display object. 22925 * DisplayObject's `interactive` property must be set to `true` to fire event. 22926 * 22927 * @event PIXI.DisplayObject#touchend 22928 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22929 */ 22930 22931 /** 22932 * Fired when the operating system cancels a touch. 22933 * DisplayObject's `interactive` property must be set to `true` to fire event. 22934 * 22935 * @event PIXI.DisplayObject#touchcancel 22936 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22937 */ 22938 22939 /** 22940 * Fired when a touch point is placed and removed from the display object. 22941 * DisplayObject's `interactive` property must be set to `true` to fire event. 22942 * 22943 * @event PIXI.DisplayObject#tap 22944 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22945 */ 22946 22947 /** 22948 * Fired when a touch point is removed outside of the display object that initially 22949 * registered a [touchstart]{@link PIXI.DisplayObject#event:touchstart}. 22950 * DisplayObject's `interactive` property must be set to `true` to fire event. 22951 * 22952 * @event PIXI.DisplayObject#touchendoutside 22953 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22954 */ 22955 22956 /** 22957 * Fired when a touch point is moved along the display object. 22958 * DisplayObject's `interactive` property must be set to `true` to fire event. 22959 * 22960 * @event PIXI.DisplayObject#touchmove 22961 * @param {PIXI.interaction.InteractionEvent} event - Interaction event 22962 */ 22963 22964 this.setTargetElement(this.renderer.view, this.renderer.resolution); 22965 } 22966 22967 if ( EventEmitter ) { InteractionManager.__proto__ = EventEmitter; } 22968 InteractionManager.prototype = Object.create( EventEmitter && EventEmitter.prototype ); 22969 InteractionManager.prototype.constructor = InteractionManager; 22970 22971 /** 22972 * Hit tests a point against the display tree, returning the first interactive object that is hit. 22973 * 22974 * @param {PIXI.Point} globalPoint - A point to hit test with, in global space. 22975 * @param {PIXI.Container} [root] - The root display object to start from. If omitted, defaults 22976 * to the last rendered root of the associated renderer. 22977 * @return {PIXI.DisplayObject} The hit display object, if any. 22978 */ 22979 InteractionManager.prototype.hitTest = function hitTest (globalPoint, root) 22980 { 22981 // clear the target for our hit test 22982 hitTestEvent.target = null; 22983 // assign the global point 22984 hitTestEvent.data.global = globalPoint; 22985 // ensure safety of the root 22986 if (!root) 22987 { 22988 root = this.renderer._lastObjectRendered; 22989 } 22990 // run the hit test 22991 this.processInteractive(hitTestEvent, root, null, true); 22992 // return our found object - it'll be null if we didn't hit anything 22993 22994 return hitTestEvent.target; 22995 }; 22996 22997 /** 22998 * Sets the DOM element which will receive mouse/touch events. This is useful for when you have 22999 * other DOM elements on top of the renderers Canvas element. With this you'll be bale to delegate 23000 * another DOM element to receive those events. 23001 * 23002 * @param {HTMLCanvasElement} element - the DOM element which will receive mouse and touch events. 23003 * @param {number} [resolution=1] - The resolution / device pixel ratio of the new element (relative to the canvas). 23004 */ 23005 InteractionManager.prototype.setTargetElement = function setTargetElement (element, resolution) 23006 { 23007 if ( resolution === void 0 ) { resolution = 1; } 23008 23009 this.removeEvents(); 23010 23011 this.interactionDOMElement = element; 23012 23013 this.resolution = resolution; 23014 23015 this.addEvents(); 23016 }; 23017 23018 /** 23019 * Registers all the DOM events 23020 * 23021 * @private 23022 */ 23023 InteractionManager.prototype.addEvents = function addEvents () 23024 { 23025 if (!this.interactionDOMElement) 23026 { 23027 return; 23028 } 23029 23030 Ticker.system.add(this.update, this, UPDATE_PRIORITY.INTERACTION); 23031 23032 if (window.navigator.msPointerEnabled) 23033 { 23034 this.interactionDOMElement.style['-ms-content-zooming'] = 'none'; 23035 this.interactionDOMElement.style['-ms-touch-action'] = 'none'; 23036 } 23037 else if (this.supportsPointerEvents) 23038 { 23039 this.interactionDOMElement.style['touch-action'] = 'none'; 23040 } 23041 23042 /** 23043 * These events are added first, so that if pointer events are normalized, they are fired 23044 * in the same order as non-normalized events. ie. pointer event 1st, mouse / touch 2nd 23045 */ 23046 if (this.supportsPointerEvents) 23047 { 23048 window.document.addEventListener('pointermove', this.onPointerMove, true); 23049 this.interactionDOMElement.addEventListener('pointerdown', this.onPointerDown, true); 23050 // pointerout is fired in addition to pointerup (for touch events) and pointercancel 23051 // we already handle those, so for the purposes of what we do in onPointerOut, we only 23052 // care about the pointerleave event 23053 this.interactionDOMElement.addEventListener('pointerleave', this.onPointerOut, true); 23054 this.interactionDOMElement.addEventListener('pointerover', this.onPointerOver, true); 23055 window.addEventListener('pointercancel', this.onPointerCancel, true); 23056 window.addEventListener('pointerup', this.onPointerUp, true); 23057 } 23058 else 23059 { 23060 window.document.addEventListener('mousemove', this.onPointerMove, true); 23061 this.interactionDOMElement.addEventListener('mousedown', this.onPointerDown, true); 23062 this.interactionDOMElement.addEventListener('mouseout', this.onPointerOut, true); 23063 this.interactionDOMElement.addEventListener('mouseover', this.onPointerOver, true); 23064 window.addEventListener('mouseup', this.onPointerUp, true); 23065 } 23066 23067 // always look directly for touch events so that we can provide original data 23068 // In a future version we should change this to being just a fallback and rely solely on 23069 // PointerEvents whenever available 23070 if (this.supportsTouchEvents) 23071 { 23072 this.interactionDOMElement.addEventListener('touchstart', this.onPointerDown, true); 23073 this.interactionDOMElement.addEventListener('touchcancel', this.onPointerCancel, true); 23074 this.interactionDOMElement.addEventListener('touchend', this.onPointerUp, true); 23075 this.interactionDOMElement.addEventListener('touchmove', this.onPointerMove, true); 23076 } 23077 23078 this.eventsAdded = true; 23079 }; 23080 23081 /** 23082 * Removes all the DOM events that were previously registered 23083 * 23084 * @private 23085 */ 23086 InteractionManager.prototype.removeEvents = function removeEvents () 23087 { 23088 if (!this.interactionDOMElement) 23089 { 23090 return; 23091 } 23092 23093 Ticker.system.remove(this.update, this); 23094 23095 if (window.navigator.msPointerEnabled) 23096 { 23097 this.interactionDOMElement.style['-ms-content-zooming'] = ''; 23098 this.interactionDOMElement.style['-ms-touch-action'] = ''; 23099 } 23100 else if (this.supportsPointerEvents) 23101 { 23102 this.interactionDOMElement.style['touch-action'] = ''; 23103 } 23104 23105 if (this.supportsPointerEvents) 23106 { 23107 window.document.removeEventListener('pointermove', this.onPointerMove, true); 23108 this.interactionDOMElement.removeEventListener('pointerdown', this.onPointerDown, true); 23109 this.interactionDOMElement.removeEventListener('pointerleave', this.onPointerOut, true); 23110 this.interactionDOMElement.removeEventListener('pointerover', this.onPointerOver, true); 23111 window.removeEventListener('pointercancel', this.onPointerCancel, true); 23112 window.removeEventListener('pointerup', this.onPointerUp, true); 23113 } 23114 else 23115 { 23116 window.document.removeEventListener('mousemove', this.onPointerMove, true); 23117 this.interactionDOMElement.removeEventListener('mousedown', this.onPointerDown, true); 23118 this.interactionDOMElement.removeEventListener('mouseout', this.onPointerOut, true); 23119 this.interactionDOMElement.removeEventListener('mouseover', this.onPointerOver, true); 23120 window.removeEventListener('mouseup', this.onPointerUp, true); 23121 } 23122 23123 if (this.supportsTouchEvents) 23124 { 23125 this.interactionDOMElement.removeEventListener('touchstart', this.onPointerDown, true); 23126 this.interactionDOMElement.removeEventListener('touchcancel', this.onPointerCancel, true); 23127 this.interactionDOMElement.removeEventListener('touchend', this.onPointerUp, true); 23128 this.interactionDOMElement.removeEventListener('touchmove', this.onPointerMove, true); 23129 } 23130 23131 this.interactionDOMElement = null; 23132 23133 this.eventsAdded = false;
23134 }; 23135 23136 /** 23137 * Updates the state of interactive objects. 23138 * Invoked by a throttled ticker update from {@link PIXI.Ticker.system}. 23139 * 23140 * @param {number} deltaTime - time delta since last tick 23141 */ 23142 InteractionManager.prototype.update = function update (deltaTime) 23143 { 23144 this._deltaTime += deltaTime; 23145 23146 if (this._deltaTime < this.interactionFrequency) 23147 { 23148 return; 23149 } 23150 23151 this._deltaTime = 0; 23152 23153 if (!this.interactionDOMElement) 23154 { 23155 return; 23156 } 23157 23158 // if the user move the mouse this check has already been done using the mouse move! 23159 if (this.didMove) 23160 { 23161 this.didMove = false; 23162 23163 return; 23164 } 23165 23166 this.cursor = null; 23167 23168 // Resets the flag as set by a stopPropagation call. This flag is usually reset by a user interaction of any kind, 23169 // but there was a scenario of a display object moving under a static mouse cursor. 23170 // In this case, mouseover and mouseevents would not pass the flag test in dispatchEvent function 23171 for (var k in this.activeInteractionData) 23172 { 23173 // eslint-disable-next-line no-prototype-builtins 23174 if (this.activeInteractionData.hasOwnProperty(k)) 23175 { 23176 var interactionData = this.activeInteractionData[k]; 23177 23178 if (interactionData.originalEvent && interactionData.pointerType !== 'touch') 23179 { 23180 var interactionEvent = this.configureInteractionEventForDOMEvent( 23181 this.eventData, 23182 interactionData.originalEvent, 23183 interactionData 23184 ); 23185 23186 this.processInteractive( 23187 interactionEvent, 23188 this.renderer._lastObjectRendered, 23189 this.processPointerOverOut, 23190 true 23191 ); 23192 } 23193 } 23194 } 23195 23196 this.setCursorMode(this.cursor); 23197 23198 // TODO 23199 }; 23200 23201 /** 23202 * Sets the current cursor mode, handling any callbacks or CSS style changes. 23203 * 23204 * @param {string} mode - cursor mode, a key from the cursorStyles dictionary 23205 */ 23206 InteractionManager.prototype.setCursorMode = function setCursorMode (mode) 23207 { 23208 mode = mode || 'default'; 23209 // if the mode didn't actually change, bail early 23210 if (this.currentCursorMode === mode) 23211 { 23212 return; 23213 } 23214 this.currentCursorMode = mode; 23215 var style = this.cursorStyles[mode]; 23216 23217 // only do things if there is a cursor style for it 23218 if (style) 23219 { 23220 switch (typeof style) 23221 { 23222 case 'string': 23223 // string styles are handled as cursor CSS 23224 this.interactionDOMElement.style.cursor = style; 23225 break; 23226 case 'function': 23227 // functions are just called, and passed the cursor mode 23228 style(mode); 23229 break; 23230 case 'object': 23231 // if it is an object, assume that it is a dictionary of CSS styles, 23232 // apply it to the interactionDOMElement 23233 Object.assign(this.interactionDOMElement.style, style); 23234 break; 23235 } 23236 } 23237 else if (typeof mode === 'string' && !Object.prototype.hasOwnProperty.call(this.cursorStyles, mode)) 23238 { 23239 // if it mode is a string (not a Symbol) and cursorStyles doesn't have any entry 23240 // for the mode, then assume that the dev wants it to be CSS for the cursor. 23241 this.interactionDOMElement.style.cursor = mode; 23242 } 23243 }; 23244 23245 /** 23246 * Dispatches an event on the display object that was interacted with 23247 * 23248 * @param {PIXI.Container|PIXI.Sprite|PIXI.TilingSprite} displayObject - the display object in question 23249 * @param {string} eventString - the name of the event (e.g, mousedown) 23250 * @param {object} eventData - the event data object 23251 * @private 23252 */ 23253 InteractionManager.prototype.dispatchEvent = function dispatchEvent (displayObject, eventString, eventData) 23254 { 23255 if (!eventData.stopped) 23256 { 23257 eventData.currentTarget = displayObject; 23258 eventData.type = eventString; 23259 23260 displayObject.emit(eventString, eventData); 23261 23262 if (displayObject[eventString]) 23263 { 23264 displayObject[eventString](eventData); 23265 } 23266 } 23267 }; 23268 23269 /** 23270 * Maps x and y coords from a DOM object and maps them correctly to the PixiJS view. The 23271 * resulting value is stored in the point. This takes into account the fact that the DOM 23272 * element could be scaled and positioned anywhere on the screen. 23273 * 23274 * @param {PIXI.Point} point - the point that the result will be stored in 23275 * @param {number} x - the x coord of the position to map 23276 * @param {number} y - the y coord of the position to map 23277 */ 23278 InteractionManager.prototype.mapPositionToPoint = function mapPositionToPoint (point, x, y) 23279 { 23280 var rect; 23281 23282 // IE 11 fix 23283 if (!this.interactionDOMElement.parentElement) 23284 { 23285 rect = { x: 0, y: 0, width: 0, height: 0 }; 23286 } 23287 else 23288 { 23289 rect = this.interactionDOMElement.getBoundingClientRect(); 23290 } 23291 23292 var resolutionMultiplier = 1.0 / this.resolution; 23293 23294 point.x = ((x - rect.left) * (this.interactionDOMElement.width / rect.width)) * resolutionMultiplier; 23295 point.y = ((y - rect.top) * (this.interactionDOMElement.height / rect.height)) * resolutionMultiplier; 23296 }; 23297 23298 /** 23299 * This function is provides a neat way of crawling through the scene graph and running a 23300 * specified function on all interactive objects it finds. It will also take care of hit 23301 * testing the interactive objects and passes the hit across in the function. 23302 * 23303 * @protected 23304 * @param {PIXI.interaction.InteractionEvent} interactionEvent - event containing the point that 23305 * is tested for collision 23306 * @param {PIXI.Container|PIXI.Sprite|PIXI.TilingSprite} displayObject - the displayObject 23307 * that will be hit test (recursively crawls its children) 23308 * @param {Function} [func] - the function that will be called on each interactive object. The 23309 * interactionEvent, displayObject and hit will be passed to the function 23310 * @param {boolean} [hitTest] - this indicates if the objects inside should be hit test against the point 23311 * @param {boolean} [interactive] - Whether the displayObject is interactive 23312 * @return {boolean} returns true if the displayObject hit the point 23313 */ 23314 InteractionManager.prototype.processInteractive = function processInteractive (interactionEvent, displayObject, func, hitTest, interactive) 23315 { 23316 if (!displayObject || !displayObject.visible) 23317 { 23318 return false;
23319 } 23320 23321 var point = interactionEvent.data.global; 23322 23323 // Took a little while to rework this function correctly! But now it is done and nice and optimized! ^_^ 23324 // 23325 // This function will now loop through all objects and then only hit test the objects it HAS 23326 // to, not all of them. MUCH faster.. 23327 // An object will be hit test if the following is true: 23328 // 23329 // 1: It is interactive. 23330 // 2: It belongs to a parent that is interactive AND one of the parents children have not already been hit. 23331 // 23332 // As another little optimization once an interactive object has been hit we can carry on 23333 // through the scenegraph, but we know that there will be no more hits! So we can avoid extra hit tests 23334 // A final optimization is that an object is not hit test directly if a child has already been hit. 23335 23336 interactive = displayObject.interactive || interactive; 23337 23338 var hit = false; 23339 var interactiveParent = interactive; 23340 23341 // Flag here can set to false if the event is outside the parents hitArea or mask 23342 var hitTestChildren = true; 23343 23344 // If there is a hitArea, no need to test against anything else if the pointer is not within the hitArea 23345 // There is also no longer a need to hitTest children. 23346 if (displayObject.hitArea) 23347 { 23348 if (hitTest) 23349 { 23350 displayObject.worldTransform.applyInverse(point, this._tempPoint); 23351 if (!displayObject.hitArea.contains(this._tempPoint.x, this._tempPoint.y)) 23352 { 23353 hitTest = false; 23354 hitTestChildren = false; 23355 } 23356 else 23357 { 23358 hit = true; 23359 } 23360 } 23361 interactiveParent = false; 23362 } 23363 // If there is a mask, no need to test against anything else if the pointer is not within the mask 23364 else if (displayObject._mask) 23365 { 23366 if (hitTest) 23367 { 23368 if (!(displayObject._mask.containsPoint && displayObject._mask.containsPoint(point))) 23369 { 23370 hitTest = false; 23371 hitTestChildren = false; 23372 } 23373 } 23374 } 23375 23376 // ** FREE TIP **! If an object is not interactive or has no buttons in it 23377 // (such as a game scene!) set interactiveChildren to false for that displayObject. 23378 // This will allow PixiJS to completely ignore and bypass checking the displayObjects children. 23379 if (hitTestChildren && displayObject.interactiveChildren && displayObject.children) 23380 { 23381 var children = displayObject.children; 23382 23383 for (var i = children.length - 1; i >= 0; i--) 23384 { 23385 var child = children[i]; 23386 23387 // time to get recursive.. if this function will return if something is hit.. 23388 var childHit = this.processInteractive(interactionEvent, child, func, hitTest, interactiveParent); 23389 23390 if (childHit) 23391 { 23392 // its a good idea to check if a child has lost its parent. 23393 // this means it has been removed whilst looping so its best 23394 if (!child.parent) 23395 { 23396 continue; 23397 } 23398 23399 // we no longer need to hit test any more objects in this container as we we 23400 // now know the parent has been hit 23401 interactiveParent = false; 23402 23403 // If the child is interactive , that means that the object hit was actually 23404 // interactive and not just the child of an interactive object. 23405 // This means we no longer need to hit test anything else. We still need to run 23406 // through all objects, but we don't need to perform any hit tests. 23407 23408 if (childHit) 23409 { 23410 if (interactionEvent.target) 23411 { 23412 hitTest = false;
23413 } 23414 hit = true; 23415 } 23416 } 23417 } 23418 } 23419 23420 // no point running this if the item is not interactive or does not have an interactive parent. 23421 if (interactive) 23422 { 23423 // if we are hit testing (as in we have no hit any objects yet) 23424 // We also don't need to worry about hit testing if once of the displayObjects children 23425 // has already been hit - but only if it was interactive, otherwise we need to keep 23426 // looking for an interactive child, just in case we hit one 23427 if (hitTest && !interactionEvent.target) 23428 { 23429 // already tested against hitArea if it is defined 23430 if (!displayObject.hitArea && displayObject.containsPoint) 23431 { 23432 if (displayObject.containsPoint(point)) 23433 { 23434 hit = true; 23435 } 23436 } 23437 } 23438 23439 if (displayObject.interactive) 23440 { 23441 if (hit && !interactionEvent.target) 23442 { 23443 interactionEvent.target = displayObject; 23444 } 23445 23446 if (func) 23447 { 23448 func(interactionEvent, displayObject, !!hit); 23449 } 23450 } 23451 } 23452 23453 return hit; 23454 }; 23455 23456 /** 23457 * Is called when the pointer button is pressed down on the renderer element 23458 * 23459 * @private 23460 * @param {PointerEvent} originalEvent - The DOM event of a pointer button being pressed down 23461 */ 23462 InteractionManager.prototype.onPointerDown = function onPointerDown (originalEvent) 23463 { 23464 // if we support touch events, then only use those for touch events, not pointer events 23465 if (this.supportsTouchEvents && originalEvent.pointerType === 'touch') { return; } 23466 23467 var events = this.normalizeToPointerData(originalEvent); 23468 23469 /** 23470 * No need to prevent default on natural pointer events, as there are no side effects 23471 * Normalized events, however, may have the double mousedown/touchstart issue on the native android browser, 23472 * so still need to be prevented. 23473 */ 23474 23475 // Guaranteed that there will be at least one event in events, and all events must have the same pointer type 23476 23477 if (this.autoPreventDefault && events[0].isNormalized) 23478 { 23479 var cancelable = originalEvent.cancelable || !('cancelable' in originalEvent); 23480 23481 if (cancelable) 23482 { 23483 originalEvent.preventDefault(); 23484 } 23485 } 23486 23487 var eventLen = events.length; 23488 23489 for (var i = 0; i < eventLen; i++) 23490 { 23491 var event = events[i]; 23492 23493 var interactionData = this.getInteractionDataForPointerId(event); 23494 23495 var interactionEvent = this.configureInteractionEventForDOMEvent(this.eventData, event, interactionData); 23496 23497 interactionEvent.data.originalEvent = originalEvent; 23498 23499 this.processInteractive(interactionEvent, this.renderer._lastObjectRendered, this.processPointerDown, true); 23500 23501 this.emit('pointerdown', interactionEvent); 23502 if (event.pointerType === 'touch') 23503 { 23504 this.emit('touchstart', interactionEvent); 23505 } 23506 // emit a mouse event for "pen" pointers, the way a browser would emit a fallback event 23507 else if (event.pointerType === 'mouse' || event.pointerType === 'pen') 23508 { 23509 var isRightButton = event.button === 2; 23510 23511 this.emit(isRightButton ? 'rightdown' : 'mousedown', this.eventData); 23512 } 23513 } 23514 }; 23515 23516 /** 23517 * Processes the result of the pointer down check and dispatches the event if need be 23518 * 23519 * @private 23520 * @param {PIXI.interaction.InteractionEvent} interactionEvent - The interaction event wrapping the DOM event 23521 * @param {PIXI.Container|PIXI.Sprite|PIXI.TilingSprite} displayObject - The display object that was tested 23522 * @param {boolean} hit - the result of the hit test on the display object 23523 */ 23524 InteractionManager.prototype.processPointerDown = function processPointerDown (interactionEvent, displayObject, hit) 23525 { 23526 var data = interactionEvent.data; 23527 var id = interactionEvent.data.identifier; 23528 23529 if (hit) 23530 { 23531 if (!displayObject.trackedPointers[id]) 23532 { 23533 displayObject.trackedPointers[id] = new InteractionTrackingData(id); 23534 } 23535 this.dispatchEvent(displayObject, 'pointerdown', interactionEvent); 23536 23537 if (data.pointerType === 'touch') 23538 { 23539 this.dispatchEvent(displayObject, 'touchstart', interactionEvent); 23540 } 23541 else if (data.pointerType === 'mouse' || data.pointerType === 'pen') 23542 { 23543 var isRightButton = data.button === 2; 23544 23545 if (isRightButton) 23546 { 23547 displayObject.trackedPointers[id].rightDown = true; 23548 } 23549 else 23550 { 23551 displayObject.trackedPointers[id].leftDown = true; 23552 } 23553 23554 this.dispatchEvent(displayObject, isRightButton ? 'rightdown' : 'mousedown', interactionEvent); 23555 } 23556 } 23557 }; 23558 23559 /** 23560 * Is called when the pointer button is released on the renderer element 23561 * 23562 * @private 23563 * @param {PointerEvent} originalEvent - The DOM event of a pointer button being released 23564 * @param {boolean} cancelled - true if the pointer is cancelled 23565 * @param {Function} func - Function passed to {@link processInteractive} 23566 */ 23567 InteractionManager.prototype.onPointerComplete = function onPointerComplete (originalEvent, cancelled, func) 23568 { 23569 var events = this.normalizeToPointerData(originalEvent); 23570 23571 var eventLen = events.length; 23572 23573 // if the event wasn't targeting our canvas, then consider it to be pointerupoutside 23574 // in all cases (unless it was a pointercancel) 23575 var eventAppend = originalEvent.target !== this.interactionDOMElement ? 'outside' : ''; 23576 23577 for (var i = 0; i < eventLen; i++) 23578 { 23579 var event = events[i]; 23580 23581 var interactionData = this.getInteractionDataForPointerId(event); 23582 23583 var interactionEvent = this.configureInteractionEventForDOMEvent(this.eventData, event, interactionData); 23584 23585 interactionEvent.data.originalEvent = originalEvent; 23586 23587 // perform hit testing for events targeting our canvas or cancel events 23588 this.processInteractive(interactionEvent, this.renderer._lastObjectRendered, func, cancelled || !eventAppend); 23589
23590 this.emit(cancelled ? 'pointercancel' : ("pointerup" + eventAppend), interactionEvent); 23591 23592 if (event.pointerType === 'mouse' || event.pointerType === 'pen') 23593 { 23594 var isRightButton = event.button === 2; 23595 23596 this.emit(isRightButton ? ("rightup" + eventAppend) : ("mouseup" + eventAppend), interactionEvent); 23597 } 23598 else if (event.pointerType === 'touch') 23599 { 23600 this.emit(cancelled ? 'touchcancel' : ("touchend" + eventAppend), interactionEvent); 23601 this.releaseInteractionDataForPointerId(event.pointerId, interactionData); 23602 } 23603 } 23604 }; 23605 23606 /** 23607 * Is called when the pointer button is cancelled 23608 * 23609 * @private 23610 * @param {PointerEvent} event - The DOM event of a pointer button being released 23611 */ 23612 InteractionManager.prototype.onPointerCancel = function onPointerCancel (event) 23613 { 23614 // if we support touch events, then only use those for touch events, not pointer events 23615 if (this.supportsTouchEvents && event.pointerType === 'touch') { return; } 23616 23617 this.onPointerComplete(event, true, this.processPointerCancel); 23618 }; 23619 23620 /** 23621 * Processes the result of the pointer cancel check and dispatches the event if need be 23622 * 23623 * @private 23624 * @param {PIXI.interaction.InteractionEvent} interactionEvent - The interaction event wrapping the DOM event 23625 * @param {PIXI.Container|PIXI.Sprite|PIXI.TilingSprite} displayObject - The display object that was tested 23626 */ 23627 InteractionManager.prototype.processPointerCancel = function processPointerCancel (interactionEvent, displayObject) 23628 { 23629 var data = interactionEvent.data; 23630 23631 var id = interactionEvent.data.identifier; 23632 23633 if (displayObject.trackedPointers[id] !== undefined) 23634 { 23635 delete displayObject.trackedPointers[id]; 23636 this.dispatchEvent(displayObject, 'pointercancel', interactionEvent); 23637 23638 if (data.pointerType === 'touch') 23639 { 23640 this.dispatchEvent(displayObject, 'touchcancel', interactionEvent); 23641 } 23642 } 23643 }; 23644 23645 /** 23646 * Is called when the pointer button is released on the renderer element 23647 * 23648 * @private 23649 * @param {PointerEvent} event - The DOM event of a pointer button being released 23650 */ 23651 InteractionManager.prototype.onPointerUp = function onPointerUp (event) 23652 { 23653 // if we support touch events, then only use those for touch events, not pointer events 23654 if (this.supportsTouchEvents && event.pointerType === 'touch') { return; } 23655 23656 this.onPointerComplete(event, false, this.processPointerUp); 23657 }; 23658 23659 /** 23660 * Processes the result of the pointer up check and dispatches the event if need be 23661 * 23662 * @private 23663 * @param {PIXI.interaction.InteractionEvent} interactionEvent - The interaction event wrapping the DOM event 23664 * @param {PIXI.Container|PIXI.Sprite|PIXI.TilingSprite} displayObject - The display object that was tested 23665 * @param {boolean} hit - the result of the hit test on the display object 23666 */ 23667 InteractionManager.prototype.processPointerUp = function processPointerUp (interactionEvent, displayObject, hit) 23668 { 23669 var data = interactionEvent.data; 23670 23671 var id = interactionEvent.data.identifier; 23672 23673 var trackingData = displayObject.trackedPointers[id]; 23674 23675 var isTouch = data.pointerType === 'touch'; 23676 23677 var isMouse = (data.pointerType === 'mouse' || data.pointerType === 'pen'); 23678 // need to track mouse down status in the mouse block so that we can emit 23679 // event in a later block 23680 var isMouseTap = false; 23681 23682 // Mouse only 23683 if (isMouse) 23684 { 23685 var isRightButton = data.button === 2; 23686 23687 var flags = InteractionTrackingData.FLAGS; 23688 23689 var test = isRightButton ? flags.RIGHT_DOWN : flags.LEFT_DOWN; 23690 23691 var isDown = trackingData !== undefined && (trackingData.flags & test); 23692 23693 if (hit) 23694 { 23695 this.dispatchEvent(displayObject, isRightButton ? 'rightup' : 'mouseup', interactionEvent); 23696 23697 if (isDown) 23698 { 23699 this.dispatchEvent(displayObject, isRightButton ? 'rightclick' : 'click', interactionEvent); 23700 // because we can confirm that the mousedown happened on this object, flag for later emit of pointertap 23701 isMouseTap = true; 23702 } 23703 } 23704 else if (isDown) 23705 { 23706 this.dispatchEvent(displayObject, isRightButton ? 'rightupoutside' : 'mouseupoutside', interactionEvent); 23707 } 23708 // update the down state of the tracking data 23709 if (trackingData) 23710 { 23711 if (isRightButton) 23712 { 23713 trackingData.rightDown = false;
23714 } 23715 else 23716 { 23717 trackingData.leftDown = false; 23718 } 23719 } 23720 } 23721 23722 // Pointers and Touches, and Mouse 23723 if (hit) 23724 { 23725 this.dispatchEvent(displayObject, 'pointerup', interactionEvent); 23726 if (isTouch) { this.dispatchEvent(displayObject, 'touchend', interactionEvent); } 23727 23728 if (trackingData) 23729 { 23730 // emit pointertap if not a mouse, or if the mouse block decided it was a tap 23731 if (!isMouse || isMouseTap) 23732 { 23733 this.dispatchEvent(displayObject, 'pointertap', interactionEvent); 23734 } 23735 if (isTouch) 23736 { 23737 this.dispatchEvent(displayObject, 'tap', interactionEvent); 23738 // touches are no longer over (if they ever were) when we get the touchend 23739 // so we should ensure that we don't keep pretending that they are 23740 trackingData.over = false; 23741 } 23742 } 23743 } 23744 else if (trackingData) 23745 { 23746 this.dispatchEvent(displayObject, 'pointerupoutside', interactionEvent); 23747 if (isTouch) { this.dispatchEvent(displayObject, 'touchendoutside', interactionEvent); } 23748 } 23749 // Only remove the tracking data if there is no over/down state still associated with it 23750 if (trackingData && trackingData.none) 23751 { 23752 delete displayObject.trackedPointers[id]; 23753 } 23754 }; 23755 23756 /** 23757 * Is called when the pointer moves across the renderer element 23758 * 23759 * @private 23760 * @param {PointerEvent} originalEvent - The DOM event of a pointer moving 23761 */ 23762 InteractionManager.prototype.onPointerMove = function onPointerMove (originalEvent) 23763 { 23764 // if we support touch events, then only use those for touch events, not pointer events 23765 if (this.supportsTouchEvents && originalEvent.pointerType === 'touch') { return; } 23766 23767 var events = this.normalizeToPointerData(originalEvent); 23768 23769 if (events[0].pointerType === 'mouse' || events[0].pointerType === 'pen') 23770 { 23771 this.didMove = true; 23772 23773 this.cursor = null; 23774 } 23775 23776 var eventLen = events.length; 23777 23778 for (var i = 0; i < eventLen; i++) 23779 { 23780 var event = events[i]; 23781 23782 var interactionData = this.getInteractionDataForPointerId(event); 23783 23784 var interactionEvent = this.configureInteractionEventForDOMEvent(this.eventData, event, interactionData); 23785 23786 interactionEvent.data.originalEvent = originalEvent; 23787 23788 var interactive = event.pointerType === 'touch' ? this.moveWhenInside : true; 23789 23790 this.processInteractive( 23791 interactionEvent, 23792 this.renderer._lastObjectRendered, 23793 this.processPointerMove, 23794 interactive 23795 ); 23796 this.emit('pointermove', interactionEvent); 23797 if (event.pointerType === 'touch') { this.emit('touchmove', interactionEvent); } 23798 if (event.pointerType === 'mouse' || event.pointerType === 'pen') { this.emit('mousemove', interactionEvent); } 23799 } 23800 23801 if (events[0].pointerType === 'mouse') 23802 { 23803 this.setCursorMode(this.cursor); 23804 23805 // TODO BUG for parents interactive object (border order issue) 23806 } 23807 }; 23808 23809 /** 23810 * Processes the result of the pointer move check and dispatches the event if need be 23811 * 23812 * @private 23813 * @param {PIXI.interaction.InteractionEvent} interactionEvent - The interaction event wrapping the DOM event 23814 * @param {PIXI.Container|PIXI.Sprite|PIXI.TilingSprite} displayObject - The display object that was tested 23815 * @param {boolean} hit - the result of the hit test on the display object 23816 */ 23817 InteractionManager.prototype.processPointerMove = function processPointerMove (interactionEvent, displayObject, hit) 23818 { 23819 var data = interactionEvent.data; 23820 23821 var isTouch = data.pointerType === 'touch'; 23822 23823 var isMouse = (data.pointerType === 'mouse' || data.pointerType === 'pen'); 23824 23825 if (isMouse) 23826 { 23827 this.processPointerOverOut(interactionEvent, displayObject, hit); 23828 } 23829 23830 if (!this.moveWhenInside || hit) 23831 { 23832 this.dispatchEvent(displayObject, 'pointermove', interactionEvent); 23833 if (isTouch) { this.dispatchEvent(displayObject, 'touchmove', interactionEvent); } 23834 if (isMouse) { this.dispatchEvent(displayObject, 'mousemove', interactionEvent); } 23835 } 23836 }; 23837 23838 /** 23839 * Is called when the pointer is moved out of the renderer element 23840 * 23841 * @private 23842 * @param {PointerEvent} originalEvent - The DOM event of a pointer being moved out 23843 */ 23844 InteractionManager.prototype.onPointerOut = function onPointerOut (originalEvent) 23845 { 23846 // if we support touch events, then only use those for touch events, not pointer events 23847 if (this.supportsTouchEvents && originalEvent.pointerType === 'touch') { return; } 23848 23849 var events = this.normalizeToPointerData(originalEvent); 23850 23851 // Only mouse and pointer can call onPointerOut, so events will always be length 1 23852 var event = events[0]; 23853 23854 if (event.pointerType === 'mouse') 23855 { 23856 this.mouseOverRenderer = false;
23857 this.setCursorMode(null); 23858 } 23859 23860 var interactionData = this.getInteractionDataForPointerId(event); 23861 23862 var interactionEvent = this.configureInteractionEventForDOMEvent(this.eventData, event, interactionData); 23863 23864 interactionEvent.data.originalEvent = event; 23865 23866 this.processInteractive(interactionEvent, this.renderer._lastObjectRendered, this.processPointerOverOut, false); 23867 23868 this.emit('pointerout', interactionEvent); 23869 if (event.pointerType === 'mouse' || event.pointerType === 'pen') 23870 { 23871 this.emit('mouseout', interactionEvent); 23872 } 23873 else 23874 { 23875 // we can get touchleave events after touchend, so we want to make sure we don't 23876 // introduce memory leaks 23877 this.releaseInteractionDataForPointerId(interactionData.identifier); 23878 } 23879 }; 23880 23881 /** 23882 * Processes the result of the pointer over/out check and dispatches the event if need be 23883 * 23884 * @private 23885 * @param {PIXI.interaction.InteractionEvent} interactionEvent - The interaction event wrapping the DOM event 23886 * @param {PIXI.Container|PIXI.Sprite|PIXI.TilingSprite} displayObject - The display object that was tested 23887 * @param {boolean} hit - the result of the hit test on the display object 23888 */ 23889 InteractionManager.prototype.processPointerOverOut = function processPointerOverOut (interactionEvent, displayObject, hit) 23890 { 23891 var data = interactionEvent.data; 23892 23893 var id = interactionEvent.data.identifier; 23894 23895 var isMouse = (data.pointerType === 'mouse' || data.pointerType === 'pen'); 23896 23897 var trackingData = displayObject.trackedPointers[id]; 23898 23899 // if we just moused over the display object, then we need to track that state 23900 if (hit && !trackingData) 23901 { 23902 trackingData = displayObject.trackedPointers[id] = new InteractionTrackingData(id); 23903 } 23904 23905 if (trackingData === undefined) { return; } 23906 23907 if (hit && this.mouseOverRenderer) 23908 { 23909 if (!trackingData.over) 23910 { 23911 trackingData.over = true; 23912 this.dispatchEvent(displayObject, 'pointerover', interactionEvent); 23913 if (isMouse) 23914 { 23915 this.dispatchEvent(displayObject, 'mouseover', interactionEvent); 23916 } 23917 } 23918 23919 // only change the cursor if it has not already been changed (by something deeper in the 23920 // display tree) 23921 if (isMouse && this.cursor === null) 23922 { 23923 this.cursor = displayObject.cursor; 23924 } 23925 } 23926 else if (trackingData.over) 23927 { 23928 trackingData.over = false; 23929 this.dispatchEvent(displayObject, 'pointerout', this.eventData); 23930 if (isMouse) 23931 { 23932 this.dispatchEvent(displayObject, 'mouseout', interactionEvent); 23933 } 23934 // if there is no mouse down information for the pointer, then it is safe to delete 23935 if (trackingData.none) 23936 { 23937 delete displayObject.trackedPointers[id]; 23938 } 23939 } 23940 }; 23941 23942 /** 23943 * Is called when the pointer is moved into the renderer element 23944 * 23945 * @private 23946 * @param {PointerEvent} originalEvent - The DOM event of a pointer button being moved into the renderer view 23947 */ 23948 InteractionManager.prototype.onPointerOver = function onPointerOver (originalEvent) 23949 { 23950 var events = this.normalizeToPointerData(originalEvent); 23951 23952 // Only mouse and pointer can call onPointerOver, so events will always be length 1 23953 var event = events[0]; 23954 23955 var interactionData = this.getInteractionDataForPointerId(event); 23956 23957 var interactionEvent = this.configureInteractionEventForDOMEvent(this.eventData, event, interactionData); 23958 23959 interactionEvent.data.originalEvent = event; 23960 23961 if (event.pointerType === 'mouse') 23962 { 23963 this.mouseOverRenderer = true; 23964 } 23965
23966 this.emit('pointerover', interactionEvent); 23967 if (event.pointerType === 'mouse' || event.pointerType === 'pen') 23968 { 23969 this.emit('mouseover', interactionEvent); 23970 } 23971 }; 23972 23973 /** 23974 * Get InteractionData for a given pointerId. Store that data as well 23975 * 23976 * @private 23977 * @param {PointerEvent} event - Normalized pointer event, output from normalizeToPointerData 23978 * @return {PIXI.interaction.InteractionData} - Interaction data for the given pointer identifier 23979 */ 23980 InteractionManager.prototype.getInteractionDataForPointerId = function getInteractionDataForPointerId (event) 23981 { 23982 var pointerId = event.pointerId; 23983 23984 var interactionData; 23985 23986 if (pointerId === MOUSE_POINTER_ID || event.pointerType === 'mouse') 23987 { 23988 interactionData = this.mouse; 23989 } 23990 else if (this.activeInteractionData[pointerId]) 23991 { 23992 interactionData = this.activeInteractionData[pointerId]; 23993 } 23994 else 23995 { 23996 interactionData = this.interactionDataPool.pop() || new InteractionData(); 23997 interactionData.identifier = pointerId; 23998 this.activeInteractionData[pointerId] = interactionData; 23999 } 24000 // copy properties from the event, so that we can make sure that touch/pointer specific 24001 // data is available 24002 interactionData.copyEvent(event); 24003 24004 return interactionData; 24005 }; 24006 24007 /** 24008 * Return unused InteractionData to the pool, for a given pointerId 24009 * 24010 * @private 24011 * @param {number} pointerId - Identifier from a pointer event 24012 */ 24013 InteractionManager.prototype.releaseInteractionDataForPointerId = function releaseInteractionDataForPointerId (pointerId) 24014 { 24015 var interactionData = this.activeInteractionData[pointerId]; 24016 24017 if (interactionData) 24018 { 24019 delete this.activeInteractionData[pointerId]; 24020 interactionData.reset(); 24021 this.interactionDataPool.push(interactionData); 24022 } 24023 }; 24024 24025 /** 24026 * Configure an InteractionEvent to wrap a DOM PointerEvent and InteractionData 24027 * 24028 * @private 24029 * @param {PIXI.interaction.InteractionEvent} interactionEvent - The event to be configured 24030 * @param {PointerEvent} pointerEvent - The DOM event that will be paired with the InteractionEvent 24031 * @param {PIXI.interaction.InteractionData} interactionData - The InteractionData that will be paired 24032 * with the InteractionEvent 24033 * @return {PIXI.interaction.InteractionEvent} the interaction event that was passed in 24034 */ 24035 InteractionManager.prototype.configureInteractionEventForDOMEvent = function configureInteractionEventForDOMEvent (interactionEvent, pointerEvent, interactionData) 24036 { 24037 interactionEvent.data = interactionData; 24038 24039 this.mapPositionToPoint(interactionData.global, pointerEvent.clientX, pointerEvent.clientY); 24040 24041 // Not really sure why this is happening, but it's how a previous version handled things 24042 if (pointerEvent.pointerType === 'touch') 24043 { 24044 pointerEvent.globalX = interactionData.global.x; 24045 pointerEvent.globalY = interactionData.global.y; 24046 } 24047 24048 interactionData.originalEvent = pointerEvent; 24049 interactionEvent.reset(); 24050 24051 return interactionEvent; 24052 }; 24053 24054 /** 24055 * Ensures that the original event object contains all data that a regular pointer event would have 24056 * 24057 * @private 24058 * @param {TouchEvent|MouseEvent|PointerEvent} event - The original event data from a touch or mouse event 24059 * @return {PointerEvent[]} An array containing a single normalized pointer event, in the case of a pointer 24060 * or mouse event, or a multiple normalized pointer events if there are multiple changed touches 24061 */ 24062 InteractionManager.prototype.normalizeToPointerData = function normalizeToPointerData (event) 24063 { 24064 var normalizedEvents = []; 24065 24066 if (this.supportsTouchEvents && event instanceof TouchEvent) 24067 { 24068 for (var i = 0, li = event.changedTouches.length; i < li; i++) 24069 { 24070 var touch = event.changedTouches[i]; 24071 24072 if (typeof touch.button === 'undefined') { touch.button = event.touches.length ? 1 : 0; } 24073 if (typeof touch.buttons === 'undefined') { touch.buttons = event.touches.length ? 1 : 0; } 24074 if (typeof touch.isPrimary === 'undefined') 24075 { 24076 touch.isPrimary = event.touches.length === 1 && event.type === 'touchstart'; 24077 } 24078 if (typeof touch.width === 'undefined') { touch.width = touch.radiusX || 1; } 24079 if (typeof touch.height === 'undefined') { touch.height = touch.radiusY || 1; } 24080 if (typeof touch.tiltX === 'undefined') { touch.tiltX = 0; } 24081 if (typeof touch.tiltY === 'undefined') { touch.tiltY = 0; } 24082 if (typeof touch.pointerType === 'undefined') { touch.pointerType = 'touch'; } 24083 if (typeof touch.pointerId === 'undefined') { touch.pointerId = touch.identifier || 0; } 24084 if (typeof touch.pressure === 'undefined') { touch.pressure = touch.force || 0.5; } 24085 if (typeof touch.twist === 'undefined') { touch.twist = 0; } 24086 if (typeof touch.tangentialPressure === 'undefined') { touch.tangentialPressure = 0; } 24087 // TODO: Remove these, as layerX/Y is not a standard, is deprecated, has uneven 24088 // support, and the fill ins are not quite the same 24089 // offsetX/Y might be okay, but is not the same as clientX/Y when the canvas's top 24090 // left is not 0,0 on the page 24091 if (typeof touch.layerX === 'undefined') { touch.layerX = touch.offsetX = touch.clientX; } 24092 if (typeof touch.layerY === 'undefined') { touch.layerY = touch.offsetY = touch.clientY; } 24093 24094 // mark the touch as normalized, just so that we know
24094we did it 24095 touch.isNormalized = true; 24096 24097 normalizedEvents.push(touch); 24098 } 24099 } 24100 // apparently PointerEvent subclasses MouseEvent, so yay 24101 else if (event instanceof MouseEvent && (!this.supportsPointerEvents || !(event instanceof window.PointerEvent))) 24102 { 24103 if (typeof event.isPrimary === 'undefined') { event.isPrimary = true; } 24104 if (typeof event.width === 'undefined') { event.width = 1; } 24105 if (typeof event.height === 'undefined') { event.height = 1; } 24106 if (typeof event.tiltX === 'undefined') { event.tiltX = 0; } 24107 if (typeof event.tiltY === 'undefined') { event.tiltY = 0; } 24108 if (typeof event.pointerType === 'undefined') { event.pointerType = 'mouse'; } 24109 if (typeof event.pointerId === 'undefined') { event.pointerId = MOUSE_POINTER_ID; } 24110 if (typeof event.pressure === 'undefined') { event.pressure = 0.5; } 24111 if (typeof event.twist === 'undefined') { event.twist = 0; } 24112 if (typeof event.tangentialPressure === 'undefined') { event.tangentialPressure = 0; } 24113 24114 // mark the mouse event as normalized, just so that we know
24114we did it 24115 event.isNormalized = true; 24116 24117 normalizedEvents.push(event); 24118 } 24119 else 24120 { 24121 normalizedEvents.push(event); 24122 } 24123 24124 return normalizedEvents; 24125 }; 24126 24127 /** 24128 * Destroys the interaction manager 24129 * 24130 */ 24131 InteractionManager.prototype.destroy = function destroy () 24132 { 24133 this.removeEvents(); 24134 24135 this.removeAllListeners(); 24136 24137 this.renderer = null; 24138 24139 this.mouse = null; 24140 24141 this.eventData = null; 24142 24143 this.interactionDOMElement = null; 24144 24145 this.onPointerDown = null; 24146 this.processPointerDown = null; 24147 24148 this.onPointerUp = null; 24149 this.processPointerUp = null; 24150 24151 this.onPointerCancel = null; 24152 this.processPointerCancel = null; 24153 24154 this.onPointerMove = null; 24155 this.processPointerMove = null; 24156 24157 this.onPointerOut = null; 24158 this.processPointerOverOut = null; 24159 24160 this.onPointerOver = null; 24161 24162 this._tempPoint = null; 24163 }; 24164 24165 return InteractionManager; 24166 }(eventemitter3)); 24167 24168 var interaction_es = ({ 24169 InteractionData: InteractionData, 24170 InteractionEvent: InteractionEvent, 24171 InteractionManager: InteractionManager, 24172 InteractionTrackingData: InteractionTrackingData, 24173 interactiveTarget: interactiveTarget 24174 }); 24175 24176 /*! 24177 * @pixi/graphics - v5.0.0-rc.3 24178 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 24179 * 24180 * @pixi/graphics is licensed under the MIT License. 24181 * http://www.opensource.org/licenses/mit-license 24182 */ 24183 24184 /** 24185 * Graphics curves resolution settings. If `adaptive` flag is set to `true`, 24186 * the resolution is calculated based on the curve's length to ensure better visual quality. 24187 * Adaptive draw works with `bezierCurveTo` and `quadraticCurveTo`. 24188 * 24189 * @static 24190 * @constant 24191 * @memberof PIXI 24192 * @name GRAPHICS_CURVES 24193 * @type {object} 24194 * @property {boolean} adaptive=false - flag indicating if the resolution should be adaptive 24195 * @property {number} maxLength=10 - maximal length of a single segment of the curve (if adaptive = false, ignored) 24196 * @property {number} minSegments=8 - minimal number of segments in the curve (if adaptive = false, ignored) 24197 * @property {number} maxSegments=2048 - maximal number of segments in the curve (if adaptive = false, ignored) 24198 */ 24199 var GRAPHICS_CURVES = { 24200 adaptive: true, 24201 maxLength: 10, 24202 minSegments: 8, 24203 maxSegments: 2048, 24204 _segmentsCount: function _segmentsCount(length, defaultSegments) 24205 { 24206 if ( defaultSegments === void 0 ) { defaultSegments = 20; } 24207 24208 if (!this.adaptive) 24209 { 24210 return defaultSegments; 24211 } 24212 24213 var result = Math.ceil(length / this.maxLength); 24214 24215 if (result < this.minSegments) 24216 { 24217 result = this.minSegments; 24218 } 24219 else if (result > this.maxSegments) 24220 { 24221 result = this.maxSegments; 24222 } 24223 24224 return result; 24225 }, 24226 }; 24227 24228 /** 24229 * Fill style object for Graphics. 24230 * 24231 * @class 24232 * @memberof PIXI 24233 */ 24234 var FillStyle = function FillStyle() 24235 { 24236 this.reset(); 24237 }; 24238 24239 /** 24240 * Clones the object 24241 * 24242 * @return {PIXI.FillStyle} 24243 */ 24244 FillStyle.prototype.clone = function clone () 24245 { 24246 var obj = new FillStyle(); 24247 24248 obj.color = this.color; 24249 obj.alpha = this.alpha; 24250 obj.texture = this.texture; 24251 obj.matrix = this.matrix; 24252 obj.visible = this.visible; 24253 24254 return obj; 24255 }; 24256 24257 /** 24258 * Reset 24259 */ 24260 FillStyle.prototype.reset = function reset () 24261 { 24262 /** 24263 * The hex color value used when coloring the Graphics object. 24264 * 24265 * @member {number} 24266 * @default 1 24267 */ 24268 this.color = 0xFFFFFF; 24269 24270 /** 24271 * The alpha value used when filling the Graphics object. 24272 * 24273 * @member {number} 24274 * @default 1 24275 */ 24276 this.alpha = 1; 24277 24278 /** 24279 * The texture to be used for the fill. 24280 * 24281 * @member {string} 24282 * @default 0 24283 */ 24284 this.texture = Texture.WHITE; 24285 24286 /** 24287 * The transform aplpied to the texture. 24288 * 24289 * @member {string} 24290 * @default 0 24291 */ 24292 this.matrix = null; 24293 24294 /** 24295 * If the current fill is visible. 24296 * 24297 * @member {boolean} 24298 * @default false 24299 */ 24300 this.visible = false;
24301 }; 24302 24303 /** 24304 * Destroy and don't use after this 24305 */ 24306 FillStyle.prototype.destroy = function destroy () 24307 { 24308 this.texture = null; 24309 this.matrix = null; 24310 }; 24311 24312 /** 24313 * A class to contain data useful for Graphics objects 24314 * 24315 * @class 24316 * @memberof PIXI 24317 */ 24318 var GraphicsData = function GraphicsData(shape, fillStyle, lineStyle, matrix) 24319 { 24320 if ( fillStyle === void 0 ) { fillStyle = null; } 24321 if ( lineStyle === void 0 ) { lineStyle = null; } 24322 if ( matrix === void 0 ) { matrix = null; } 24323 24324 /** 24325 * The shape object to draw. 24326 * @member {PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.Rectangle|PIXI.RoundedRectangle} 24327 */ 24328 this.shape = shape; 24329 24330 /** 24331 * The style of the line. 24332 * @member {PIXI.LineStyle} 24333 */ 24334 this.lineStyle = lineStyle; 24335 24336 /** 24337 * The style of the fill. 24338 * @member {PIXI.FillStyle} 24339 */ 24340 this.fillStyle = fillStyle; 24341 24342 /** 24343 * The transform matrix. 24344 * @member {PIXI.Matrix} 24345 */ 24346 this.matrix = matrix; 24347 24348 /** 24349 * The type of the shape, see the Const.Shapes file for all the existing types, 24350 * @member {number} 24351 */ 24352 this.type = shape.type; 24353 24354 /** 24355 * The collection of points. 24356 * @member {number[]} 24357 */ 24358 this.points = []; 24359 24360 /** 24361 * The collection of holes. 24362 * @member {PIXI.GraphicsData[]} 24363 */ 24364 this.holes = []; 24365 }; 24366 24367 /** 24368 * Creates a new GraphicsData object with the same values as this one. 24369 * 24370 * @return {PIXI.GraphicsData} Cloned GraphicsData object 24371 */ 24372 GraphicsData.prototype.clone = function clone () 24373 { 24374 return new GraphicsData( 24375 this.shape, 24376 this.fillStyle, 24377 this.lineStyle, 24378 this.matrix 24379 ); 24380 }; 24381 24382 /** 24383 * Destroys the Graphics data. 24384 */ 24385 GraphicsData.prototype.destroy = function destroy () 24386 { 24387 this.shape = null; 24388 this.holes.length = 0; 24389 this.holes = null; 24390 this.points.length = 0; 24391 this.points = null; 24392 this.lineStyle = null; 24393 this.fillStyle = null; 24394 }; 24395 24396 /** 24397 * Builds a circle to draw 24398 * 24399 * Ignored from docs since it is not directly exposed. 24400 * 24401 * @ignore 24402 * @private 24403 * @param {PIXI.WebGLGraphicsData} graphicsData - The graphics object to draw 24404 * @param {object}
24404 webGLData - an object containing all the WebGL-specific information to create this shape 24405 * @param {object} webGLDataNativeLines - an object containing all the WebGL-specific information to create nativeLines 24406 */ 24407 var buildCircle = { 24408 24409 build: function build(graphicsData) 24410 { 24411 // need to convert points to a nice regular data 24412 var circleData = graphicsData.shape; 24413 var points = graphicsData.points; 24414 var x = circleData.x; 24415 var y = circleData.y; 24416 var width; 24417 var height; 24418 24419 points.length = 0; 24420 24421 // TODO - bit hacky?? 24422 if (graphicsData.type === SHAPES.CIRC) 24423 { 24424 width = circleData.radius; 24425 height = circleData.radius; 24426 } 24427 else 24428 { 24429 width = circleData.width; 24430 height = circleData.height; 24431 } 24432 24433 if (width === 0 || height === 0) 24434 { 24435 return; 24436 } 24437 24438 var totalSegs = Math.floor(30 * Math.sqrt(circleData.radius)) 24439 || Math.floor(15 * Math.sqrt(circleData.width + circleData.height)); 24440 24441 totalSegs /= 2.3; 24442 24443 var seg = (Math.PI * 2) / totalSegs; 24444 24445 for (var i = 0; i < totalSegs; i++) 24446 { 24447 points.push( 24448 x + (Math.sin(seg * i) * width), 24449 y + (Math.cos(seg * i) * height) 24450 ); 24451 } 24452 24453 points.push( 24454 points[0], 24455 points[1] 24456 ); 24457 }, 24458 24459 triangulate: function triangulate(graphicsData, graphicsGeometry) 24460 { 24461 var points = graphicsData.points; 24462 var verts = graphicsGeometry.points; 24463 var indices = graphicsGeometry.indices; 24464 24465 var vertPos = verts.length / 2; 24466 var center = vertPos; 24467 24468 verts.push(graphicsData.shape.x, graphicsData.shape.y); 24469 24470 for (var i = 0; i < points.length; i += 2) 24471 { 24472 verts.push(points[i], points[i + 1]); 24473 24474 // add some uvs 24475 indices.push(vertPos++, center, vertPos); 24476 } 24477 }, 24478 }; 24479 24480 /** 24481 * Builds a line to draw 24482 * 24483 * Ignored from docs since it is not directly exposed. 24484 * 24485 * @ignore 24486 * @private 24487 * @param {PIXI.GraphicsData} graphicsData - The graphics object containing all the necessary properties 24488 * @param {PIXI.GraphicsGeometry} graphicsGeometry - Geometry where to append output 24489 */ 24490 function buildLine (graphicsData, graphicsGeometry) 24491 { 24492 if (graphicsData.lineStyle.native) 24493 { 24494 buildNativeLine(graphicsData, graphicsGeometry); 24495 } 24496 else 24497 { 24498 buildLine$1(graphicsData, graphicsGeometry); 24499 } 24500 } 24501 24502 /** 24503 * Builds a line to draw using the polygon method. 24504 * 24505 * Ignored from docs since it is not directly exposed. 24506 * 24507 * @ignore 24508 * @private 24509 * @param {PIXI.GraphicsData} graphicsData - The graphics object containing all the necessary properties 24510 * @param {PIXI.GraphicsGeometry} graphicsGeometry - Geometry where to append output 24511 */ 24512 function buildLine$1(graphicsData, graphicsGeometry) 24513 { 24514 var shape = graphicsData.shape; 24515 var points = graphicsData.points || shape.points.slice(); 24516 24517 if (points.length === 0) 24518 { 24519 return; 24520 } 24521 // if the line width is an odd number add 0.5 to align to a whole pixel 24522 // commenting this out fixes #711 and #1620 24523 // if (graphicsData.lineWidth%2) 24524 // { 24525 // for (i = 0; i < points.length; i++) 24526 // { 24527 // points[i] += 0.5; 24528 // } 24529 // } 24530 24531 var style = graphicsData.lineStyle; 24532 24533 // get first and last point.. figure out the middle! 24534 var firstPoint = new Point(points[0], points[1]); 24535 var lastPoint = new Point(points[points.length - 2], points[points.length - 1]); 24536 var closedShape = shape.type !== SHAPES.POLY || shape.closeStroke; 24537 var closedPath = firstPoint.x === lastPoint.x && firstPoint.y === lastPoint.y; 24538 24539 // if the first point is the last point - gonna have issues :) 24540 if (closedShape) 24541 { 24542 // need to clone as we are going to slightly modify the shape.. 24543 points = points.slice(); 24544 24545 if (closedPath) 24546 { 24547 points.pop(); 24548 points.pop(); 24549 lastPoint.set(points[points.length - 2], points[points.length - 1]); 24550 } 24551 24552 var midPointX = lastPoint.x + ((firstPoint.x - lastPoint.x) * 0.5); 24553 var midPointY = lastPoint.y + ((firstPoint.y - lastPoint.y) * 0.5); 24554 24555 points.unshift(midPointX, midPointY); 24556 points.push(midPointX, midPointY); 24557 } 24558 24559 var verts = graphicsGeometry.points; 24560 var length = points.length / 2; 24561 var indexCount = points.length; 24562 var indexStart = verts.length / 2; 24563 24564 // DRAW the Line 24565 var width = style.width / 2; 24566 24567 // sort color 24568 var p1x = points[0]; 24569 var p1y = points[1]; 24570 var p2x = points[2]; 24571 var p2y = points[3]; 24572 var p3x = 0; 24573 var p3y = 0; 24574
24575 var perpx = -(p1y - p2y); 24576 var perpy = p1x - p2x; 24577 var perp2x = 0; 24578 var perp2y = 0; 24579 var perp3x = 0; 24580 var perp3y = 0; 24581 24582 var dist = Math.sqrt((perpx * perpx) + (perpy * perpy)); 24583 24584 perpx /= dist; 24585 perpy /= dist; 24586 perpx *= width; 24587 perpy *= width; 24588 24589 var ratio = style.alignment;// 0.5; 24590 var r1 = (1 - ratio) * 2; 24591 var r2 = ratio * 2; 24592 24593 // start 24594 verts.push( 24595 p1x - (perpx * r1), 24596 p1y - (perpy * r1)); 24597 24598 verts.push( 24599 p1x + (perpx * r2), 24600 p1y + (perpy * r2)); 24601 24602 for (var i = 1; i < length - 1; ++i) 24603 { 24604 p1x = points[(i - 1) * 2]; 24605 p1y = points[((i - 1) * 2) + 1]; 24606 24607 p2x = points[i * 2]; 24608 p2y = points[(i * 2) + 1]; 24609 24610 p3x = points[(i + 1) * 2]; 24611 p3y = points[((i + 1) * 2) + 1]; 24612 24613 perpx = -(p1y - p2y); 24614 perpy = p1x - p2x; 24615 24616 dist = Math.sqrt((perpx * perpx) + (perpy * perpy)); 24617 perpx /= dist; 24618 perpy /= dist; 24619 perpx *= width; 24620 perpy *= width; 24621 24622 perp2x = -(p2y - p3y); 24623 perp2y = p2x - p3x; 24624 24625 dist = Math.sqrt((perp2x * perp2x) + (perp2y * perp2y)); 24626 perp2x /= dist; 24627 perp2y /= dist; 24628 perp2x *= width; 24629 perp2y *= width; 24630 24631 var a1 = (-perpy + p1y) - (-perpy + p2y); 24632 var b1 = (-perpx + p2x) - (-perpx + p1x); 24633 var c1 = ((-perpx + p1x) * (-perpy + p2y)) - ((-perpx + p2x) * (-perpy + p1y)); 24634 var a2 = (-perp2y + p3y) - (-perp2y + p2y); 24635 var b2 = (-perp2x + p2x) - (-perp2x + p3x); 24636 var c2 = ((-perp2x + p3x) * (-perp2y + p2y)) - ((-perp2x + p2x) * (-perp2y + p3y)); 24637 24638 var denom = (a1 * b2) - (a2 * b1); 24639 24640 if (Math.abs(denom) < 0.1) 24641 { 24642 denom += 10.1; 24643 verts.push( 24644 p2x - (perpx * r1), 24645 p2y - (perpy * r1)); 24646 24647 verts.push( 24648 p2x + (perpx * r2), 24649 p2y + (perpy * r2)); 24650 24651 continue; 24652 } 24653 24654 var px = ((b1 * c2) - (b2 * c1)) / denom; 24655 var py = ((a2 * c1) - (a1 * c2)) / denom; 24656 var pdist = ((px - p2x) * (px - p2x)) + ((py - p2y) * (py - p2y)); 24657 24658 if (pdist > (196 * width * width)) 24659 { 24660 perp3x = perpx - perp2x; 24661 perp3y = perpy - perp2y; 24662 24663 dist = Math.sqrt((perp3x * perp3x) + (perp3y * perp3y)); 24664 perp3x /= dist; 24665 perp3y /= dist; 24666 perp3x *= width; 24667 perp3y *= width; 24668 24669 verts.push(p2x - (perp3x * r1), p2y - (perp3y * r1)); 24670 24671 verts.push(p2x + (perp3x * r2), p2y + (perp3y * r2)); 24672 24673 verts.push(p2x - (perp3x * r2 * r1), p2y - (perp3y * r1)); 24674 24675 indexCount++; 24676 } 24677 else 24678 { 24679 verts.push(p2x + ((px - p2x) * r1), p2y + ((py - p2y) * r1)); 24680 24681 verts.push(p2x - ((px - p2x) * r2), p2y - ((py - p2y) * r2)); 24682 } 24683 } 24684 24685 p1x = points[(length - 2) * 2]; 24686 p1y = points[((length - 2) * 2) + 1]; 24687 24688 p2x = points[(length - 1) * 2]; 24689 p2y = points[((length - 1) * 2) + 1]; 24690 24691 perpx = -(p1y - p2y); 24692 perpy = p1x - p2x; 24693 24694 dist = Math.sqrt((perpx * perpx) + (perpy * perpy)); 24695 perpx /= dist; 24696 perpy /= dist; 24697 perpx *= width; 24698 perpy *= width; 24699 24700 verts.push(p2x - (perpx * r1), p2y - (perpy * r1)); 24701 24702 verts.push(p2x + (perpx * r2), p2y + (perpy * r2)); 24703 24704 var indices = graphicsGeometry.indices; 24705 24706 // indices.push(indexStart); 24707 24708 for (var i$1 = 0; i$1 < indexCount - 2; ++i$1) 24709 { 24710 indices.push(indexStart, indexStart + 1, indexStart + 2); 24711 24712 indexStart++; 24713 } 24714 } 24715 24716 /** 24717 * Builds a line to draw using the gl.drawArrays(gl.LINES) method 24718 * 24719 * Ignored from docs since it is not directly exposed. 24720 * 24721 * @ignore 24722 * @private 24723 * @param {PIXI.GraphicsData} graphicsData - The graphics object containing all the necessary properties 24724 * @param {PIXI.GraphicsGeometry} graphicsGeometry - Geometry where to append output 24725 */ 24726 function buildNativeLine(graphicsData, graphicsGeometry) 24727 { 24728 var i = 0; 24729 24730 var points = graphicsData.points || graphicsData.shape.points; 24731 24732 if (points.length === 0) { return; } 24733 24734 var verts = graphicsGeometry.points; 24735 var indices = graphicsGeometry.indices; 24736 var length = points.length / 2; 24737 24738 var indexStart = verts.length / 2; 24739 // sort color 24740 24741 for (i = 1; i < length; i++) 24742 { 24743 var p1x = points[(i - 1) * 2]; 24744 var p1y = points[((i - 1) * 2) + 1]; 24745 24746 var p2x = points[i * 2]; 24747 var p2y = points[(i * 2) + 1]; 24748 24749 verts.push(p1x, p1y); 24750 24751 verts.push(p2x, p2y); 24752 24753 indices.push(indexStart++, indexStart++); 24754 } 24755 } 24756
24757 /** 24758 * Builds a polygon to draw 24759 * 24760 * Ignored from docs since it is not directly exposed. 24761 * 24762 * @ignore 24763 * @private 24764 * @param {PIXI.WebGLGraphicsData} graphicsData - The graphics object containing all the necessary properties 24765 * @param {object} webGLData - an object containing all the WebGL-specific information to create this shape 24766 * @param {object} webGLDataNativeLines - an object containing all the WebGL-specific information to create nativeLines 24767 */ 24768 var buildPoly = { 24769 24770 build: function build(graphicsData) 24771 { 24772 graphicsData.points = graphicsData.shape.points.slice(); 24773 }, 24774 24775 triangulate: function triangulate(graphicsData, graphicsGeometry) 24776 { 24777 var points = graphicsData.points; 24778 var holes = graphicsData.holes; 24779 var verts = graphicsGeometry.points; 24780 var indices = graphicsGeometry.indices; 24781 24782 if (points.length >= 6) 24783 { 24784 var holeArray = []; 24785 // Process holes.. 24786 24787 for (var i = 0; i < holes.length; i++) 24788 { 24789 var hole = holes[i]; 24790 24791 holeArray.push(points.length / 2); 24792 points = points.concat(hole.points); 24793 } 24794 24795 // sort color 24796 var triangles = earcut_1(points, holeArray, 2); 24797 24798 if (!triangles) 24799 { 24800 return; 24801 } 24802 24803 var vertPos = verts.length / 2; 24804 24805 for (var i$1 = 0; i$1 < triangles.length; i$1 += 3) 24806 { 24807 indices.push(triangles[i$1] + vertPos); 24808 indices.push(triangles[i$1 + 1] + vertPos); 24809 indices.push(triangles[i$1 + 2] + vertPos); 24810 } 24811 24812 for (var i$2 = 0; i$2 < points.length; i$2++) 24813 { 24814 verts.push(points[i$2]); 24815 } 24816 } 24817 }, 24818 }; 24819 24820 /** 24821 * Builds a rectangle to draw 24822 * 24823 * Ignored from docs since it is not directly exposed. 24824 * 24825 * @ignore 24826 * @private 24827 * @param {PIXI.WebGLGraphicsData} graphicsData - The graphics object containing all the necessary properties 24828 * @param {object}
24828 webGLData - an object containing all the WebGL-specific information to create this shape 24829 * @param {object} webGLDataNativeLines - an object containing all the WebGL-specific information to create nativeLines 24830 */ 24831 var buildRectangle = { 24832 24833 build: function build(graphicsData) 24834 { 24835 // --- // 24836 // need to convert points to a nice regular data 24837 // 24838 var rectData = graphicsData.shape; 24839 var x = rectData.x; 24840 var y = rectData.y; 24841 var width = rectData.width; 24842 var height = rectData.height; 24843 24844 var points = graphicsData.points; 24845 24846 points.length = 0; 24847 24848 points.push(x, y, 24849 x + width, y, 24850 x + width, y + height, 24851 x, y + height); 24852 }, 24853 24854 triangulate: function triangulate(graphicsData, graphicsGeometry) 24855 { 24856 var points = graphicsData.points; 24857 var verts = graphicsGeometry.points; 24858 24859 var vertPos = verts.length / 2; 24860 24861 verts.push(points[0], points[1], 24862 points[2], points[3], 24863 points[6], points[7], 24864 points[4], points[5]); 24865 24866 graphicsGeometry.indices.push(vertPos, vertPos + 1, vertPos + 2, 24867 vertPos + 1, vertPos + 2, vertPos + 3); 24868 }, 24869 }; 24870 24871 /** 24872 * Builds a rounded rectangle to draw 24873 * 24874 * Ignored from docs since it is not directly exposed. 24875 * 24876 * @ignore 24877 * @private 24878 * @param {PIXI.WebGLGraphicsData} graphicsData - The graphics object containing all the necessary properties 24879 * @param {object}
24879 webGLData - an object containing all the WebGL-specific information to create this shape 24880 * @param {object} webGLDataNativeLines - an object containing all the WebGL-specific information to create nativeLines 24881 */ 24882 var buildRoundedRectangle = { 24883 24884 build: function build(graphicsData) 24885 { 24886 var rrectData = graphicsData.shape; 24887 var points = graphicsData.points; 24888 var x = rrectData.x; 24889 var y = rrectData.y; 24890 var width = rrectData.width; 24891 var height = rrectData.height; 24892 24893 var radius = rrectData.radius; 24894 24895 points.length = 0; 24896 24897 points.push(x, y + radius); 24898 quadraticBezierCurve(x, y + height - radius, x, y + height, x + radius, y + height, points); 24899 quadraticBezierCurve(x + width - radius, y + height, x + width, y + height, x + width, y + height - radius, points); 24900 quadraticBezierCurve(x + width, y + radius, x + width, y, x + width - radius, y, points); 24901 quadraticBezierCurve(x + radius, y, x, y, x, y + radius + 0.0000000001, points); 24902 24903 // this tiny number deals with the issue that occurs when points overlap and earcut fails to triangulate the item. 24904 // TODO - fix this properly, this is not very elegant.. but it works for now. 24905 }, 24906 24907 triangulate: function triangulate(graphicsData, graphicsGeometry) 24908 { 24909 var points = graphicsData.points; 24910 24911 var verts = graphicsGeometry.points; 24912 var indices = graphicsGeometry.indices; 24913 24914 var vecPos = verts.length / 2; 24915 24916 var triangles = earcut_1(points, null, 2); 24917 24918 for (var i = 0, j = triangles.length; i < j; i += 3) 24919 { 24920 indices.push(triangles[i] + vecPos); 24921 // indices.push(triangles[i] + vecPos); 24922 indices.push(triangles[i + 1] + vecPos); 24923 // indices.push(triangles[i + 2] + vecPos); 24924 indices.push(triangles[i + 2] + vecPos); 24925 } 24926 24927 for (var i$1 = 0, j$1 = points.length; i$1 < j$1; i$1++) 24928 { 24929 verts.push(points[i$1], points[++i$1]); 24930 } 24931 }, 24932 }; 24933 24934 /** 24935 * Calculate a single point for a quadratic bezier curve. 24936 * Utility function used by quadraticBezierCurve. 24937 * Ignored from docs since it is not directly exposed. 24938 * 24939 * @ignore 24940 * @private 24941 * @param {number} n1 - first number 24942 * @param {number} n2 - second number 24943 * @param {number} perc - percentage 24944 * @return {number} the result 24945 * 24946 */ 24947 function getPt(n1, n2, perc) 24948 { 24949 var diff = n2 - n1; 24950 24951 return n1 + (diff * perc); 24952 } 24953 24954 /** 24955 * Calculate the points for a quadratic bezier curve. (helper function..) 24956 * Based on: https://stackoverflow.com/questions/785097/how-do-i-implement-a-bezier-curve-in-c 24957 * 24958 * Ignored from docs since it is not directly exposed. 24959 * 24960 * @ignore 24961 * @private 24962 * @param {number} fromX - Origin point x 24963 * @param {number} fromY - Origin point x 24964 * @param {number} cpX - Control point x 24965 * @param {number} cpY - Control point y 24966 * @param {number} toX - Destination point x 24967 * @param {number} toY - Destination point y 24968 * @param {number[]} [out=[]] - The output array to add points into. If not passed, a new array is created. 24969 * @return {number[]} an array of points 24970 */ 24971 function quadraticBezierCurve(fromX, fromY, cpX, cpY, toX, toY, out) 24972 { 24973 if ( out === void 0 ) { out = []; } 24974 24975 var n = 20; 24976 var points = out; 24977 24978 var xa = 0; 24979 var ya = 0; 24980 var xb = 0; 24981 var yb = 0; 24982 var x = 0; 24983 var y = 0; 24984 24985 for (var i = 0, j = 0; i <= n; ++i) 24986 { 24987 j = i / n; 24988 24989 // The Green Line 24990 xa = getPt(fromX, cpX, j); 24991 ya = getPt(fromY, cpY, j); 24992 xb = getPt(cpX, toX, j); 24993 yb = getPt(cpY, toY, j); 24994 24995 // The Black Dot 24996 x = getPt(xa, xb, j); 24997 y = getPt(ya, yb, j); 24998 24999 points.push(x, y); 25000 } 25001 25002 return points; 25003 } 25004 25005 var BATCH_POOL = []; 25006 var DRAW_CALL_POOL = []; 25007 25008 var TICK$1 = 0; 25009 /** 25010 * Map of fill commands for each shape type. 25011 * 25012 * @member {Object} 25013 * @private 25014 */ 25015 var fillCommands = {}; 25016 25017 fillCommands[SHAPES.POLY] = buildPoly; 25018 fillCommands[SHAPES.CIRC] = buildCircle; 25019 fillCommands[SHAPES.ELIP] = buildCircle; 25020 fillCommands[SHAPES.RECT] = buildRectangle; 25021 fillCommands[SHAPES.RREC] = buildRoundedRectangle; 25022 25023 /** 25024 * A little internal structure to hold interim batch objects. 25025 * 25026 * @private 25027 */ 25028 var BatchPart = function BatchPart() 25029 { 25030 this.style = null; 25031 this.size = 0; 25032 this.start = 0; 25033 this.attribStart = 0; 25034 this.attribSize = 0; 25035 }; 25036 25037 /** 25038 * The Graphics class contains methods used to draw primitive shapes such as lines, circles and 25039 * rectangles to the display, and to color and fill them. 25040 * 25041 * GraphicsGeometry is designed to not be continually updating the geometry since it's expensive 25042 * to re-tesselate using **earcut**. Consider using {@link PIXI.Mesh} for this use-case, it's much faster. 25043 * 25044 * @class 25045 * @extends PIXI.BatchGeometry 25046 * @memberof PIXI 25047 */ 25048 var GraphicsGeometry = /*@__PURE__*/(function (BatchGeometry) { 25049 function GraphicsGeometry() 25050 { 25051 BatchGeometry.call(this); 25052 25053 /** 25054 * An array of points to draw 25055 * 25056 * @member {PIXI.Point[]} 25057 * @protected 25058 */ 25059 this.points = []; 25060 25061 /** 25062 * The collection of colors 25063 * 25064 * @member {number[]} 25065 * @protected 25066 */ 25067 this.colors = []; 25068 25069 /** 25070 * The UVs collection 25071 * 25072 * @member {number[]} 25073 * @protected 25074 */ 25075 this.uvs = []; 25076 25077 /** 25078 * The indices of the vertices 25079 * 25080 * @member {number[]} 25081 * @protected 25082 */ 25083 this.indices = []; 25084 25085 /** 25086 * Reference to the texture IDs. 25087 * 25088 * @member {number[]} 25089 * @protected 25090 */ 25091 this.textureIds = []; 25092 25093 /** 25094 * The collection of drawn shapes. 25095 * 25096 * @member {PIXI.GraphicsData[]} 25097 * @protected 25098 */ 25099 this.graphicsData = []; 25100 25101 /** 25102 * Used to detect if the graphics object has changed. If this is set to true then the graphics 25103 * object will be recalculated. 25104 * 25105 * @member {number} 25106 * @protected 25107 */ 25108 this.dirty = 0; 25109 25110 /** 25111 * Batches need to regenerated if the geometry is updated. 25112 * 25113 * @member {number} 25114 * @protected 25115 */ 25116 this.batchDirty = -1; 25117 25118 /** 25119 * Used to check if the cache is dirty. 25120 * 25121 * @member {number} 25122 * @protected 25123 */ 25124 this.cacheDirty = -1; 25125 25126 /** 25127 * Used to detect if we clear the graphics WebGL data. 25128 * 25129 * @member {number} 25130 * @default 0 25131 * @protected 25132 */ 25133 this.clearDirty = 0; 25134 25135 /** 25136 * List of current draw calls drived from the batches. 25137 * 25138 * @member {object[]} 25139 * @protected 25140 */ 25141 this.drawCalls = []; 25142 25143 /** 25144 * Intermediate abstract format sent to batch system. 25145 * Can be converted to drawCalls or to batchable objects. 25146 * 25147 * @member {object[]} 25148 * @protected 25149 */ 25150 this.batches = []; 25151 25152 /** 25153 * Index of the current last shape in the stack of calls. 25154 * 25155 * @member {number} 25156 * @protected 25157 */ 25158 this.shapeIndex = 0; 25159 25160 /**
25161 * Cached bounds. 25162 * 25163 * @member {PIXI.Bounds} 25164 * @protected 25165 */ 25166 this._bounds = new Bounds(); 25167 25168 /** 25169 * The bounds dirty flag. 25170 * 25171 * @member {number} 25172 * @protected 25173 */ 25174 this.boundsDirty = -1; 25175 25176 /** 25177 * Padding to add to the bounds. 25178 * 25179 * @member {number} 25180 * @default 0 25181 */ 25182 this.boundsPadding = 0; 25183 25184 this.batchable = false; 25185 25186 this.indicesUint16 = null; 25187 25188 this.uvsFloat32 = null; 25189 } 25190 25191 if ( BatchGeometry ) { GraphicsGeometry.__proto__ = BatchGeometry; } 25192 GraphicsGeometry.prototype = Object.create( BatchGeometry && BatchGeometry.prototype ); 25193 GraphicsGeometry.prototype.constructor = GraphicsGeometry; 25194 25195 var prototypeAccessors = { bounds: { configurable: true } }; 25196 25197 /** 25198 * Get the current bounds of the graphic geometry. 25199 * 25200 * @member {PIXI.Bounds} 25201 * @readonly 25202 */ 25203 prototypeAccessors.bounds.get = function () 25204 { 25205 if (this.boundsDirty !== this.dirty) 25206 { 25207 this.boundsDirty = this.dirty; 25208 this.calculateBounds(); 25209 } 25210 25211 return this._bounds; 25212 }; 25213 25214 /** 25215 * Clears the graphics that were drawn to this Graphics object, and resets fill and line style settings. 25216 * 25217 * @return {PIXI.GraphicsGeometry} This GraphicsGeometry object. Good for chaining method calls 25218 */ 25219 GraphicsGeometry.prototype.clear = function clear () 25220 { 25221 if (this.graphicsData.length > 0) 25222 { 25223 this.boundsDirty = -1; 25224 this.dirty++; 25225 this.clearDirty++; 25226 this.batchDirty++; 25227 this.graphicsData.length = 0; 25228 this.shapeIndex = 0; 25229 25230 this.points.length = 0; 25231 this.colors.length = 0; 25232 this.uvs.length = 0; 25233 this.indices.length = 0; 25234 this.textureIds.length = 0; 25235 25236 for (var i = 0; i < this.drawCalls.length; i++) 25237 { 25238 this.drawCalls[i].textures.length = 0; 25239 DRAW_CALL_POOL.push(this.drawCalls[i]); 25240 } 25241 25242 this.drawCalls.length = 0; 25243 25244 for (var i$1 = 0; i$1 < this.batches.length; i$1++) 25245 { 25246 var batch = this.batches[i$1]; 25247 25248 batch.start = 0; 25249 batch.attribStart = 0; 25250 batch.style = null; 25251 BATCH_POOL.push(batch); 25252 } 25253 25254 this.batches.length = 0; 25255 } 25256 25257 return this; 25258 }; 25259 25260 /** 25261 * Draws the given shape to this Graphics object. Can be any of Circle, Rectangle, Ellipse, Line or Polygon. 25262 * 25263 * @param {PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.Rectangle|PIXI.RoundedRectangle} shape - The shape object to draw. 25264 * @param {PIXI.FillStyle} fillStyle - Defines style of the fill. 25265 * @param {PIXI.LineStyle} lineStyle - Defines style of the lines. 25266 * @param {PIXI.Matrix} matrix - Transform applied to the points of the shape. 25267 * @return {PIXI.GraphicsGeometry} Returns geometry for chaining. 25268 */ 25269 GraphicsGeometry.prototype.drawShape = function drawShape (shape, fillStyle, lineStyle, matrix) 25270 { 25271 var data = new GraphicsData(shape, fillStyle, lineStyle, matrix); 25272 25273 this.graphicsData.push(data); 25274 this.dirty++; 25275 25276 return this; 25277 }; 25278 25279 /** 25280 * Draws the given shape to this Graphics object. Can be any of Circle, Rectangle, Ellipse, Line or Polygon. 25281 * 25282 * @param {PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.Rectangle|PIXI.RoundedRectangle} shape - The shape object to draw. 25283 * @param {PIXI.Matrix} matrix - Transform applied to the points of the shape. 25284 * @return {PIXI.GraphicsGeometry} Returns geometry for chaining. 25285 */ 25286 GraphicsGeometry.prototype.drawHole = function drawHole (shape, matrix) 25287 { 25288 if (!this.graphicsData.length) 25289 { 25290 return null; 25291 } 25292
25293 var data = new GraphicsData(shape, null, null, matrix); 25294 25295 var lastShape = this.graphicsData[this.graphicsData.length - 1]; 25296 25297 data.lineStyle = lastShape.lineStyle; 25298 25299 lastShape.holes.push(data); 25300 25301 this.dirty++; 25302 25303 return data; 25304 }; 25305 25306 /** 25307 * Destroys the Graphics object. 25308 * 25309 * @param {object|boolean} [options] - Options parameter. A boolean will act as if all 25310 * options have been set to that value 25311 * @param {boolean} [options.children=false] - if set to true, all the children will have 25312 * their destroy method called as well. 'options' will be passed on to those calls. 25313 * @param {boolean} [options.texture=false] - Only used for child Sprites if options.children is set to true 25314 * Should it destroy the texture of the child sprite 25315 * @param {boolean} [options.baseTexture=false] - Only used for child Sprites if options.children is set to true 25316 * Should it destroy the base texture of the child sprite 25317 */ 25318 GraphicsGeometry.prototype.destroy = function destroy (options) 25319 { 25320 BatchGeometry.prototype.destroy.call(this, options); 25321 25322 // destroy each of the GraphicsData objects 25323 for (var i = 0; i < this.graphicsData.length; ++i) 25324 { 25325 this.graphicsData[i].destroy(); 25326 } 25327 25328 this.points.length = 0; 25329 this.points = null; 25330 this.colors.length = 0; 25331 this.colors = null; 25332 this.uvs.length = 0; 25333 this.uvs = null; 25334 this.indices.length = 0; 25335 this.indices = null; 25336 this.indexBuffer.destroy(); 25337 this.indexBuffer = null; 25338 this.graphicsData.length = 0; 25339 this.graphicsData = null; 25340 this.drawCalls.length = 0; 25341 this.drawCalls = null; 25342 this.batches.length = 0; 25343 this.batches = null; 25344 this._bounds = null; 25345 }; 25346 25347 /** 25348 * Check to see if a point is contained within this geometry. 25349 * 25350 * @param {PIXI.Point} point - Point to check if it's contained. 25351 * @return {Boolean} `true` if the point is contained within geometry. 25352 */ 25353 GraphicsGeometry.prototype.containsPoint = function containsPoint (point) 25354 { 25355 var graphicsData = this.graphicsData; 25356 25357 for (var i = 0; i < graphicsData.length; ++i) 25358 { 25359 var data = graphicsData[i]; 25360 25361 if (!data.fillStyle.visible) 25362 { 25363 continue; 25364 } 25365 25366 // only deal with fills.. 25367 if (data.shape) 25368 { 25369 if (data.shape.contains(point.x, point.y)) 25370 { 25371 if (data.holes) 25372 { 25373 for (var i$1 = 0; i$1 < data.holes.length; i$1++) 25374 { 25375 var hole = data.holes[i$1]; 25376 25377 if (hole.shape.contains(point.x, point.y)) 25378 { 25379 return false; 25380 } 25381 } 25382 } 25383 25384 return true; 25385 } 25386 } 25387 } 25388 25389 return false; 25390 }; 25391 25392 /** 25393 * Generates intermediate batch data. Either gets converted to drawCalls 25394 * or used to convert to batch objects directly by the Graphics object. 25395 * @protected 25396 */ 25397 GraphicsGeometry.prototype.updateBatches = function updateBatches () 25398 { 25399 if (this.dirty === this.cacheDirty) { return; } 25400 if (this.graphicsData.length === 0) { return; } 25401 25402 if (this.dirty !== this.cacheDirty) 25403 { 25404 for (var i = 0; i < this.graphicsData.length; i++) 25405 { 25406 var data = this.graphicsData[i]; 25407 25408 if (data.fillStyle && !data.fillStyle.texture.baseTexture.valid) { return; } 25409 if (data.lineStyle && !data.lineStyle.texture.baseTexture.valid) { return; } 25410 } 25411 } 25412 25413 this.cacheDirty = this.dirty; 25414 25415 var uvs = this.uvs; 25416 25417 var batchPart = this.batches.pop() 25418 || BATCH_POOL.pop() 25419 || new BatchPart(); 25420 25421 batchPart.style = batchPart.style 25422 || this.graphicsData[0].fillStyle 25423 || this.graphicsData[0].lineStyle; 25424 25425 var currentTexture = batchPart.style.texture.baseTexture; 25426 var currentColor = batchPart.style.color + batchPart.style.alpha; 25427 25428 this.batches.push(batchPart); 25429 25430 // TODO - this can be simplified 25431 for (var i$1 = this.shapeIndex; i$1 < this.graphicsData.length; i$1++) 25432 { 25433 this.shapeIndex++; 25434 25435 var data$1 = this.graphicsData[i$1]; 25436 var command = fillCommands[data$1.type]; 25437 25438 var fillStyle = data$1.fillStyle; 25439 var lineStyle = data$1.lineStyle; 25440 25441 // build out the shapes points.. 25442 command.build(data$1); 25443 25444 if (data$1.matrix) 25445 { 25446 this.transformPoints(data$1.points, data$1.matrix); 25447 } 25448 25449 for (var j = 0; j < 2; j++) 25450 { 25451 var style = (j === 0) ? fillStyle : lineStyle; 25452 25453 if (!style.visible) { continue; } 25454 25455 var nextTexture = style.texture.baseTexture; 25456 25457 if (currentTexture !== nextTexture || (style.color + style.alpha) !== currentColor) 25458 { 25459 // TODO use a const 25460 nextTexture.wrapMode = 10497; 25461 currentTexture = nextTexture; 25462 currentColor = style.color + style.alpha; 25463 25464 var index$1 = this.indices.length; 25465 var attribIndex = this.points.length / 2; 25466 25467 batchPart.size = index$1 - batchPart.start; 25468 batchPart.attribSize = attribIndex - batchPart.attribStart; 25469 25470 if (batchPart.size > 0) 25471 { 25472 batchPart = BATCH_POOL.pop() || new BatchPart(); 25473 25474 this.batches.push(batchPart); 25475 } 25476 25477 batchPart.style = style; 25478 batchPart.start = index$1; 25479 batchPart.attribStart = attribIndex; 25480 25481 // TODO add this to the render part.. 25482 } 25483 25484 var start = this.points.length / 2; 25485 25486 if (j === 0) 25487 { 25488 if (data$1.holes.length) 25489 { 25490 this.processHoles(data$1.holes); 25491 25492 buildPoly.triangulate(data$1, this); 25493 } 25494 else 25495 { 25496 command.triangulate(data$1, this); 25497 } 25498 } 25499 else 25500 { 25501 buildLine(data$1, this); 25502 25503 for (var i$2 = 0; i$2 < data$1.holes.length; i$2++) 25504 { 25505 buildLine(data$1.holes[i$2], this); 25506 } 25507 } 25508 25509 var size = (this.points.length / 2) - start; 25510 25511 this.addUvs(this.points, uvs, style.texture, start, size, style.matrix); 25512 } 25513 } 25514 25515 var index = this.indices.length; 25516 var attrib = this.points.length / 2; 25517 25518 batchPart.size = index - batchPart.start; 25519 batchPart.attribSize = attrib - batchPart.attribStart; 25520 this.indicesUint16 = new Uint16Array(this.indices); 25521 25522 // TODO make this a const.. 25523 this.batchable = this.isBatchable(); 25524 25525 if (this.batchable) 25526 { 25527 this.batchDirty++; 25528 25529 this.uvsFloat32 = new Float32Array(this.uvs); 25530 25531 // offset the indices so that it works with the batcher... 25532 for (var i$3 = 0; i$3 < this.batches.length; i$3++) 25533 { 25534 var batch = this.batches[i$3]; 25535 25536 for (var j$1 = 0; j$1 < batch.size; j$1++) 25537 { 25538 var index$2 = batch.start + j$1; 25539 25540 this.indicesUint16[index$2] = this.indicesUint16[index$2] - batch.attribStart; 25541 } 25542 } 25543 } 25544 else 25545 { 25546 this.buildDrawCalls(); 25547 } 25548 }; 25549 25550 /** 25551 * Checks to see if this graphics geometry can be batched. 25552 * Currently it needs to be small enough and not contain any native lines. 25553 * @protected 25554 */ 25555 GraphicsGeometry.prototype.isBatchable = function isBatchable () 25556 { 25557 var batches = this.batches; 25558 25559 for (var i = 0; i < batches.length; i++) 25560 { 25561 if (batches[i].style.native) 25562 { 25563 return false;
25564 } 25565 } 25566 25567 return (this.points.length < GraphicsGeometry.BATCHABLE_SIZE * 2); 25568 }; 25569 25570 /** 25571 * Converts intermediate batches data to drawCalls. 25572 * @protected 25573 */ 25574 GraphicsGeometry.prototype.buildDrawCalls = function buildDrawCalls () 25575 { 25576 TICK$1++; 25577 25578 for (var i = 0; i < this.drawCalls.length; i++) 25579 { 25580 this.drawCalls[i].textures.length = 0; 25581 DRAW_CALL_POOL.push(this.drawCalls[i]); 25582 } 25583 25584 this.drawCalls.length = 0; 25585 25586 var uvs = this.uvs; 25587 var colors = this.colors; 25588 var textureIds = this.textureIds; 25589 25590 var currentGroup = DRAW_CALL_POOL.pop() || new BatchDrawCall(); 25591 25592 currentGroup.textureCount = 0; 25593 currentGroup.start = 0; 25594 currentGroup.size = 0; 25595 currentGroup.type = DRAW_MODES.TRIANGLES; 25596 25597 var textureCount = 0; 25598 var currentTexture = null; 25599 var textureId = 0; 25600 var native = false; 25601 var drawMode = DRAW_MODES.TRIANGLES; 25602 25603 var index = 0; 25604 25605 this.drawCalls.push(currentGroup); 25606 25607 // TODO - this can be simplified 25608 for (var i$1 = 0; i$1 < this.batches.length; i$1++) 25609 { 25610 var data = this.batches[i$1]; 25611 25612 // TODO add some full on MAX_TEXTURE CODE.. 25613 var MAX_TEXTURES = 8; 25614 25615 var style = data.style; 25616 25617 var nextTexture = style.texture.baseTexture; 25618 25619 if (native !== style.native) 25620 { 25621 native = style.native; 25622 drawMode = native ? DRAW_MODES.LINES : DRAW_MODES.TRIANGLES; 25623 25624 // force the batch to break! 25625 currentTexture = null; 25626 textureCount = MAX_TEXTURES; 25627 TICK$1++; 25628 } 25629 25630 if (currentTexture !== nextTexture) 25631 { 25632 currentTexture = nextTexture; 25633 25634 if (nextTexture._enabled !== TICK$1) 25635 { 25636 if (textureCount === MAX_TEXTURES) 25637 { 25638 TICK$1++; 25639 25640 textureCount = 0; 25641 25642 if (currentGroup.size > 0) 25643 { 25644 currentGroup = DRAW_CALL_POOL.pop() || new BatchDrawCall(); 25645 this.drawCalls.push(currentGroup); 25646 } 25647 25648 currentGroup.start = index; 25649 currentGroup.size = 0; 25650 currentGroup.textureCount = 0; 25651 currentGroup.type = drawMode; 25652 } 25653 25654 // TODO add this to the render part.. 25655 nextTexture.touched = 1;// touch; 25656 nextTexture._enabled = TICK$1; 25657 nextTexture._id = textureCount; 25658 nextTexture.wrapMode = 10497; 25659 25660 currentGroup.textures[currentGroup.textureCount++] = nextTexture; 25661 textureCount++; 25662 } 25663 } 25664 25665 currentGroup.size += data.size; 25666 index += data.size; 25667 25668 textureId = nextTexture._id; 25669 25670 this.addColors(colors, style.color, style.alpha, data.attribSize); 25671 this.addTextureIds(textureIds, textureId, data.attribSize); 25672 } 25673 25674 // upload.. 25675 // merge for now! 25676 var verts = this.points; 25677 25678 // verts are 2 positions.. so we * by 3 as there are 6 properties.. then 4 cos its bytes 25679 var glPoints = new ArrayBuffer(verts.length * 3 * 4); 25680 var f32 = new Float32Array(glPoints); 25681 var u32 = new Uint32Array(glPoints); 25682 25683 var p = 0; 25684 25685 for (var i$2 = 0; i$2 < verts.length / 2; i$2++) 25686 { 25687 f32[p++] = verts[i$2 * 2]; 25688 f32[p++] = verts[(i$2 * 2) + 1]; 25689 25690 f32[p++] = uvs[i$2 * 2]; 25691 f32[p++] = uvs[(i$2 * 2) + 1]; 25692 25693 u32[p++] = colors[i$2]; 25694 25695 f32[p++] = textureIds[i$2]; 25696 } 25697 25698 this._buffer.update(glPoints); 25699 this._indexBuffer.update(this.indicesUint16); 25700 }; 25701 25702 /** 25703 * Process the holes data. 25704 * 25705 * @param {PIXI.GraphicsData[]} holes - Holes to render 25706 * @protected 25707 */ 25708 GraphicsGeometry.prototype.processHoles = function processHoles (holes) 25709 { 25710 for (var i = 0; i < holes.length; i++) 25711 { 25712 var hole = holes[i]; 25713 25714 var command = fillCommands[hole.type]; 25715 25716 command.build(hole); 25717 25718 if (hole.matrix) 25719 { 25720 this.transformPoints(hole.points, hole.matrix); 25721 } 25722 } 25723 }; 25724 25725 /** 25726 * Update the local bounds of the object. Expensive to use performance-wise. 25727 * @protected 25728 */ 25729 GraphicsGeometry.prototype.calculateBounds = function calculateBounds () 25730 { 25731 var minX = Infinity; 25732 var maxX = -Infinity; 25733 25734 var minY = Infinity; 25735 var maxY = -Infinity; 25736 25737 if (this.graphicsData.length) 25738 { 25739 var shape = null; 25740 var x = 0; 25741 var y = 0; 25742 var w = 0; 25743 var h = 0; 25744 25745 for (var i = 0; i < this.graphicsData.length; i++) 25746 { 25747 var data = this.graphicsData[i]; 25748 25749 var type = data.type; 25750 var lineWidth = data.lineStyle ? data.lineStyle.width : 0; 25751 25752 shape = data.shape; 25753 25754 if (type === SHAPES.RECT || type === SHAPES.RREC) 25755 { 25756 x = shape.x - (lineWidth / 2); 25757 y = shape.y - (lineWidth / 2); 25758 w = shape.width + lineWidth; 25759 h = shape.height + lineWidth; 25760 25761 minX = x < minX ? x : minX; 25762 maxX = x + w > maxX ? x + w : maxX; 25763 25764 minY = y < minY ? y : minY; 25765 maxY = y + h > maxY ? y + h : maxY; 25766 } 25767 else if (type === SHAPES.CIRC) 25768 { 25769 x = shape.x; 25770 y = shape.y;
25771 w = shape.radius + (lineWidth / 2); 25772 h = shape.radius + (lineWidth / 2); 25773 25774 minX = x - w < minX ? x - w : minX; 25775 maxX = x + w > maxX ? x + w : maxX; 25776 25777 minY = y - h < minY ? y - h : minY; 25778 maxY = y + h > maxY ? y + h : maxY; 25779 } 25780 else if (type === SHAPES.ELIP) 25781 { 25782 x = shape.x; 25783 y = shape.y; 25784 w = shape.width + (lineWidth / 2); 25785 h = shape.height + (lineWidth / 2); 25786 25787 minX = x - w < minX ? x - w : minX; 25788 maxX = x + w > maxX ? x + w : maxX; 25789 25790 minY = y - h < minY ? y - h : minY; 25791 maxY = y + h > maxY ? y + h : maxY; 25792 } 25793 else 25794 { 25795 // POLY 25796 var points = shape.points; 25797 var x2 = 0; 25798 var y2 = 0; 25799 var dx = 0; 25800 var dy = 0; 25801 var rw = 0; 25802 var rh = 0; 25803 var cx = 0; 25804 var cy = 0; 25805 25806 for (var j = 0; j + 2 < points.length; j += 2) 25807 { 25808 x = points[j]; 25809 y = points[j + 1]; 25810 x2 = points[j + 2]; 25811 y2 = points[j + 3]; 25812 dx = Math.abs(x2 - x); 25813 dy = Math.abs(y2 - y); 25814 h = lineWidth; 25815 w = Math.sqrt((dx * dx) + (dy * dy)); 25816 25817 if (w < 1e-9) 25818 { 25819 continue; 25820 } 25821 25822 rw = ((h / w * dy) + dx) / 2; 25823 rh = ((h / w * dx) + dy) / 2; 25824 cx = (x2 + x) / 2; 25825 cy = (y2 + y) / 2; 25826 25827 minX = cx - rw < minX ? cx - rw : minX; 25828 maxX = cx + rw > maxX ? cx + rw : maxX; 25829 25830 minY = cy - rh < minY ? cy - rh : minY; 25831 maxY = cy + rh > maxY ? cy + rh : maxY; 25832 } 25833 } 25834 } 25835 } 25836 else 25837 { 25838 minX = 0; 25839 maxX = 0; 25840 minY = 0; 25841 maxY = 0; 25842 } 25843 25844 var padding = this.boundsPadding; 25845 25846 this._bounds.minX = minX - padding; 25847 this._bounds.maxX = maxX + padding; 25848 25849 this._bounds.minY = minY - padding; 25850 this._bounds.maxY = maxY + padding; 25851 }; 25852 25853 /** 25854 * Transform points using matrix. 25855 * 25856 * @protected 25857 * @param {number[]} points - Points to transform 25858 * @param {PIXI.Matrix} matrix - Transform matrix 25859 */ 25860 GraphicsGeometry.prototype.transformPoints = function transformPoints (points, matrix) 25861 { 25862 for (var i = 0; i < points.length / 2; i++) 25863 { 25864 var x = points[(i * 2)]; 25865 var y = points[(i * 2) + 1]; 25866 25867 points[(i * 2)] = (matrix.a * x) + (matrix.c * y) + matrix.tx; 25868 points[(i * 2) + 1] = (matrix.b * x) + (matrix.d * y) + matrix.ty; 25869 } 25870 }; 25871 25872 /** 25873 * Add colors. 25874 * 25875 * @protected 25876 * @param {number[]} colors - List of colors to add to 25877 * @param {number} color - Color to add 25878 * @param {number} alpha - Alpha to use 25879 * @param {number} size - Number of colors to add 25880 */ 25881 GraphicsGeometry.prototype.addColors = function addColors (colors, color, alpha, size) 25882 { 25883 // TODO use the premultiply bits Ivan added 25884 var rgb = (color >> 16) + (color & 0xff00) + ((color & 0xff) << 16); 25885 25886 var rgba = premultiplyTint(rgb, alpha); 25887 25888 while (size-- > 0) 25889 { 25890 colors.push(rgba); 25891 } 25892 }; 25893 25894 /** 25895 * Add texture id that the shader/fragment wants to use. 25896 * 25897 * @protected 25898 * @param {number[]} textureIds 25899 * @param {number} id 25900 * @param {number} size 25901 */ 25902 GraphicsGeometry.prototype.addTextureIds = function addTextureIds (textureIds, id, size) 25903 { 25904 while (size-- > 0) 25905 { 25906 textureIds.push(id); 25907 } 25908 }; 25909 25910 /** 25911 * Generates the UVs for a shape. 25912 * 25913 * @protected 25914 * @param {number[]} verts - Vertices 25915 * @param {number[]} uvs - UVs 25916 * @param {PIXI.Texture} texture - Reference to Texture 25917 * @param {number} start - Index buffer start index. 25918 * @param {number} size - The size/length for index buffer. 25919 * @param {PIXI.Matrix} [matrix] - Optional transform for all points. 25920 */ 25921 GraphicsGeometry.prototype.addUvs = function addUvs (verts, uvs, texture, start, size, matrix
25921) 25922 { 25923 var index = 0; 25924 var uvsStart = uvs.length; 25925 var frame = texture.frame; 25926 25927 while (index < size) 25928 { 25929 var x = verts[(start + index) * 2]; 25930 var y = verts[((start + index) * 2) + 1]; 25931 25932 if (matrix) 25933 { 25934 var nx = (matrix.a * x) + (matrix.c * y) + matrix.tx; 25935 25936 y = (matrix.b * x) + (matrix.d * y) + matrix.ty; 25937 x = nx; 25938 } 25939 25940 index++; 25941 25942 uvs.push(x / frame.width, y / frame.height); 25943 } 25944 25945 var baseTexture = texture.baseTexture; 25946 25947 if (frame.width < baseTexture.width 25948 || frame.height < baseTexture.height) 25949 { 25950 this.adjustUvs(uvs, texture, uvsStart, size); 25951 } 25952 }; 25953 25954 /** 25955 * Modify uvs array according to position of texture region 25956 * Does not work with rotated or trimmed textures 25957 * @param {number} uvs array 25958 * @param {PIXI.Texture} texture region 25959 * @param {number} start starting index for uvs 25960 * @param {number} size how many points to adjust 25961 */ 25962 GraphicsGeometry.prototype.adjustUvs = function adjustUvs (uvs, texture, start, size) 25963 { 25964 var baseTexture = texture.baseTexture; 25965 var eps = 1e-6; 25966 var finish = start + (size * 2); 25967 var frame = texture.frame; 25968 var scaleX = frame.width / baseTexture.width; 25969 var scaleY = frame.height / baseTexture.height; 25970 var offsetX = frame.x / frame.width; 25971 var offsetY = frame.y / frame.width; 25972 var minX = Math.floor(uvs[start] + eps); 25973 var minY = Math.floor(uvs[start + 1] + eps); 25974 25975 for (var i = start + 2; i < finish; i += 2) 25976 { 25977 minX = Math.min(minX, Math.floor(uvs[i] + eps)); 25978 minY = Math.min(minY, Math.floor(uvs[i + 1] + eps)); 25979 } 25980 offsetX -= minX; 25981 offsetY -= minY; 25982 for (var i$1 = start; i$1 < finish; i$1 += 2) 25983 { 25984 uvs[i$1] = (uvs[i$1] + offsetX) * scaleX; 25985 uvs[i$1 + 1] = (uvs[i$1 + 1] + offsetY) * scaleY; 25986 } 25987 }; 25988 25989 Object.defineProperties( GraphicsGeometry.prototype, prototypeAccessors ); 25990 25991 return GraphicsGeometry; 25992 }(BatchGeometry)); 25993 25994 /** 25995 * The maximum number of points to consider an object "batchable", 25996 * able to be batched by the renderer's batch system. 25997 * 25998 * @memberof PIXI.GraphicsGeometry 25999 * @static 26000 * @member {number} BATCHABLE_SIZE 26001 * @default 100 26002 */ 26003 GraphicsGeometry.BATCHABLE_SIZE = 100; 26004 26005 /** 26006 * Represents the line style for Graphics. 26007 * @memberof PIXI 26008 * @class 26009 * @extends PIXI.FillStyle 26010 */ 26011 var LineStyle = /*@__PURE__*/(function (FillStyle) { 26012 function LineStyle () { 26013 FillStyle.apply(this, arguments); 26014 } 26015 26016 if ( FillStyle ) { LineStyle.__proto__ = FillStyle; } 26017 LineStyle.prototype = Object.create( FillStyle && FillStyle.prototype ); 26018 LineStyle.prototype.constructor = LineStyle; 26019 26020 LineStyle.prototype.clone = function clone () 26021 { 26022 var obj = new LineStyle(); 26023 26024 obj.color = this.color; 26025 obj.alpha = this.alpha; 26026 obj.texture = this.texture; 26027 obj.matrix = this.matrix; 26028 obj.visible = this.visible; 26029 obj.width = this.width; 26030 obj.alignment = this.alignment; 26031 obj.native = this.native; 26032 26033 return obj; 26034 }; 26035 /** 26036 * Reset the line style to default. 26037 */ 26038 LineStyle.prototype.reset = function reset () 26039 { 26040 FillStyle.prototype.reset.call(this); 26041 26042 // Override default line style color 26043 this.color = 0x0; 26044 26045 /** 26046 * The width (thickness) of any lines drawn. 26047 * 26048 * @member {number} 26049 * @default 0 26050 */ 26051 this.width = 0; 26052 26053 /** 26054 * The alignment of any lines drawn (0.5 = middle, 1 = outter, 0 = inner). 26055 * 26056 * @member {number} 26057 * @default 0 26058 */ 26059 this.alignment = 0.5; 26060 26061 /** 26062 * If true the lines will be draw using LINES instead of TRIANGLE_STRIP 26063 * 26064 * @member {boolean} 26065 * @default false 26066 */ 26067 this.native = false;
26068 }; 26069 26070 return LineStyle; 26071 }(FillStyle)); 26072 26073 /** 26074 * Utilities for bezier curves 26075 * @class 26076 * @private 26077 */ 26078 var BezierUtils = function BezierUtils () {}; 26079 26080 BezierUtils.curveLength = function curveLength (fromX, fromY, cpX, cpY, cpX2, cpY2, toX, toY) 26081 { 26082 var n = 10; 26083 var result = 0.0; 26084 var t = 0.0; 26085 var t2 = 0.0; 26086 var t3 = 0.0; 26087 var nt = 0.0; 26088 var nt2 = 0.0; 26089 var nt3 = 0.0; 26090 var x = 0.0; 26091 var y = 0.0; 26092 var dx = 0.0; 26093 var dy = 0.0; 26094 var prevX = fromX; 26095 var prevY = fromY; 26096 26097 for (var i = 1; i <= n; ++i) 26098 { 26099 t = i / n; 26100 t2 = t * t; 26101 t3 = t2 * t; 26102 nt = (1.0 - t); 26103 nt2 = nt * nt; 26104 nt3 = nt2 * nt; 26105 26106 x = (nt3 * fromX) + (3.0 * nt2 * t * cpX) + (3.0 * nt * t2 * cpX2) + (t3 * toX); 26107 y = (nt3 * fromY) + (3.0 * nt2 * t * cpY) + (3 * nt * t2 * cpY2) + (t3 * toY); 26108 dx = prevX - x; 26109 dy = prevY - y; 26110 prevX = x; 26111 prevY = y; 26112 26113 result += Math.sqrt((dx * dx) + (dy * dy)); 26114 } 26115 26116 return result; 26117 }; 26118 26119 /** 26120 * Calculate the points for a bezier curve and then draws it. 26121 * 26122 * Ignored from docs since it is not directly exposed. 26123 * 26124 * @ignore 26125 * @param {number} cpX - Control point x 26126 * @param {number} cpY - Control point y 26127 * @param {number} cpX2 - Second Control point x 26128 * @param {number} cpY2 - Second Control point y 26129 * @param {number} toX - Destination point x 26130 * @param {number} toY - Destination point y 26131 * @param {number[]} points - Path array to push points into 26132 */ 26133 BezierUtils.curveTo = function curveTo (cpX, cpY, cpX2, cpY2, toX, toY, points) 26134 { 26135 var fromX = points[points.length - 2]; 26136 var fromY = points[points.length - 1]; 26137 26138 points.length -= 2; 26139 26140 var n = GRAPHICS_CURVES._segmentsCount( 26141 BezierUtils.curveLength(fromX, fromY, cpX, cpY, cpX2, cpY2, toX, toY) 26142 ); 26143 26144 var dt = 0; 26145 var dt2 = 0; 26146 var dt3 = 0; 26147 var t2 = 0; 26148 var t3 = 0; 26149 26150 points.push(fromX, fromY); 26151 26152 for (var i = 1, j = 0; i <= n; ++i) 26153 { 26154 j = i / n; 26155 26156 dt = (1 - j); 26157 dt2 = dt * dt; 26158 dt3 = dt2 * dt; 26159 26160 t2 = j * j; 26161 t3 = t2 * j; 26162 26163 points.push( 26164 (dt3 * fromX) + (3 * dt2 * j * cpX) + (3 * dt * t2 * cpX2) + (t3 * toX), 26165 (dt3 * fromY) + (3 * dt2 * j * cpY) + (3 * dt * t2 * cpY2) + (t3 * toY) 26166 ); 26167 } 26168 }; 26169 26170 /** 26171 * Utilities for quadratic curves 26172 * @class 26173 * @private 26174 */ 26175 var QuadraticUtils = function QuadraticUtils () {}; 26176 26177 QuadraticUtils.curveLength = function curveLength (fromX, fromY, cpX, cpY, toX, toY) 26178 { 26179 var ax = fromX - (2.0 * cpX) + toX; 26180 var ay = fromY - (2.0 * cpY) + toY; 26181 var bx = (2.0 * cpX) - (2.0 * fromX); 26182 var by = (2.0 * cpY) - (2.0 * fromY); 26183 var a = 4.0 * ((ax * ax) + (ay * ay)); 26184 var b = 4.0 * ((ax * bx) + (ay * by)); 26185 var c = (bx * bx) + (by * by); 26186 26187 var s = 2.0 * Math.sqrt(a + b + c); 26188 var a2 = Math.sqrt(a); 26189 var a32 = 2.0 * a * a2; 26190 var c2 = 2.0 * Math.sqrt(c); 26191 var ba = b / a2; 26192 26193 return ( 26194 (a32 * s) 26195 + (a2 * b * (s - c2)) 26196 + ( 26197 ((4.0 * c * a) - (b * b)) 26198 * Math.log(((2.0 * a2) + ba + s) / (ba + c2)) 26199 ) 26200 ) / (4.0 * a32); 26201 }; 26202 26203 /** 26204 * Calculate the points for a quadratic bezier curve and then draws it. 26205 * Based on: https://stackoverflow.com/questions/785097/how-do-i-implement-a-bezier-curve-in-c 26206 * 26207 * @private 26208 * @param {number} cpX - Control point x 26209 * @param {number} cpY - Control point y 26210 * @param {number} toX - Destination point x 26211 * @param {number} toY - Destination point y 26212 * @param {number[]} points - Points to add segments to. 26213 */ 26214 QuadraticUtils.curveTo = function curveTo (cpX, cpY, toX, toY, points) 26215 { 26216 var fromX = points[points.length - 2]; 26217 var fromY = points[points.length - 1]; 26218 26219 var n = GRAPHICS_CURVES._segmentsCount( 26220 QuadraticUtils.curveLength(fromX, fromY, cpX, cpY, toX, toY) 26221 ); 26222 26223 var xa = 0; 26224 var ya = 0; 26225 26226 for (var i = 1; i <= n; ++i) 26227 { 26228 var j = i / n; 26229 26230 xa = fromX + ((cpX - fromX) * j); 26231 ya = fromY + ((cpY - fromY) * j); 26232 26233 points.push(xa + (((cpX + ((toX - cpX) * j)) - xa) * j), 26234 ya + (((cpY + ((toY - cpY) * j)) - ya) * j)); 26235 } 26236 }; 26237 26238 /** 26239 * Utilities for arc curves 26240 * @class 26241 * @private 26242 */ 26243 var ArcUtils = function ArcUtils () {}; 26244 26245 ArcUtils.curveTo = function curveTo (x1, y1, x2, y2, radius, points) 26246 { 26247 var fromX = points[points.length - 2]; 26248 var fromY = points[points.length - 1]; 26249 26250 var a1 = fromY - y1; 26251 var b1 = fromX - x1; 26252 var a2 = y2 - y1; 26253 var b2 = x2 - x1; 26254 var mm = Math.abs((a1 * b2) - (b1 * a2)); 26255 26256 if (mm < 1.0e-8 || radius === 0) 26257 { 26258 if (points[points.length - 2] !== x1 || points[points.length - 1] !== y1) 26259 { 26260 points.push(x1, y1); 26261 } 26262 26263 return null; 26264 } 26265 26266 var dd = (a1 * a1) + (b1 * b1); 26267 var cc = (a2 * a2) + (b2 * b2); 26268 var tt = (a1 * a2) + (b1 * b2);
26269 var k1 = radius * Math.sqrt(dd) / mm; 26270 var k2 = radius * Math.sqrt(cc) / mm; 26271 var j1 = k1 * tt / dd; 26272 var j2 = k2 * tt / cc; 26273 var cx = (k1 * b2) + (k2 * b1); 26274 var cy = (k1 * a2) + (k2 * a1); 26275 var px = b1 * (k2 + j1); 26276 var py = a1 * (k2 + j1); 26277 var qx = b2 * (k1 + j2); 26278 var qy = a2 * (k1 + j2); 26279 var startAngle = Math.atan2(py - cy, px - cx); 26280 var endAngle = Math.atan2(qy - cy, qx - cx); 26281 26282 return { 26283 cx: (cx + x1), 26284 cy: (cy + y1), 26285 radius: radius, 26286 startAngle: startAngle, 26287 endAngle: endAngle, 26288 anticlockwise: (b1 * a2 > b2 * a1), 26289 }; 26290 }; 26291 26292 /** 26293 * The arc method creates an arc/curve (used to create circles, or parts of circles). 26294 * 26295 * @private 26296 * @param {number} startX - Start x location of arc 26297 * @param {number} startY - Start y location of arc 26298 * @param {number} cx - The x-coordinate of the center of the circle 26299 * @param {number} cy - The y-coordinate of the center of the circle 26300 * @param {number} radius - The radius of the circle 26301 * @param {number} startAngle - The starting angle, in radians (0 is at the 3 o'clock position 26302 * of the arc's circle) 26303 * @param {number} endAngle - The ending angle, in radians 26304 * @param {boolean} anticlockwise - Specifies whether the drawing should be 26305 * counter-clockwise or clockwise. False is default, and indicates clockwise, while true 26306 * indicates counter-clockwise. 26307 * @param {number} n - Number of segments 26308 * @param {number[]} points - Collection of points to add to 26309 */ 26310 ArcUtils.arc = function arc (startX, startY, cx, cy, radius, startAngle, endAngle, anticlockwise, points) 26311 { 26312 var sweep = endAngle - startAngle; 26313 var n = GRAPHICS_CURVES._segmentsCount( 26314 Math.abs(sweep) * radius, 26315 Math.ceil(Math.abs(sweep) / PI_2) * 40 26316 ); 26317 26318 var theta = (sweep) / (n * 2); 26319 var theta2 = theta * 2; 26320 var cTheta = Math.cos(theta); 26321 var sTheta = Math.sin(theta); 26322 var segMinus = n - 1; 26323 var remainder = (segMinus % 1) / segMinus; 26324 26325 for (var i = 0; i <= segMinus; ++i) 26326 { 26327 var real = i + (remainder * i); 26328 var angle = ((theta) + startAngle + (theta2 * real)); 26329 var c = Math.cos(angle); 26330 var s = -Math.sin(angle); 26331 26332 points.push( 26333 (((cTheta * c) + (sTheta * s)) * radius) + cx, 26334 (((cTheta * -s) + (sTheta * c)) * radius) + cy 26335 ); 26336 } 26337 }; 26338 26339 /** 26340 * Draw a star shape with an arbitrary number of points. 26341 * 26342 * @class 26343 * @extends PIXI.Polygon 26344 * @memberof PIXI 26345 * @param {number} x - Center X position of the star 26346 * @param {number} y - Center Y position of the star 26347 * @param {number} points - The number of points of the star, must be > 1 26348 * @param {number} radius - The outer radius of the star 26349 * @param {number} [innerRadius] - The inner radius between points, default half `radius` 26350 * @param {number} [rotation=0] - The rotation of the star in radians, where 0 is vertical 26351 * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls 26352 */ 26353 var Star = /*@__PURE__*/(function (Polygon) { 26354 function Star(x, y, points, radius, innerRadius, rotation) 26355 { 26356 innerRadius = innerRadius || radius / 2; 26357 26358 var startAngle = (-1 * Math.PI / 2) + rotation; 26359 var len = points * 2; 26360 var delta = PI_2 / len; 26361 var polygon = []; 26362 26363 for (var i = 0; i < len; i++) 26364 { 26365 var r = i % 2 ? innerRadius : radius; 26366 var angle = (i * delta) + startAngle; 26367 26368 polygon.push( 26369 x + (r * Math.cos(angle)), 26370 y + (r * Math.sin(angle)) 26371 ); 26372 } 26373 26374 Polygon.call(this, polygon); 26375 } 26376 26377 if ( Polygon ) { Star.__proto__ = Polygon; } 26378 Star.prototype = Object.create( Polygon && Polygon.prototype ); 26379 Star.prototype.constructor = Star; 26380 26381 return Star; 26382 }(Polygon)); 26383 26384 var temp = new Float32Array(3); 26385 26386 // a default shader used by graphics.. 26387 var defaultShader = null; 26388 26389 /** 26390 * The Graphics class contains methods used to draw primitive shapes such as lines, circles and 26391 * rectangles to the display, and to color and fill them. 26392 * 26393 * @class 26394 * @extends PIXI.Container 26395 * @memberof PIXI 26396 */ 26397 var Graphics = /*@__PURE__*/(function (Container) { 26398 function Graphics(geometry) 26399 { 26400 if ( geometry === void 0 ) { geometry = null; } 26401 26402 Container.call(this); 26403 /** 26404 * Includes vertex positions, face indices, normals, colors, UVs, and 26405 * custom attributes within buffers, reducing the cost of passing all 26406 * this data to the GPU. Can be shared between multiple Mesh or Graphics objects. 26407 * @member {PIXI.Geometry} 26408 * @readonly 26409 */ 26410 this.geometry = geometry || new GraphicsGeometry(); 26411 26412 this.geometry.refCount++; 26413 26414 /** 26415 * Represents the vertex and fragment shaders that processes the geometry and runs on the GPU. 26416 * Can be shared between multiple Graphics objects. 26417 * @member {PIXI.Shader} 26418 */ 26419 this.shader = null; 26420 26421 /** 26422 * Represents the WebGL state the Graphics required to render, excludes shader and geometry. E.g., 26423 * blend mode, culling, depth testing, direction of rendering triangles, backface, etc. 26424 * @member {PIXI.State} 26425 */ 26426 this.state = State.for2d(); 26427 26428 /** 26429 * Current fill style 26430 * 26431 * @member {PIXI.FillStyle} 26432 * @protected 26433 */ 26434 this._fillStyle = new FillStyle(); 26435 26436 /** 26437 * Current line style 26438 * 26439 * @member {PIXI.LineStyle} 26440 * @protected 26441 */ 26442 this._lineStyle = new LineStyle(); 26443 26444 /** 26445 * Current shape transform matrix. 26446 * 26447 * @member {PIXI.Matrix} 26448 * @protected 26449 */ 26450 this._matrix = null; 26451 26452 /** 26453 * Current hole mode is enabled. 26454 * 26455 * @member {boolean} 26456 * @default false 26457 * @protected 26458 */ 26459 this._holeMode = false;
26460 26461 /** 26462 * Current path 26463 * 26464 * @member {PIXI.Polygon} 26465 * @protected 26466 */ 26467 this.currentPath = null; 26468 26469 /** 26470 * When cacheAsBitmap is set to true the graphics object will be rendered as if it was a sprite. 26471 * This is useful if your graphics element does not change often, as it will speed up the rendering 26472 * of the object in exchange for taking up texture memory. It is also useful if you need the graphics 26473 * object to be anti-aliased, because it will be rendered using canvas. This is not recommended if 26474 * you are constantly redrawing the graphics element. 26475 * 26476 * @name cacheAsBitmap 26477 * @member {boolean} 26478 * @memberof PIXI.Graphics# 26479 * @default false 26480 */ 26481 26482 /** 26483 * A collections of batches! These can be drawn by the renderer batch system. 26484 * 26485 * @protected 26486 * @member {object[]} 26487 */ 26488 this.batches = []; 26489 26490 /** 26491 * Update dirty for limiting calculating tints for batches. 26492 * 26493 * @protected 26494 * @member {number} 26495 * @default -1 26496 */ 26497 this.batchTint = -1; 26498 26499 /** 26500 * Copy of the object vertex data. 26501 * 26502 * @protected 26503 * @member {Float32Array} 26504 */ 26505 this.vertexData = null; 26506 26507 this._transformID = -1; 26508 this.batchDirty = -1; 26509 26510 // Set default 26511 this.tint = 0xFFFFFF; 26512 this.blendMode = BLEND_MODES.NORMAL; 26513 } 26514 26515 if ( Container ) { Graphics.__proto__ = Container; } 26516 Graphics.prototype = Object.create( Container && Container.prototype ); 26517 Graphics.prototype.constructor = Graphics; 26518 26519 var prototypeAccessors = { blendMode: { configurable: true },tint: { configurable: true },fill: { configurable: true },line: { configurable: true } }; 26520 26521 /** 26522 * Creates a new Graphics object with the same values as this one. 26523 * Note that the only the properties of the object are cloned, not its transform (position,scale,etc) 26524 * 26525 * @return {PIXI.Graphics} A clone of the graphics object 26526 */ 26527 Graphics.prototype.clone = function clone () 26528 { 26529 this.finishPoly(); 26530 26531 return new Graphics(this.geometry); 26532 }; 26533 26534 /** 26535 * The blend mode to be applied to the graphic shape. Apply a value of 26536 * `PIXI.BLEND_MODES.NORMAL` to reset the blend mode. 26537 * 26538 * @member {number} 26539 * @default PIXI.BLEND_MODES.NORMAL; 26540 * @see PIXI.BLEND_MODES 26541 */ 26542 prototypeAccessors.blendMode.set = function (value) 26543 { 26544 this.state.blendMode = value; 26545 }; 26546 26547 prototypeAccessors.blendMode.get = function () 26548 { 26549 return this.state.blendMode; 26550 }; 26551 26552 /** 26553 * The tint applied to the graphic shape. This is a hex value. A value of 26554 * 0xFFFFFF will remove any tint effect. 26555 * 26556 * @member {number} 26557 * @default 0xFFFFFF 26558 */ 26559 prototypeAccessors.tint.get = function () 26560 { 26561 return this._tint; 26562 }; 26563 prototypeAccessors.tint.set = function (value) 26564 { 26565 this._tint = value; 26566 }; 26567 26568 /** 26569 * The current fill style. 26570 * 26571 * @member {PIXI.FillStyle} 26572 * @readonly 26573 */ 26574 prototypeAccessors.fill.get = function () 26575 { 26576 return this._fillStyle; 26577 }; 26578 26579 /** 26580 * The current line style. 26581 * 26582 * @member {PIXI.LineStyle} 26583 * @readonly 26584 */ 26585 prototypeAccessors.line.get = function () 26586 { 26587 return this._lineStyle; 26588 }; 26589 26590 /** 26591 * Specifies the line style used for subsequent calls to Graphics methods such as the lineTo() 26592 * method or the drawCircle() method. 26593 * 26594 * @param {number} [width=0] - width of the line to draw, will update the objects stored style 26595 * @param {number} [color=0] - color of the line to draw, will update the objects stored style 26596 * @param {number} [alpha=1] - alpha of the line to draw, will update the objects stored style 26597 * @param {number}
26597 [alignment=1] - alignment of the line to draw, (0 = inner, 0.5 = middle, 1 = outter) 26598 * @param {boolean} [native=false] - If true the lines will be draw using LINES instead of TRIANGLE_STRIP 26599 * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls 26600 */ 26601 Graphics.prototype.lineStyle = function lineStyle (width, color, alpha, alignment, native) 26602 { 26603 if ( width === void 0 ) { width = 0; } 26604 if ( color === void 0 ) { color = 0; } 26605 if ( alpha === void 0 ) { alpha = 1; } 26606 if ( alignment === void 0 ) { alignment = 0.5; } 26607 if ( native === void 0 ) { native = false; } 26608 26609 this.lineTextureStyle(width, Texture.WHITE, color, alpha, null, alignment, native); 26610 26611 return this; 26612 }; 26613 26614 /** 26615 * Like line style but support texture for line fill. 26616 * 26617 * @param {number} [width=0] - width of the line to draw, will update the objects stored style 26618 * @param {PIXI.Texture} [texture=PIXI.Texture.WHITE] - Texture to use 26619 * @param {number} [color=0] - color of the line to draw, will update the objects stored style 26620 * @param {number} [alpha=1] - alpha of the line to draw, will update the objects stored style 26621 * @param {PIXI.Matrix} [matrix=null] Texture matrix to transform texture 26622 * @param {number} [alignment=0.5] - alignment of the line to draw, (0 = inner, 0.5 = middle, 1 = outter) 26623 * @param {boolean} [native=false] - If true the lines will be draw using LINES instead of TRIANGLE_STRIP 26624 * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls 26625 */ 26626 Graphics.prototype.lineTextureStyle = function lineTextureStyle (width, texture, color, alpha, 26627 matrix, alignment, native) 26628 { 26629 if ( width === void 0 ) { width = 0; } 26630 if ( texture === void 0 ) { texture = Texture.WHITE; } 26631 if ( color === void 0 ) { color = 0xFFFFFF; } 26632 if ( alpha === void 0 ) { alpha = 1; } 26633 if ( matrix === void 0 ) { matrix = null; } 26634 if ( alignment === void 0 ) { alignment = 0.5; } 26635 if ( native === void 0 ) { native = false; } 26636 26637 if (this.currentPath) 26638 { 26639 this.startPoly(); 26640 } 26641 26642 var visible = width > 0 && alpha > 0; 26643 26644 if (!visible) 26645 { 26646 this._lineStyle.reset(); 26647 } 26648 else 26649 { 26650 if (matrix) 26651 { 26652 matrix = matrix.clone(); 26653 matrix.invert(); 26654 } 26655 26656 Object.assign(this._lineStyle, { 26657 color: color, 26658 width: width, 26659 alpha: alpha, 26660 matrix: matrix, 26661 texture: texture, 26662 alignment: alignment, 26663 native: native, 26664 visible: visible, 26665 }); 26666 } 26667 26668 return this; 26669 }; 26670 26671 /** 26672 * Start a polygon object internally 26673 * @protected 26674 */ 26675 Graphics.prototype.startPoly = function startPoly () 26676 { 26677 if (this.currentPath) 26678 { 26679 var points = this.currentPath.points; 26680 var len = this.currentPath.points.length; 26681 26682 if (len > 2) 26683 { 26684 this.drawShape(this.currentPath); 26685 this.currentPath = new Polygon(); 26686 this.currentPath.closeStroke = false; 26687 this.currentPath.points.push(points[len - 2], points[len - 1]); 26688 } 26689 } 26690 else 26691 { 26692 this.currentPath = new Polygon(); 26693 this.currentPath.closeStroke = false; 26694 } 26695 }; 26696 26697 /** 26698 * Finish the polygon object. 26699 * @protected 26700 */ 26701 Graphics.prototype.finishPoly = function finishPoly () 26702 { 26703 if (this.currentPath) 26704 { 26705 if (this.currentPath.points.length > 2) 26706 { 26707 this.drawShape(this.currentPath); 26708 this.currentPath = null; 26709 } 26710 else 26711 { 26712 this.currentPath.points.length = 0; 26713 } 26714 } 26715 }; 26716 26717 /** 26718 * Moves the current drawing position to x, y. 26719 * 26720 * @param {number} x - the X coordinate to move to 26721 * @param {number} y - the Y coordinate to move to 26722 * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls 26723 */ 26724 Graphics.prototype.moveTo = function moveTo (x, y) 26725 { 26726 this.startPoly(); 26727 this.currentPath.points[0] = x; 26728 this.currentPath.points[1] = y; 26729 26730 return this; 26731 }; 26732 26733 /** 26734 * Draws a line using the current line style from the current drawing position to (x, y); 26735 * The current drawing position is then set to (x, y). 26736 * 26737 * @param {number} x - the X coordinate to draw to 26738 * @param {number} y - the Y coordinate to draw to 26739 * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls 26740 */ 26741 Graphics.prototype.lineTo = function lineTo (x, y) 26742 { 26743 if (!this.currentPath) 26744 { 26745 this.moveTo(0, 0); 26746 } 26747 26748 // remove duplicates.. 26749 var points = this.currentPath.points; 26750 var fromX = points[points.length - 2]; 26751 var fromY = points[points.length - 1]; 26752 26753 if (fromX !== x || fromY !== y) 26754 { 26755 points.push(x, y); 26756 } 26757 26758 return this; 26759 }; 26760 26761 /** 26762 * Initialize the curve 26763 * 26764 * @protected 26765 * @param {number} [x=0] 26766 * @param {number} [y=0] 26767 */ 26768 Graphics.prototype._initCurve = function _initCurve (x, y) 26769 { 26770 if ( x === void 0 ) { x = 0; } 26771 if ( y === void 0 ) { y = 0; } 26772 26773 if (this.currentPath) 26774 { 26775 if (this.currentPath.points.length === 0) 26776 { 26777 this.currentPath.points = [x, y]; 26778 } 26779 } 26780 else 26781 { 26782 this.moveTo(x, y); 26783 } 26784 }; 26785 26786 /** 26787 * Calculate the points for a quadratic bezier curve and then draws it. 26788 * Based on: https://stackoverflow.com/questions/785097/how-do-i-implement-a-bezier-curve-in-c 26789 * 26790 * @param {number} cpX - Control point x 26791 * @param {number} cpY - Control point y 26792 * @param {number} toX - Destination point x 26793 * @param {number} toY - Destination point y 26794 * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls 26795 */ 26796 Graphics.prototype.quadraticCurveTo = function quadraticCurveTo (cpX, cpY, toX, toY) 26797 { 26798 this._initCurve(); 26799 26800 var points = this.currentPath.points; 26801 26802 if (points.length === 0) 26803 { 26804 this.moveTo(0, 0); 26805 } 26806 26807 QuadraticUtils.curveTo(cpX, cpY, toX, toY, points); 26808 26809 return this; 26810 }; 26811 26812 /** 26813 * Calculate the points for a bezier curve and then draws it. 26814 * 26815 * @param {number} cpX - Control point x 26816 * @param {number} cpY - Control point y 26817 * @param {number} cpX2 - Second Control point x 26818 * @param {number} cpY2 - Second Control point y 26819 * @param {number} toX - Destination point x 26820 * @param {number} toY - Destination point y 26821 * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls 26822 */ 26823 Graphics.prototype.bezierCurveTo = function bezierCurveTo (cpX, cpY, cpX2, cpY2, toX, toY) 26824 { 26825 this._initCurve(); 26826 26827 BezierUtils.curveTo(cpX, cpY, cpX2, cpY2, toX, toY, this.currentPath.points); 26828 26829 return this; 26830 }; 26831 26832 /** 26833 * The arcTo() method creates an arc/curve between two tangents on the canvas. 26834 * 26835 * "borrowed" from https://code.google.com/p/fxcanvas/ - thanks google! 26836 * 26837 * @param {number} x1 - The x-coordinate of the beginning of the arc 26838 * @param {number} y1 - The y-coordinate of the beginning of the arc 26839 * @param {number} x2 - The x-coordinate of the end of the arc 26840 * @param {number} y2 - The y-coordinate of the end of the arc 26841 * @param {number} radius - The radius of the arc 26842 * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls 26843 */ 26844 Graphics.prototype.arcTo = function arcTo (x1, y1, x2, y2, radius) 26845 { 26846 this._initCurve(x1, y1); 26847 26848 var points = this.currentPath.points; 26849 26850 var result = ArcUtils.curveTo(x1, y1, x2, y2, radius, points); 26851 26852 if (result) 26853 { 26854 var cx = result.cx; 26855 var cy = result.cy;
26856 var radius$1 = result.radius; 26857 var startAngle = result.startAngle; 26858 var endAngle = result.endAngle; 26859 var anticlockwise = result.anticlockwise; 26860 26861 this.arc(cx, cy, radius$1, startAngle, endAngle, anticlockwise); 26862 } 26863 26864 return this; 26865 }; 26866 26867 /** 26868 * The arc method creates an arc/curve (used to create circles, or parts of circles). 26869 * 26870 * @param {number} cx - The x-coordinate of the center of the circle 26871 * @param {number} cy - The y-coordinate of the center of the circle 26872 * @param {number} radius - The radius of the circle 26873 * @param {number} startAngle - The starting angle, in radians (0 is at the 3 o'clock position 26874 * of the arc's circle) 26875 * @param {number} endAngle - The ending angle, in radians 26876 * @param {boolean} [anticlockwise=false] - Specifies whether the drawing should be 26877 * counter-clockwise or clockwise. False is default, and indicates clockwise, while true 26878 * indicates counter-clockwise. 26879 * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls 26880 */ 26881 Graphics.prototype.arc = function arc (cx, cy, radius, startAngle, endAngle, anticlockwise) 26882 { 26883 if ( anticlockwise === void 0 ) { anticlockwise = false; } 26884 26885 if (startAngle === endAngle) 26886 { 26887 return this; 26888 } 26889 26890 if (!anticlockwise && endAngle <= startAngle) 26891 { 26892 endAngle += PI_2; 26893 } 26894 else if (anticlockwise && startAngle <= endAngle) 26895 { 26896 startAngle += PI_2; 26897 } 26898 26899 var sweep = endAngle - startAngle; 26900 26901 if (sweep === 0) 26902 { 26903 return this; 26904 } 26905 26906 var startX = cx + (Math.cos(startAngle) * radius); 26907 var startY = cy + (Math.sin(startAngle) * radius); 26908 26909 // If the currentPath exists, take its points. Otherwise call `moveTo` to start a path. 26910 var points = this.currentPath ? this.currentPath.points : null; 26911 26912 if (points) 26913 { 26914 // TODO: make a better fix. 26915 26916 // We check how far our start is from the last existing point 26917 var xDiff = Math.abs(points[points.length - 2] - startX); 26918 var yDiff = Math.abs(points[points.length - 1] - startY); 26919 26920 if (xDiff < 0.001 && yDiff < 0.001) 26921 { ; } 26922 else 26923 { 26924 points.push(startX, startY); 26925 } 26926 } 26927 else 26928 { 26929 this.moveTo(startX, startY); 26930 points = this.currentPath.points; 26931 } 26932 26933 ArcUtils.arc(startX, startY, cx, cy, radius, startAngle, endAngle, anticlockwise, points); 26934 26935 return this; 26936 }; 26937 26938 /** 26939 * Specifies a simple one-color fill that subsequent calls to other Graphics methods 26940 * (such as lineTo() or drawCircle()) use when drawing. 26941 * 26942 * @param {number} [color=0] - the color of the fill 26943 * @param {number} [alpha=1] - the alpha of the fill 26944 * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls 26945 */ 26946 Graphics.prototype.beginFill = function beginFill (color, alpha) 26947 { 26948 if ( color === void 0 ) { color = 0; } 26949 if ( alpha === void 0 ) { alpha = 1; } 26950 26951 return this.beginTextureFill(Texture.WHITE, color, alpha); 26952 }; 26953 26954 /** 26955 * Begin the texture fill 26956 * 26957 * @param {PIXI.Texture} [texture=PIXI.Texture.WHITE] - Texture to fill 26958 * @param {number} [color=0xffffff] - Background to fill behind texture 26959 * @param {number} [alpha=1] - Alpha of fill 26960 * @param {PIXI.Matrix} [matrix=null] - Transform matrix 26961 * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls 26962 */ 26963 Graphics.prototype.beginTextureFill = function beginTextureFill (texture, color, alpha, matrix) 26964 { 26965 if ( texture === void 0 ) { texture = Texture.WHITE; } 26966 if ( color === void 0 ) { color = 0xFFFFFF; } 26967 if ( alpha === void 0 ) { alpha = 1; } 26968 if ( matrix === void 0 ) { matrix = null; } 26969 26970 if (this.currentPath) 26971 { 26972 this.startPoly(); 26973 } 26974 26975 var visible = alpha > 0; 26976 26977 if (!visible) 26978 { 26979 this._fillStyle.reset(); 26980 } 26981 else 26982 { 26983 if (matrix) 26984 { 26985 matrix = matrix.clone(); 26986 matrix.invert(); 26987 } 26988 26989 Object.assign(this._fillStyle, { 26990 color: color, 26991 alpha: alpha, 26992 texture: texture, 26993 matrix: matrix, 26994 visible: visible, 26995 }); 26996 } 26997 26998 return this; 26999 }; 27000 27001 /** 27002 * Applies a fill to the lines and shapes that were added since the last call to the beginFill() method. 27003 * 27004 * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls 27005 */ 27006 Graphics.prototype.endFill = function endFill () 27007 { 27008 this.finishPoly(); 27009 27010 this._fillStyle.reset(); 27011 27012 return this; 27013 }; 27014 27015 /** 27016 * Draws a rectangle shape. 27017 * 27018 * @param {number} x - The X coord of the top-left of the rectangle 27019 * @param {number} y - The Y coord of the top-left of the rectangle 27020 * @param {number} width - The width of the rectangle 27021 * @param {number} height - The height of the rectangle 27022 * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls 27023 */ 27024 Graphics.prototype.drawRect = function drawRect (x, y, width, height) 27025 { 27026 return this.drawShape(new Rectangle(x, y, width, height)); 27027 }; 27028 27029 /** 27030 * Draw a rectangle shape with rounded/beveled corners. 27031 * 27032 * @param {number} x - The X coord of the top-left of the rectangle 27033 * @param {number} y - The Y coord of the top-left of the rectangle 27034 * @param {number} width - The width of the rectangle 27035 * @param {number} height - The height of the rectangle 27036 * @param {number} radius - Radius of the rectangle corners 27037 * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls 27038 */ 27039 Graphics.prototype.drawRoundedRect = function drawRoundedRect (x, y, width, height, radius) 27040 { 27041 return this.drawShape(new RoundedRectangle(x, y, width, height, radius)); 27042 }; 27043 27044 /** 27045 * Draws a circle. 27046 * 27047 * @param {number} x - The X coordinate of the center of the circle 27048 * @param {number} y - The Y coordinate of the center of the circle 27049 * @param {number} radius - The radius of the circle 27050 * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls 27051 */ 27052 Graphics.prototype.drawCircle = function drawCircle (x, y, radius) 27053 { 27054 return this.drawShape(new Circle(x, y, radius)); 27055 }; 27056 27057 /** 27058 * Draws an ellipse. 27059 * 27060 * @param {number} x - The X coordinate of the center of the ellipse 27061 * @param {number} y - The Y coordinate of the center of the ellipse 27062 * @param {number} width - The half width of the ellipse 27063 * @param {number} height - The half height of the ellipse 27064 * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls 27065 */ 27066 Graphics.prototype.drawEllipse = function drawEllipse (x, y, width, height) 27067 { 27068 return this.drawShape(new Ellipse(x, y, width, height)); 27069 }; 27070 27071 /** 27072 * Draws a polygon using the given path. 27073 * 27074 * @param {number[]|PIXI.Point[]|PIXI.Polygon} path - The path data used to construct the polygon. 27075 * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls 27076 */ 27077 Graphics.prototype.drawPolygon = function drawPolygon (path) 27078 { 27079 var arguments$1 = arguments; 27080 27081 // prevents an argument assignment deopt 27082 // see section 3.1: https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#3-managing-arguments 27083 var points = path; 27084 27085 var closeStroke = true;// !!this._fillStyle; 27086 27087 // check if data has points.. 27088 if (points.points) 27089 { 27090 closeStroke = points.closeStroke; 27091 points = points.points; 27092 } 27093 27094 if (!Array.isArray(points)) 27095 { 27096 // prevents an argument leak deopt 27097 // see section 3.2: https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#3-managing-arguments 27098 points = new Array(arguments.length); 27099 27100 for (var i = 0; i < points.length; ++i) 27101 { 27102 points[i] = arguments$1[i]; // eslint-disable-line prefer-rest-params 27103 } 27104 } 27105 27106 var shape = new Polygon(points); 27107 27108 shape.closeStroke = closeStroke; 27109 27110 this.drawShape(shape); 27111 27112 return this; 27113 }; 27114 27115 /** 27116 * Draw any shape. 27117 * 27118 * @param {PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.Rectangle|PIXI.RoundedRectangle} shape - Shape to draw 27119 * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls 27120 */ 27121 Graphics.prototype.drawShape = function drawShape (shape) 27122 { 27123 if (!this._holeMode) 27124 { 27125 this.geometry.drawShape( 27126 shape, 27127 this._fillStyle.clone(), 27128 this._lineStyle.clone(), 27129 this._matrix 27130 ); 27131 } 27132 else 27133 { 27134 this.geometry.drawHole(shape, this._matrix); 27135 } 27136 27137 return this; 27138 }; 27139 27140 /** 27141 * Draw a star shape with an arbitrary number of points. 27142 * 27143 * @param {number} x - Center X position of the star 27144 * @param {number} y - Center Y position of the star 27145 * @param {number} points - The number of points of the star, must be > 1 27146 * @param {number} radius - The outer radius of the star 27147 * @param {number} [innerRadius] - The inner radius between points, default half `radius` 27148 * @param {number} [rotation=0] - The rotation of the star in radians, where 0 is vertical 27149 * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls 27150 */ 27151 Graphics.prototype.drawStar = function drawStar (x, y, points, radius, innerRadius, rotation) 27152 { 27153 if ( rotation === void 0 ) { rotation = 0; } 27154 27155 return this.drawPolygon(new Star(x, y, points, radius, innerRadius, rotation)); 27156 }; 27157 27158 /** 27159 * Clears the graphics that were drawn to this Graphics object, and resets fill and line style settings. 27160 * 27161 * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls 27162 */ 27163 Graphics.prototype.clear = function clear () 27164 { 27165 this.geometry.clear(); 27166 27167 this._matrix = null; 27168 this._holeMode = false;
27169 this.currentPath = null; 27170 this._spriteRect = null; 27171 27172 return this; 27173 }; 27174 27175 /** 27176 * True if graphics consists of one rectangle, and thus, can be drawn like a Sprite and 27177 * masked with gl.scissor. 27178 * 27179 * @returns {boolean} True if only 1 rect. 27180 */ 27181 Graphics.prototype.isFastRect = function isFastRect () 27182 { 27183 // will fix this! 27184 return false; 27185 // this.graphicsData.length === 1 27186 // && this.graphicsData[0].shape.type === SHAPES.RECT 27187 // && !this.graphicsData[0].lineWidth; 27188 }; 27189 27190 /** 27191 * Renders the object using the WebGL renderer 27192 * 27193 * @protected 27194 * @param {PIXI.Renderer} renderer - The renderer 27195 */ 27196 Graphics.prototype._render = function _render (renderer) 27197 { 27198 this.finishPoly(); 27199 27200 var geometry = this.geometry; 27201 27202 // batch part.. 27203 // batch it! 27204 geometry.updateBatches(); 27205 27206 if (geometry.batchable) 27207 { 27208 if (this.batchDirty !== geometry.batchDirty) 27209 { 27210 this.batches = []; 27211 this.batchTint = -1; 27212 this._transformID = -1; 27213 this.batchDirty = geometry.batchDirty; 27214 27215 this.vertexData = new Float32Array(geometry.points); 27216 27217 var blendMode = this.blendMode; 27218 27219 for (var i = 0; i < geometry.batches.length; i++) 27220 { 27221 var gI = geometry.batches[i]; 27222 27223 var color = gI.style.color; 27224 27225 // + (alpha * 255 << 24); 27226 27227 var vertexData = new Float32Array(this.vertexData.buffer, 27228 gI.attribStart * 4 * 2, 27229 gI.attribSize * 2); 27230 27231 var uvs = new Float32Array(geometry.uvsFloat32.buffer, 27232 gI.attribStart * 4 * 2, 27233 gI.attribSize * 2); 27234 27235 var indices = new Uint16Array(geometry.indicesUint16.buffer, 27236 gI.start * 2, 27237 gI.size); 27238 27239 var batch = { 27240 vertexData: vertexData, 27241 blendMode: blendMode, 27242 indices: indices, 27243 uvs: uvs, 27244 _batchRGB: hex2rgb(color), 27245 _tintRGB: color, 27246 _texture: gI.style.texture, 27247 alpha: gI.style.alpha, 27248 worldAlpha: 1 }; 27249 27250 this.batches[i] = batch; 27251 } 27252 } 27253 27254 renderer.batch.setObjectRenderer(renderer.plugins.batch); 27255 27256 if (this.batches.length) 27257 { 27258 this.calculateVertices(); 27259 this.calculateTints(); 27260 27261 for (var i$1 = 0; i$1 < this.batches.length; i$1++) 27262 { 27263 var batch$1 = this.batches[i$1]; 27264 27265 batch$1.worldAlpha = this.worldAlpha * batch$1.alpha; 27266 27267 renderer.plugins.batch.render(batch$1); 27268 } 27269 } 27270 } 27271 else 27272 { 27273 // no batching... 27274 renderer.batch.flush(); 27275 27276 if (!this.shader) 27277 { 27278 // if there is no shader here, we can use the default shader. 27279 // and that only gets created if we actually need it.. 27280 if (!defaultShader) 27281 { 27282 var sampleValues = new Int32Array(16); 27283 27284 for (var i$2 = 0; i$2 < 16; i$2++) 27285 { 27286 sampleValues[i$2] = i$2; 27287 } 27288 27289 var uniforms = { 27290 tint: new Float32Array([1, 1, 1, 1]), 27291 translationMatrix: new Matrix(), 27292 default: UniformGroup.from({ uSamplers: sampleValues }, true), 27293 }; 27294 27295 // we can bbase default shader of the batch renderers program 27296 var program = renderer.plugins.batch.shader.program; 27297 27298 defaultShader = new Shader(program, uniforms); 27299 } 27300 27301 this.shader = defaultShader; 27302 } 27303 27304 var uniforms$1 = this.shader.uniforms; 27305 27306 // lets set the transfomr 27307 uniforms$1.translationMatrix = this.transform.worldTransform; 27308 27309 var tint = this.tint; 27310 var wa = this.worldAlpha; 27311 27312 // and then lets set the tint.. 27313 uniforms$1.tint[0] = (((tint >> 16) & 0xFF) / 255) * wa; 27314 uniforms$1.tint[1] = (((tint >> 8) & 0xFF) / 255) * wa; 27315 uniforms$1.tint[2] = ((tint & 0xFF) / 255) * wa; 27316 uniforms$1.tint[3] = wa; 27317 27318 // the first draw call, we can set the uniforms of the shader directly here. 27319 27320 // this means that we can tack advantage of the sync function of pixi! 27321 // bind and sync uniforms.. 27322 // there is a way to optimise this.. 27323 renderer.shader.bind(this.shader); 27324 27325 // then render it 27326 renderer.geometry.bind(geometry, this.shader); 27327 27328 // set state.. 27329 renderer.state.setState(this.state); 27330 27331 // then render the rest of them... 27332 for (var i$3 = 0; i$3 < geometry.drawCalls.length; i$3++) 27333 { 27334 var drawCall = geometry.drawCalls[i$3]; 27335 27336 var groupTextureCount = drawCall.textureCount; 27337 27338 for (var j = 0; j < groupTextureCount; j++) 27339 { 27340 renderer.texture.bind(drawCall.textures[j], j); 27341 } 27342 27343 // bind the geometry... 27344 renderer.geometry.draw(drawCall.type, drawCall.size, drawCall.start); 27345 } 27346 } 27347 }; 27348 27349 /** 27350 * Retrieves the bounds of the graphic shape as a rectangle object 27351 * 27352 * @protected 27353 */ 27354 Graphics.prototype._calculateBounds = function _calculateBounds () 27355 { 27356 this.finishPoly(); 27357 var lb = this.geometry.bounds; 27358 27359 this._bounds.addFrame(this.transform, lb.minX, lb.minY, lb.maxX, lb.maxY); 27360 }; 27361 27362 /** 27363 * Tests if a point is inside this graphics object 27364 * 27365 * @param {PIXI.Point} point - the point to test 27366 * @return {boolean} the result of the test 27367 */ 27368 Graphics.prototype.containsPoint = function containsPoint (point) 27369 { 27370 this.worldTransform.applyInverse(point, Graphics._TEMP_POINT); 27371 27372 return this.geometry.containsPoint(Graphics._TEMP_POINT); 27373 }; 27374 27375 /** 27376 * Recalcuate the tint by applying tin to batches using Graphics tint. 27377 * @protected 27378 */ 27379 Graphics.prototype.calculateTints = function calculateTints () 27380 { 27381 if (this.batchTint !== this.tint) 27382 { 27383 this.batchTint = this.tint; 27384 27385 var tintRGB = hex2rgb(this.tint, temp); 27386 27387 for (var i = 0; i < this.batches.length; i++) 27388 { 27389 var batch = this.batches[i]; 27390 27391 var batchTint = batch._batchRGB; 27392 27393 var r = (tintRGB[0] * batchTint[0]) * 255; 27394 var g = (tintRGB[1] * batchTint[1]) * 255; 27395 var b = (tintRGB[2] * batchTint[2]) * 255; 27396 27397 // TODO Ivan, can this be done in one go? 27398 var color = (r << 16) + (g << 8) + (b | 0); 27399 27400 batch._tintRGB = (color >> 16) 27401 + (color & 0xff00) 27402 + ((color & 0xff) << 16); 27403 } 27404 } 27405 }; 27406 27407 /** 27408 * If there's a transform update or a change to the shape of the 27409 * geometry, recaculate the vertices. 27410 * @protected 27411 */ 27412 Graphics.prototype.calculateVertices = function calculateVertices () 27413 { 27414 if (this._transformID === this.transform._worldID) 27415 { 27416 return; 27417 } 27418 27419 this._transformID = this.transform._worldID; 27420 27421 var wt = this.transform.worldTransform; 27422 var a = wt.a; 27423 var b = wt.b; 27424 var c = wt.c; 27425 var d = wt.d; 27426 var tx = wt.tx; 27427 var ty = wt.ty; 27428 27429 var data = this.geometry.points;// batch.vertexDataOriginal; 27430 var vertexData = this.vertexData; 27431 27432 var count = 0; 27433 27434 for (var i = 0; i < data.length; i += 2) 27435 { 27436 var x = data[i]; 27437 var y = data[i + 1]; 27438
27439 vertexData[count++] = (a * x) + (c * y) + tx; 27440 vertexData[count++] = (d * y) + (b * x) + ty; 27441 } 27442 }; 27443 27444 /** 27445 * Closes the current path. 27446 * 27447 * @return {PIXI.Graphics} Returns itself. 27448 */ 27449 Graphics.prototype.closePath = function closePath () 27450 { 27451 var currentPath = this.currentPath; 27452 27453 if (currentPath) 27454 { 27455 // we don't need to add extra point in the end because buildLine will take care of that 27456 currentPath.closeStroke = true; 27457 } 27458 27459 return this; 27460 }; 27461 27462 /** 27463 * Apply a matrix to the positional data. 27464 * 27465 * @param {PIXI.Matrix} matrix - Matrix to use for transform current shape. 27466 * @return {PIXI.Graphics} Returns itself. 27467 */ 27468 Graphics.prototype.setMatrix = function setMatrix (matrix) 27469 { 27470 this._matrix = matrix; 27471 27472 return this; 27473 }; 27474 27475 /** 27476 * Begin adding holes to the last draw shape 27477 * IMPORTANT: holes must be fully inside a shape to work 27478 * Also weirdness ensues if holes overlap! 27479 * Ellipses, Circles, Rectangles and Rounded Rectangles cannot be holes or host for holes in CanvasRenderer, 27480 * please use `moveTo` `lineTo`, `quadraticCurveTo` if you rely on pixi-legacy bundle. 27481 * @return {PIXI.Graphics} Returns itself. 27482 */ 27483 Graphics.prototype.beginHole = function beginHole () 27484 { 27485 this.finishPoly(); 27486 this._holeMode = true; 27487 27488 return this; 27489 }; 27490 27491 /** 27492 * End adding holes to the last draw shape 27493 * @return {PIXI.Graphics} Returns itself. 27494 */ 27495 Graphics.prototype.endHole = function endHole () 27496 { 27497 this.finishPoly(); 27498 this._holeMode = false; 27499 27500 return this; 27501 }; 27502 27503 /** 27504 * Destroys the Graphics object. 27505 * 27506 * @param {object|boolean} [options] - Options parameter. A boolean will act as if all 27507 * options have been set to that value 27508 * @param {boolean} [options.children=false] - if set to true, all the children will have 27509 * their destroy method called as well. 'options' will be passed on to those calls. 27510 * @param {boolean} [options.texture=false] - Only used for child Sprites if options.children is set to true 27511 * Should it destroy the texture of the child sprite 27512 * @param {boolean} [options.baseTexture=false] - Only used for child Sprites if options.children is set to true 27513 * Should it destroy the base texture of the child sprite 27514 */ 27515 Graphics.prototype.destroy = function destroy (options) 27516 { 27517 Container.prototype.destroy.call(this, options); 27518 27519 this.geometry.refCount--; 27520 if (this.geometry.refCount === 0) 27521 { 27522 this.geometry.dispose(); 27523 } 27524 27525 this._matrix = null; 27526 this.currentPath = null; 27527 this._lineStyle.destroy(); 27528 this._lineStyle = null; 27529 this._fillStyle.destroy(); 27530 this._fillStyle = null; 27531 this.geometry = null; 27532 this.shader = null; 27533 this.vertexData = null; 27534 this.batches.length = 0; 27535 this.batches = null; 27536 27537 Container.prototype.destroy.call(this, options); 27538 }; 27539 27540 Object.defineProperties( Graphics.prototype, prototypeAccessors ); 27541 27542 return Graphics; 27543 }(Container)); 27544 27545 /** 27546 * Temporary point to use for containsPoint 27547 * 27548 * @static 27549 * @private 27550 * @member {PIXI.Point} 27551 */ 27552 Graphics._TEMP_POINT = new Point(); 27553 27554 /*! 27555 * @pixi/sprite - v5.0.0-rc.3 27556 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 27557 * 27558 * @pixi/sprite is licensed under the MIT License. 27559 * http://www.opensource.org/licenses/mit-license 27560 */ 27561 27562 var tempPoint = new Point(); 27563 var indices = new Uint16Array([0, 1, 2, 0, 2, 3]); 27564 27565 /** 27566 * The Sprite object is the base for all textured objects that are rendered to the screen 27567 * 27568 * A sprite can be created directly from an image like this: 27569 * 27570 * ```js 27571 * let sprite = new PIXI.Sprite.from('assets/image.png'); 27572 * ``` 27573 * 27574 * The more efficient way to create sprites is using a {@link PIXI.Spritesheet}, 27575 * as swapping base textures when rendering to the screen is inefficient. 27576 * 27577 * ```js 27578 * PIXI.loader.add("assets/spritesheet.json").load(setup); 27579 * 27580 * function setup() { 27581 * let sheet = PIXI.loader.resources["assets/spritesheet.json"].spritesheet; 27582 * let sprite = new PIXI.Sprite(sheet.textures["image.png"]); 27583 * ... 27584 * } 27585 * ``` 27586 * 27587 * @class 27588 * @extends PIXI.Container 27589 * @memberof PIXI 27590 */ 27591 var Sprite = /*@__PURE__*/(function (Container) { 27592 function Sprite(texture) 27593 { 27594 Container.call(this); 27595 27596 /** 27597 * The anchor sets the origin point of the texture. 27598 * The default is 0,0 or taken from the {@link PIXI.Texture#defaultAnchor|Texture} 27599 * passed to the constructor. A value of 0,0 means the texture's origin is the top left.
27600 * Setting the anchor to 0.5,0.5 means the texture's origin is centered. 27601 * Setting the anchor to 1,1 would mean the texture's origin point will be the bottom right corner. 27602 * Note: Updating the {@link PIXI.Texture#defaultAnchor} after a Texture is 27603 * created does _not_ update the Sprite's anchor values. 27604 * 27605 * @member {PIXI.ObservablePoint} 27606 * @private 27607 */ 27608 this._anchor = new ObservablePoint( 27609 this._onAnchorUpdate, 27610 this, 27611 (texture ? texture.defaultAnchor.x : 0), 27612 (texture ? texture.defaultAnchor.y : 0) 27613 ); 27614 27615 /** 27616 * The texture that the sprite is using 27617 * 27618 * @private 27619 * @member {PIXI.Texture} 27620 */ 27621 this._texture = null; 27622 27623 /** 27624 * The width of the sprite (this is initially set by the texture) 27625 * 27626 * @private 27627 * @member {number} 27628 */ 27629 this._width = 0; 27630 27631 /** 27632 * The height of the sprite (this is initially set by the texture) 27633 * 27634 * @private 27635 * @member {number} 27636 */ 27637 this._height = 0; 27638 27639 /** 27640 * The tint applied to the sprite. This is a hex value. A value of 0xFFFFFF will remove any tint effect. 27641 * 27642 * @private 27643 * @member {number} 27644 * @default 0xFFFFFF 27645 */ 27646 this._tint = null; 27647 this._tintRGB = null; 27648 this.tint = 0xFFFFFF; 27649 27650 /** 27651 * The blend mode to be applied to the sprite. Apply a value of `PIXI.BLEND_MODES.NORMAL` to reset the blend mode. 27652 * 27653 * @member {number} 27654 * @default PIXI.BLEND_MODES.NORMAL 27655 * @see PIXI.BLEND_MODES 27656 */ 27657 this.blendMode = BLEND_MODES.NORMAL; 27658 27659 /** 27660 * The shader that will be used to render the sprite. Set to null to remove a current shader. 27661 * 27662 * @member {PIXI.Filter|PIXI.Shader} 27663 */ 27664 this.shader = null; 27665 27666 /** 27667 * An internal cached value of the tint. 27668 * 27669 * @private 27670 * @member {number} 27671 * @default 0xFFFFFF 27672 */ 27673 this.cachedTint = 0xFFFFFF; 27674 27675 this.uvs = null; 27676 27677 // call texture setter 27678 this.texture = texture || Texture.EMPTY; 27679 27680 /** 27681 * this is used to store the vertex data of the sprite (basically a quad) 27682 * 27683 * @private 27684 * @member {Float32Array} 27685 */ 27686 this.vertexData = new Float32Array(8); 27687 27688 /** 27689 * This is used to calculate the bounds of the object IF it is a trimmed sprite 27690 * 27691 * @private 27692 * @member {Float32Array} 27693 */ 27694 this.vertexTrimmedData = null; 27695 27696 this._transformID = -1; 27697 this._textureID = -1; 27698 27699 this._transformTrimmedID = -1; 27700 this._textureTrimmedID = -1; 27701 27702 // Batchable stuff.. 27703 // TODO could make this a mixin? 27704 this.indices = indices; 27705 this.size = 4; 27706 this.start = 0; 27707 27708 /** 27709 * Plugin that is responsible for rendering this element. 27710 * Allows to customize the rendering process without overriding '_render' & '_renderCanvas' methods. 27711 * 27712 * @member {string} 27713 * @default 'sprite' 27714 */ 27715 this.pluginName = 'batch'; 27716 27717 /** 27718 * used to fast check if a sprite is.. a sprite! 27719 * @member {boolean} 27720 */ 27721 this.isSprite = true; 27722 27723 /** 27724 * Internal roundPixels field 27725 * 27726 * @member {boolean} 27727 * @private 27728 */ 27729 this._roundPixels = settings.ROUND_PIXELS; 27730 } 27731 27732 if ( Container ) { Sprite.__proto__ = Container; } 27733 Sprite.prototype = Object.create( Container && Container.prototype ); 27734 Sprite.prototype.constructor = Sprite; 27735 27736 var prototypeAccessors = { roundPixels: { configurable: true },width: { configurable: true },height: { configurable: true },anchor: { configurable: true },tint: { configurable: true },texture: { configurable: true } }; 27737 27738 /** 27739 * When the texture is updated, this event will fire to update the scale and frame 27740 * 27741 * @private 27742 */ 27743 Sprite.prototype._onTextureUpdate = function _onTextureUpdate () 27744 { 27745 this._textureID = -1; 27746 this._textureTrimmedID = -1; 27747 this.cachedTint = 0xFFFFFF; 27748 27749 this.uvs = this._texture._uvs.uvsFloat32; 27750 // so if _width is 0 then width was not set.. 27751 if (this._width) 27752 { 27753 this.scale.x = sign(this.scale.x) * this._width / this._texture.orig.width; 27754 } 27755 27756 if (this._height) 27757 { 27758 this.scale.y = sign(this.scale.y) * this._height / this._texture.orig.height; 27759 } 27760 }; 27761 27762 /**
27763 * Called when the anchor position updates. 27764 * 27765 * @private 27766 */ 27767 Sprite.prototype._onAnchorUpdate = function _onAnchorUpdate () 27768 { 27769 this._transformID = -1; 27770 this._transformTrimmedID = -1; 27771 }; 27772 27773 /** 27774 * calculates worldTransform * vertices, store it in vertexData 27775 */ 27776 Sprite.prototype.calculateVertices = function calculateVertices () 27777 { 27778 var texture = this._texture; 27779 27780 if (this._transformID === this.transform._worldID && this._textureID === texture._updateID) 27781 { 27782 return; 27783 } 27784 27785 this._transformID = this.transform._worldID; 27786 this._textureID = texture._updateID; 27787 27788 // set the vertex data 27789 27790 var wt = this.transform.worldTransform; 27791 var a = wt.a; 27792 var b = wt.b; 27793 var c = wt.c; 27794 var d = wt.d; 27795 var tx = wt.tx; 27796 var ty = wt.ty; 27797 var vertexData = this.vertexData; 27798 var trim = texture.trim; 27799 var orig = texture.orig; 27800 var anchor = this._anchor; 27801 27802 var w0 = 0; 27803 var w1 = 0; 27804 var h0 = 0; 27805 var h1 = 0; 27806 27807 if (trim) 27808 { 27809 // if the sprite is trimmed and is not a tilingsprite then we need to add the extra 27810 // space before transforming the sprite coords. 27811 w1 = trim.x - (anchor._x * orig.width); 27812 w0 = w1 + trim.width; 27813 27814 h1 = trim.y - (anchor._y * orig.height); 27815 h0 = h1 + trim.height; 27816 } 27817 else 27818 { 27819 w1 = -anchor._x * orig.width; 27820 w0 = w1 + orig.width; 27821 27822 h1 = -anchor._y * orig.height; 27823 h0 = h1 + orig.height; 27824 } 27825 27826 // xy 27827 vertexData[0] = (a * w1) + (c * h1) + tx; 27828 vertexData[1] = (d * h1) + (b * w1) + ty; 27829 27830 // xy 27831 vertexData[2] = (a * w0) + (c * h1) + tx; 27832 vertexData[3] = (d * h1) + (b * w0) + ty; 27833 27834 // xy 27835 vertexData[4] = (a * w0) + (c * h0) + tx; 27836 vertexData[5] = (d * h0) + (b * w0) + ty; 27837 27838 // xy 27839 vertexData[6] = (a * w1) + (c * h0) + tx; 27840 vertexData[7] = (d * h0) + (b * w1) + ty; 27841 27842 if (this._roundPixels) 27843 { 27844 for (var i = 0; i < 8; i++) 27845 { 27846 vertexData[i] = Math.round(vertexData[i]); 27847 } 27848 } 27849 }; 27850 27851 /** 27852 * calculates worldTransform * vertices for a non texture with a trim. store it in vertexTrimmedData 27853 * This is used to ensure that the true width and height of a trimmed texture is respected 27854 */ 27855 Sprite.prototype.calculateTrimmedVertices = function calculateTrimmedVertices () 27856 { 27857 if (!this.vertexTrimmedData) 27858 { 27859 this.vertexTrimmedData = new Float32Array(8); 27860 } 27861 else if (this._transformTrimmedID === this.transform._worldID && this._textureTrimmedID === this._texture._updateID) 27862 { 27863 return; 27864 } 27865 27866 this._transformTrimmedID = this.transform._worldID; 27867 this._textureTrimmedID = this._texture._updateID; 27868
27869 // lets do some special trim code! 27870 var texture = this._texture; 27871 var vertexData = this.vertexTrimmedData; 27872 var orig = texture.orig; 27873 var anchor = this._anchor; 27874 27875 // lets calculate the new untrimmed bounds.. 27876 var wt = this.transform.worldTransform; 27877 var a = wt.a; 27878 var b = wt.b; 27879 var c = wt.c; 27880 var d = wt.d; 27881 var tx = wt.tx; 27882 var ty = wt.ty; 27883 27884 var w1 = -anchor._x * orig.width; 27885 var w0 = w1 + orig.width; 27886 27887 var h1 = -anchor._y * orig.height; 27888 var h0 = h1 + orig.height; 27889 27890 // xy 27891 vertexData[0] = (a * w1) + (c * h1) + tx; 27892 vertexData[1] = (d * h1) + (b * w1) + ty; 27893 27894 // xy 27895 vertexData[2] = (a * w0) + (c * h1) + tx; 27896 vertexData[3] = (d * h1) + (b * w0) + ty; 27897 27898 // xy 27899 vertexData[4] = (a * w0) + (c * h0) + tx; 27900 vertexData[5] = (d * h0) + (b * w0) + ty; 27901 27902 // xy 27903 vertexData[6] = (a * w1) + (c * h0) + tx; 27904 vertexData[7] = (d * h0) + (b * w1) + ty; 27905 }; 27906 27907 /** 27908 * 27909 * Renders the object using the WebGL renderer 27910 * 27911 * @protected 27912 * @param {PIXI.Renderer} renderer - The webgl renderer to use. 27913 */ 27914 Sprite.prototype._render = function _render (renderer) 27915 { 27916 this.calculateVertices(); 27917 27918 renderer.batch.setObjectRenderer(renderer.plugins[this.pluginName]); 27919 renderer.plugins[this.pluginName].render(this); 27920 }; 27921 27922 /** 27923 * Updates the bounds of the sprite. 27924 * 27925 * @protected 27926 */ 27927 Sprite.prototype._calculateBounds = function _calculateBounds () 27928 { 27929 var trim = this._texture.trim; 27930 var orig = this._texture.orig; 27931 27932 // First lets check to see if the current texture has a trim.. 27933 if (!trim || (trim.width === orig.width && trim.height === orig.height)) 27934 { 27935 // no trim! lets use the usual calculations.. 27936 this.calculateVertices(); 27937 this._bounds.addQuad(this.vertexData); 27938 } 27939 else 27940 { 27941 // lets calculate a special trimmed bounds... 27942 this.calculateTrimmedVertices(); 27943 this._bounds.addQuad(this.vertexTrimmedData); 27944 } 27945 }; 27946 27947 /** 27948 * Gets the local bounds of the sprite object. 27949 * 27950 * @param {PIXI.Rectangle} rect - The output rectangle. 27951 * @return {PIXI.Rectangle} The bounds. 27952 */ 27953 Sprite.prototype.getLocalBounds = function getLocalBounds (rect) 27954 { 27955 // we can do a fast local bounds if the sprite has no children! 27956 if (this.children.length === 0) 27957 { 27958 this._bounds.minX = this._texture.orig.width * -this._anchor._x; 27959 this._bounds.minY = this._texture.orig.height * -this._anchor._y; 27960 this._bounds.maxX = this._texture.orig.width * (1 - this._anchor._x); 27961 this._bounds.maxY = this._texture.orig.height * (1 - this._anchor._y); 27962 27963 if (!rect) 27964 { 27965 if (!this._localBoundsRect) 27966 { 27967 this._localBoundsRect = new Rectangle(); 27968 } 27969 27970 rect = this._localBoundsRect; 27971 } 27972 27973 return this._bounds.getRectangle(rect); 27974 } 27975 27976 return Container.prototype.getLocalBounds.call(this, rect); 27977 }; 27978 27979 /** 27980 * Tests if a point is inside this sprite 27981 * 27982 * @param {PIXI.Point} point - the point to test 27983 * @return {boolean} the result of the test 27984 */ 27985 Sprite.prototype.containsPoint = function containsPoint (point) 27986 { 27987 this.worldTransform.applyInverse(point, tempPoint); 27988 27989 var width = this._texture.orig.width; 27990 var height = this._texture.orig.height; 27991 var x1 = -width * this.anchor.x; 27992 var y1 = 0; 27993 27994 if (tempPoint.x >= x1 && tempPoint.x < x1 + width) 27995 { 27996 y1 = -height * this.anchor.y; 27997 27998 if (tempPoint.y >= y1 && tempPoint.y < y1 + height) 27999 { 28000 return true; 28001 } 28002 } 28003 28004 return false;
28005 }; 28006 28007 /** 28008 * Destroys this sprite and optionally its texture and children 28009 * 28010 * @param {object|boolean} [options] - Options parameter. A boolean will act as if all options 28011 * have been set to that value 28012 * @param {boolean} [options.children=false] - if set to true, all the children will have their destroy 28013 * method called as well. 'options' will be passed on to those calls. 28014 * @param {boolean} [options.texture=false] - Should it destroy the current texture of the sprite as well 28015 * @param {boolean} [options.baseTexture=false] - Should it destroy the base texture of the sprite as well 28016 */ 28017 Sprite.prototype.destroy = function destroy (options) 28018 { 28019 Container.prototype.destroy.call(this, options); 28020 28021 this._texture.off('update', this._onTextureUpdate, this); 28022 28023 this._anchor = null; 28024 28025 var destroyTexture = typeof options === 'boolean' ? options : options && options.texture; 28026 28027 if (destroyTexture) 28028 { 28029 var destroyBaseTexture = typeof options === 'boolean' ? options : options && options.baseTexture; 28030 28031 this._texture.destroy(!!destroyBaseTexture); 28032 } 28033 28034 this._texture = null; 28035 this.shader = null; 28036 }; 28037 28038 // some helper functions.. 28039 28040 /** 28041 * Helper function that creates a new sprite based on the source you provide. 28042 * The source can be - frame id, image url, video url, canvas element, video element, base texture 28043 * 28044 * @static 28045 * @param {number|string|PIXI.Texture|HTMLCanvasElement|HTMLVideoElement} source Source to create texture from 28046 * @param {object} [options] See {@link PIXI.BaseTexture}'s constructor for options. 28047 * @return {PIXI.Sprite} The newly created sprite 28048 */ 28049 Sprite.from = function from (source, options) 28050 { 28051 var texture = (source instanceof Texture) 28052 ? source 28053 : new Texture.from(source, options); 28054 28055 return new Sprite(texture); 28056 }; 28057 28058 /** 28059 * If true PixiJS will Math.floor() x/y values when rendering, stopping pixel interpolation. 28060 * Advantages can include sharper image quality (like text) and faster rendering on canvas. 28061 * The main disadvantage is movement of objects may appear less smooth. 28062 * To set the global default, change {@link PIXI.settings.ROUND_PIXELS} 28063 * 28064 * @member {boolean} 28065 * @default false 28066 */ 28067 prototypeAccessors.roundPixels.set = function (value) 28068 { 28069 if (this._roundPixels !== value) 28070 { 28071 this._transformID = -1; 28072 } 28073 this._roundPixels = value; 28074 }; 28075 28076 prototypeAccessors.roundPixels.get = function () 28077 { 28078 return this._roundPixels; 28079 }; 28080 28081 /** 28082 * The width of the sprite, setting this will actually modify the scale to achieve the value set 28083 * 28084 * @member {number} 28085 */ 28086 prototypeAccessors.width.get = function () 28087 { 28088 return Math.abs(this.scale.x) * this._texture.orig.width; 28089 }; 28090 28091 prototypeAccessors.width.set = function (value) // eslint-disable-line require-jsdoc 28092 { 28093 var s = sign(this.scale.x) || 1; 28094 28095 this.scale.x = s * value / this._texture.orig.width; 28096 this._width = value; 28097 }; 28098 28099 /** 28100 * The height of the sprite, setting this will actually modify the scale to achieve the value set 28101 * 28102 * @member {number} 28103 */ 28104 prototypeAccessors.height.get = function () 28105 { 28106 return Math.abs(this.scale.y) * this._texture.orig.height; 28107 }; 28108 28109 prototypeAccessors.height.set = function (value) // eslint-disable-line require-jsdoc 28110 { 28111 var s = sign(this.scale.y) || 1; 28112 28113 this.scale.y = s * value / this._texture.orig.height; 28114 this._height = value; 28115 }; 28116 28117 /** 28118 * The anchor sets the origin point of the text. The default value is taken from the {@link PIXI.Texture|Texture} 28119 * and passed to the constructor. 28120 * 28121 * The default is `(0,0)`, this means the text's origin is the top left. 28122 *
28123 * Setting the anchor to `(0.5,0.5)` means the text's origin is centered. 28124 * 28125 * Setting the anchor to `(1,1)` would mean the text's origin point will be the bottom right corner. 28126 * 28127 * If you pass only single parameter, it will set both x and y to the same value as shown in the example below. 28128 * 28129 * @example 28130 * const sprite = new PIXI.Sprite(texture); 28131 * sprite.anchor.set(0.5); // This will set the origin to center. (0.5) is same as (0.5, 0.5). 28132 * 28133 * @member {PIXI.ObservablePoint} 28134 */ 28135 prototypeAccessors.anchor.get = function () 28136 { 28137 return this._anchor; 28138 }; 28139 28140 prototypeAccessors.anchor.set = function (value) // eslint-disable-line require-jsdoc 28141 { 28142 this._anchor.copyFrom(value); 28143 }; 28144 28145 /** 28146 * The tint applied to the sprite. This is a hex value. 28147 * A value of 0xFFFFFF will remove any tint effect. 28148 * 28149 * @member {number} 28150 * @default 0xFFFFFF 28151 */ 28152 prototypeAccessors.tint.get = function () 28153 { 28154 return this._tint; 28155 }; 28156 28157 prototypeAccessors.tint.set = function (value) // eslint-disable-line require-jsdoc 28158 { 28159 this._tint = value; 28160 this._tintRGB = (value >> 16) + (value & 0xff00) + ((value & 0xff) << 16); 28161 }; 28162 28163 /** 28164 * The texture that the sprite is using 28165 * 28166 * @member {PIXI.Texture} 28167 */ 28168 prototypeAccessors.texture.get = function () 28169 { 28170 return this._texture; 28171 }; 28172 28173 prototypeAccessors.texture.set = function (value) // eslint-disable-line require-jsdoc 28174 { 28175 if (this._texture === value) 28176 { 28177 return; 28178 } 28179 28180 this._texture = value || Texture.EMPTY; 28181 this.cachedTint = 0xFFFFFF; 28182 28183 this._textureID = -1; 28184 this._textureTrimmedID = -1; 28185 28186 if (value) 28187 { 28188 // wait for the texture to load 28189 if (value.baseTexture.valid) 28190 { 28191 this._onTextureUpdate(); 28192 } 28193 else 28194 { 28195 value.once('update', this._onTextureUpdate, this); 28196 } 28197 } 28198 }; 28199 28200 Object.defineProperties( Sprite.prototype, prototypeAccessors ); 28201 28202 return Sprite; 28203 }(Container)); 28204 28205 /*! 28206 * @pixi/text - v5.0.0-rc.3 28207 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 28208 * 28209 * @pixi/text is licensed under the MIT License. 28210 * http://www.opensource.org/licenses/mit-license 28211 */ 28212 28213 /** 28214 * Constants that define the type of gradient on text. 28215 * 28216 * @static 28217 * @constant 28218 * @name TEXT_GRADIENT 28219 * @memberof PIXI 28220 * @type {object} 28221 * @property {number} LINEAR_VERTICAL Vertical gradient 28222 * @property {number} LINEAR_HORIZONTAL Linear gradient 28223 */ 28224 var TEXT_GRADIENT = { 28225 LINEAR_VERTICAL: 0, 28226 LINEAR_HORIZONTAL: 1, 28227 }; 28228 28229 // disabling eslint for now, going to rewrite this in v5 28230 28231 var defaultStyle = { 28232 align: 'left', 28233 breakWords: false, 28234 dropShadow: false, 28235 dropShadowAlpha: 1, 28236 dropShadowAngle: Math.PI / 6, 28237 dropShadowBlur: 0, 28238 dropShadowColor: 'black', 28239 dropShadowDistance: 5, 28240 fill: 'black', 28241 fillGradientType: TEXT_GRADIENT.LINEAR_VERTICAL, 28242 fillGradientStops: [], 28243 fontFamily: 'Arial', 28244 fontSize: 26, 28245 fontStyle: 'normal', 28246 fontVariant: 'normal', 28247 fontWeight: 'normal', 28248 letterSpacing: 0, 28249 lineHeight: 0, 28250 lineJoin: 'miter', 28251 miterLimit: 10, 28252 padding: 0, 28253 stroke: 'black', 28254 strokeThickness: 0, 28255 textBaseline: 'alphabetic', 28256 trim: false, 28257 whiteSpace: 'pre', 28258 wordWrap: false, 28259 wordWrapWidth: 100, 28260 leading: 0, 28261 }; 28262 28263 /** 28264 * A TextStyle Object contains information to decorate a Text objects. 28265 * 28266 * An instance can be shared between multiple Text objects; then changing the style will update all text objects using it. 28267 * 28268 * A tool can be used to generate a text style [here](https://pixijs.io/pixi-text-style). 28269 * 28270 * @class 28271 * @memberof PIXI 28272 */ 28273 var TextStyle = function TextStyle(style) 28274 { 28275 this.styleID = 0; 28276 28277 this.reset(); 28278 28279 deepCopyProperties(this, style, style); 28280 }; 28281 28282 var prototypeAccessors$7 = { align: { configurable: true },breakWords: { configurable: true },dropShadow: { configurable: true },dropShadowAlpha: { configurable: true },dropShadowAngle: { configurable: true },dropShadowBlur: { configurable: true },dropShadowColor: { configurable: true },dropShadowDistance: { configurable: true },fill: { configurable: true },fillGradientType: { configurable: true },fillGradientStops: { configurable: true },fontFamily: { configurable: true },fontSize: { configurable: true },fontStyle: { configurable: true },fontVariant: { configurable: true },fontWeight: { configurable: true },letterSpacing: { configurable: true },lineHeight: { configurable: true },leading: { configurable: true },lineJoin: { configurable: true },miterLimit: { configurable: true },padding: { configurable: true },stroke: { configurable: true },strokeThickness: { configurable: true },textBaseline: { configurable: true },trim: { configurable: true },whiteSpace: { configurable: true },wordWrap: { configurable: true },wordWrapWidth: { configurable: true } }; 28283 28284 /** 28285 * Creates a new TextStyle object with the same values as this one. 28286 * Note that the only the properties of the object are cloned. 28287 * 28288 * @return {PIXI.TextStyle} New cloned TextStyle object 28289 */ 28290 TextStyle.prototype.clone = function clone () 28291 { 28292 var clonedProperties = {}; 28293 28294 deepCopyProperties(clonedProperties, this, defaultStyle); 28295 28296 return new TextStyle(clonedProperties); 28297 }; 28298 28299 /** 28300 * Resets all properties to the defaults specified in TextStyle.prototype._default 28301 */ 28302 TextStyle.prototype.reset = function reset () 28303 { 28304 deepCopyProperties(this, defaultStyle, defaultStyle); 28305 }; 28306 28307 /** 28308 * Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text 28309 * 28310 * @member {string} 28311 */ 28312 prototypeAccessors$7.align.get = function () 28313 { 28314 return this._align; 28315 }; 28316 prototypeAccessors$7.align.set = function (align) // eslint-disable-line require-jsdoc 28317 { 28318 if (this._align !== align) 28319 { 28320 this._align = align; 28321 this.styleID++; 28322 } 28323 }; 28324 28325 /** 28326 * Indicates if lines can be wrapped within words, it needs wordWrap to be set to true 28327 * 28328 * @member {boolean} 28329 */ 28330 prototypeAccessors$7.breakWords.get = function () 28331 { 28332 return this._breakWords; 28333 }; 28334 prototypeAccessors$7.breakWords.set = function (breakWords) // eslint-disable-line require-jsdoc 28335 { 28336 if (this._breakWords !== breakWords) 28337 { 28338 this._breakWords = breakWords; 28339 this.styleID++; 28340 } 28341 }; 28342 28343 /** 28344 * Set a drop shadow for the text 28345 * 28346 * @member {boolean} 28347 */ 28348 prototypeAccessors$7.dropShadow.get = function () 28349 { 28350 return this._dropShadow; 28351 }; 28352 prototypeAccessors$7.dropShadow.set = function (dropShadow) // eslint-disable-line require-jsdoc 28353 { 28354 if (this._dropShadow !== dropShadow) 28355 { 28356 this._dropShadow = dropShadow; 28357 this.styleID++; 28358 } 28359 }; 28360 28361 /** 28362 * Set alpha for the drop shadow 28363 * 28364 * @member {number} 28365 */ 28366 prototypeAccessors$7.dropShadowAlpha.get = function () 28367 { 28368 return this._dropShadowAlpha; 28369 }; 28370 prototypeAccessors$7.dropShadowAlpha.set = function (dropShadowAlpha) // eslint-disable-line require-jsdoc 28371 { 28372 if (this._dropShadowAlpha !== dropShadowAlpha) 28373 { 28374 this._dropShadowAlpha = dropShadowAlpha; 28375 this.styleID++; 28376 } 28377 }; 28378 28379 /** 28380 * Set a angle of the drop shadow 28381 * 28382 * @member {number} 28383 */ 28384 prototypeAccessors$7.dropShadowAngle.get = function () 28385 { 28386 return this._dropShadowAngle; 28387 }; 28388 prototypeAccessors$7.dropShadowAngle.set = function (dropShadowAngle) // eslint-disable-line require-jsdoc 28389 { 28390 if (this._dropShadowAngle !== dropShadowAngle) 28391 { 28392 this._dropShadowAngle = dropShadowAngle; 28393 this.styleID++; 28394 } 28395 }; 28396 28397 /** 28398 * Set a shadow blur radius 28399 * 28400 * @member {number} 28401 */ 28402 prototypeAccessors$7.dropShadowBlur.get = function () 28403 { 28404 return this._dropShadowBlur; 28405 }; 28406 prototypeAccessors$7.dropShadowBlur.set = function (dropShadowBlur) // eslint-disable-line require-jsdoc 28407 { 28408 if (this._dropShadowBlur !== dropShadowBlur) 28409 { 28410 this._dropShadowBlur = dropShadowBlur; 28411 this.styleID++; 28412 } 28413 }; 28414 28415 /** 28416 * A fill style to be used on the dropshadow e.g 'red', '#00FF00' 28417 * 28418 * @member {string|number} 28419 */ 28420 prototypeAccessors$7.dropShadowColor.get = function () 28421 { 28422 return this._dropShadowColor; 28423 }; 28424 prototypeAccessors$7.dropShadowColor.set = function (dropShadowColor) // eslint-disable-line require-jsdoc 28425 { 28426 var outputColor = getColor(dropShadowColor); 28427 if (this._dropShadowColor !== outputColor) 28428 { 28429 this._dropShadowColor = outputColor; 28430 this.styleID++; 28431 } 28432 }; 28433 28434 /** 28435 * Set a distance of the drop shadow 28436 * 28437 * @member {number} 28438 */ 28439 prototypeAccessors$7.dropShadowDistance.get = function () 28440 { 28441 return this._dropShadowDistance; 28442 }; 28443 prototypeAccessors$7.dropShadowDistance.set = function (dropShadowDistance) // eslint-disable-line require-jsdoc 28444 { 28445 if (this._dropShadowDistance !== dropShadowDistance) 28446 { 28447 this._dropShadowDistance = dropShadowDistance; 28448 this.styleID++; 28449 } 28450 }; 28451 28452 /** 28453 * A canvas fillstyle that will be used on the text e.g 'red', '#00FF00'. 28454 * Can be an array to create a gradient eg ['#000000','#FFFFFF'] 28455 * {@link https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle|MDN} 28456 * 28457 * @member {string|string[]|number|number[]|CanvasGradient|CanvasPattern} 28458 */ 28459 prototypeAccessors$7.fill.get = function () 28460 { 28461 return this._fill; 28462 }; 28463 prototypeAccessors$7.fill.set = function (fill) // eslint-disable-line require-jsdoc 28464 { 28465 var outputColor = getColor(fill); 28466 if (this._fill !== outputColor) 28467 { 28468 this._fill = outputColor; 28469 this.styleID++; 28470 } 28471 }; 28472 28473 /** 28474 * If fill is an array of colours to create a gradient, this can change the type/direction of the gradient. 28475 * See {@link PIXI.TEXT_GRADIENT} 28476 * 28477 * @member {number} 28478 */ 28479 prototypeAccessors$7.fillGradientType.get = function () 28480 { 28481 return this._fillGradientType; 28482 }; 28483 prototypeAccessors$7.fillGradientType.set = function (fillGradientType) // eslint-disable-line require-jsdoc 28484 { 28485 if (this._fillGradientType !== fillGradientType) 28486 { 28487 this._fillGradientType = fillGradientType; 28488 this.styleID++; 28489 } 28490 }; 28491 28492 /** 28493 * If fill is an array of colours to create a gradient, this array can set the stop points 28494 * (numbers between 0 and 1) for the color, overriding the default behaviour of evenly spacing them. 28495 * 28496 * @member {number[]} 28497 */ 28498 prototypeAccessors$7.fillGradientStops.get = function () 28499 { 28500 return this._fillGradientStops; 28501 }; 28502 prototypeAccessors$7.fillGradientStops.set = function (fillGradientStops) // eslint-disable-line require-jsdoc 28503 { 28504 if (!areArraysEqual(this._fillGradientStops,fillGradientStops)) 28505 { 28506 this._fillGradientStops = fillGradientStops; 28507 this.styleID++; 28508 } 28509 }; 28510 28511 /** 28512 * The font family 28513 * 28514 * @member {string|string[]} 28515 */ 28516 prototypeAccessors$7.fontFamily.get = function () 28517 { 28518 return this._fontFamily; 28519 }; 28520 prototypeAccessors$7.fontFamily.set = function (fontFamily) // eslint-disable-line require-jsdoc 28521 { 28522 if (this.fontFamily !== fontFamily) 28523 { 28524 this._fontFamily = fontFamily; 28525 this.styleID++; 28526 } 28527 }; 28528 28529 /** 28530 * The font size 28531 * (as a number it converts to px, but as a string, equivalents are '26px','20pt','160%' or '1.6em') 28532 * 28533 * @member {number|string} 28534 */ 28535 prototypeAccessors$7.fontSize.get = function () 28536 { 28537 return this._fontSize; 28538 }; 28539 prototypeAccessors$7.fontSize.set = function (fontSize) // eslint-disable-line require-jsdoc 28540 { 28541 if (this._fontSize !== fontSize) 28542 { 28543 this._fontSize = fontSize; 28544 this.styleID++; 28545 } 28546 }; 28547 28548 /** 28549 * The font style 28550 * ('normal', 'italic' or 'oblique') 28551 * 28552 * @member {string} 28553 */ 28554 prototypeAccessors$7.fontStyle.get = function () 28555 { 28556 return this._fontStyle; 28557 }; 28558 prototypeAccessors$7.fontStyle.set = function (fontStyle) // eslint-disable-line require-jsdoc 28559 { 28560 if (this._fontStyle !== fontStyle) 28561 { 28562 this._fontStyle = fontStyle; 28563 this.styleID++; 28564 } 28565 }; 28566 28567 /** 28568 * The font variant 28569 * ('normal' or 'small-caps') 28570 * 28571 * @member {string} 28572 */ 28573 prototypeAccessors$7.fontVariant.get = function () 28574 { 28575 return this._fontVariant; 28576 }; 28577 prototypeAccessors$7.fontVariant.set = function (fontVariant) // eslint-disable-line require-jsdoc 28578 { 28579 if (this._fontVariant !== fontVariant) 28580 { 28581 this._fontVariant = fontVariant; 28582 this.styleID++; 28583 } 28584 }; 28585 28586 /** 28587 * The font weight 28588 * ('normal', 'bold', 'bolder', 'lighter' and '100', '200', '300', '400', '500', '600', '700', 800' or '900') 28589 * 28590 * @member {string} 28591 */ 28592 prototypeAccessors$7.fontWeight.get = function () 28593 { 28594 return this._fontWeight; 28595 }; 28596 prototypeAccessors$7.fontWeight.set = function (fontWeight) // eslint-disable-line require-jsdoc 28597 { 28598 if (this._fontWeight !== fontWeight) 28599 { 28600 this._fontWeight = fontWeight; 28601 this.styleID++; 28602 } 28603 }; 28604 28605 /** 28606 * The amount of spacing between letters, default is 0 28607 * 28608 * @member {number} 28609 */ 28610 prototypeAccessors$7.letterSpacing.get = function () 28611 { 28612 return this._letterSpacing; 28613 }; 28614 prototypeAccessors$7.letterSpacing.set = function (letterSpacing) // eslint-disable-line require-jsdoc 28615 { 28616 if (this._letterSpacing !== letterSpacing) 28617 { 28618 this._letterSpacing = letterSpacing; 28619 this.styleID++; 28620 } 28621 }; 28622 28623 /** 28624 * The line height, a number that represents the vertical space that a letter uses 28625 * 28626 * @member {number} 28627 */ 28628 prototypeAccessors$7.lineHeight.get = function () 28629 { 28630 return this._lineHeight; 28631 }; 28632 prototypeAccessors$7.lineHeight.set = function (lineHeight) // eslint-disable-line require-jsdoc 28633 { 28634 if (this._lineHeight !== lineHeight) 28635 { 28636 this._lineHeight = lineHeight; 28637 this.styleID++; 28638 } 28639 }; 28640 28641 /** 28642 * The space between lines 28643 * 28644 * @member {number} 28645 */ 28646 prototypeAccessors$7.leading.get = function () 28647 { 28648 return this._leading; 28649 }; 28650 prototypeAccessors$7.leading.set = function (leading) // eslint-disable-line require-jsdoc 28651 { 28652 if (this._leading !== leading) 28653 { 28654 this._leading = leading; 28655 this.styleID++; 28656 } 28657 }; 28658 28659 /** 28660 * The lineJoin property sets the type of corner created, it can resolve spiked text issues. 28661 * Default is 'miter' (creates a sharp corner). 28662 * 28663 * @member {string} 28664 */ 28665 prototypeAccessors$7.lineJoin.get = function () 28666 { 28667 return this._lineJoin; 28668 }; 28669 prototypeAccessors$7.lineJoin.set = function (lineJoin) // eslint-disable-line require-jsdoc 28670 { 28671 if (this._lineJoin !== lineJoin) 28672 { 28673 this._lineJoin = lineJoin; 28674 this.styleID++; 28675 } 28676 }; 28677 28678 /** 28679 * The miter limit to use when using the 'miter' lineJoin mode 28680 * This can reduce or increase the spikiness of rendered text. 28681 * 28682 * @member {number} 28683 */ 28684 prototypeAccessors$7.miterLimit.get = function () 28685 { 28686 return this._miterLimit; 28687 }; 28688 prototypeAccessors$7.miterLimit.set = function (miterLimit) // eslint-disable-line require-jsdoc 28689 { 28690 if (this._miterLimit !== miterLimit) 28691 {
28692 this._miterLimit = miterLimit; 28693 this.styleID++; 28694 } 28695 }; 28696 28697 /** 28698 * Occasionally some fonts are cropped. Adding some padding will prevent this from happening 28699 * by adding padding to all sides of the text. 28700 * 28701 * @member {number} 28702 */ 28703 prototypeAccessors$7.padding.get = function () 28704 { 28705 return this._padding; 28706 }; 28707 prototypeAccessors$7.padding.set = function (padding) // eslint-disable-line require-jsdoc 28708 { 28709 if (this._padding !== padding) 28710 { 28711 this._padding = padding; 28712 this.styleID++; 28713 } 28714 }; 28715 28716 /** 28717 * A canvas fillstyle that will be used on the text stroke 28718 * e.g 'blue', '#FCFF00' 28719 * 28720 * @member {string|number} 28721 */ 28722 prototypeAccessors$7.stroke.get = function () 28723 { 28724 return this._stroke; 28725 }; 28726 prototypeAccessors$7.stroke.set = function (stroke) // eslint-disable-line require-jsdoc 28727 { 28728 var outputColor = getColor(stroke); 28729 if (this._stroke !== outputColor) 28730 { 28731 this._stroke = outputColor; 28732 this.styleID++; 28733 } 28734 }; 28735 28736 /** 28737 * A number that represents the thickness of the stroke. 28738 * Default is 0 (no stroke) 28739 * 28740 * @member {number} 28741 */ 28742 prototypeAccessors$7.strokeThickness.get = function () 28743 { 28744 return this._strokeThickness; 28745 }; 28746 prototypeAccessors$7.strokeThickness.set = function (strokeThickness) // eslint-disable-line require-jsdoc 28747 { 28748 if (this._strokeThickness !== strokeThickness) 28749 { 28750 this._strokeThickness = strokeThickness; 28751 this.styleID++; 28752 } 28753 }; 28754 28755 /** 28756 * The baseline of the text that is rendered. 28757 * 28758 * @member {string} 28759 */ 28760 prototypeAccessors$7.textBaseline.get = function () 28761 { 28762 return this._textBaseline; 28763 }; 28764 prototypeAccessors$7.textBaseline.set = function (textBaseline) // eslint-disable-line require-jsdoc 28765 { 28766 if (this._textBaseline !== textBaseline) 28767 { 28768 this._textBaseline = textBaseline; 28769 this.styleID++; 28770 } 28771 }; 28772 28773 /** 28774 * Trim transparent borders 28775 * 28776 * @member {boolean} 28777 */ 28778 prototypeAccessors$7.trim.get = function () 28779 { 28780 return this._trim; 28781 }; 28782 prototypeAccessors$7.trim.set = function (trim) // eslint-disable-line require-jsdoc 28783 { 28784 if (this._trim !== trim) 28785 { 28786 this._trim = trim; 28787 this.styleID++; 28788 } 28789 }; 28790 28791 /** 28792 * How newlines and spaces should be handled. 28793 * Default is 'pre' (preserve, preserve). 28794 * 28795 * value | New lines | Spaces 28796 * --- | --- | --- 28797 * 'normal' | Collapse | Collapse 28798 * 'pre' | Preserve | Preserve 28799 * 'pre-line' | Preserve | Collapse 28800 * 28801 * @member {string} 28802 */ 28803 prototypeAccessors$7.whiteSpace.get = function () 28804 { 28805 return this._whiteSpace; 28806 }; 28807 prototypeAccessors$7.whiteSpace.set = function (whiteSpace) // eslint-disable-line require-jsdoc 28808 { 28809 if (this._whiteSpace !== whiteSpace) 28810 { 28811 this._whiteSpace = whiteSpace; 28812 this.styleID++; 28813 } 28814 }; 28815 28816 /** 28817 * Indicates if word wrap should be used 28818 * 28819 * @member {boolean} 28820 */ 28821 prototypeAccessors$7.wordWrap.get = function () 28822 { 28823 return this._wordWrap; 28824 }; 28825 prototypeAccessors$7.wordWrap.set = function (wordWrap) // eslint-disable-line require-jsdoc 28826 { 28827 if (this._wordWrap !== wordWrap) 28828 { 28829 this._wordWrap = wordWrap; 28830 this.styleID++; 28831 } 28832 }; 28833 28834 /** 28835 * The width at which text will wrap, it needs wordWrap to be set to true 28836 * 28837 * @member {number} 28838 */ 28839 prototypeAccessors$7.wordWrapWidth.get = function () 28840 { 28841 return this._wordWrapWidth; 28842 }; 28843 prototypeAccessors$7.wordWrapWidth.set = function (wordWrapWidth) // eslint-disable-line require-jsdoc 28844 { 28845 if (this._wordWrapWidth !== wordWrapWidth) 28846 { 28847 this._wordWrapWidth = wordWrapWidth; 28848 this.styleID++; 28849 } 28850 }; 28851 28852 /** 28853 * Generates a font style string to use for `TextMetrics.measureFont()`. 28854 * 28855 * @return {string} Font style string, for passing to `TextMetrics.measureFont()` 28856 */ 28857 TextStyle.prototype.toFontString = function toFontString () 28858 { 28859 // build canvas api font setting from individual components. Convert a numeric this.fontSize to px 28860 var fontSizeString = (typeof this.fontSize === 'number') ? ((this.fontSize) + "px") : this.fontSize; 28861 28862 // Clean-up fontFamily property by quoting each font name 28863 // this will support font names with spaces 28864 var fontFamilies = this.fontFamily; 28865 28866 if (!Array.isArray(this.fontFamily)) 28867 { 28868 fontFamilies = this.fontFamily.split(','); 28869 } 28870 28871 for (var i = fontFamilies.length - 1; i >= 0; i--) 28872 { 28873 // Trim any extra white-space 28874 var fontFamily = fontFamilies[i].trim(); 28875 28876 // Check if font already contains strings 28877 if (!(/([\"\'])[^\'\"]+\1/).test(fontFamily)) 28878 { 28879 fontFamily = "\"" + fontFamily + "\""; 28880 } 28881 fontFamilies[i] = fontFamily; 28882 } 28883 28884 return ((this.fontStyle) + " " + (this.fontVariant) + " " + (this.fontWeight) + " " + fontSizeString + " " + (fontFamilies.join(','))); 28885 }; 28886 28887 Object.defineProperties( TextStyle.prototype, prototypeAccessors$7 ); 28888 28889 /** 28890 * Utility function to convert hexadecimal colors to strings, and simply return the color if it's a string. 28891 * @private 28892 * @param {number|number[]} color 28893 * @return {string} The color as a string. 28894 */ 28895 function getSingleColor(color) 28896 { 28897 if (typeof color === 'number') 28898 { 28899 return hex2string(color); 28900 } 28901 else if ( typeof color === 'string' ) 28902 { 28903 if ( color.indexOf('0x') === 0 ) 28904 { 28905 color = color.replace('0x', '#'); 28906 } 28907 } 28908 28909 return color; 28910 } 28911 28912 /** 28913 * Utility function to convert hexadecimal colors to strings, and simply return the color if it's a string. 28914 * This version can also convert array of colors 28915 * @private 28916 * @param {number|number[]} color 28917 * @return {string} The color as a string. 28918 */ 28919 function getColor(color) 28920 { 28921 if (!Array.isArray(color)) 28922 { 28923 return getSingleColor(color); 28924 } 28925 else 28926 { 28927 for (var i = 0; i < color.length; ++i) 28928 { 28929 color[i] = getSingleColor(color[i]); 28930 } 28931 28932 return color; 28933 } 28934 } 28935
28936 /** 28937 * Utility function to convert hexadecimal colors to strings, and simply return the color if it's a string. 28938 * This version can also convert array of colors 28939 * @private 28940 * @param {Array} array1 First array to compare 28941 * @param {Array} array2 Second array to compare 28942 * @return {boolean} Do the arrays contain the same values in the same order 28943 */ 28944 function areArraysEqual(array1, array2) 28945 { 28946 if (!Array.isArray(array1) || !Array.isArray(array2)) 28947 { 28948 return false; 28949 } 28950 28951 if (array1.length !== array2.length) 28952 { 28953 return false; 28954 } 28955 28956 for (var i = 0; i < array1.length; ++i) 28957 { 28958 if (array1[i] !== array2[i]) 28959 { 28960 return false; 28961 } 28962 } 28963 28964 return true; 28965 } 28966 28967 /** 28968 * Utility function to ensure that object properties are copied by value, and not by reference 28969 * @private 28970 * @param {Object} target Target object to copy properties into 28971 * @param {Object} source Source object for the properties to copy 28972 * @param {string} propertyObj Object containing properties names we want to loop over 28973 */ 28974 function deepCopyProperties(target, source, propertyObj) { 28975 for (var prop in propertyObj) { 28976 if (Array.isArray(source[prop])) { 28977 target[prop] = source[prop].slice(); 28978 } else { 28979 target[prop] = source[prop]; 28980 } 28981 } 28982 } 28983 28984 /** 28985 * The TextMetrics object represents the measurement of a block of text with a specified style. 28986 * 28987 * ```js 28988 * let style = new PIXI.TextStyle({fontFamily : 'Arial', fontSize: 24, fill : 0xff1010, align : 'center'}) 28989 * let textMetrics = PIXI.TextMetrics.measureText('Your text', style) 28990 * ``` 28991 * 28992 * @class 28993 * @memberof PIXI 28994 */ 28995 var TextMetrics = function TextMetrics(text, style, width, height, lines, lineWidths, lineHeight, maxLineWidth, fontProperties) 28996 { 28997 this.text = text; 28998 this.style = style; 28999 this.width = width; 29000 this.height = height; 29001 this.lines = lines; 29002 this.lineWidths = lineWidths; 29003 this.lineHeight = lineHeight; 29004 this.maxLineWidth = maxLineWidth; 29005 this.fontProperties = fontProperties; 29006 }; 29007 29008 /** 29009 * Measures the supplied string of text and returns a Rectangle. 29010 * 29011 * @param {string} text - the text to measure. 29012 * @param {PIXI.TextStyle} style - the text style to use for measuring 29013 * @param {boolean} [wordWrap] - optional override for if word-wrap should be applied to the text. 29014 * @param {HTMLCanvasElement} [canvas] - optional specification of the canvas to use for measuring. 29015 * @return {PIXI.TextMetrics} measured width and height of the text. 29016 */ 29017 TextMetrics.measureText = function measureText (text, style, wordWrap, canvas) 29018 { 29019 if ( canvas === void 0 ) { canvas = TextMetrics._canvas; } 29020 29021 wordWrap = (wordWrap === undefined || wordWrap === null) ? style.wordWrap : wordWrap; 29022 var font = style.toFontString(); 29023 var fontProperties = TextMetrics.measureFont(font); 29024 29025 // fallback in case UA disallow canvas data extraction 29026 // (toDataURI, getImageData functions) 29027 if (fontProperties.fontSize === 0) 29028 { 29029 fontProperties.fontSize = style.fontSize; 29030 fontProperties.ascent = style.fontSize; 29031 } 29032 29033 var context = canvas.getContext('2d'); 29034 29035 context.font = font; 29036 29037 var outputText = wordWrap ? TextMetrics.wordWrap(text, style, canvas) : text; 29038 var lines = outputText.split(/(?:\r\n|\r|\n)/); 29039 var lineWidths = new Array(lines.length); 29040 var maxLineWidth = 0; 29041 29042 for (var i = 0; i < lines.length; i++) 29043 { 29044 var lineWidth = context.measureText(lines[i]).width + ((lines[i].length - 1) * style.letterSpacing); 29045 29046 lineWidths[i] = lineWidth; 29047 maxLineWidth = Math.max(maxLineWidth, lineWidth); 29048 } 29049 var width = maxLineWidth + style.strokeThickness; 29050 29051 if (style.dropShadow) 29052 { 29053 width += style.dropShadowDistance; 29054 } 29055 29056 var lineHeight = style.lineHeight || fontProperties.fontSize + style.strokeThickness; 29057 var height = Math.max(lineHeight, fontProperties.fontSize + style.strokeThickness) 29058 + ((lines.length - 1) * (lineHeight + style.leading)); 29059 29060 if (style.dropShadow) 29061 { 29062 height += style.dropShadowDistance; 29063 } 29064 29065 return new TextMetrics( 29066 text, 29067 style, 29068 width, 29069 height, 29070 lines, 29071 lineWidths, 29072 lineHeight + style.leading, 29073 maxLineWidth, 29074 fontProperties 29075 ); 29076 }; 29077 29078 /**
29079 * Applies newlines to a string to have it optimally fit into the horizontal 29080 * bounds set by the Text object's wordWrapWidth property. 29081 * 29082 * @private 29083 * @param {string} text - String to apply word wrapping to 29084 * @param {PIXI.TextStyle} style - the style to use when wrapping 29085 * @param {HTMLCanvasElement} [canvas] - optional specification of the canvas to use for measuring. 29086 * @return {string} New string with new lines applied where required 29087 */ 29088 TextMetrics.wordWrap = function wordWrap (text, style, canvas) 29089 { 29090 if ( canvas === void 0 ) { canvas = TextMetrics._canvas; } 29091 29092 var context = canvas.getContext('2d'); 29093 29094 var width = 0; 29095 var line = ''; 29096 var lines = ''; 29097 29098 var cache = {}; 29099 var letterSpacing = style.letterSpacing; 29100 var whiteSpace = style.whiteSpace; 29101 29102 // How to handle whitespaces 29103 var collapseSpaces = TextMetrics.collapseSpaces(whiteSpace); 29104 var collapseNewlines = TextMetrics.collapseNewlines(whiteSpace); 29105 29106 // whether or not spaces may be added to the beginning of lines 29107 var canPrependSpaces = !collapseSpaces; 29108 29109 // There is letterSpacing after every char except the last one 29110 // t_h_i_s_' '_i_s_' '_a_n_' '_e_x_a_m_p_l_e_' '_! 29111 // so for convenience the above needs to be compared to width + 1 extra letterSpace 29112 // t_h_i_s_' '_i_s_' '_a_n_' '_e_x_a_m_p_l_e_' '_!_ 29113 // ________________________________________________ 29114 // And then the final space is simply no appended to each line 29115 var wordWrapWidth = style.wordWrapWidth + letterSpacing; 29116 29117 // break text into words, spaces and newline chars 29118 var tokens = TextMetrics.tokenize(text); 29119 29120 for (var i = 0; i < tokens.length; i++) 29121 { 29122 // get the word, space or newlineChar 29123 var token = tokens[i]; 29124 29125 // if word is a new line 29126 if (TextMetrics.isNewline(token)) 29127 { 29128 // keep the new line 29129 if (!collapseNewlines) 29130 { 29131 lines += TextMetrics.addLine(line); 29132 canPrependSpaces = !collapseSpaces; 29133 line = ''; 29134 width = 0; 29135 continue; 29136 } 29137 29138 // if we should collapse new lines 29139 // we simply convert it into a space 29140 token = ' '; 29141 } 29142 29143 // if we should collapse repeated whitespaces 29144 if (collapseSpaces) 29145 { 29146 // check both this and the last tokens for spaces 29147 var currIsBreakingSpace = TextMetrics.isBreakingSpace(token); 29148 var lastIsBreakingSpace = TextMetrics.isBreakingSpace(line[line.length - 1]); 29149 29150 if (currIsBreakingSpace && lastIsBreakingSpace) 29151 { 29152 continue; 29153 } 29154 } 29155 29156 // get word width from cache if possible 29157 var tokenWidth = TextMetrics.getFromCache(token, letterSpacing, cache, context); 29158 29159 // word is longer than desired bounds 29160 if (tokenWidth > wordWrapWidth) 29161 { 29162 // if we are not already at the beginning of a line 29163 if (line !== '') 29164 { 29165 // start newlines for overflow words 29166 lines += TextMetrics.addLine(line); 29167 line = ''; 29168 width = 0; 29169 } 29170 29171 // break large word over multiple lines 29172 if (TextMetrics.canBreakWords(token, style.breakWords)) 29173 { 29174 // break word into characters 29175 var characters = token.split(''); 29176 29177 // loop the characters 29178 for (var j = 0; j < characters.length; j++) 29179 { 29180 var char = characters[j]; 29181 29182 var k = 1; 29183 // we are not at the end of the token 29184 29185 while (characters[j + k]) 29186 { 29187 var nextChar = characters[j + k]; 29188 var lastChar = char[char.length - 1]; 29189 29190 // should not split chars 29191 if (!TextMetrics.canBreakChars(lastChar, nextChar, token, j, style.breakWords)) 29192 {
29193 // combine chars & move forward one 29194 char += nextChar; 29195 } 29196 else 29197 { 29198 break; 29199 } 29200 29201 k++; 29202 } 29203 29204 j += char.length - 1; 29205 29206 var characterWidth = TextMetrics.getFromCache(char, letterSpacing, cache, context); 29207 29208 if (characterWidth + width > wordWrapWidth) 29209 { 29210 lines += TextMetrics.addLine(line); 29211 canPrependSpaces = false; 29212 line = ''; 29213 width = 0; 29214 } 29215 29216 line += char; 29217 width += characterWidth; 29218 } 29219 } 29220 29221 // run word out of the bounds 29222 else 29223 { 29224 // if there are words in this line already 29225 // finish that line and start a new one 29226 if (line.length > 0) 29227 { 29228 lines += TextMetrics.addLine(line); 29229 line = ''; 29230 width = 0; 29231 } 29232 29233 var isLastToken = i === tokens.length - 1; 29234 29235 // give it its own line if it's not the end 29236 lines += TextMetrics.addLine(token, !isLastToken); 29237 canPrependSpaces = false; 29238 line = ''; 29239 width = 0; 29240 } 29241 } 29242 29243 // word could fit 29244 else 29245 { 29246 // word won't fit because of existing words 29247 // start a new line 29248 if (tokenWidth + width > wordWrapWidth) 29249 { 29250 // if its a space we don't want it 29251 canPrependSpaces = false; 29252 29253 // add a new line 29254 lines += TextMetrics.addLine(line); 29255 29256 // start a new line 29257 line = ''; 29258 width = 0; 29259 } 29260 29261 // don't add spaces to the beginning of lines 29262 if (line.length > 0 || !TextMetrics.isBreakingSpace(token) || canPrependSpaces) 29263 { 29264 // add the word to the current line 29265 line += token; 29266 29267 // update width counter 29268 width += tokenWidth; 29269 } 29270 } 29271 } 29272 29273 lines += TextMetrics.addLine(line, false); 29274 29275 return lines; 29276 }; 29277 29278 /** 29279 * Convienience function for logging each line added during the wordWrap 29280 * method 29281 * 29282 * @private 29283 * @param {string} line - The line of text to add 29284 * @param {boolean} newLine - Add new line character to end 29285 * @return {string} A formatted line 29286 */ 29287 TextMetrics.addLine = function addLine (line, newLine) 29288 { 29289 if ( newLine === void 0 ) { newLine = true; } 29290 29291 line = TextMetrics.trimRight(line); 29292 29293 line = (newLine) ? (line + "\n") : line; 29294 29295 return line; 29296 }; 29297 29298 /** 29299 * Gets & sets the widths of calculated characters in a cache object 29300 * 29301 * @private 29302 * @param {string} key The key 29303 * @param {number} letterSpacing The letter spacing 29304 * @param {object} cache The cache 29305 * @param {CanvasRenderingContext2D} context The canvas context 29306 * @return {number} The from cache. 29307 */ 29308 TextMetrics.getFromCache = function getFromCache (key, letterSpacing, cache, context) 29309 { 29310 var width = cache[key]; 29311 29312 if (width === undefined) 29313 { 29314 var spacing = ((key.length) * letterSpacing); 29315 29316 width = context.measureText(key).width + spacing; 29317 cache[key] = width; 29318 } 29319 29320 return width; 29321 }; 29322 29323 /** 29324 * Determines whether we should collapse breaking spaces 29325 * 29326 * @private 29327 * @param {string} whiteSpace The TextStyle property whiteSpace 29328 * @return {boolean} should collapse 29329 */ 29330 TextMetrics.collapseSpaces = function collapseSpaces (whiteSpace) 29331 { 29332 return (whiteSpace === 'normal' || whiteSpace === 'pre-line'); 29333 }; 29334 29335 /** 29336 * Determines whether we should collapse newLine chars 29337 * 29338 * @private 29339 * @param {string} whiteSpace The white space 29340 * @return {boolean} should collapse 29341 */ 29342 TextMetrics.collapseNewlines = function collapseNewlines (whiteSpace) 29343 { 29344 return (whiteSpace === 'normal'); 29345 }; 29346 29347 /**
29348 * trims breaking whitespaces from string 29349 * 29350 * @private 29351 * @param {string} text The text 29352 * @return {string} trimmed string 29353 */ 29354 TextMetrics.trimRight = function trimRight (text) 29355 { 29356 if (typeof text !== 'string') 29357 { 29358 return ''; 29359 } 29360 29361 for (var i = text.length - 1; i >= 0; i--) 29362 { 29363 var char = text[i]; 29364 29365 if (!TextMetrics.isBreakingSpace(char)) 29366 { 29367 break; 29368 } 29369 29370 text = text.slice(0, -1); 29371 } 29372 29373 return text; 29374 }; 29375 29376 /** 29377 * Determines if char is a newline. 29378 * 29379 * @private 29380 * @param {string} char The character 29381 * @return {boolean} True if newline, False otherwise. 29382 */ 29383 TextMetrics.isNewline = function isNewline (char) 29384 { 29385 if (typeof char !== 'string') 29386 { 29387 return false; 29388 } 29389 29390 return (TextMetrics._newlines.indexOf(char.charCodeAt(0)) >= 0); 29391 }; 29392 29393 /** 29394 * Determines if char is a breaking whitespace. 29395 * 29396 * @private 29397 * @param {string} char The character 29398 * @return {boolean} True if whitespace, False otherwise. 29399 */ 29400 TextMetrics.isBreakingSpace = function isBreakingSpace (char) 29401 { 29402 if (typeof char !== 'string') 29403 { 29404 return false; 29405 } 29406 29407 return (TextMetrics._breakingSpaces.indexOf(char.charCodeAt(0)) >= 0); 29408 }; 29409 29410 /** 29411 * Splits a string into words, breaking-spaces and newLine characters 29412 * 29413 * @private 29414 * @param {string} text The text 29415 * @return {string[]} A tokenized array 29416 */ 29417 TextMetrics.tokenize = function tokenize (text) 29418 { 29419 var tokens = []; 29420 var token = ''; 29421 29422 if (typeof text !== 'string') 29423 { 29424 return tokens; 29425 } 29426 29427 for (var i = 0; i < text.length; i++) 29428 { 29429 var char = text[i]; 29430 29431 if (TextMetrics.isBreakingSpace(char) || TextMetrics.isNewline(char)) 29432 { 29433 if (token !== '') 29434 { 29435 tokens.push(token); 29436 token = ''; 29437 } 29438 29439 tokens.push(char); 29440 29441 continue; 29442 } 29443 29444 token += char; 29445 } 29446 29447 if (token !== '') 29448 { 29449 tokens.push(token); 29450 } 29451 29452 return tokens; 29453 }; 29454 29455 /** 29456 * This method exists to be easily overridden 29457 * It allows one to customise which words should break 29458 * Examples are if the token is CJK or numbers. 29459 * It must return a boolean. 29460 * 29461 * @private 29462 * @param {string} token The token 29463 * @param {boolean} breakWords The style attr break words 29464 * @return {boolean} whether to break word or not 29465 */ 29466 TextMetrics.canBreakWords = function canBreakWords (token, breakWords) 29467 { 29468 return breakWords; 29469 }; 29470 29471 /** 29472 * This method exists to be easily overridden 29473 * It allows one to determine whether a pair of characters 29474 * should be broken by newlines 29475 * For example certain characters in CJK langs or numbers. 29476 * It must return a boolean. 29477 * 29478 * @private 29479 * @param {string} char The character 29480 * @param {string} nextChar The next character 29481 * @param {string} token The token/word the characters are from 29482 * @param {number} index The index in the token of the char 29483 * @param {boolean} breakWords The style attr break words 29484 * @return {boolean} whether to break word or not 29485 */ 29486 TextMetrics.canBreakChars = function canBreakChars (char, nextChar, token, index, breakWords) // eslint-disable-line no-unused-vars 29487 { 29488 return true; 29489 }; 29490 29491 /** 29492 * Calculates the ascent, descent and fontSize of a given font-style 29493 * 29494 * @static 29495 * @param {string} font - String representing the style of the font 29496 * @return {PIXI.IFontMetrics} Font properties object 29497 */ 29498 TextMetrics.measureFont = function measureFont (font) 29499 { 29500 // as this method is used for preparing assets, don't recalculate things if we don't need to 29501 if (TextMetrics._fonts[font]) 29502 { 29503 return TextMetrics._fonts[font]; 29504 } 29505 29506 var properties = {}; 29507 29508 var canvas = TextMetrics._canvas; 29509 var context = TextMetrics._context; 29510 29511 context.font = font; 29512 29513 var metricsString = TextMetrics.METRICS_STRING + TextMetrics.BASELINE_SYMBOL; 29514 var width = Math.ceil(context.measureText(metricsString).width);
29515 var baseline = Math.ceil(context.measureText(TextMetrics.BASELINE_SYMBOL).width); 29516 var height = 2 * baseline; 29517 29518 baseline = baseline * TextMetrics.BASELINE_MULTIPLIER | 0; 29519 29520 canvas.width = width; 29521 canvas.height = height; 29522 29523 context.fillStyle = '#f00'; 29524 context.fillRect(0, 0, width, height); 29525 29526 context.font = font; 29527 29528 context.textBaseline = 'alphabetic'; 29529 context.fillStyle = '#000'; 29530 context.fillText(metricsString, 0, baseline); 29531 29532 var imagedata = context.getImageData(0, 0, width, height).data; 29533 var pixels = imagedata.length; 29534 var line = width * 4; 29535 29536 var i = 0; 29537 var idx = 0; 29538 var stop = false; 29539 29540 // ascent. scan from top to bottom until we find a non red pixel 29541 for (i = 0; i < baseline; ++i) 29542 { 29543 for (var j = 0; j < line; j += 4) 29544 { 29545 if (imagedata[idx + j] !== 255) 29546 { 29547 stop = true; 29548 break; 29549 } 29550 } 29551 if (!stop) 29552 { 29553 idx += line; 29554 } 29555 else 29556 { 29557 break; 29558 } 29559 } 29560 29561 properties.ascent = baseline - i; 29562 29563 idx = pixels - line; 29564 stop = false; 29565 29566 // descent. scan from bottom to top until we find a non red pixel 29567 for (i = height; i > baseline; --i) 29568 { 29569 for (var j$1 = 0; j$1 < line; j$1 += 4) 29570 { 29571 if (imagedata[idx + j$1] !== 255) 29572 { 29573 stop = true; 29574 break; 29575 } 29576 } 29577 29578 if (!stop) 29579 { 29580 idx -= line; 29581 } 29582 else 29583 { 29584 break; 29585 } 29586 } 29587 29588 properties.descent = i - baseline; 29589 properties.fontSize = properties.ascent + properties.descent; 29590 29591 TextMetrics._fonts[font] = properties; 29592 29593 return properties; 29594 }; 29595 29596 /** 29597 * Clear font metrics in metrics cache. 29598 * 29599 * @static 29600 * @param {string} [font] - font name. If font name not set then clear cache for all fonts. 29601 */ 29602 TextMetrics.clearMetrics = function clearMetrics (font) 29603 { 29604 if ( font === void 0 ) { font = ''; } 29605 29606 if (font) 29607 { 29608 delete TextMetrics._fonts[font]; 29609 } 29610 else 29611 { 29612 TextMetrics._fonts = {}; 29613 } 29614 }; 29615 29616 /** 29617 * Internal return object for {@link PIXI.TextMetrics.measureFont `TextMetrics.measureFont`}. 29618 * 29619 * @typedef {object} FontMetrics 29620 * @property {number} ascent - The ascent distance 29621 * @property {number} descent - The descent distance 29622 * @property {number} fontSize - Font size from ascent to descent 29623 * @memberof PIXI.TextMetrics 29624 * @private 29625 */ 29626 29627 var canvas = document.createElement('canvas'); 29628 29629 canvas.width = canvas.height = 10; 29630 29631 /** 29632 * Cached canvas element for measuring text 29633 * @memberof PIXI.TextMetrics 29634 * @type {HTMLCanvasElement} 29635 * @private 29636 */ 29637 TextMetrics._canvas = canvas; 29638 29639 /** 29640 * Cache for context to use. 29641 * @memberof PIXI.TextMetrics 29642 * @type {CanvasRenderingContext2D} 29643 * @private 29644 */ 29645 TextMetrics._context = canvas.getContext('2d'); 29646 29647 /** 29648 * Cache of {@see PIXI.TextMetrics.FontMetrics} objects. 29649 * @memberof PIXI.TextMetrics 29650 * @type {Object} 29651 * @private 29652 */ 29653 TextMetrics._fonts = {}; 29654 29655 /** 29656 * String used for calculate font metrics. 29657 * @static 29658 * @memberof PIXI.TextMetrics 29659 * @name METRICS_STRING 29660 * @type {string} 29661 * @default |Éq 29662 */ 29663 TextMetrics.METRICS_STRING = '|Éq'; 29664 29665 /** 29666 * Baseline symbol for calculate font metrics. 29667 * @static 29668 * @memberof PIXI.TextMetrics 29669 * @name BASELINE_SYMBOL 29670 * @type {string} 29671 * @default M 29672 */ 29673 TextMetrics.BASELINE_SYMBOL = 'M'; 29674 29675 /** 29676 * Baseline multiplier for calculate font metrics. 29677 * @static 29678 * @memberof PIXI.TextMetrics 29679 * @name BASELINE_MULTIPLIER 29680 * @type {number} 29681 * @default 1.4 29682 */ 29683 TextMetrics.BASELINE_MULTIPLIER = 1.4; 29684 29685 /** 29686 * Cache of new line chars. 29687 * @memberof PIXI.TextMetrics 29688 * @type {number[]} 29689 * @private 29690 */ 29691 TextMetrics._newlines = [ 29692 0x000A, // line feed 29693 0x000D ]; 29694 29695 /** 29696 * Cache of breaking spaces. 29697 * @memberof PIXI.TextMetrics 29698 * @type {number[]} 29699 * @private 29700 */ 29701 TextMetrics._breakingSpaces = [ 29702 0x0009, // character tabulation 29703 0x0020, // space 29704 0x2000, // en quad 29705 0x2001, // em quad 29706 0x2002, // en space 29707 0x2003, // em space 29708 0x2004, // three-per-em space 29709 0x2005, // four-per-em space 29710 0x2006, // six-per-em space
29711 0x2008, // punctuation space 29712 0x2009, // thin space 29713 0x200A, // hair space 29714 0x205F, // medium mathematical space 29715 0x3000 ]; 29716 29717 /** 29718 * A number, or a string containing a number. 29719 * @memberof PIXI 29720 * @typedef IFontMetrics 29721 * @property {number} ascent - Font ascent 29722 * @property {number} descent - Font descent 29723 * @property {number} fontSize - Font size 29724 */ 29725 29726 /* eslint max-depth: [2, 8] */ 29727 29728 var defaultDestroyOptions = { 29729 texture: true, 29730 children: false, 29731 baseTexture: true, 29732 }; 29733 29734 /** 29735 * A Text Object will create a line or multiple lines of text. 29736 * 29737 * The text is created using the [Canvas API](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API). 29738 * 29739 * The primary advantage of this class over BitmapText is that you have great control over the style of the next, 29740 * which you can change at runtime. 29741 * 29742 * The primary disadvantages is that each piece of text has it's own texture, which can use more memory. 29743 * When text changes, this texture has to be re-generated and re-uploaded to the GPU, taking up time. 29744 *
29745 * To split a line you can use '\n' in your text string, or, on the `style` object, 29746 * change its `wordWrap` property to true and and give the `wordWrapWidth` property a value. 29747 * 29748 * A Text can be created directly from a string and a style object, 29749 * which can be generated [here](https://pixijs.io/pixi-text-style). 29750 * 29751 * ```js 29752 * let text = new PIXI.Text('This is a PixiJS text',{fontFamily : 'Arial', fontSize: 24, fill : 0xff1010, align : 'center'}); 29753 * ``` 29754 * 29755 * @class 29756 * @extends PIXI.Sprite 29757 * @memberof PIXI 29758 */ 29759 var Text = /*@__PURE__*/(function (Sprite) { 29760 function Text(text, style, canvas) 29761 { 29762 canvas = canvas || document.createElement('canvas'); 29763 29764 canvas.width = 3; 29765 canvas.height = 3; 29766 29767 var texture = Texture.from(canvas); 29768 29769 texture.orig = new Rectangle(); 29770 texture.trim = new Rectangle(); 29771 29772 Sprite.call(this, texture); 29773 29774 /** 29775 * The canvas element that everything is drawn to 29776 * 29777 * @member {HTMLCanvasElement} 29778 */ 29779 this.canvas = canvas; 29780 29781 /** 29782 * The canvas 2d context that everything is drawn with 29783 * @member {CanvasRenderingContext2D} 29784 */ 29785 this.context = this.canvas.getContext('2d'); 29786 29787 /** 29788 * The resolution / device pixel ratio of the canvas. 29789 * This is set to automatically match the renderer resolution by default, but can be overridden by setting manually. 29790 * @member {number} 29791 * @default 1 29792 */ 29793 this._resolution = settings.RESOLUTION; 29794 this._autoResolution = true; 29795 29796 /** 29797 * Private tracker for the current text. 29798 * 29799 * @member {string} 29800 * @private 29801 */ 29802 this._text = null; 29803 29804 /** 29805 * Private tracker for the current style. 29806 * 29807 * @member {object} 29808 * @private 29809 */ 29810 this._style = null; 29811 /** 29812 * Private listener to track style changes. 29813 * 29814 * @member {Function} 29815 * @private 29816 */ 29817 this._styleListener = null; 29818 29819 /** 29820 * Private tracker for the current font. 29821 * 29822 * @member {string} 29823 * @private 29824 */ 29825 this._font = ''; 29826 29827 this.text = text; 29828 this.style = style; 29829 29830 this.localStyleID = -1; 29831 } 29832 29833 if ( Sprite ) { Text.__proto__ = Sprite; } 29834 Text.prototype = Object.create( Sprite && Sprite.prototype ); 29835 Text.prototype.constructor = Text; 29836 29837 var prototypeAccessors = { width: { configurable: true },height: { configurable: true },style: { configurable: true },text: { configurable: true },resolution: { configurable: true } }; 29838 29839 /**
29840 * Renders text and updates it when needed. 29841 * 29842 * @private 29843 * @param {boolean} respectDirty - Whether to abort updating the text if the Text isn't dirty and the function is called. 29844 */ 29845 Text.prototype.updateText = function updateText (respectDirty) 29846 { 29847 var style = this._style; 29848 29849 // check if style has changed.. 29850 if (this.localStyleID !== style.styleID) 29851 { 29852 this.dirty = true; 29853 this.localStyleID = style.styleID; 29854 } 29855 29856 if (!this.dirty && respectDirty) 29857 { 29858 return; 29859 } 29860 29861 this._font = this._style.toFontString(); 29862 29863 var context = this.context; 29864 var measured = TextMetrics.measureText(this._text || ' ', this._style, this._style.wordWrap, this.canvas); 29865 var width = measured.width; 29866 var height = measured.height; 29867 var lines = measured.lines; 29868 var lineHeight = measured.lineHeight; 29869 var lineWidths = measured.lineWidths; 29870 var maxLineWidth = measured.maxLineWidth; 29871 var fontProperties = measured.fontProperties; 29872 29873 this.canvas.width = Math.ceil((Math.max(1, width) + (style.padding * 2)) * this._resolution); 29874 this.canvas.height = Math.ceil((Math.max(1, height) + (style.padding * 2)) * this._resolution); 29875 29876 context.scale(this._resolution, this._resolution); 29877 29878 context.clearRect(0, 0, this.canvas.width, this.canvas.height); 29879 29880 context.font = this._font; 29881 context.strokeStyle = style.stroke; 29882 context.lineWidth = style.strokeThickness; 29883 context.textBaseline = style.textBaseline; 29884 context.lineJoin = style.lineJoin; 29885 context.miterLimit = style.miterLimit; 29886 29887 var linePositionX; 29888 var linePositionY; 29889 29890 if (style.dropShadow) 29891 { 29892 var dropShadowColor = style.dropShadowColor; 29893 var rgb = hex2rgb(typeof dropShadowColor === 'number' ? dropShadowColor : string2hex(dropShadowColor)); 29894 29895 context.shadowColor = "rgba(" + (rgb[0] * 255) + "," + (rgb[1] * 255) + "," + (rgb[2] * 255) + "," + (style.dropShadowAlpha) + ")"; 29896 context.shadowBlur = style.dropShadowBlur; 29897 context.shadowOffsetX = Math.cos(style.dropShadowAngle) * style.dropShadowDistance; 29898 context.shadowOffsetY = Math.sin(style.dropShadowAngle) * style.dropShadowDistance; 29899 } 29900 else 29901 { 29902 context.shadowColor = 0; 29903 context.shadowBlur = 0; 29904 context.shadowOffsetX = 0; 29905 context.shadowOffsetY = 0; 29906 } 29907 29908 // set canvas text styles 29909 context.fillStyle = this._generateFillStyle(style, lines); 29910 29911 // draw lines line by line 29912 for (var i = 0; i < lines.length; i++) 29913 { 29914 linePositionX = style.strokeThickness / 2; 29915 linePositionY = ((style.strokeThickness / 2) + (i * lineHeight)) + fontProperties.ascent; 29916 29917 if (style.align === 'right') 29918 { 29919 linePositionX += maxLineWidth - lineWidths[i]; 29920 } 29921 else if (style.align === 'center') 29922 { 29923 linePositionX += (maxLineWidth - lineWidths[i]) / 2; 29924 } 29925 29926 if (style.stroke && style.strokeThickness) 29927 { 29928 this.drawLetterSpacing( 29929 lines[i], 29930 linePositionX + style.padding, 29931 linePositionY + style.padding, 29932 true 29933 ); 29934 } 29935 29936 if (style.fill) 29937 { 29938 this.drawLetterSpacing( 29939 lines[i], 29940 linePositionX + style.padding, 29941 linePositionY + style.padding 29942 ); 29943 } 29944 } 29945 29946 this.updateTexture(); 29947 }; 29948 29949 /**
29950 * Render the text with letter-spacing. 29951 * @param {string} text - The text to draw 29952 * @param {number} x - Horizontal position to draw the text 29953 * @param {number} y - Vertical position to draw the text 29954 * @param {boolean} [isStroke=false] - Is this drawing for the outside stroke of the 29955 * text? If not, it's for the inside fill 29956 * @private 29957 */ 29958 Text.prototype.drawLetterSpacing = function drawLetterSpacing (text, x, y, isStroke) 29959 { 29960 if ( isStroke === void 0 ) { isStroke = false; } 29961 29962 var style = this._style; 29963 29964 // letterSpacing of 0 means normal 29965 var letterSpacing = style.letterSpacing; 29966 29967 if (letterSpacing === 0) 29968 { 29969 if (isStroke) 29970 { 29971 this.context.strokeText(text, x, y); 29972 } 29973 else 29974 { 29975 this.context.fillText(text, x, y); 29976 } 29977 29978 return; 29979 } 29980 29981 var characters = String.prototype.split.call(text, ''); 29982 var currentPosition = x; 29983 var index = 0; 29984 var current = ''; 29985 29986 while (index < text.length) 29987 { 29988 current = characters[index++]; 29989 if (isStroke) 29990 { 29991 this.context.strokeText(current, currentPosition, y); 29992 } 29993 else 29994 { 29995 this.context.fillText(current, currentPosition, y); 29996 } 29997 currentPosition += this.context.measureText(current).width + letterSpacing; 29998 } 29999 }; 30000 30001 /** 30002 * Updates texture size based on canvas size 30003 * 30004 * @private 30005 */ 30006 Text.prototype.updateTexture = function updateTexture () 30007 { 30008 var canvas = this.canvas; 30009 30010 if (this._style.trim) 30011 { 30012 var trimmed = trimCanvas(canvas); 30013 30014 if (trimmed.data) 30015 { 30016 canvas.width = trimmed.width; 30017 canvas.height = trimmed.height; 30018 this.context.putImageData(trimmed.data, 0, 0); 30019 } 30020 } 30021 30022 var texture = this._texture; 30023 var style = this._style; 30024 var padding = style.trim ? 0 : style.padding; 30025 var baseTexture = texture.baseTexture; 30026 30027 texture.trim.width = texture._frame.width = canvas.width / this._resolution; 30028 texture.trim.height = texture._frame.height = canvas.height / this._resolution; 30029 texture.trim.x = -padding; 30030 texture.trim.y = -padding; 30031 30032 texture.orig.width = texture._frame.width - (padding * 2); 30033 texture.orig.height = texture._frame.height - (padding * 2); 30034 30035 // call sprite onTextureUpdate to update scale if _width or _height were set 30036 this._onTextureUpdate(); 30037 30038 baseTexture.setRealSize(canvas.width, canvas.height, this._resolution); 30039 30040 this.dirty = false; 30041 }; 30042 30043 /**
30044 * Renders the object using the WebGL renderer 30045 * 30046 * @param {PIXI.Renderer} renderer - The renderer 30047 */ 30048 Text.prototype.render = function render (renderer) 30049 { 30050 if (this._autoResolution && this._resolution !== renderer.resolution) 30051 { 30052 this._resolution = renderer.resolution; 30053 this.dirty = true; 30054 } 30055 30056 this.updateText(true); 30057 30058 Sprite.prototype.render.call(this, renderer); 30059 }; 30060 30061 /** 30062 * Renders the object using the Canvas renderer 30063 * 30064 * @private 30065 * @param {PIXI.CanvasRenderer} renderer - The renderer 30066 */ 30067 Text.prototype._renderCanvas = function _renderCanvas (renderer) 30068 { 30069 if (this._autoResolution && this._resolution !== renderer.resolution) 30070 { 30071 this._resolution = renderer.resolution; 30072 this.dirty = true; 30073 } 30074 30075 this.updateText(true); 30076 30077 Sprite.prototype._renderCanvas.call(this, renderer); 30078 }; 30079 30080 /** 30081 * Gets the local bounds of the text object. 30082 * 30083 * @param {Rectangle} rect - The output rectangle. 30084 * @return {Rectangle} The bounds. 30085 */ 30086 Text.prototype.getLocalBounds = function getLocalBounds (rect) 30087 { 30088 this.updateText(true); 30089 30090 return Sprite.prototype.getLocalBounds.call(this, rect); 30091 }; 30092 30093 /** 30094 * calculates the bounds of the Text as a rectangle. The bounds calculation takes the worldTransform into account. 30095 * @protected 30096 */ 30097 Text.prototype._calculateBounds = function _calculateBounds () 30098 { 30099 this.updateText(true); 30100 this.calculateVertices(); 30101 // if we have already done this on THIS frame. 30102 this._bounds.addQuad(this.vertexData); 30103 }; 30104 30105 /** 30106 * Method to be called upon a TextStyle change. 30107 * @private 30108 */ 30109 Text.prototype._onStyleChange = function _onStyleChange () 30110 { 30111 this.dirty = true; 30112 }; 30113 30114 /** 30115 * Generates the fill style. Can automatically generate a gradient based on the fill style being an array 30116 * 30117 * @private 30118 * @param {object} style - The style. 30119 * @param {string[]} lines - The lines of text. 30120 * @return {string|number|CanvasGradient} The fill style 30121 */ 30122 Text.prototype._generateFillStyle = function _generateFillStyle (style, lines) 30123 { 30124 if (!Array.isArray(style.fill)) 30125 { 30126 return style.fill; 30127 } 30128 30129 // the gradient will be evenly spaced out according to how large the array is. 30130 // ['#FF0000', '#00FF00', '#0000FF'] would created stops at 0.25, 0.5 and 0.75 30131 var gradient; 30132 var totalIterations; 30133 var currentIteration; 30134 var stop; 30135 30136 var width = this.canvas.width / this._resolution; 30137 var height = this.canvas.height / this._resolution; 30138 30139 // make a copy of the style settings, so we can manipulate them later 30140 var fill = style.fill.slice(); 30141 var fillGradientStops = style.fillGradientStops.slice(); 30142 30143 // wanting to evenly distribute the fills. So an array of 4 colours should give fills of 0.25, 0.5 and 0.75 30144 if (!fillGradientStops.length) 30145 { 30146 var lengthPlus1 = fill.length + 1; 30147 30148 for (var i = 1; i < lengthPlus1; ++i) 30149 { 30150 fillGradientStops.push(i / lengthPlus1); 30151 } 30152 } 30153 30154 // stop the bleeding of the last gradient on the line above to the top gradient of the this line 30155 // by hard defining the first gradient colour at point 0, and last gradient colour at point 1 30156 fill.unshift(style.fill[0]); 30157 fillGradientStops.unshift(0); 30158 30159 fill.push(style.fill[style.fill.length - 1]); 30160 fillGradientStops.push(1); 30161 30162 if (style.fillGradientType === TEXT_GRADIENT.LINEAR_VERTICAL) 30163 { 30164 // start the gradient at the top center of the canvas, and end at the bottom middle of the canvas 30165 gradient = this.context.createLinearGradient(width / 2, 0, width / 2, height); 30166 30167 // we need to repeat the gradient so that each individual line of text has the same vertical gradient effect 30168 // ['#FF0000', '#00FF00', '#0000FF'] over 2 lines would create stops at 0.125, 0.25, 0.375, 0.625, 0.75, 0.875 30169 totalIterations = (fill.length + 1) * lines.length; 30170 currentIteration = 0; 30171 for (var i$1 = 0; i$1 < lines.length; i$1++) 30172 { 30173 currentIteration += 1; 30174 for (var j = 0; j < fill.length; j++) 30175 { 30176 if (typeof fillGradientStops[j] === 'number') 30177 { 30178 stop = (fillGradientStops[j] / lines.length) + (i$1 / lines.length); 30179 } 30180 else 30181 { 30182 stop = currentIteration / totalIterations; 30183 } 30184 gradient.addColorStop(stop, fill[j]); 30185 currentIteration++; 30186 } 30187 } 30188 } 30189 else 30190 { 30191 // start the gradient at the center left of the canvas, and end at the center right of the canvas 30192 gradient = this.context.createLinearGradient(0, height / 2, width, height / 2); 30193 30194 // can just evenly space out the gradients in this case, as multiple lines makes no difference 30195 // to an even left to right gradient 30196 totalIterations = fill.length + 1; 30197 currentIteration = 1; 30198 30199 for (var i$2 = 0; i$2 < fill.length; i$2++) 30200 { 30201 if (typeof fillGradientStops[i$2] === 'number') 30202 { 30203 stop = fillGradientStops[i$2]; 30204 } 30205 else 30206 { 30207 stop = currentIteration / totalIterations; 30208 } 30209 gradient.addColorStop(stop, fill[i$2]); 30210 currentIteration++; 30211 } 30212 } 30213 30214 return gradient; 30215 }; 30216 30217 /** 30218 * Destroys this text object. 30219 * Note* Unlike a Sprite, a Text object will automatically destroy its baseTexture and texture as 30220 * the majority of the time the texture will not be shared with any other Sprites. 30221 * 30222 * @param {object|boolean} [options] - Options parameter. A boolean will act as if all options 30223 * have been set to that value 30224 * @param {boolean} [options.children=false] - if set to true, all the children will have their 30225 * destroy method called as well. 'options' will be passed on to those calls. 30226 * @param {boolean} [options.texture=true] - Should it destroy the current texture of the sprite as well 30227 * @param {boolean} [options.baseTexture=true] - Should it destroy the base texture of the sprite as well 30228 */ 30229 Text.prototype.destroy = function destroy (options) 30230 { 30231 if (typeof options === 'boolean') 30232 { 30233 options = { children: options }; 30234 } 30235 30236 options = Object.assign({}, defaultDestroyOptions, options); 30237 30238 Sprite.prototype.destroy.call(this, options); 30239 30240 // make sure to reset the the context and canvas.. dont want this hanging around in memory! 30241 this.context = null; 30242 this.canvas = null; 30243 30244 this._style = null; 30245 }; 30246 30247 /** 30248 * The width of the Text, setting this will actually modify the scale to achieve the value set 30249 * 30250 * @member {number} 30251 */ 30252 prototypeAccessors.width.get = function () 30253 { 30254 this.updateText(true); 30255 30256 return Math.abs(this.scale.x) * this._texture.orig.width; 30257 }; 30258 30259 prototypeAccessors.width.set = function (value) // eslint-disable-line require-jsdoc 30260 { 30261 this.updateText(true); 30262 30263 var s = sign(this.scale.x) || 1; 30264 30265 this.scale.x = s * value / this._texture.orig.width; 30266 this._width = value; 30267 }; 30268 30269 /** 30270 * The height of the Text, setting this will actually modify the scale to achieve the value set 30271 * 30272 * @member {number} 30273 */ 30274 prototypeAccessors.height.get = function () 30275 { 30276 this.updateText(true); 30277 30278 return Math.abs(this.scale.y) * this._texture.orig.height; 30279 }; 30280 30281 prototypeAccessors.height.set = function (value) // eslint-disable-line require-jsdoc 30282 { 30283 this.updateText(true); 30284 30285 var s = sign(this.scale.y) || 1; 30286 30287 this.scale.y = s * value / this._texture.orig.height; 30288 this._height = value; 30289 }; 30290 30291 /** 30292 * Set the style of the text. Set up an event listener to listen for changes on the style 30293 * object and mark the text as dirty. 30294 * 30295 * @member {object|PIXI.TextStyle} 30296 */ 30297 prototypeAccessors.style.get = function () 30298 { 30299 return this._style; 30300 }; 30301 30302 prototypeAccessors.style.set = function (style) // eslint-disable-line require-jsdoc 30303 { 30304 style = style || {}; 30305 30306 if (style instanceof TextStyle) 30307 { 30308 this._style = style; 30309 } 30310 else 30311 { 30312 this._style = new TextStyle(style); 30313 } 30314 30315 this.localStyleID = -1; 30316 this.dirty = true; 30317 }; 30318 30319 /** 30320 * Set the copy for the text object. To split a line you can use '\n'. 30321 * 30322 * @member {string} 30323 */ 30324 prototypeAccessors.text.get = function () 30325 { 30326 return this._text; 30327 }; 30328 30329 prototypeAccessors.text.set = function (text) // eslint-disable-line require-jsdoc 30330 { 30331 text = String(text === null || text === undefined ? '' : text); 30332 30333 if (this._text === text) 30334 { 30335 return; 30336 } 30337 this._text = text; 30338 this.dirty = true; 30339 }; 30340 30341 /** 30342 * The resolution / device pixel ratio of the canvas. 30343 * This is set to automatically match the renderer resolution by default, but can be overridden by setting manually. 30344 * @member {number} 30345 * @default 1 30346 */ 30347 prototypeAccessors.resolution.get = function () 30348 { 30349 return this._resolution; 30350 }; 30351 30352 prototypeAccessors.resolution.set = function (value) // eslint-disable-line require-jsdoc 30353 { 30354 this._autoResolution = false;
30355 30356 if (this._resolution === value) 30357 { 30358 return; 30359 } 30360 30361 this._resolution = value; 30362 this.dirty = true; 30363 }; 30364 30365 Object.defineProperties( Text.prototype, prototypeAccessors ); 30366 30367 return Text; 30368 }(Sprite)); 30369 30370 /*! 30371 * @pixi/prepare - v5.0.0-rc.3 30372 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 30373 * 30374 * @pixi/prepare is licensed under the MIT License. 30375 * http://www.opensource.org/licenses/mit-license 30376 */ 30377 30378 /** 30379 * Default number of uploads per frame using prepare plugin. 30380 * 30381 * @static 30382 * @memberof PIXI.settings 30383 * @name UPLOADS_PER_FRAME 30384 * @type {number} 30385 * @default 4 30386 */ 30387 settings.UPLOADS_PER_FRAME = 4; 30388 30389 /** 30390 * CountLimiter limits the number of items handled by a {@link PIXI.prepare.BasePrepare} to a specified 30391 * number of items per frame. 30392 * 30393 * @class 30394 * @memberof PIXI.prepare 30395 */ 30396 var CountLimiter = function CountLimiter(maxItemsPerFrame) 30397 { 30398 /** 30399 * The maximum number of items that can be prepared each frame. 30400 * @type {number} 30401 * @private 30402 */ 30403 this.maxItemsPerFrame = maxItemsPerFrame; 30404 /** 30405 * The number of items that can be prepared in the current frame. 30406 * @type {number} 30407 * @private 30408 */ 30409 this.itemsLeft = 0; 30410 }; 30411 30412 /** 30413 * Resets any counting properties to start fresh on a new frame. 30414 */ 30415 CountLimiter.prototype.beginFrame = function beginFrame () 30416 { 30417 this.itemsLeft = this.maxItemsPerFrame; 30418 }; 30419 30420 /** 30421 * Checks to see if another item can be uploaded. This should only be called once per item. 30422 * @return {boolean} If the item is allowed to be uploaded. 30423 */ 30424 CountLimiter.prototype.allowedToUpload = function allowedToUpload () 30425 { 30426 return this.itemsLeft-- > 0; 30427 }; 30428 30429 /** 30430 * The prepare manager provides functionality to upload content to the GPU. 30431 * 30432 * BasePrepare handles basic queuing functionality and is extended by 30433 * {@link PIXI.prepare.WebGLPrepare} and {@link PIXI.prepare.CanvasPrepare} 30434 * to provide preparation capabilities specific to their respective renderers. 30435 * 30436 * @example 30437 * // Create a sprite 30438 * const sprite = new PIXI.Sprite.from('something.png'); 30439 * 30440 * // Load object into GPU 30441 * app.renderer.plugins.prepare.upload(sprite, () => { 30442 * 30443 * //Texture(s) has been uploaded to GPU 30444 * app.stage.addChild(sprite); 30445 * 30446 * }) 30447 * 30448 * @abstract 30449 * @class 30450 * @memberof PIXI.prepare 30451 */ 30452 var BasePrepare = function BasePrepare(renderer) 30453 { 30454 var this$1 = this; 30455 30456 /** 30457 * The limiter to be used to control how quickly items are prepared. 30458 * @type {PIXI.prepare.CountLimiter|PIXI.prepare.TimeLimiter} 30459 */ 30460 this.limiter = new CountLimiter(settings.UPLOADS_PER_FRAME); 30461 30462 /** 30463 * Reference to the renderer. 30464 * @type {PIXI.AbstractRenderer} 30465 * @protected 30466 */ 30467 this.renderer = renderer; 30468 30469 /** 30470 * The only real difference between CanvasPrepare and WebGLPrepare is what they pass 30471 * to upload hooks. That different parameter is stored here. 30472 * @type {PIXI.prepare.CanvasPrepare|PIXI.Renderer} 30473 * @protected 30474 */ 30475 this.uploadHookHelper = null; 30476 30477 /** 30478 * Collection of items to uploads at once. 30479 * @type {Array<*>} 30480 * @private 30481 */ 30482 this.queue = []; 30483 30484 /** 30485 * Collection of additional hooks for finding assets. 30486 * @type {Array<Function>} 30487 * @private 30488 */ 30489 this.addHooks = []; 30490 30491 /** 30492 * Collection of additional hooks for processing assets. 30493 * @type {Array<Function>} 30494 * @private 30495 */ 30496 this.uploadHooks = []; 30497 30498 /** 30499 * Callback to call after completed. 30500 * @type {Array<Function>} 30501 * @private 30502 */ 30503 this.completes = []; 30504 30505 /** 30506 * If prepare is ticking (running). 30507 * @type {boolean} 30508 * @private 30509 */ 30510 this.ticking = false; 30511 30512 /** 30513 * 'bound' call for prepareItems(). 30514 * @type {Function} 30515 * @private 30516 */ 30517 this.delayedTick = function () { 30518 // unlikely, but in case we were destroyed between tick() and delayedTick() 30519 if (!this$1.queue) 30520 { 30521 return; 30522 } 30523 this$1.prepareItems(); 30524 }; 30525 30526 // hooks to find the correct texture 30527 this.registerFindHook(findText); 30528 this.registerFindHook(findTextStyle); 30529 this.registerFindHook(findMultipleBaseTextures); 30530 this.registerFindHook(findBaseTexture); 30531 this.registerFindHook(findTexture); 30532 30533 // upload hooks 30534 this.registerUploadHook(drawText); 30535 this.registerUploadHook(calculateTextStyle); 30536 }; 30537 30538 /** 30539 * Upload all the textures and graphics to the GPU. 30540 * 30541 * @param {Function|PIXI.DisplayObject|PIXI.Container|PIXI.BaseTexture|PIXI.Texture|PIXI.Graphics|PIXI.Text} item - 30542 * Either the container or display object to search for items to upload, the items to upload themselves, 30543 * or the callback function, if items have been added using `prepare.add`. 30544 * @param {Function} [done] - Optional callback when all queued uploads have completed 30545 */ 30546 BasePrepare.prototype.upload = function upload (item, done) 30547 { 30548 if (typeof item === 'function') 30549 { 30550 done = item; 30551 item = null; 30552 } 30553 30554 // If a display object, search for items 30555 // that we could upload 30556 if (item) 30557 { 30558 this.add(item); 30559 } 30560 30561 // Get the items for upload from the display 30562 if (this.queue.length) 30563 { 30564 if (done) 30565 { 30566 this.completes.push(done); 30567 } 30568 30569 if (!this.ticking) 30570 { 30571 this.ticking = true; 30572 Ticker.system.addOnce(this.tick, this, UPDATE_PRIORITY.UTILITY); 30573 } 30574 } 30575 else if (done) 30576 { 30577 done(); 30578 } 30579 }; 30580 30581 /** 30582 * Handle tick update 30583 * 30584 * @private 30585 */ 30586 BasePrepare.prototype.tick = function tick () 30587 { 30588 setTimeout(this.delayedTick, 0); 30589 }; 30590 30591 /** 30592 * Actually prepare items. This is handled outside of the tick because it will take a while 30593 * and we do NOT want to block the current animation frame from rendering. 30594 * 30595 * @private 30596 */ 30597 BasePrepare.prototype.prepareItems = function prepareItems () 30598 { 30599 this.limiter.beginFrame(); 30600 // Upload the graphics 30601 while (this.queue.length && this.limiter.allowedToUpload()) 30602 { 30603 var item = this.queue[0]; 30604 var uploaded = false;
30605 30606 if (item && !item._destroyed) 30607 { 30608 for (var i = 0, len = this.uploadHooks.length; i < len; i++) 30609 { 30610 if (this.uploadHooks[i](this.uploadHookHelper, item)) 30611 { 30612 this.queue.shift(); 30613 uploaded = true; 30614 break; 30615 } 30616 } 30617 } 30618 30619 if (!uploaded) 30620 { 30621 this.queue.shift(); 30622 } 30623 } 30624 30625 // We're finished 30626 if (!this.queue.length) 30627 { 30628 this.ticking = false; 30629 30630 var completes = this.completes.slice(0); 30631 30632 this.completes.length = 0; 30633 30634 for (var i$1 = 0, len$1 = completes.length; i$1 < len$1; i$1++) 30635 { 30636 completes[i$1](); 30637 } 30638 } 30639 else 30640 { 30641 // if we are not finished, on the next rAF do this again 30642 Ticker.system.addOnce(this.tick, this, UPDATE_PRIORITY.UTILITY); 30643 } 30644 }; 30645 30646 /** 30647 * Adds hooks for finding items. 30648 * 30649 * @param {Function} addHook - Function call that takes two parameters: `item:*, queue:Array` 30650 * function must return `true` if it was able to add item to the queue. 30651 * @return {PIXI.prepare.BasePrepare} Instance of plugin for chaining. 30652 */ 30653 BasePrepare.prototype.registerFindHook = function registerFindHook (addHook) 30654 { 30655 if (addHook) 30656 { 30657 this.addHooks.push(addHook); 30658 } 30659 30660 return this; 30661 }; 30662 30663 /** 30664 * Adds hooks for uploading items. 30665 * 30666 * @param {Function} uploadHook - Function call that takes two parameters: `prepare:CanvasPrepare, item:*` and 30667 * function must return `true` if it was able to handle upload of item. 30668 * @return {PIXI.prepare.BasePrepare} Instance of plugin for chaining. 30669 */ 30670 BasePrepare.prototype.registerUploadHook = function registerUploadHook (uploadHook) 30671 { 30672 if (uploadHook) 30673 { 30674 this.uploadHooks.push(uploadHook); 30675 } 30676 30677 return this; 30678 }; 30679 30680 /** 30681 * Manually add an item to the uploading queue. 30682 * 30683 * @param {PIXI.DisplayObject|PIXI.Container|PIXI.BaseTexture|PIXI.Texture|PIXI.Graphics|PIXI.Text|*} item - Object to 30684 * add to the queue 30685 * @return {PIXI.prepare.BasePrepare} Instance of plugin for chaining. 30686 */ 30687 BasePrepare.prototype.add = function add (item) 30688 { 30689 // Add additional hooks for finding elements on special 30690 // types of objects that 30691 for (var i = 0, len = this.addHooks.length; i < len; i++) 30692 { 30693 if (this.addHooks[i](item, this.queue)) 30694 { 30695 break; 30696 } 30697 } 30698 30699 // Get children recursively 30700 if (item instanceof Container) 30701 { 30702 for (var i$1 = item.children.length - 1; i$1 >= 0; i$1--) 30703 { 30704 this.add(item.children[i$1]); 30705 } 30706 } 30707 30708 return this; 30709 }; 30710 30711 /** 30712 * Destroys the plugin, don't use after this. 30713 * 30714 */ 30715 BasePrepare.prototype.destroy = function destroy () 30716 { 30717 if (this.ticking) 30718 { 30719 Ticker.system.remove(this.tick, this); 30720 } 30721 this.ticking = false; 30722 this.addHooks = null; 30723 this.uploadHooks = null; 30724 this.renderer = null; 30725 this.completes = null; 30726 this.queue = null; 30727 this.limiter = null; 30728 this.uploadHookHelper = null; 30729 }; 30730 30731 /** 30732 * Built-in hook to find multiple textures from objects like AnimatedSprites. 30733 * 30734 * @private 30735 * @param {PIXI.DisplayObject} item - Display object to check 30736 * @param {Array<*>} queue - Collection of items to upload 30737 * @return {boolean} if a PIXI.Texture object was found. 30738 */ 30739 function findMultipleBaseTextures(item, queue) 30740 { 30741 var result = false;
30742 30743 // Objects with multiple textures 30744 if (item && item._textures && item._textures.length) 30745 { 30746 for (var i = 0; i < item._textures.length; i++) 30747 { 30748 if (item._textures[i] instanceof Texture) 30749 { 30750 var baseTexture = item._textures[i].baseTexture; 30751 30752 if (queue.indexOf(baseTexture) === -1) 30753 { 30754 queue.push(baseTexture); 30755 result = true; 30756 } 30757 } 30758 } 30759 } 30760 30761 return result; 30762 } 30763 30764 /** 30765 * Built-in hook to find BaseTextures from Sprites. 30766 * 30767 * @private 30768 * @param {PIXI.DisplayObject} item - Display object to check 30769 * @param {Array<*>} queue - Collection of items to upload 30770 * @return {boolean} if a PIXI.Texture object was found. 30771 */ 30772 function findBaseTexture(item, queue) 30773 { 30774 // Objects with textures, like Sprites/Text 30775 if (item instanceof BaseTexture) 30776 { 30777 if (queue.indexOf(item) === -1) 30778 { 30779 queue.push(item); 30780 } 30781 30782 return true; 30783 } 30784 30785 return false; 30786 } 30787 30788 /** 30789 * Built-in hook to find textures from objects. 30790 * 30791 * @private 30792 * @param {PIXI.DisplayObject} item - Display object to check 30793 * @param {Array<*>} queue - Collection of items to upload 30794 * @return {boolean} if a PIXI.Texture object was found. 30795 */ 30796 function findTexture(item, queue) 30797 { 30798 if (item._texture && item._texture instanceof Texture) 30799 { 30800 var texture = item._texture.baseTexture; 30801 30802 if (queue.indexOf(texture) === -1) 30803 { 30804 queue.push(texture); 30805 } 30806 30807 return true; 30808 } 30809 30810 return false; 30811 } 30812 30813 /** 30814 * Built-in hook to draw PIXI.Text to its texture. 30815 * 30816 * @private 30817 * @param {PIXI.Renderer|PIXI.CanvasPrepare} helper - Not used by this upload handler 30818 * @param {PIXI.DisplayObject} item - Item to check 30819 * @return {boolean} If item was uploaded. 30820 */ 30821 function drawText(helper, item) 30822 { 30823 if (item instanceof Text) 30824 { 30825 // updating text will return early if it is not dirty 30826 item.updateText(true); 30827 30828 return true; 30829 } 30830 30831 return false; 30832 } 30833 30834 /** 30835 * Built-in hook to calculate a text style for a PIXI.Text object. 30836 * 30837 * @private 30838 * @param {PIXI.Renderer|PIXI.CanvasPrepare} helper - Not used by this upload handler 30839 * @param {PIXI.DisplayObject} item - Item to check 30840 * @return {boolean} If item was uploaded. 30841 */ 30842 function calculateTextStyle(helper, item) 30843 { 30844 if (item instanceof TextStyle) 30845 { 30846 var font = item.toFontString(); 30847 30848 TextMetrics.measureFont(font); 30849 30850 return true; 30851 } 30852 30853 return false; 30854 } 30855 30856 /** 30857 * Built-in hook to find Text objects. 30858 * 30859 * @private 30860 * @param {PIXI.DisplayObject} item - Display object to check 30861 * @param {Array<*>} queue - Collection of items to upload 30862 * @return {boolean} if a PIXI.Text object was found. 30863 */ 30864 function findText(item, queue) 30865 { 30866 if (item instanceof Text) 30867 { 30868 // push the text style to prepare it - this can be really expensive 30869 if (queue.indexOf(item.style) === -1) 30870 { 30871 queue.push(item.style); 30872 } 30873 // also push the text object so that we can render it (to canvas/texture) if needed 30874 if (queue.indexOf(item) === -1) 30875 { 30876 queue.push(item); 30877 } 30878 // also push the Text's texture for upload to GPU 30879 var texture = item._texture.baseTexture; 30880 30881 if (queue.indexOf(texture) === -1) 30882 { 30883 queue.push(texture); 30884 } 30885 30886 return true; 30887 } 30888 30889 return false; 30890 } 30891 30892 /** 30893 * Built-in hook to find TextStyle objects. 30894 * 30895 * @private 30896 * @param {PIXI.TextStyle} item - Display object to check 30897 * @param {Array<*>} queue - Collection of items to upload 30898 * @return {boolean} if a PIXI.TextStyle object was found. 30899 */ 30900 function findTextStyle(item, queue) 30901 { 30902 if (item instanceof TextStyle) 30903 { 30904 if (queue.indexOf(item) === -1) 30905 { 30906 queue.push(item); 30907 } 30908 30909 return true; 30910 } 30911 30912 return false; 30913 } 30914 30915 /** 30916 * The prepare manager provides functionality to upload content to the GPU. 30917 * 30918 * An instance of this class is automatically created by default, and can be found at `renderer.plugins.prepare` 30919 * 30920 * @class 30921 * @extends PIXI.prepare.BasePrepare 30922 * @memberof PIXI.prepare 30923 */ 30924 var Prepare = /*@__PURE__*/(function (BasePrepare) { 30925 function Prepare(renderer) 30926 { 30927 BasePrepare.call(this, renderer); 30928 30929 this.uploadHookHelper = this.renderer; 30930 30931 // Add textures and graphics to upload 30932 this.registerFindHook(findGraphics); 30933 this.registerUploadHook(uploadBaseTextures); 30934 this.registerUploadHook(uploadGraphics); 30935 } 30936 30937 if ( BasePrepare ) { Prepare.__proto__ = BasePrepare; } 30938 Prepare.prototype = Object.create( BasePrepare && BasePrepare.prototype ); 30939 Prepare.prototype.constructor = Prepare; 30940 30941 return Prepare; 30942 }(BasePrepare)); 30943 /** 30944 * Built-in hook to upload PIXI.Texture objects to the GPU. 30945 * 30946 * @private 30947 * @param {PIXI.Renderer} renderer - instance of the webgl renderer 30948 * @param {PIXI.DisplayObject} item - Item to check 30949 * @return {boolean} If item was uploaded.
30950 */ 30951 function uploadBaseTextures(renderer, item) 30952 { 30953 if (item instanceof BaseTexture) 30954 { 30955 // if the texture already has a GL texture, then the texture has been prepared or rendered 30956 // before now. If the texture changed, then the changer should be calling texture.update() which 30957 // reuploads the texture without need for preparing it again 30958 if (!item._glTextures[renderer.CONTEXT_UID]) 30959 { 30960 renderer.textureManager.updateTexture(item); 30961 } 30962 30963 return true; 30964 } 30965 30966 return false; 30967 } 30968 30969 /** 30970 * Built-in hook to upload PIXI.Graphics to the GPU. 30971 * 30972 * @private 30973 * @param {PIXI.Renderer} renderer - instance of the webgl renderer 30974 * @param {PIXI.DisplayObject} item - Item to check 30975 * @return {boolean} If item was uploaded. 30976 */ 30977 function uploadGraphics(renderer, item) 30978 { 30979 if (item instanceof Graphics) 30980 { 30981 // if the item is not dirty and already has webgl data, then it got prepared or rendered 30982 // before now and we shouldn't waste time updating it again 30983 if (item.dirty || item.clearDirty || !item._webGL[renderer.plugins.graphics.CONTEXT_UID]) 30984 { 30985 renderer.plugins.graphics.updateGraphics(item); 30986 } 30987 30988 return true; 30989 } 30990 30991 return false; 30992 } 30993 30994 /** 30995 * Built-in hook to find graphics. 30996 * 30997 * @private 30998 * @param {PIXI.DisplayObject} item - Display object to check 30999 * @param {Array<*>} queue - Collection of items to upload 31000 * @return {boolean} if a PIXI.Graphics object was found. 31001 */ 31002 function findGraphics(item, queue) 31003 { 31004 if (item instanceof Graphics) 31005 { 31006 queue.push(item); 31007 31008 return true; 31009 } 31010 31011 return false; 31012 } 31013 31014 /** 31015 * TimeLimiter limits the number of items handled by a {@link PIXI.BasePrepare} to a specified 31016 * number of milliseconds per frame. 31017 * 31018 * @class 31019 * @memberof PIXI.prepare 31020 */ 31021 var TimeLimiter = function TimeLimiter(maxMilliseconds) 31022 { 31023 /** 31024 * The maximum milliseconds that can be spent preparing items each frame. 31025 * @type {number} 31026 * @private 31027 */ 31028 this.maxMilliseconds = maxMilliseconds; 31029 /** 31030 * The start time of the current frame. 31031 * @type {number} 31032 * @private 31033 */ 31034 this.frameStart = 0; 31035 }; 31036 31037 /** 31038 * Resets any counting properties to start fresh on a new frame. 31039 */ 31040 TimeLimiter.prototype.beginFrame = function beginFrame () 31041 { 31042 this.frameStart = Date.now(); 31043 }; 31044 31045 /** 31046 * Checks to see if another item can be uploaded. This should only be called once per item. 31047 * @return {boolean} If the item is allowed to be uploaded. 31048 */ 31049 TimeLimiter.prototype.allowedToUpload = function allowedToUpload () 31050 { 31051 return Date.now() - this.frameStart < this.maxMilliseconds; 31052 }; 31053 31054 var prepare = ({ 31055 BasePrepare: BasePrepare, 31056 CountLimiter: CountLimiter, 31057 Prepare: Prepare, 31058 TimeLimiter: TimeLimiter 31059 }); 31060 31061 /*! 31062 * @pixi/app - v5.0.0-rc.3 31063 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 31064 * 31065 * @pixi/app is licensed under the MIT License. 31066 * http://www.opensource.org/licenses/mit-license 31067 */ 31068 31069 /** 31070 * Convenience class to create a new PIXI application. 31071 * 31072 * This class automatically creates the renderer, ticker and root container. 31073 * 31074 * @example 31075 * // Create the application 31076 * const app = new PIXI.Application(); 31077 * 31078 * // Add the view to the DOM 31079 * document.body.appendChild(app.view); 31080 * 31081 * // ex, add display objects 31082 * app.stage.addChild(PIXI.Sprite.from('something.png')); 31083 * 31084 * @class 31085 * @memberof PIXI 31086 */ 31087 var Application = function Application(options) 31088 { 31089 var this$1 = this; 31090 31091 // The default options 31092 options = Object.assign({ 31093 forceCanvas: false, 31094 }, options); 31095 31096 /** 31097 * WebGL renderer if available, otherwise CanvasRenderer. 31098 * @member {PIXI.Renderer|PIXI.CanvasRenderer} 31099 */ 31100 this.renderer = autoDetectRenderer(options); 31101 31102 /** 31103 * The root display container that's rendered. 31104 * @member {PIXI.Container} 31105 */ 31106 this.stage = new Container(); 31107 31108 // install plugins here 31109 Application._plugins.forEach(function (plugin) { 31110 plugin.init.call(this$1, options); 31111 }); 31112 }; 31113 31114 var prototypeAccessors$8 = { view: { configurable: true },screen: { configurable: true } }; 31115 31116 /** 31117 * Register a middleware plugin for the application 31118 * @static 31119 * @param {PIXI.Application.Plugin} plugin - Plugin being installed 31120 */ 31121 Application.registerPlugin = function registerPlugin (plugin) 31122 { 31123 Application._plugins.push(plugin); 31124 }; 31125 31126 /** 31127 * Render the current stage. 31128 */ 31129 Application.prototype.render = function render () 31130 { 31131 this.renderer.render(this.stage); 31132 }; 31133 31134 /** 31135 * Reference to the renderer's canvas element. 31136 * @member {HTMLCanvasElement} 31137 * @readonly 31138 */ 31139 prototypeAccessors$8.view.get = function () 31140 { 31141 return this.renderer.view; 31142 }; 31143 31144 /** 31145 * Reference to the renderer's screen rectangle. Its safe to use as `filterArea` or `hitArea` for the whole screen. 31146 * @member {PIXI.Rectangle} 31147 * @readonly 31148 */ 31149 prototypeAccessors$8.screen.get = function () 31150 { 31151 return this.renderer.screen; 31152 }; 31153 31154 /** 31155 * Destroy and don't use after this. 31156 * @param {Boolean} [removeView=false] Automatically remove canvas from DOM. 31157 * @param {object|boolean} [stageOptions] - Options parameter. A boolean will act as if all options 31158 * have been set to that value 31159 * @param {boolean} [stageOptions.children=false] - if set to true, all the children will have their destroy 31160 * method called as well. 'stageOptions' will be passed on to those calls. 31161 * @param {boolean} [stageOptions.texture=false] - Only used for child Sprites if stageOptions.children is set 31162 * to true. Should it destroy the texture of the child sprite 31163 * @param {boolean} [stageOptions.baseTexture=false] - Only used for child Sprites if stageOptions.children is set 31164 * to true. Should it destroy the base texture of the child sprite 31165 */ 31166 Application.prototype.destroy = function destroy (removeView) 31167 { 31168 var this$1 = this; 31169 31170 // Destroy plugins in the opposite order 31171 // which they were constructed 31172 var plugins = Application._plugins.slice(0); 31173 31174 plugins.reverse(); 31175 plugins.forEach(function (plugin) { 31176 plugin.destroy.call(this$1); 31177 }); 31178 31179 this.stage.destroy(); 31180 this.stage = null; 31181 31182 this.renderer.destroy(removeView); 31183 this.renderer = null; 31184 31185 this._options = null; 31186 }; 31187 31188 Object.defineProperties( Application.prototype, prototypeAccessors$8 ); 31189 31190 /** 31191 * @memberof PIXI.Application 31192 * @typedef {object} Plugin 31193 * @property {function} init - Called when Application is constructed, scoped to Application instance. 31194 * Passes in `options` as the only argument, which are Application constructor options. 31195 * @property {function} destroy - Called when destroying Application, scoped to Application instance 31196 */ 31197 31198 /** 31199 * Collection of installed plugins. 31200 * @static 31201 * @private 31202 * @type {PIXI.Application.Plugin[]} 31203 */ 31204 Application._plugins = []; 31205 31206 /** 31207 * Middleware for for Application's resize functionality 31208 * @private 31209 * @class 31210 */ 31211 var ResizePlugin = function ResizePlugin () {}; 31212 31213 ResizePlugin.init = function init (options) 31214 { 31215 var this$1 = this; 31216 31217 /** 31218 * The element or window to resize the application to. 31219 * @type {Window|HTMLElement} 31220 * @name resizeTo 31221 * @memberof PIXI.Application# 31222 */ 31223 Object.defineProperty(this, 'resizeTo', 31224 { 31225 set: function set(dom) 31226 { 31227 window.removeEventListener('resize', this.resize); 31228 this._resizeTo = dom; 31229 if (dom) 31230 { 31231 window.addEventListener('resize', this.resize); 31232 this.resize(); 31233 } 31234 }, 31235 get: function get() 31236 { 31237 return this._resizeTo; 31238 }, 31239 }); 31240 31241 /** 31242 * If `resizeTo` is set, calling this function 31243 * will resize to the width and height of that element. 31244 * @method PIXI.Application#resize 31245 */ 31246 this.resize = function () { 31247 if (this$1._resizeTo) 31248 { 31249 // Resize to the window 31250 if (this$1._resizeTo === window) 31251 { 31252 this$1.renderer.resize( 31253 window.innerWidth, 31254 window.innerHeight 31255 ); 31256 } 31257 // Resize to other HTML entities 31258 else 31259 { 31260 this$1.renderer.resize( 31261 this$1._resizeTo.clientWidth, 31262 this$1._resizeTo.clientHeight 31263 ); 31264 } 31265 } 31266 }; 31267 31268 // On resize 31269 this._resizeTo = null; 31270 this.resizeTo = options.resizeTo || null; 31271 }; 31272 31273 /** 31274 * Clean up the ticker, scoped to application 31275 * @static 31276 * @private 31277 */ 31278 ResizePlugin.destroy = function destroy () 31279 { 31280 this.resizeTo = null; 31281 this.resize = null; 31282 }; 31283 31284 Application.registerPlugin(ResizePlugin); 31285 31286 var miniSignals = createCommonjsModule(function (module, exports
31286) { 31287 'use strict'; 31288 31289 Object.defineProperty(exports, '__esModule', { 31290 value: true 31291 }); 31292 31293 var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) { descriptor.writable = true; } Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) { defineProperties(Constructor.prototype, protoProps); } if (staticProps) { defineProperties(Constructor, staticProps); } return Constructor; }; })(); 31294 31295 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 31296 31297 var MiniSignalBinding = (function () { 31298 function MiniSignalBinding(fn, once, thisArg) { 31299 if (once === undefined) { once = false; } 31300 31301 _classCallCheck(this, MiniSignalBinding); 31302 31303 this._fn = fn; 31304 this._once = once; 31305 this._thisArg = thisArg; 31306 this._next = this._prev = this._owner = null; 31307 } 31308 31309 _createClass(MiniSignalBinding, [{ 31310 key: 'detach', 31311 value: function detach() { 31312 if (this._owner === null) { return false; } 31313 this._owner.detach(this); 31314 return true; 31315 } 31316 }]); 31317 31318 return MiniSignalBinding; 31319 })(); 31320 31321 function _addMiniSignalBinding(self, node) { 31322 if (!self._head) { 31323 self._head = node; 31324 self._tail = node; 31325 } else { 31326 self._tail._next = node; 31327 node._prev = self._tail; 31328 self._tail = node; 31329 } 31330 31331 node._owner = self; 31332 31333 return node; 31334 } 31335 31336 var MiniSignal = (function () { 31337 function MiniSignal() { 31338 _classCallCheck(this, MiniSignal); 31339 31340 this._head = this._tail = undefined; 31341 } 31342 31343 _createClass(MiniSignal, [{ 31344 key: 'handlers', 31345 value: function handlers() { 31346 var exists = arguments.length <= 0 || arguments[0] === undefined ? false : arguments[0]; 31347 31348 var node = this._head; 31349 31350 if (exists) { return !!node; } 31351 31352 var ee = []; 31353 31354 while (node) { 31355 ee.push(node); 31356 node = node._next; 31357 } 31358 31359 return ee; 31360 } 31361 }, { 31362 key: 'has', 31363 value: function has(node) { 31364 if (!(node instanceof MiniSignalBinding)) { 31365 throw new Error('MiniSignal#has(): First arg must be a MiniSignalBinding object.'); 31366 } 31367 31368 return node._owner === this; 31369 } 31370 }, { 31371 key: 'dispatch', 31372 value: function dispatch() { 31373 var arguments$1 = arguments; 31374 31375 var node = this._head; 31376 31377 if (!node) { return false; } 31378 31379 while (node) { 31380 if (node._once) { this.detach(node); } 31381 node._fn.apply(node._thisArg, arguments$1); 31382 node = node._next; 31383 } 31384 31385 return true; 31386 } 31387 }, { 31388 key: 'add', 31389 value: function add(fn) { 31390 var thisArg = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1]; 31391 31392 if (typeof fn !== 'function') { 31393 throw new Error('MiniSignal#add(): First arg must be a Function.'); 31394 } 31395 return _addMiniSignalBinding(this, new MiniSignalBinding(fn, false, thisArg)); 31396 } 31397 }, { 31398 key: 'once', 31399 value: function once(fn) { 31400 var thisArg = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1]; 31401 31402 if (typeof fn !== 'function') { 31403 throw new Error('MiniSignal#once(): First arg must be a Function.'); 31404 } 31405 return _addMiniSignalBinding(this, new MiniSignalBinding(fn, true, thisArg)); 31406 } 31407 }, { 31408 key: 'detach', 31409 value: function detach(node) { 31410 if (!(node instanceof MiniSignalBinding)) { 31411 throw new Error('MiniSignal#detach(): First arg must be a MiniSignalBinding object.'); 31412 } 31413 if (node._owner !== this) { return this; } 31414 31415 if (node._prev) { node._prev._next = node._next; } 31416 if (node._next) { node._next._prev = node._prev; } 31417 31418 if (node === this._head) { 31419 this._head = node._next; 31420 if (node._next === null) { 31421 this._tail = null; 31422 } 31423 } else if (node === this._tail) { 31424 this._tail = node._prev; 31425 this._tail._next = null; 31426 } 31427 31428 node._owner = null; 31429 return this; 31430 } 31431 }, { 31432 key: 'detachAll', 31433 value: function detachAll() { 31434 var node = this._head; 31435 if (!node) { return this; } 31436 31437 this._head = this._tail = null; 31438 31439 while (node) { 31440 node._owner = null; 31441 node = node._next; 31442 } 31443 return this; 31444 } 31445 }]); 31446 31447 return MiniSignal; 31448 })(); 31449 31450 MiniSignal.MiniSignalBinding = MiniSignalBinding; 31451 31452 exports['default'] = MiniSignal; 31453 module.exports = exports['default']; 31454 }); 31455 31456 var miniSignals$1 = unwrapExports(miniSignals); 31457 31458 'use strict'; 31459 31460 var parseUri = function parseURI (str, opts) { 31461 opts = opts || {}; 31462 31463 var o = { 31464 key: ['source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'], 31465 q: { 31466 name: 'queryKey', 31467 parser: /(?:^|&)([^&=]*)=?([^&]*)/g 31468 }, 31469 parser: {
31470 strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, 31471 loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ 31472 } 31473 }; 31474 31475 var m = o.parser[opts.strictMode ? 'strict' : 'loose'].exec(str); 31476 var uri = {}; 31477 var i = 14; 31478 31479 while (i--) { uri[o.key[i]] = m[i] || ''; } 31480 31481 uri[o.q.name] = {}; 31482 uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) { 31483 if ($1) { uri[o.q.name][$1] = $2; } 31484 }); 31485 31486 return uri 31487 }; 31488 31489 var async = createCommonjsModule(function (module, exports) { 31490 'use strict'; 31491 31492 exports.__esModule = true; 31493 exports.eachSeries = eachSeries; 31494 exports.queue = queue; 31495 /** 31496 * Smaller version of the async library constructs. 31497 * 31498 * @namespace async 31499 */ 31500 31501 /** 31502 * Noop function 31503 * 31504 * @ignore 31505 * @function 31506 * @memberof async 31507 */ 31508 function _noop() {} /* empty */ 31509 31510 /** 31511 * Iterates an array in series. 31512 * 31513 * @memberof async 31514 * @param {Array.<*>} array - Array to iterate. 31515 * @param {function} iterator - Function to call for each element. 31516 * @param {function} callback - Function to call when done, or on error. 31517 * @param {boolean} [deferNext=false] - Break synchronous each loop by calling next with a setTimeout of 1. 31518 */ 31519 function eachSeries(array, iterator, callback, deferNext) { 31520 var i = 0; 31521 var len = array.length; 31522 31523 (function next(err) { 31524 if (err || i === len) { 31525 if (callback) { 31526 callback(err); 31527 } 31528 31529 return; 31530 } 31531 31532 if (deferNext) { 31533 setTimeout(function () { 31534 iterator(array[i++], next); 31535 }, 1); 31536 } else { 31537 iterator(array[i++], next); 31538 } 31539 })(); 31540 } 31541 31542 /** 31543 * Ensures a function is only called once. 31544 * 31545 * @ignore 31546 * @memberof async 31547 * @param {function} fn - The function to wrap. 31548 * @return {function} The wrapping function. 31549 */ 31550 function onlyOnce(fn) { 31551 return function onceWrapper() { 31552 if (fn === null) { 31553 throw new Error('Callback was already called.'); 31554 } 31555 31556 var callFn = fn; 31557 31558 fn = null; 31559 callFn.apply(this, arguments); 31560 }; 31561 } 31562 31563 /** 31564 * Async queue implementation, 31565 * 31566 * @memberof async 31567 * @param {function} worker - The worker function to call for each task. 31568 * @param {number} concurrency - How many workers to run in parrallel. 31569 * @return {*} The async queue object. 31570 */ 31571 function queue(worker, concurrency) { 31572 if (concurrency == null) { 31573 // eslint-disable-line no-eq-null,eqeqeq 31574 concurrency = 1; 31575 } else if (concurrency === 0) { 31576 throw new Error('Concurrency must not be zero'); 31577 } 31578 31579 var workers = 0; 31580 var q = { 31581 _tasks: [], 31582 concurrency: concurrency, 31583 saturated: _noop, 31584 unsaturated: _noop, 31585 buffer: concurrency / 4, 31586 empty: _noop, 31587 drain: _noop, 31588 error: _noop, 31589 started: false, 31590 paused: false, 31591 push: function push(data, callback) { 31592 _insert(data, false, callback); 31593 }, 31594 kill: function kill() { 31595 workers = 0; 31596 q.drain = _noop; 31597 q.started = false; 31598 q._tasks = []; 31599 }, 31600 unshift: function unshift(data, callback) { 31601 _insert(data, true, callback); 31602 }, 31603 process: function process() { 31604 while (!q.paused && workers < q.concurrency && q._tasks.length) { 31605 var task = q._tasks.shift(); 31606 31607 if (q._tasks.length === 0) { 31608 q.empty(); 31609 } 31610 31611 workers += 1; 31612 31613 if (workers === q.concurrency) { 31614 q.saturated(); 31615 } 31616 31617 worker(task.data, onlyOnce(_next(task))); 31618 } 31619 }, 31620 length: function length() { 31621 return q._tasks.length; 31622 }, 31623 running: function running() { 31624 return workers; 31625 }, 31626 idle: function idle() { 31627 return q._tasks.length + workers === 0; 31628 }, 31629 pause: function pause() { 31630 if (q.paused === true) { 31631 return; 31632 } 31633 31634 q.paused = true; 31635 }, 31636 resume: function resume() { 31637 if (q.paused === false) { 31638 return; 31639 } 31640 31641 q.paused = false;
31642 31643 // Need to call q.process once per concurrent 31644 // worker to preserve full concurrency after pause 31645 for (var w = 1; w <= q.concurrency; w++) { 31646 q.process(); 31647 } 31648 } 31649 }; 31650 31651 function _insert(data, insertAtFront, callback) { 31652 if (callback != null && typeof callback !== 'function') { 31653 // eslint-disable-line no-eq-null,eqeqeq 31654 throw new Error('task callback must be a function'); 31655 } 31656 31657 q.started = true; 31658 31659 if (data == null && q.idle()) { 31660 // eslint-disable-line no-eq-null,eqeqeq 31661 // call drain immediately if there are no tasks 31662 setTimeout(function () { 31663 return q.drain(); 31664 }, 1); 31665 31666 return; 31667 } 31668 31669 var item = { 31670 data: data, 31671 callback: typeof callback === 'function' ? callback : _noop 31672 }; 31673 31674 if (insertAtFront) { 31675 q._tasks.unshift(item); 31676 } else { 31677 q._tasks.push(item); 31678 } 31679 31680 setTimeout(function () { 31681 return q.process(); 31682 }, 1); 31683 } 31684 31685 function _next(task) { 31686 return function next() { 31687 workers -= 1; 31688 31689 task.callback.apply(task, arguments); 31690 31691 if (arguments[0] != null) { 31692 // eslint-disable-line no-eq-null,eqeqeq 31693 q.error(arguments[0], task.data); 31694 } 31695 31696 if (workers <= q.concurrency - q.buffer) { 31697 q.unsaturated(); 31698 } 31699 31700 if (q.idle()) { 31701 q.drain(); 31702 } 31703 31704 q.process(); 31705 }; 31706 } 31707 31708 return q; 31709 } 31710 31711 }); 31712 31713 var async$1 = unwrapExports(async); 31714 var async_1 = async.eachSeries; 31715 var async_2 = async.queue; 31716 31717 var Resource_1 = createCommonjsModule(function (module, exports) { 31718 'use strict'; 31719 31720 exports.__esModule = true; 31721 exports.Resource = undefined; 31722 31723 var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) { descriptor.writable = true; } Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) { defineProperties(Constructor.prototype, protoProps); } if (staticProps) { defineProperties(Constructor, staticProps); } return Constructor; }; }(); 31724 31725 31726 31727 var _parseUri2 = _interopRequireDefault(parseUri); 31728 31729 31730 31731 var _miniSignals2 = _interopRequireDefault(miniSignals); 31732 31733 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 31734 31735 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 31736 31737 // tests if CORS is supported in XHR, if not we need to use XDR 31738 var useXdr = !!(window.XDomainRequest && !('withCredentials' in new XMLHttpRequest())); 31739 var tempAnchor = null; 31740 31741 // some status constants 31742 var STATUS_NONE = 0; 31743 var STATUS_OK = 200; 31744 var STATUS_EMPTY = 204; 31745 var STATUS_IE_BUG_EMPTY = 1223; 31746 var STATUS_TYPE_OK = 2; 31747 31748 // noop 31749 function _noop() {} /* empty */ 31750 31751 /** 31752 * Manages the state and loading of a resource and all child resources. 31753 * 31754 * @class 31755 */ 31756 31757 var Resource = exports.Resource = function () { 31758 /** 31759 * Sets the load type to be used for a specific extension. 31760 * 31761 * @static 31762 * @param {string} extname - The extension to set the type for, e.g. "png" or "fnt" 31763 * @param {Resource.LOAD_TYPE} loadType - The load type to set it to. 31764 */ 31765 Resource.setExtensionLoadType = function setExtensionLoadType(extname, loadType) { 31766 setExtMap(Resource._loadTypeMap, extname, loadType); 31767 }; 31768 31769 /** 31770 * Sets the load type to be used for a specific extension. 31771 * 31772 * @static 31773 * @param {string} extname - The extension to set the type for, e.g. "png" or "fnt" 31774 * @param {Resource.XHR_RESPONSE_TYPE} xhrType - The xhr type to set it to. 31775 */ 31776 31777 31778 Resource.setExtensionXhrType = function setExtensionXhrType(extname, xhrType) { 31779 setExtMap(Resource._xhrTypeMap, extname, xhrType); 31780 }; 31781 31782 /** 31783 * @param {string} name - The name of the resource to load. 31784 * @param {string|string[]} url - The url for this resource, for audio/video loads you can pass 31785 * an array of sources. 31786 * @param {object} [options] - The options for the load. 31787 * @param {string|boolean} [options.crossOrigin] - Is this request cross-origin? Default is to 31788 * determine automatically. 31789 * @param {number} [options.timeout=0] - A timeout in milliseconds for the load. If the load takes 31790 * longer than this time it is cancelled and the load is considered a failure. If this value is 31791 * set to `0` then there is no explicit timeout. 31792 * @param {Resource.LOAD_TYPE} [options.loadType=Resource.LOAD_TYPE.XHR] - How should this resource 31793 * be loaded? 31794 * @param {Resource.XHR_RESPONSE_TYPE} [options.xhrType=Resource.XHR_RESPONSE_TYPE.DEFAULT] - How 31795 * should the data being loaded be interpreted when using XHR? 31796 * @param {Resource.IMetadata} [options.metadata] - Extra configuration for middleware and the Resource object. 31797 */ 31798 31799 31800 function Resource(name, url, options) { 31801 _classCallCheck(this, Resource); 31802 31803 if (typeof name !== 'string' || typeof url !== 'string') { 31804 throw new Error('Both name and url are required for constructing a resource.'); 31805 } 31806 31807 options = options || {}; 31808 31809 /** 31810 * The state flags of this resource. 31811 * 31812 * @private 31813 * @member {number} 31814 */ 31815 this._flags = 0; 31816 31817 // set data url flag, needs to be set early for some _determineX checks to work. 31818 this._setFlag(Resource.STATUS_FLAGS.DATA_URL, url.indexOf('data:') === 0); 31819 31820 /** 31821 * The name of this resource. 31822 * 31823 * @readonly 31824 * @member {string} 31825 */ 31826 this.name = name; 31827 31828 /** 31829 * The url used to load this resource. 31830 * 31831 * @readonly 31832 * @member {string} 31833 */ 31834 this.url = url; 31835 31836 /** 31837 * The extension used to load this resource. 31838 * 31839 * @readonly 31840 * @member {string} 31841 */ 31842 this.extension = this._getExtension(); 31843 31844 /** 31845 * The data that was loaded by the resource. 31846 * 31847 * @member {any} 31848 */ 31849 this.data = null; 31850 31851 /** 31852 * Is this request cross-origin? If unset, determined automatically. 31853 * 31854 * @member {string} 31855 */ 31856 this.crossOrigin = options.crossOrigin === true ? 'anonymous' : options.crossOrigin; 31857 31858 /** 31859 * A timeout in milliseconds for the load. If the load takes longer than this time 31860 * it is cancelled and the load is considered a failure. If this value is set to `0` 31861 * then there is no explicit timeout. 31862 * 31863 * @member {number} 31864 */ 31865 this.timeout = options.timeout || 0; 31866 31867 /** 31868 * The method of loading to use for this resource. 31869 * 31870 * @member {Resource.LOAD_TYPE} 31871 */ 31872 this.loadType = options.loadType || this._determineLoadType(); 31873 31874 /** 31875 * The type used to load the resource via XHR. If unset, determined automatically. 31876 * 31877 * @member {string} 31878 */ 31879 this.xhrType = options.xhrType; 31880 31881 /** 31882 * Extra info for middleware, and controlling specifics about how the resource loads. 31883 * 31884 * Note that if you pass in a `loadElement`, the Resource class takes ownership of it. 31885 * Meaning it will modify it as it sees fit. 31886 * 31887 * @member {Resource.IMetadata} 31888 */ 31889 this.metadata = options.metadata || {}; 31890 31891 /** 31892 * The error that occurred while loading (if any). 31893 * 31894 * @readonly 31895 * @member {Error} 31896 */ 31897 this.error = null; 31898 31899 /** 31900 * The XHR object that was used to load this resource. This is only set 31901 * when `loadType` is `Resource.LOAD_TYPE.XHR`. 31902 * 31903 * @readonly 31904 * @member {XMLHttpRequest} 31905 */ 31906 this.xhr = null; 31907 31908 /** 31909 * The child resources this resource owns. 31910 * 31911 * @readonly 31912 * @member {Resource[]} 31913 */ 31914 this.children = []; 31915 31916 /** 31917 * The resource type. 31918 * 31919 * @readonly 31920 * @member {Resource.TYPE} 31921 */ 31922 this.type = Resource.TYPE.UNKNOWN; 31923 31924 /** 31925 * The progress chunk owned by this resource. 31926 * 31927 * @readonly 31928 * @member {number} 31929 */ 31930 this.progressChunk = 0; 31931 31932 /** 31933 * The `dequeue` method that will be used a storage place for the async queue dequeue method 31934 * used privately by the loader. 31935 * 31936 * @private 31937 * @member {function} 31938 */ 31939 this._dequeue = _noop; 31940 31941 /**
31942 * Used a storage place for the on load binding used privately by the loader. 31943 * 31944 * @private 31945 * @member {function} 31946 */ 31947 this._onLoadBinding = null; 31948 31949 /** 31950 * The timer for element loads to check if they timeout. 31951 * 31952 * @private 31953 * @member {number} 31954 */ 31955 this._elementTimer = 0; 31956 31957 /** 31958 * The `complete` function bound to this resource's context. 31959 * 31960 * @private 31961 * @member {function} 31962 */ 31963 this._boundComplete = this.complete.bind(this); 31964 31965 /** 31966 * The `_onError` function bound to this resource's context. 31967 * 31968 * @private 31969 * @member {function} 31970 */ 31971 this._boundOnError = this._onError.bind(this); 31972 31973 /** 31974 * The `_onProgress` function bound to this resource's context. 31975 * 31976 * @private 31977 * @member {function} 31978 */ 31979 this._boundOnProgress = this._onProgress.bind(this); 31980 31981 /** 31982 * The `_onTimeout` function bound to this resource's context. 31983 * 31984 * @private 31985 * @member {function} 31986 */ 31987 this._boundOnTimeout = this._onTimeout.bind(this); 31988 31989 // xhr callbacks 31990 this._boundXhrOnError = this._xhrOnError.bind(this); 31991 this._boundXhrOnTimeout = this._xhrOnTimeout.bind(this); 31992 this._boundXhrOnAbort = this._xhrOnAbort.bind(this); 31993 this._boundXhrOnLoad = this._xhrOnLoad.bind(this); 31994 31995 /** 31996 * Dispatched when the resource beings to load. 31997 * 31998 * The callback looks like {@link Resource.OnStartSignal}. 31999 * 32000 * @member {Signal} 32001 */ 32002 this.onStart = new _miniSignals2.default(); 32003 32004 /** 32005 * Dispatched each time progress of this resource load updates. 32006 * Not all resources types and loader systems can support this event 32007 * so sometimes it may not be available. If the resource 32008 * is being loaded on a modern browser, using XHR, and the remote server 32009 * properly sets Content-Length headers, then this will be available. 32010 * 32011 * The callback looks like {@link Resource.OnProgressSignal}. 32012 * 32013 * @member {Signal} 32014 */ 32015 this.onProgress = new _miniSignals2.default(); 32016 32017 /** 32018 * Dispatched once this resource has loaded, if there was an error it will 32019 * be in the `error` property. 32020 * 32021 * The callback looks like {@link Resource.OnCompleteSignal}. 32022 * 32023 * @member {Signal} 32024 */ 32025 this.onComplete = new _miniSignals2.default(); 32026 32027 /** 32028 * Dispatched after this resource has had all the *after* middleware run on it. 32029 * 32030 * The callback looks like {@link Resource.OnCompleteSignal}. 32031 * 32032 * @member {Signal} 32033 */ 32034 this.onAfterMiddleware = new _miniSignals2.default(); 32035 } 32036 32037 /** 32038 * When the resource starts to load. 32039 * 32040 * @memberof Resource 32041 * @callback OnStartSignal 32042 * @param {Resource} resource - The resource that the event happened on. 32043 */ 32044 32045 /** 32046 * When the resource reports loading progress. 32047 * 32048 * @memberof Resource 32049 * @callback OnProgressSignal 32050 * @param {Resource} resource - The resource that the event happened on. 32051 * @param {number} percentage - The progress of the load in the range [0, 1]. 32052 */ 32053 32054 /** 32055 * When the resource finishes loading. 32056 * 32057 * @memberof Resource 32058 * @callback OnCompleteSignal 32059 * @param {Resource} resource - The resource that the event happened on. 32060 */ 32061 32062 /** 32063 * @memberof Resource 32064 * @typedef {object} IMetadata 32065 * @property {HTMLImageElement|HTMLAudioElement|HTMLVideoElement} [loadElement=null] - The 32066 * element to use for loading, instead of creating one. 32067 * @property {boolean} [skipSource=false] - Skips adding source(s) to the load element. This 32068 * is useful if you want to pass in a `loadElement` that you already added load sources to. 32069 * @property {string|string[]} [mimeType] - The mime type to use for the source element 32070 * of a video/audio elment. If the urls are an array, you can pass this as an array as well 32071 * where each index is the mime type to use for the corresponding url index. 32072 */ 32073 32074 /** 32075 * Stores whether or not this url is a data url. 32076 * 32077 * @readonly 32078 * @member {boolean} 32079 */ 32080 32081 32082 /** 32083 * Marks the resource as complete. 32084 * 32085 */ 32086 Resource.prototype.complete = function complete() { 32087 this._clearEvents(); 32088 this._finish(); 32089 }; 32090 32091 /** 32092 * Aborts the loading of this resource, with an optional message. 32093 * 32094 * @param {string} message - The message to use for the error 32095 */ 32096 32097 32098 Resource.prototype.abort = function abort(message) { 32099 // abort can be called multiple times, ignore subsequent calls. 32100 if (this.error) { 32101 return; 32102 } 32103 32104 // store error 32105 this.error = new Error(message); 32106 32107 // clear events before calling aborts 32108 this._clearEvents(); 32109 32110 // abort the actual loading 32111 if (this.xhr) { 32112 this.xhr.abort(); 32113 } else if (this.xdr) { 32114 this.xdr.abort(); 32115 } else if (this.data) { 32116 // single source 32117 if (this.data.src) { 32118 this.data.src = Resource.EMPTY_GIF; 32119 } 32120 // multi-source 32121 else { 32122 while (this.data.firstChild) { 32123 this.data.removeChild(this.data.firstChild); 32124 } 32125 } 32126 } 32127 32128 // done now. 32129 this._finish(); 32130 }; 32131 32132 /** 32133 * Kicks off loading of this resource. This method is asynchronous. 32134 * 32135 * @param {Resource.OnCompleteSignal} [cb] - Optional callback to call once the resource is loaded. 32136 */ 32137 32138 32139 Resource.prototype.load = function load(cb) { 32140 var _this = this; 32141 32142 if (this.isLoading) { 32143 return; 32144 } 32145 32146 if (this.isComplete) { 32147 if (cb) { 32148 setTimeout(function () { 32149 return cb(_this); 32150 }, 1); 32151 } 32152 32153 return; 32154 } else if (cb) { 32155 this.onComplete.once(cb); 32156 } 32157 32158 this._setFlag(Resource.STATUS_FLAGS.LOADING, true); 32159 32160 this.onStart.dispatch(this); 32161 32162 // if unset, determine the value 32163 if (this.crossOrigin === false || typeof this.crossOrigin !== 'string') { 32164 this.crossOrigin = this._determineCrossOrigin(this.url); 32165 } 32166 32167 switch (this.loadType) { 32168 case Resource.LOAD_TYPE.IMAGE: 32169 this.type = Resource.TYPE.IMAGE; 32170 this._loadElement('image'); 32171 break; 32172 32173 case Resource.LOAD_TYPE.AUDIO: 32174 this.type = Resource.TYPE.AUDIO; 32175 this._loadSourceElement('audio'); 32176 break; 32177 32178 case Resource.LOAD_TYPE.VIDEO: 32179 this.type = Resource.TYPE.VIDEO; 32180 this._loadSourceElement('video'); 32181 break; 32182 32183 case Resource.LOAD_TYPE.XHR: 32184 /* falls through */ 32185 default: 32186 if (useXdr && this.crossOrigin) { 32187 this._loadXdr(); 32188 } else { 32189 this._loadXhr(); 32190 } 32191 break; 32192 } 32193 }; 32194 32195 /** 32196 * Checks if the flag is set. 32197 * 32198 * @private 32199 * @param {number} flag - The flag to check. 32200 * @return {boolean} True if the flag is set. 32201 */ 32202 32203 32204 Resource.prototype._hasFlag = function _hasFlag(flag) { 32205 return (this._flags & flag) !== 0; 32206 }; 32207 32208 /** 32209 * (Un)Sets the flag. 32210 * 32211 * @private 32212 * @param {number} flag - The flag to (un)set. 32213 * @param {boolean} value - Whether to set or (un)set the flag. 32214 */ 32215 32216 32217 Resource.prototype._setFlag = function _setFlag(flag, value) { 32218 this._flags = value ? this._flags | flag : this._flags & ~flag; 32219 }; 32220 32221 /** 32222 * Clears all the events from the underlying loading source. 32223 * 32224 * @private 32225 */ 32226 32227 32228 Resource.prototype._clearEvents = function _clearEvents() { 32229 clearTimeout(this._elementTimer); 32230 32231 if (this.data && this.data.removeEventListener) { 32232 this.data.removeEventListener('error', this._boundOnError, false); 32233 this.data.removeEventListener('load', this._boundComplete, false); 32234 this.data.removeEventListener('progress', this._boundOnProgress, false); 32235 this.data.removeEventListener('canplaythrough', this._boundComplete, false); 32236 } 32237 32238 if (this.xhr) { 32239 if (this.xhr.removeEventListener) { 32240 this.xhr.removeEventListener('error', this._boundXhrOnError, false); 32241 this.xhr.removeEventListener('timeout', this._boundXhrOnTimeout, false); 32242 this.xhr.removeEventListener('abort', this._boundXhrOnAbort, false); 32243 this.xhr.removeEventListener('progress', this._boundOnProgress, false); 32244 this.xhr.removeEventListener('load', this._boundXhrOnLoad, false); 32245 } else { 32246 this.xhr.onerror = null; 32247 this.xhr.ontimeout = null; 32248 this.xhr.onprogress = null; 32249 this.xhr.onload = null; 32250 } 32251 } 32252 }; 32253 32254 /** 32255 * Finalizes the load. 32256 * 32257 * @private 32258 */ 32259 32260 32261 Resource.prototype._finish = function _finish() { 32262 if (this.isComplete) { 32263 throw new Error('Complete called again for an already completed resource.'); 32264 } 32265 32266 this._setFlag(Resource.STATUS_FLAGS.COMPLETE, true); 32267 this._setFlag(Resource.STATUS_FLAGS.LOADING, false); 32268 32269 this.onComplete.dispatch(this); 32270 }; 32271 32272 /** 32273 * Loads this resources using an element that has a single source, 32274 * like an HTMLImageElement. 32275 * 32276 * @private 32277 * @param {string} type - The type of element to use. 32278 */ 32279 32280 32281 Resource.prototype._loadElement = function _loadElement(type) { 32282 if (this.metadata.loadElement) { 32283 this.data = this.metadata.loadElement; 32284 } else if (type === 'image' && typeof window.Image !== 'undefined') { 32285 this.data = new Image(); 32286 } else { 32287 this.data = document.createElement(type); 32288 } 32289 32290 if (this.crossOrigin) { 32291 this.data.crossOrigin = this.crossOrigin; 32292 } 32293 32294 if (!this.metadata.skipSource) { 32295 this.data.src = this.url; 32296 } 32297 32298 this.data.addEventListener('error', this._boundOnError, false); 32299 this.data.addEventListener('load', this._boundComplete, false); 32300 this.data.addEventListener('progress', this._boundOnProgress, false); 32301 32302 if (this.timeout) { 32303 this._elementTimer = setTimeout(this._boundOnTimeout, this.timeout); 32304 } 32305 }; 32306 32307 /** 32308 * Loads this resources using an element that has multiple sources, 32309 * like an HTMLAudioElement or HTMLVideoElement. 32310 * 32311 * @private 32312 * @param {string} type - The type of element to use. 32313 */ 32314 32315 32316 Resource.prototype._loadSourceElement = function _loadSourceElement(type) { 32317 if (this.metadata.loadElement) { 32318 this.data = this.metadata.loadElement; 32319 } else if (type === 'audio' && typeof window.Audio !== 'undefined') { 32320 this.data = new Audio(); 32321 } else { 32322 this.data = document.createElement(type); 32323 } 32324 32325 if (this.data === null) { 32326 this.abort('Unsupported element: ' + type); 32327 32328 return; 32329 } 32330 32331 if (this.crossOrigin) { 32332 this.data.crossOrigin = this.crossOrigin; 32333 } 32334 32335 if (!this.metadata.skipSource) { 32336 // support for CocoonJS Canvas+ runtime, lacks document.createElement('source') 32337 if (navigator.isCocoonJS) { 32338 this.data.src = Array.isArray(this.url) ? this.url[0] : this.url; 32339 } else if (Array.isArray(this.url)) { 32340 var mimeTypes = this.metadata.mimeType; 32341 32342 for (var i = 0; i < this.url.length; ++i) { 32343 this.data.appendChild(this._createSource(type, this.url[i], Array.isArray(mimeTypes) ? mimeTypes[i] : mimeTypes)); 32344 } 32345 } else { 32346 var _mimeTypes = this.metadata.mimeType; 32347 32348 this.data.appendChild(this._createSource(type, this.url, Array.isArray(_mimeTypes) ? _mimeTypes[0] : _mimeTypes)); 32349 } 32350 } 32351 32352 this.data.addEventListener('error', this._boundOnError, false); 32353 this.data.addEventListener('load', this._boundComplete, false); 32354 this.data.addEventListener('progress', this._boundOnProgress, false); 32355 this.data.addEventListener('canplaythrough', this._boundComplete, false); 32356 32357 this.data.load(); 32358 32359 if (this.timeout) { 32360 this._elementTimer = setTimeout(this._boundOnTimeout, this.timeout); 32361 } 32362 }; 32363 32364 /** 32365 * Loads this resources using an XMLHttpRequest. 32366 * 32367 * @private 32368 */ 32369 32370 32371 Resource.prototype._loadXhr = function _loadXhr() { 32372 // if unset, determine the value 32373 if (typeof this.xhrType !== 'string') { 32374 this.xhrType = this._determineXhrType(); 32375 } 32376 32377 var xhr = this.xhr = new XMLHttpRequest(); 32378 32379 // set the request type and url 32380 xhr.open('GET', this.url, true); 32381 32382 xhr.timeout = this.timeout; 32383 32384 // load json as text and parse it ourselves. We do this because some browsers 32385 // *cough* safari *cough* can't deal with it. 32386 if (this.xhrType === Resource.XHR_RESPONSE_TYPE.JSON || this.xhrType === Resource.XHR_RESPONSE_TYPE.DOCUMENT) { 32387 xhr.responseType = Resource.XHR_RESPONSE_TYPE.TEXT; 32388 } else { 32389 xhr.responseType = this.xhrType; 32390 } 32391 32392 xhr.addEventListener('error', this._boundXhrOnError, false); 32393 xhr.addEventListener('timeout', this._boundXhrOnTimeout, false); 32394 xhr.addEventListener('abort', this._boundXhrOnAbort, false); 32395 xhr.addEventListener('progress', this._boundOnProgress, false); 32396 xhr.addEventListener('load', this._boundXhrOnLoad, false); 32397 32398 xhr.send(); 32399 }; 32400 32401 /** 32402 * Loads this resources using an XDomainRequest. This is here because we need to support IE9 (gross). 32403 * 32404 * @private 32405 */ 32406 32407 32408 Resource.prototype._loadXdr = function _loadXdr() { 32409 // if unset, determine the value 32410 if (typeof this.xhrType !== 'string') { 32411 this.xhrType = this._determineXhrType(); 32412 } 32413 32414 var xdr = this.xhr = new XDomainRequest(); // eslint-disable-line no-undef 32415 32416 // XDomainRequest has a few quirks. Occasionally it will abort requests 32417 // A way to avoid this is to make sure ALL callbacks are set even if not used 32418 // More info here: http://stackoverflow.com/questions/15786966/xdomainrequest-aborts-post-on-ie-9 32419 xdr.timeout = this.timeout || 5000; // XDR needs a timeout value or it breaks in IE9 32420 32421 xdr.onerror = this._boundXhrOnError; 32422 xdr.ontimeout = this._boundXhrOnTimeout; 32423 xdr.onprogress = this._boundOnProgress; 32424 xdr.onload = this._boundXhrOnLoad; 32425
32426 xdr.open('GET', this.url, true); 32427 32428 // Note: The xdr.send() call is wrapped in a timeout to prevent an 32429 // issue with the interface where some requests are lost if multiple 32430 // XDomainRequests are being sent at the same time. 32431 // Some info here: https://github.com/photonstorm/phaser/issues/1248 32432 setTimeout(function () { 32433 return xdr.send(); 32434 }, 1); 32435 }; 32436 32437 /** 32438 * Creates a source used in loading via an element. 32439 * 32440 * @private 32441 * @param {string} type - The element type (video or audio). 32442 * @param {string} url - The source URL to load from. 32443 * @param {string} [mime] - The mime type of the video 32444 * @return {HTMLSourceElement} The source element. 32445 */ 32446 32447 32448 Resource.prototype._createSource = function _createSource(type, url, mime) { 32449 if (!mime) { 32450 mime = type + '/' + this._getExtension(url); 32451 } 32452 32453 var source = document.createElement('source'); 32454 32455 source.src = url; 32456 source.type = mime; 32457 32458 return source; 32459 }; 32460 32461 /** 32462 * Called if a load errors out. 32463 * 32464 * @param {Event} event - The error event from the element that emits it. 32465 * @private 32466 */ 32467 32468 32469 Resource.prototype._onError = function _onError(event) { 32470 this.abort('Failed to load element using: ' + event.target.nodeName); 32471 }; 32472 32473 /** 32474 * Called if a load progress event fires for an element or xhr/xdr. 32475 * 32476 * @private 32477 * @param {XMLHttpRequestProgressEvent|Event} event - Progress event. 32478 */ 32479 32480 32481 Resource.prototype._onProgress = function _onProgress(event) { 32482 if (event && event.lengthComputable) { 32483 this.onProgress.dispatch(this, event.loaded / event.total); 32484 } 32485 }; 32486 32487 /** 32488 * Called if a timeout event fires for an element. 32489 * 32490 * @private 32491 */ 32492 32493
32494 Resource.prototype._onTimeout = function _onTimeout() { 32495 this.abort('Load timed out.'); 32496 }; 32497 32498 /** 32499 * Called if an error event fires for xhr/xdr. 32500 * 32501 * @private 32502 */ 32503 32504 32505 Resource.prototype._xhrOnError = function _xhrOnError() { 32506 var xhr = this.xhr; 32507 32508 this.abort(reqType(xhr) + ' Request failed. Status: ' + xhr.status + ', text: "' + xhr.statusText + '"'); 32509 }; 32510 32511 /** 32512 * Called if an error event fires for xhr/xdr. 32513 * 32514 * @private 32515 */ 32516 32517 32518 Resource.prototype._xhrOnTimeout = function _xhrOnTimeout() { 32519 var xhr = this.xhr; 32520 32521 this.abort(reqType(xhr) + ' Request timed out.'); 32522 }; 32523 32524 /** 32525 * Called if an abort event fires for xhr/xdr. 32526 * 32527 * @private 32528 */ 32529 32530 32531 Resource.prototype._xhrOnAbort = function _xhrOnAbort() { 32532 var xhr = this.xhr; 32533 32534 this.abort(reqType(xhr) + ' Request was aborted by the user.'); 32535 }; 32536 32537 /** 32538 * Called when data successfully loads from an xhr/xdr request. 32539 * 32540 * @private 32541 * @param {XMLHttpRequestLoadEvent|Event} event - Load event 32542 */ 32543 32544 32545 Resource.prototype._xhrOnLoad = function _xhrOnLoad() { 32546 var xhr = this.xhr; 32547 var text = ''; 32548 var status = typeof xhr.status === 'undefined' ? STATUS_OK : xhr.status; // XDR has no `.status`, assume 200. 32549 32550 // responseText is accessible only if responseType is '' or 'text' and on older browsers 32551 if (xhr.responseType === '' || xhr.responseType === 'text' || typeof xhr.responseType === 'undefined') { 32552 text = xhr.responseText; 32553 } 32554 32555 // status can be 0 when using the `file://` protocol so we also check if a response is set. 32556 // If it has a response, we assume 200; otherwise a 0 status code with no contents is an aborted request. 32557 if (status === STATUS_NONE && (text.length > 0 || xhr.responseType === Resource.XHR_RESPONSE_TYPE.BUFFER)) { 32558 status = STATUS_OK; 32559 } 32560 // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request 32561 else if (status === STATUS_IE_BUG_EMPTY) { 32562 status = STATUS_EMPTY; 32563 } 32564 32565 var statusType = status / 100 | 0; 32566 32567 if (statusType === STATUS_TYPE_OK) { 32568 // if text, just return it 32569 if (this.xhrType === Resource.XHR_RESPONSE_TYPE.TEXT) { 32570 this.data = text; 32571 this.type = Resource.TYPE.TEXT; 32572 } 32573 // if json, parse into json object 32574 else if (this.xhrType === Resource.XHR_RESPONSE_TYPE.JSON) { 32575 try { 32576 this.data = JSON.parse(text); 32577 this.type = Resource.TYPE.JSON; 32578 } catch (e) { 32579 this.abort('Error trying to parse loaded json: ' + e); 32580 32581 return; 32582 } 32583 } 32584 // if xml, parse into an xml document or div element 32585 else if (this.xhrType === Resource.XHR_RESPONSE_TYPE.DOCUMENT) { 32586 try { 32587 if (window.DOMParser) { 32588 var domparser = new DOMParser(); 32589 32590 this.data = domparser.parseFromString(text, 'text/xml'); 32591 } else { 32592 var div = document.createElement('div'); 32593 32594 div.innerHTML = text; 32595 32596 this.data = div; 32597 } 32598 32599 this.type = Resource.TYPE.XML; 32600 } catch (e) { 32601 this.abort('Error trying to parse loaded xml: ' + e); 32602 32603 return; 32604 } 32605 } 32606 // other types just return the response 32607 else { 32608 this.data = xhr.response || text; 32609 } 32610 } else { 32611 this.abort('[' + xhr.status + '] ' + xhr.statusText + ': ' + xhr.responseURL); 32612 32613 return; 32614 } 32615 32616 this.complete(); 32617 }; 32618 32619 /** 32620 * Sets the `crossOrigin` property for this resource based on if the url 32621 * for this resource is cross-origin. If crossOrigin was manually set, this 32622 * function does nothing. 32623 * 32624 * @private 32625 * @param {string} url - The url to test. 32626 * @param {object} [loc=window.location] - The location object to test against. 32627 * @return {string} The crossOrigin value to use (or empty string for none). 32628 */ 32629 32630 32631 Resource.prototype._determineCrossOrigin = function _determineCrossOrigin(url, loc) { 32632 // data: and javascript: urls are considered same-origin 32633 if (url.indexOf('data:') === 0) { 32634 return ''; 32635 } 32636 32637 // A sandboxed iframe without the 'allow-same-origin' attribute will have a special 32638 // origin designed not to match window.location.origin, and will always require 32639 // crossOrigin requests regardless of whether the location matches. 32640 if (window.origin !== window.location.origin) { 32641 return 'anonymous'; 32642 } 32643 32644 // default is window.location 32645 loc = loc || window.location; 32646 32647 if (!tempAnchor) { 32648 tempAnchor = document.createElement('a'); 32649 } 32650 32651 // let the browser determine the full href for the url of this resource and then 32652 // parse with the node url lib, we can't use the properties of the anch
32652or element 32653 // because they don't work in IE9 :( 32654 tempAnchor.href = url; 32655 url = (0, _parseUri2.default)(tempAnchor.href, { strictMode: true }); 32656 32657 var samePort = !url.port && loc.port === '' || url.port === loc.port; 32658 var protocol = url.protocol ? url.protocol + ':' : ''; 32659 32660 // if cross origin 32661 if (url.host !== loc.hostname || !samePort || protocol !== loc.protocol) { 32662 return 'anonymous'; 32663 } 32664 32665 return ''; 32666 }; 32667 32668 /** 32669 * Determines the responseType of an XHR request based on the extension of the 32670 * resource being loaded. 32671 * 32672 * @private 32673 * @return {Resource.XHR_RESPONSE_TYPE} The responseType to use. 32674 */ 32675 32676 32677 Resource.prototype._determineXhrType = function _determineXhrType() { 32678 return Resource._xhrTypeMap[this.extension] || Resource.XHR_RESPONSE_TYPE.TEXT; 32679 }; 32680 32681 /** 32682 * Determines the loadType of a resource based on the extension of the 32683 * resource being loaded. 32684 * 32685 * @private 32686 * @return {Resource.LOAD_TYPE} The loadType to use. 32687 */ 32688 32689 32690 Resource.prototype._determineLoadType = function _determineLoadType() { 32691 return Resource._loadTypeMap[this.extension] || Resource.LOAD_TYPE.XHR; 32692 }; 32693 32694 /** 32695 * Extracts the extension (sans '.') of the file being loaded by the resource. 32696 * 32697 * @private 32698 * @return {string} The extension. 32699 */ 32700 32701 32702 Resource.prototype._getExtension = function _getExtension() { 32703 var url = this.url; 32704 var ext = ''; 32705 32706 if (this.isDataUrl) { 32707 var slashIndex = url.indexOf('/'); 32708 32709 ext = url.substring(slashIndex + 1, url.indexOf(';', slashIndex)); 32710 } else { 32711 var queryStart = url.indexOf('?'); 32712 var hashStart = url.indexOf('#'); 32713 var index = Math.min(queryStart > -1 ? queryStart : url.length, hashStart > -1 ? hashStart : url.length); 32714 32715 url = url.substring(0, index); 32716 ext = url.substring(url.lastIndexOf('.') + 1); 32717 } 32718 32719 return ext.toLowerCase(); 32720 }; 32721 32722 /** 32723 * Determines the mime type of an XHR request based on the responseType of 32724 * resource being loaded. 32725 * 32726 * @private 32727 * @param {Resource.XHR_RESPONSE_TYPE} type - The type to get a mime type for. 32728 * @return {string} The mime type to use. 32729 */ 32730 32731 32732 Resource.prototype._getMimeFromXhrType = function _getMimeFromXhrType(type) { 32733 switch (type) { 32734 case Resource.XHR_RESPONSE_TYPE.BUFFER: 32735 return 'application/octet-binary'; 32736 32737 case Resource.XHR_RESPONSE_TYPE.BLOB: 32738 return 'application/blob'; 32739 32740 case Resource.XHR_RESPONSE_TYPE.DOCUMENT: 32741 return 'application/xml'; 32742 32743 case Resource.XHR_RESPONSE_TYPE.JSON: 32744 return 'application/json'; 32745 32746 case Resource.XHR_RESPONSE_TYPE.DEFAULT: 32747 case Resource.XHR_RESPONSE_TYPE.TEXT: 32748 /* falls through */ 32749 default: 32750 return 'text/plain'; 32751 } 32752 }; 32753 32754 _createClass(Resource, [{ 32755 key: 'isDataUrl', 32756 get: function get() { 32757 return this._hasFlag(Resource.STATUS_FLAGS.DATA_URL); 32758 } 32759 32760 /** 32761 * Describes if this resource has finished loading. Is true when the resource has completely 32762 * loaded. 32763 * 32764 * @readonly 32765 * @member {boolean} 32766 */ 32767 32768 }, { 32769 key: 'isComplete', 32770 get: function get() { 32771 return this._hasFlag(Resource.STATUS_FLAGS.COMPLETE); 32772 } 32773 32774 /** 32775 * Describes if this resource is currently loading. Is true when the resource starts loading, 32776 * and is false again when complete. 32777 * 32778 * @readonly 32779 * @member {boolean} 32780 */ 32781 32782 }, { 32783 key: 'isLoading', 32784 get: function get() { 32785 return this._hasFlag(Resource.STATUS_FLAGS.LOADING); 32786 } 32787 }]); 32788 32789 return Resource; 32790 }(); 32791 32792 /** 32793 * The types of resources a resource could represent. 32794 * 32795 * @static 32796 * @readonly 32797 * @enum {number} 32798 */ 32799 32800 32801 Resource.STATUS_FLAGS = { 32802 NONE: 0, 32803 DATA_URL: 1 << 0, 32804 COMPLETE: 1 << 1, 32805 LOADING: 1 << 2 32806 }; 32807 32808 /** 32809 * The types of resources a resource could represent. 32810 * 32811 * @static 32812 * @readonly 32813 * @enum {number} 32814 */ 32815 Resource.TYPE = { 32816 UNKNOWN: 0, 32817 JSON: 1, 32818 XML: 2, 32819 IMAGE: 3, 32820 AUDIO: 4, 32821 VIDEO: 5, 32822 TEXT: 6 32823 }; 32824 32825 /** 32826 * The types of loading a resource can use. 32827 * 32828 * @static 32829 * @readonly 32830 * @enum {number} 32831 */ 32832 Resource.LOAD_TYPE = { 32833 /** Uses XMLHttpRequest to load the resource. */ 32834 XHR: 1, 32835 /** Uses an `Image` object to load the resource. */ 32836 IMAGE: 2, 32837 /** Uses an `Audio` object to load the resource. */ 32838 AUDIO: 3, 32839 /** Uses a `Video` object to load the resource. */ 32840 VIDEO: 4 32841 }; 32842 32843 /** 32844 * The XHR ready states, used internally. 32845 * 32846 * @static 32847 * @readonly 32848 * @enum {string} 32849 */ 32850 Resource.XHR_RESPONSE_TYPE = { 32851 /** string */ 32852 DEFAULT: 'text', 32853 /** ArrayBuffer */ 32854 BUFFER: 'arraybuffer', 32855 /** Blob */ 32856 BLOB: 'blob', 32857 /** Document */ 32858 DOCUMENT: 'document', 32859 /** Object */ 32860 JSON: 'json', 32861 /** String */ 32862 TEXT: 'text' 32863 }; 32864 32865 Resource._loadTypeMap = { 32866 // images 32867 gif: Resource.LOAD_TYPE.IMAGE, 32868 png: Resource.LOAD_TYPE.IMAGE, 32869 bmp: Resource.LOAD_TYPE.IMAGE, 32870 jpg: Resource.LOAD_TYPE.IMAGE, 32871 jpeg: Resource.LOAD_TYPE.IMAGE, 32872 tif: Resource.LOAD_TYPE.IMAGE, 32873 tiff: Resource.LOAD_TYPE.IMAGE, 32874 webp: Resource.LOAD_TYPE.IMAGE, 32875 tga: Resource.LOAD_TYPE.IMAGE, 32876 svg: Resource.LOAD_TYPE.IMAGE, 32877 'svg+xml': Resource.LOAD_TYPE.IMAGE, // for SVG data urls 32878 32879 // audio 32880 mp3: Resource.LOAD_TYPE.AUDIO, 32881 ogg: Resource.LOAD_TYPE.AUDIO, 32882 wav: Resource.LOAD_TYPE.AUDIO, 32883 32884 // videos 32885 mp4: Resource.LOAD_TYPE.VIDEO, 32886 webm: Resource.LOAD_TYPE.VIDEO 32887 }; 32888 32889 Resource._xhrTypeMap = { 32890 // xml 32891 xhtml: Resource.XHR_RESPONSE_TYPE.DOCUMENT, 32892 html: Resource.XHR_RESPONSE_TYPE.DOCUMENT, 32893 htm: Resource.XHR_RESPONSE_TYPE.DOCUMENT, 32894 xml: Resource.XHR_RESPONSE_TYPE.DOCUMENT, 32895 tmx: Resource.XHR_RESPONSE_TYPE.DOCUMENT, 32896 svg: Resource.XHR_RESPONSE_TYPE.DOCUMENT, 32897 32898 // This was added to handle Tiled Tileset XML, but .tsx is also a TypeScript React Component. 32899 // Since it is way less likely for people to be loading TypeScript files instead of Tiled files, 32900 // this should probably be fine. 32901 tsx: Resource.XHR_RESPONSE_TYPE.DOCUMENT, 32902 32903 // images 32904 gif: Resource.XHR_RESPONSE_TYPE.BLOB, 32905 png: Resource.XHR_RESPONSE_TYPE.BLOB, 32906 bmp: Resource.XHR_RESPONSE_TYPE.BLOB, 32907 jpg: Resource.XHR_RESPONSE_TYPE.BLOB, 32908 jpeg: Resource.XHR_RESPONSE_TYPE.BLOB, 32909 tif: Resource.XHR_RESPONSE_TYPE.BLOB, 32910 tiff: Resource.XHR_RESPONSE_TYPE.BLOB, 32911 webp: Resource.XHR_RESPONSE_TYPE.BLOB, 32912 tga: Resource.XHR_RESPONSE_TYPE.BLOB, 32913 32914 // json 32915 json: Resource.XHR_RESPONSE_TYPE.JSON, 32916 32917 // text 32918 text: Resource.XHR_RESPONSE_TYPE.TEXT, 32919 txt: Resource.XHR_RESPONSE_TYPE.TEXT, 32920 32921 // fonts 32922 ttf: Resource.XHR_RESPONSE_TYPE.BUFFER, 32923 otf: Resource.XHR_RESPONSE_TYPE.BUFFER 32924 }; 32925 32926 // We can't set the `src` attribute to empty string, so on abort we set it to this 1px transparent gif 32927 Resource.EMPTY_GIF = 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='; 32928 32929 /** 32930 * Quick helper to set a value on one of the extension maps. Ensures there is no 32931 * dot at the start of the extension. 32932 * 32933 * @ignore 32934 * @param {object} map - The map to set on. 32935 * @param {string}
32935 extname - The extension (or key) to set. 32936 * @param {number} val - The value to set. 32937 */ 32938 function setExtMap(map, extname, val) { 32939 if (extname && extname.indexOf('.') === 0) { 32940 extname = extname.substring(1); 32941 } 32942 32943 if (!extname) { 32944 return; 32945 } 32946 32947 map[extname] = val; 32948 } 32949 32950 /** 32951 * Quick helper to get string xhr type. 32952 * 32953 * @ignore 32954 * @param {XMLHttpRequest|XDomainRequest} xhr - The request to check. 32955 * @return {string} The type. 32956 */ 32957 function reqType(xhr) { 32958 return xhr.toString().replace('object ', ''); 32959 } 32960 32961 // Backwards compat 32962 if ('object' !== 'undefined') { 32963 module.exports.default = Resource; // eslint-disable-line no-undef 32964 } 32965 32966 }); 32967 32968 var Resource$1 = unwrapExports(Resource_1); 32969 var Resource_2 = Resource_1.Resource; 32970 32971 var Loader_1 = createCommonjsModule(function (module, exports) { 32972 'use strict'; 32973 32974 exports.__esModule = true; 32975 exports.Loader = undefined; 32976 32977 var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; 32978 32979 var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) { descriptor.writable = true; } Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) { defineProperties(Constructor.prototype, protoProps); } if (staticProps) { defineProperties(Constructor, staticProps); } return Constructor; }; }(); 32980 32981 32982 32983 var _miniSignals2 = _interopRequireDefault(miniSignals); 32984 32985 32986 32987 var _parseUri2 = _interopRequireDefault(parseUri); 32988 32989 32990 32991 var async$1 = _interopRequireWildcard(async); 32992 32993 32994 32995 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } 32996 32997 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 32998 32999 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 33000 33001 // some constants 33002 var MAX_PROGRESS = 100; 33003 var rgxExtractUrlHash = /(#[\w-]+)?$/; 33004 33005 /** 33006 * Manages the state and loading of multiple resources to load. 33007 * 33008 * @class 33009 */ 33010 33011 var Loader = exports.Loader = function () { 33012 /** 33013 * @param {string} [baseUrl=''] - The base url for all resources loaded by this loader. 33014 * @param {number} [concurrency=10] - The number of resources to load concurrently. 33015 */ 33016 function Loader() { 33017 var _this = this; 33018 33019 var baseUrl = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; 33020 var concurrency = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 10; 33021 33022 _classCallCheck(this, Loader); 33023 33024 /** 33025 * The base url for all resources loaded by this loader. 33026 * 33027 * @member {string} 33028 */ 33029 this.baseUrl = baseUrl; 33030 33031 /** 33032 * The progress percent of the loader going through the queue. 33033 * 33034 * @member {number} 33035 */ 33036 this.progress = 0; 33037 33038 /** 33039 * Loading state of the loader, true if it is currently loading resources. 33040 * 33041 * @member {boolean} 33042 */ 33043 this.loading = false; 33044 33045 /** 33046 * A querystring to append to every URL added to the loader. 33047 * 33048 * This should be a valid query string *without* the question-mark (`?`). The loader will 33049 * also *not* escape values for you. Make sure to escape your parameters with 33050 * [`encodeURIComponent`](https://mdn.io/encodeURIComponent) before assigning this property. 33051 * 33052 * @example 33053 * const loader = new Loader(); 33054 * 33055 * loader.defaultQueryString = 'user=me&password=secret'; 33056 * 33057 * // This will request 'image.png?user=me&password=secret' 33058 * loader.add('image.png').load(); 33059 * 33060 * loader.reset(); 33061 * 33062 * // This will request 'image.png?v=1&user=me&password=secret' 33063 * loader.add('iamge.png?v=1').load(); 33064 * 33065 * @member {string} 33066 */ 33067 this.defaultQueryString = ''; 33068 33069 /** 33070 * The middleware to run before loading each resource. 33071 * 33072 * @private 33073 * @member {function[]} 33074 */ 33075 this._beforeMiddleware = []; 33076 33077 /** 33078 * The middleware to run after loading each resource. 33079 * 33080 * @private 33081 * @member {function[]} 33082 */ 33083 this._afterMiddleware = []; 33084 33085 /** 33086 * The tracks the resources we are currently completing parsing for. 33087 * 33088 * @private 33089 * @member {Resource[]} 33090 */ 33091 this._resourcesParsing = []; 33092 33093 /** 33094 * The `_loadResource` function bound with this object c
33094ontext. 33095 * 33096 * @private 33097 * @member {function} 33098 * @param {Resource} r - The resource to load 33099 * @param {Function} d - The dequeue function 33100 * @return {undefined} 33101 */ 33102 this._boundLoadResource = function (r, d) { 33103 return _this._loadResource(r, d); 33104 }; 33105 33106 /** 33107 * The resources waiting to be loaded. 33108 * 33109 * @private 33110 * @member {Resource[]} 33111 */ 33112 this._queue = async$1.queue(this._boundLoadResource, concurrency); 33113 33114 this._queue.pause(); 33115 33116 /** 33117 * All the resources for this loader keyed by name. 33118 * 33119 * @member {object<string, Resource>} 33120 */ 33121 this.resources = {}; 33122 33123 /** 33124 * Dispatched once per loaded or errored resource. 33125 * 33126 * The callback looks like {@link Loader.OnProgressSignal}. 33127 * 33128 * @member {Signal} 33129 */ 33130 this.onProgress = new _miniSignals2.default(); 33131 33132 /** 33133 * Dispatched once per errored resource. 33134 * 33135 * The callback looks like {@link Loader.OnErrorSignal}. 33136 * 33137 * @member {Signal} 33138 */ 33139 this.onError = new _miniSignals2.default(); 33140 33141 /** 33142 * Dispatched once per loaded resource. 33143 * 33144 * The callback looks like {@link Loader.OnLoadSignal}. 33145 * 33146 * @member {Signal} 33147 */ 33148 this.onLoad = new _miniSignals2.default(); 33149 33150 /** 33151 * Dispatched when the loader begins to process the queue. 33152 * 33153 * The callback looks like {@link Loader.OnStartSignal}. 33154 * 33155 * @member {Signal} 33156 */ 33157 this.onStart = new _miniSignals2.default(); 33158 33159 /** 33160 * Dispatched when the queued resources all load. 33161 * 33162 * The callback looks like {@link Loader.OnCompleteSignal}. 33163 * 33164 * @member {Signal} 33165 */ 33166 this.onComplete = new _miniSignals2.default(); 33167 33168 // Add default before middleware 33169 for (var i = 0; i < Loader._defaultBeforeMiddleware.length; ++i) { 33170 this.pre(Loader._defaultBeforeMiddleware[i]); 33171 } 33172 33173 // Add default after middleware 33174 for (var _i = 0; _i < Loader._defaultAfterMiddleware.length; ++_i) { 33175 this.use(Loader._defaultAfterMiddleware[_i]); 33176 } 33177 } 33178 33179 /** 33180 * When the progress changes the loader and resource are disaptched. 33181 * 33182 * @memberof Loader 33183 * @callback OnProgressSignal 33184 * @param {Loader} loader - The loader the progress is advancing on. 33185 * @param {Resource} resource - The resource that has completed or failed to cause the progress to advance. 33186 */ 33187 33188 /** 33189 * When an error occurrs the loader and resource are disaptched. 33190 * 33191 * @memberof Loader 33192 * @callback OnErrorSignal 33193 * @param {Loader} loader - The loader the error happened in. 33194 * @param {Resource} resource - The resource that caused the error. 33195 */ 33196 33197 /** 33198 * When a load completes the loader and resource are disaptched. 33199 * 33200 * @memberof Loader 33201 * @callback OnLoadSignal 33202 * @param {Loader} loader - The loader that laoded the resource. 33203 * @param {Resource} resource - The resource that has completed loading. 33204 */ 33205 33206 /** 33207 * When the loader starts loading resources it dispatches this callback. 33208 * 33209 * @memberof Loader 33210 * @callback OnStartSignal 33211 * @param {Loader} loader - The loader that has started loading resources. 33212 */ 33213 33214 /** 33215 * When the loader completes loading resources it dispatches this callback. 33216 * 33217 * @memberof Loader 33218 * @callback OnCompleteSignal 33219 * @param {Loader} loader - The loader that has finished loading resources. 33220 */ 33221 33222 /** 33223 * Options for a call to `.add()`. 33224 * 33225 * @see Loader#add 33226 * 33227 * @typedef {object} IAddOptions 33228 * @property {string} [name] - The name of the resource to load, if not passed the url is used. 33229 * @property {string} [key] - Alias for `name`. 33230 * @property {string} [url] - The url for this resource, relative to the baseUrl of this loader. 33231 * @property {string|boolean} [crossOrigin] - Is this request cross-origin? Default is to 33232 * determine automatically. 33233 * @property {number} [timeout=0] - A timeout in milliseconds for the load. If the load takes 33234 * longer than this time it is cancelled and the load is considered a failure. If this value is 33235 * set to `0` then there is no explicit timeout. 33236 * @property {Resource.LOAD_TYPE} [loadType=Resource.LOAD_TYPE.XHR] - How should this resource 33237 * be loaded? 33238 * @property {Resource.XHR_RESPONSE_TYPE} [xhrType=Resource.XHR_RESPONSE_TYPE.DEFAULT] - How 33239 * should the data being loaded be interpreted when using XHR? 33240 * @property {Loader.OnCompleteSignal} [onComplete] - Callback to add an an onComplete signal istener. 33241 * @property {Loader.OnCompleteSignal} [callback] - Alias for `onComplete`. 33242 * @property {Resource.IMetadata} [metadata] - Extra configuration for middleware and the Resource object. 33243 */ 33244 33245 /** 33246 * Adds a resource (or multiple resources) to the loader queue. 33247 * 33248 * This function can take a wide variety of different parameters. The only thing that is always 33249 * required the url to load. All the following will work: 33250 * 33251 * ```js 33252 * loader 33253 * // normal param syntax 33254 * .add('key', 'http://...', function () {}) 33255 * .add('http://...', function () {}) 33256 * .add('http://...') 33257 * 33258 * // object syntax 33259 * .add({ 33260 * name: 'key2', 33261 * url: 'http://...' 33262 * }, function () {}) 33263 * .add({ 33264 * url: 'http://...' 33265 * }, function () {}) 33266 * .add({ 33267 * name: 'key3', 33268 * url: 'http://...' 33269 * onComplete: function () {} 33270 * }) 33271 * .add({ 33272 * url: 'https://...', 33273 * onComplete: function () {}, 33274 * crossOrigin: true 33275 * }) 33276 * 33277 * // you can also pass an array of objects or urls or both 33278 * .add([ 33279 * { name: 'key4', url: 'http://...', onComplete: function () {} }, 33280 * { url: 'http://...', onComplete: function () {} }, 33281 * 'http://...' 33282 * ]) 33283 * 33284 * // and you can use both params and options 33285 * .add('key', 'http://...', { crossOrigin: true }, function () {}) 33286 * .add('http://...', { crossOrigin: true }, function () {}); 33287 * ``` 33288 * 33289 * @param {string|IAddOptions} [name] - The name of the resource to load, if not passed the url is used. 33290 * @param {string} [url] - The url for this resource, relative to the baseUrl of this loader. 33291 * @param {IAddOptions} [options] - The options for the load. 33292 * @param {Loader.OnCompleteSignal}
33292 [cb] - Function to call when this specific resource completes loading. 33293 * @return {this} Returns itself. 33294 */ 33295 33296 33297 Loader.prototype.add = function add(name, url, options, cb) { 33298 // special case of an array of objects or urls 33299 if (Array.isArray(name)) { 33300 for (var i = 0; i < name.length; ++i) { 33301 this.add(name[i]); 33302 } 33303 33304 return this; 33305 } 33306 33307 // if an object is passed instead of params 33308 if ((typeof name === 'undefined' ? 'undefined' : _typeof(name)) === 'object') { 33309 cb = url || name.callback || name.onComplete; 33310 options = name; 33311 url = name.url; 33312 name = name.name || name.key || name.url; 33313 } 33314 33315 // case where no name is passed shift all args over by one. 33316 if (typeof url !== 'string') { 33317 cb = options; 33318 options = url; 33319 url = name; 33320 } 33321 33322 // now that we shifted make sure we have a proper url. 33323 if (typeof url !== 'string') { 33324 throw new Error('No url passed to add resource to loader.'); 33325 } 33326 33327 // options are optional so people might pass a function and no options 33328 if (typeof options === 'function') { 33329 cb = options; 33330 options = null; 33331 } 33332 33333 // if loading already you can only add resources that have a parent. 33334 if (this.loading && (!options || !options.parentResource)) { 33335 throw new Error('Cannot add resources while the loader is running.'); 33336 } 33337 33338 // check if resource already exists. 33339 if (this.resources[name]) { 33340 throw new Error('Resource named "' + name + '" already exists.'); 33341 } 33342 33343 // add base url if this isn't an absolute url 33344 url = this._prepareUrl(url); 33345 33346 // create the store the resource 33347 this.resources[name] = new Resource_1.Resource(name, url, options); 33348 33349 if (typeof cb === 'function') { 33350 this.resources[name].onAfterMiddleware.once(cb); 33351 } 33352 33353 // if actively loading, make sure to adjust progress chunks for that parent and its children 33354 if (this.loading) { 33355 var parent = options.parentResource; 33356 var incompleteChildren = []; 33357 33358 for (var _i2 = 0; _i2 < parent.children.length; ++_i2) { 33359 if (!parent.children[_i2].isComplete) { 33360 incompleteChildren.push(parent.children[_i2]); 33361 } 33362 } 33363 33364 var fullChunk = parent.progressChunk * (incompleteChildren.length + 1); // +1 for parent 33365 var eachChunk = fullChunk / (incompleteChildren.length + 2); // +2 for parent & new child 33366 33367 parent.children.push(this.resources[name]); 33368 parent.progressChunk = eachChunk; 33369 33370 for (var _i3 = 0; _i3 < incompleteChildren.length; ++_i3) { 33371 incompleteChildren[_i3].progressChunk = eachChunk; 33372 } 33373 33374 this.resources[name].progressChunk = eachChunk; 33375 } 33376 33377 // add the resource to the queue 33378 this._queue.push(this.resources[name]); 33379 33380 return this; 33381 }; 33382 33383 /** 33384 * Sets up a middleware function that will run *before* the 33385 * resource is loaded. 33386 * 33387 * @param {function} fn - The middleware function to register. 33388 * @return {this} Returns itself. 33389 */ 33390 33391 33392 Loader.prototype.pre = function pre(fn) { 33393 this._beforeMiddleware.push(fn); 33394 33395 return this; 33396 }; 33397 33398 /** 33399 * Sets up a middleware function that will run *after* the 33400 * resource is loaded. 33401 * 33402 * @param {function} fn - The middleware function to register. 33403 * @return {this} Returns itself. 33404 */ 33405 33406 33407 Loader.prototype.use = function use(fn) { 33408 this._afterMiddleware.push(fn); 33409 33410 return this; 33411 }; 33412 33413 /** 33414 * Resets the queue of the loader to prepare for a new load. 33415 * 33416 * @return {this} Returns itself. 33417 */ 33418 33419 33420 Loader.prototype.reset = function reset() { 33421 this.progress = 0; 33422 this.loading = false;
33423 33424 this._queue.kill(); 33425 this._queue.pause(); 33426 33427 // abort all resource loads 33428 for (var k in this.resources) { 33429 var res = this.resources[k]; 33430 33431 if (res._onLoadBinding) { 33432 res._onLoadBinding.detach(); 33433 } 33434 33435 if (res.isLoading) { 33436 res.abort(); 33437 } 33438 } 33439 33440 this.resources = {}; 33441 33442 return this; 33443 }; 33444 33445 /** 33446 * Starts loading the queued resources. 33447 * 33448 * @param {function} [cb] - Optional callback that will be bound to the `complete` event. 33449 * @return {this} Returns itself. 33450 */ 33451 33452 33453 Loader.prototype.load = function load(cb) { 33454 // register complete callback if they pass one 33455 if (typeof cb === 'function') { 33456 this.onComplete.once(cb); 33457 } 33458 33459 // if the queue has already started we are done here 33460 if (this.loading) { 33461 return this; 33462 } 33463 33464 if (this._queue.idle()) { 33465 this._onStart(); 33466 this._onComplete(); 33467 } else { 33468 // distribute progress chunks 33469 var numTasks = this._queue._tasks.length; 33470 var chunk = MAX_PROGRESS / numTasks; 33471 33472 for (var i = 0; i < this._queue._tasks.length; ++i) { 33473 this._queue._tasks[i].data.progressChunk = chunk; 33474 } 33475 33476 // notify we are starting 33477 this._onStart(); 33478 33479 // start loading 33480 this._queue.resume(); 33481 } 33482 33483 return this; 33484 }; 33485 33486 /** 33487 * The number of resources to load concurrently. 33488 * 33489 * @member {number} 33490 * @default 10 33491 */ 33492 33493 33494 /** 33495 * Prepares a url for usage based on the configuration of this object 33496 * 33497 * @private 33498 * @param {string} url - The url to prepare. 33499 * @return {string} The prepared url. 33500 */ 33501 Loader.prototype._prepareUrl = function _prepareUrl(url) { 33502 var parsedUrl = (0, _parseUri2.default)(url, { strictMode: true }); 33503 var result = void 0; 33504 33505 // absolute url, just use it as is. 33506 if (parsedUrl.protocol || !parsedUrl.path || url.indexOf('//') === 0) { 33507 result = url; 33508 } 33509 // if baseUrl doesn't end in slash and url doesn't start with slash, then add a slash inbetween 33510 else if (this.baseUrl.length && this.baseUrl.lastIndexOf('/') !== this.baseUrl.length - 1 && url.charAt(0) !== '/') { 33511 result = this.baseUrl + '/' + url; 33512 } else { 33513 result = this.baseUrl + url; 33514 } 33515 33516 // if we need to add a default querystring, there is a bit more work 33517 if (this.defaultQueryString) { 33518 var hash = rgxExtractUrlHash.exec(result)[0]; 33519 33520 result = result.substr(0, result.length - hash.length); 33521 33522 if (result.indexOf('?') !== -1) { 33523 result += '&' + this.defaultQueryString; 33524 } else { 33525 result += '?' + this.defaultQueryString; 33526 } 33527 33528 result += hash; 33529 } 33530 33531 return result; 33532 }; 33533 33534 /** 33535 * Loads a single resource. 33536 * 33537 * @private 33538 * @param {Resource} resource - The resource to load. 33539 * @param {function} dequeue - The function to call when we need to dequeue this item. 33540 */ 33541 33542 33543 Loader.prototype._loadResource = function _loadResource(resource, dequeue) { 33544 var _this2 = this; 33545 33546 resource._dequeue = dequeue; 33547 33548 // run before middleware 33549 async$1.eachSeries(this._beforeMiddleware, function (fn, next) { 33550 fn.call(_this2, resource, function () { 33551 // if the before middleware marks the resource as complete, 33552 // break and don't process any more before middleware 33553 next(resource.isComplete ? {} : null); 33554 }); 33555 }, function () { 33556 if (resource.isComplete) { 33557 _this2._onLoad(resource); 33558 } else { 33559 resource._onLoadBinding = resource.onComplete.once(_this2._onLoad, _this2); 33560 resource.load(); 33561 } 33562 }, true); 33563 }; 33564 33565 /** 33566 * Called once loading has started. 33567 * 33568 * @private 33569 */ 33570 33571 33572 Loader.prototype._onStart = function _onStart() { 33573 this.progress = 0; 33574 this.loading = true; 33575 this.onStart.dispatch(this); 33576 }; 33577 33578 /** 33579 * Called once each resource has loaded. 33580 * 33581 * @private 33582 */ 33583 33584 33585 Loader.prototype._onComplete = function _onComplete() { 33586 this.progress = MAX_PROGRESS; 33587 this.loading = false;
33588 this.onComplete.dispatch(this, this.resources); 33589 }; 33590 33591 /** 33592 * Called each time a resources is loaded. 33593 * 33594 * @private 33595 * @param {Resource} resource - The resource that was loaded 33596 */ 33597 33598 33599 Loader.prototype._onLoad = function _onLoad(resource) { 33600 var _this3 = this; 33601 33602 resource._onLoadBinding = null; 33603 33604 // remove this resource from the async queue, and add it to our list of resources that are being parsed 33605 this._resourcesParsing.push(resource); 33606 resource._dequeue(); 33607 33608 // run all the after middleware for this resource 33609 async$1.eachSeries(this._afterMiddleware, function (fn, next) { 33610 fn.call(_this3, resource, next); 33611 }, function () { 33612 resource.onAfterMiddleware.dispatch(resource); 33613 33614 _this3.progress = Math.min(MAX_PROGRESS, _this3.progress + resource.progressChunk); 33615 _this3.onProgress.dispatch(_this3, resource); 33616 33617 if (resource.error) { 33618 _this3.onError.dispatch(resource.error, _this3, resource); 33619 } else { 33620 _this3.onLoad.dispatch(_this3, resource); 33621 } 33622 33623 _this3._resourcesParsing.splice(_this3._resourcesParsing.indexOf(resource), 1); 33624 33625 // do completion check 33626 if (_this3._queue.idle() && _this3._resourcesParsing.length === 0) { 33627 _this3._onComplete(); 33628 } 33629 }, true); 33630 }; 33631 33632 _createClass(Loader, [{ 33633 key: 'concurrency', 33634 get: function get() { 33635 return this._queue.concurrency; 33636 } 33637 // eslint-disable-next-line require-jsdoc 33638 , 33639 set: function set(concurrency) { 33640 this._queue.concurrency = concurrency; 33641 } 33642 }]); 33643 33644 return Loader; 33645 }(); 33646 33647 /** 33648 * A default array of middleware to run before loading each resource. 33649 * Each of these middlewares are added to any new Loader instances when they are created. 33650 * 33651 * @private 33652 * @member {function[]} 33653 */ 33654 33655 33656 Loader._defaultBeforeMiddleware = []; 33657 33658 /** 33659 * A default array of middleware to run after loading each resource. 33660 * Each of these middlewares are added to any new Loader instances when they are created. 33661 * 33662 * @private 33663 * @member {function[]} 33664 */ 33665 Loader._defaultAfterMiddleware = []; 33666 33667 /** 33668 * Sets up a middleware function that will run *before* the 33669 * resource is loaded. 33670 * 33671 * @static 33672 * @param {function} fn - The middleware function to register. 33673 * @return {Loader} Returns itself. 33674 */ 33675 Loader.pre = function LoaderPreStatic(fn) { 33676 Loader._defaultBeforeMiddleware.push(fn); 33677 33678 return Loader; 33679 }; 33680 33681 /** 33682 * Sets up a middleware function that will run *after* the 33683 * resource is loaded. 33684 * 33685 * @static 33686 * @param {function} fn - The middleware function to register. 33687 * @return {Loader} Returns itself. 33688 */ 33689 Loader.use = function LoaderUseStatic(fn) { 33690 Loader._defaultAfterMiddleware.push(fn); 33691 33692 return Loader; 33693 }; 33694 33695 }); 33696 33697 var Loader = unwrapExports(Loader_1); 33698 var Loader_2 = Loader_1.Loader; 33699 33700 var b64 = createCommonjsModule(function (module, exports) { 33701 'use strict'; 33702 33703 exports.__esModule = true; 33704 exports.encodeBinary = encodeBinary; 33705 var _keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; 33706 33707 /** 33708 * Encodes binary into base64. 33709 * 33710 * @param {string} input The input data to encode. 33711 * @returns {string} The encoded base64 string 33712 */ 33713 function encodeBinary(input) { 33714 var output = ''; 33715 var inx = 0; 33716 33717 while (inx < input.length) { 33718 // Fill byte buffer array 33719 var bytebuffer = [0, 0, 0]; 33720 var encodedCharIndexes = [0, 0, 0, 0]; 33721 33722 for (var jnx = 0; jnx < bytebuffer.length; ++jnx) { 33723 if (inx < input.length) { 33724 // throw away high-order byte, as documented at: 33725 // https://developer.mozilla.org/En/Using_XMLHttpRequest#Handling_binary_data 33726 bytebuffer[jnx] = input.charCodeAt(inx++) & 0xff; 33727 } else { 33728 bytebuffer[jnx] = 0; 33729 } 33730 } 33731 33732 // Get each encoded character, 6 bits at a time 33733 // index 1: first 6 bits 33734 encodedCharIndexes[0] = bytebuffer[0] >> 2; 33735 33736 // index 2: second 6 bits (2 least significant bits from input byte 1 + 4 most significant bits from byte 2) 33737 encodedCharIndexes[1] = (bytebuffer[0] & 0x3) << 4 | bytebuffer[1] >> 4; 33738 33739 // index 3: third 6 bits (4 least significant bits from input byte 2 + 2 most significant bits from byte 3) 33740 encodedCharIndexes[2] = (bytebuffer[1] & 0x0f) << 2 | bytebuffer[2] >> 6; 33741 33742 // index 3: forth 6 bits (6 least significant bits from input byte 3) 33743 encodedCharIndexes[3] = bytebuffer[2] & 0x3f; 33744 33745 // Determine whether padding happened, and adjust accordingly 33746 var paddingBytes = inx - (input.length - 1); 33747 33748 switch (paddingBytes) { 33749 case 2: 33750 // Set last 2 characters to padding char 33751 encodedCharIndexes[3] = 64; 33752 encodedCharIndexes[2] = 64; 33753 break; 33754 33755 case 1: 33756 // Set last character to padding char 33757 encodedCharIndexes[3] = 64; 33758 break; 33759 33760 default: 33761 break; // No padding - proceed 33762 } 33763 33764 // Now we will grab each appropriate character out of our keystring 33765 // based on our index array and append it to the output string 33766 for (var _jnx = 0; _jnx < encodedCharIndexes.length; ++_jnx) { 33767 output += _keyStr.charAt(encodedCharIndexes[_jnx]); 33768 } 33769 } 33770 33771 return output; 33772 } 33773 33774 // Backwards compat 33775 if ('object' !== 'undefined') { 33776 module.exports.default = encodeBinary; // eslint-disable-line no-undef 33777 } 33778 33779 }); 33780 33781 var b64$1 = unwrapExports(b64); 33782 var b64_1 = b64.encodeBinary; 33783 33784 'use strict'; 33785 33786 // import Loader from './Loader'; 33787 // import Resource from './Resource'; 33788 // import * as async from './async'; 33789 // import * as b64 from './b64'; 33790 33791 /* eslint-disable no-undef */ 33792 33793 var Loader$1 = Loader_1.Loader; 33794 var Resource$2 = Resource_1.Resource; 33795 33796 33797 33798 /** 33799 * 33800 * @static 33801 * @memberof Loader 33802 * @member {Class<Resource>} 33803 */
33804 Loader$1.Resource = Resource$2; 33805 33806 /** 33807 * 33808 * @static 33809 * @memberof Loader 33810 * @member {Class<async>} 33811 */ 33812 Loader$1.async = async; 33813 33814 /** 33815 * 33816 * @static 33817 * @memberof Loader 33818 * @member {Class<encodeBinary>} 33819 */ 33820 Loader$1.encodeBinary = b64; 33821 33822 /** 33823 * 33824 * @deprecated 33825 * @see Loader.encodeBinary 33826 * 33827 * @static 33828 * @memberof Loader 33829 * @member {Class<encodeBinary>} 33830 */ 33831 Loader$1.base64 = b64; 33832 33833 // export manually, and also as default 33834 var lib = Loader$1; 33835 33836 // default & named export 33837 var Loader_1$1 = Loader$1; 33838 var default_1$1 = Loader$1; 33839 var lib_1 = lib.Resource; 33840 lib.Loader = Loader_1$1; 33841 lib.default = default_1$1; 33842 33843 /*! 33844 * @pixi/loaders - v5.0.0-rc.3 33845 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 33846 * 33847 * @pixi/loaders is licensed under the MIT License. 33848 * http://www.opensource.org/licenses/mit-license 33849 */ 33850 33851 function unwrapExports$1 (x) { 33852 return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x.default : x; 33853 } 33854 33855 function createCommonjsModule$1(fn, module) { 33856 return module = { exports: {} }, fn(module, module.exports), module.exports; 33857 } 33858 33859 var parseUri$1 = function parseURI (str, opts) { 33860 opts = opts || {}; 33861 33862 var o = { 33863 key: ['source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'], 33864 q: { 33865 name: 'queryKey', 33866 parser: /(?:^|&)([^&=]*)=?([^&]*)/g 33867 }, 33868 parser: { 33869 strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, 33870 loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ 33871 } 33872 }; 33873 33874 var m = o.parser[opts.strictMode ? 'strict' : 'loose'].exec(str); 33875 var uri = {}; 33876 var i = 14; 33877 33878 while (i--) { uri[o.key[i]] = m[i] || ''; } 33879 33880 uri[o.q.name] = {}; 33881 uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) { 33882 if ($1) { uri[o.q.name][$1] = $2; } 33883 }); 33884 33885 return uri 33886 }; 33887 33888 var miniSignals$2 = createCommonjsModule$1(function (module, exports) { 33889 33890 Object.defineProperty(exports, '__esModule', { 33891 value: true 33892 }); 33893 33894 var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) { descriptor.writable = true; } Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) { defineProperties(Constructor.prototype, protoProps); } if (staticProps) { defineProperties(Constructor, staticProps); } return Constructor; }; })(); 33895 33896 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 33897 33898 var MiniSignalBinding = (function () { 33899 function MiniSignalBinding(fn, once, thisArg) { 33900 if (once === undefined) { once = false; } 33901 33902 _classCallCheck(this, MiniSignalBinding); 33903 33904 this._fn = fn; 33905 this._once = once; 33906 this._thisArg = thisArg; 33907 this._next = this._prev = this._owner = null; 33908 } 33909 33910 _createClass(MiniSignalBinding, [{ 33911 key: 'detach', 33912 value: function detach() { 33913 if (this._owner === null) { return false; } 33914 this._owner.detach(this); 33915 return true; 33916 } 33917 }]); 33918 33919 return MiniSignalBinding; 33920 })(); 33921 33922 function _addMiniSignalBinding(self, node) { 33923 if (!self._head) { 33924 self._head = node; 33925 self._tail = node; 33926 } else { 33927 self._tail._next = node; 33928 node._prev = self._tail; 33929 self._tail = node; 33930 } 33931 33932 node._owner = self; 33933 33934 return node; 33935 } 33936 33937 var MiniSignal = (function () { 33938 function MiniSignal() { 33939 _classCallCheck(this, MiniSignal); 33940 33941 this._head = this._tail = undefined; 33942 } 33943 33944 _createClass(MiniSignal, [{ 33945 key: 'handlers', 33946 value: function handlers() { 33947 var exists = arguments.length <= 0 || arguments[0] === undefined ? false : arguments[0]; 33948 33949 var node = this._head; 33950 33951 if (exists) { return !!node; } 33952 33953 var ee = []; 33954 33955 while (node) { 33956 ee.push(node); 33957 node = node._next; 33958 } 33959 33960 return ee; 33961 } 33962 }, { 33963 key: 'has', 33964 value: function has(node) { 33965 if (!(node instanceof MiniSignalBinding)) { 33966 throw new Error('MiniSignal#has(): First arg must be a MiniSignalBinding object.'); 33967 } 33968 33969 return node._owner === this; 33970 } 33971 }, { 33972 key: 'dispatch', 33973 value: function dispatch() { 33974 var arguments$1 = arguments; 33975 33976 var node = this._head; 33977 33978 if (!node) { return false; } 33979 33980 while (node) { 33981 if (node._once) { this.detach(node); } 33982 node._fn.apply(node._thisArg, arguments$1); 33983 node = node._next; 33984 } 33985 33986 return true; 33987 } 33988 }, { 33989 key: 'add', 33990 value: function add(fn) { 33991 var thisArg = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1]; 33992 33993 if (typeof fn !== 'function') { 33994 throw new Error('MiniSignal#add(): First arg must be a Function.'); 33995 } 33996 return _addMiniSignalBinding(this, new MiniSignalBinding(fn, false, thisArg)); 33997 } 33998 }, { 33999 key: 'once', 34000 value: function once(fn) { 34001 var thisArg = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1]; 34002 34003 if (typeof fn !== 'function') { 34004 throw new Error('MiniSignal#once(): First arg must be a Function.'); 34005 } 34006 return _addMiniSignalBinding(this, new MiniSignalBinding(fn, true, thisArg)); 34007 } 34008 }, { 34009 key: 'detach', 34010 value: function detach(node) { 34011 if (!(node instanceof MiniSignalBinding)) { 34012 throw new Error('MiniSignal#detach(): First arg must be a MiniSignalBinding object.'); 34013 } 34014 if (node._owner !== this) { return this; } 34015 34016 if (node._prev) { node._prev._next = node._next; } 34017 if (node._next) { node._next._prev = node._prev; } 34018 34019 if (node === this._head) { 34020 this._head = node._next; 34021 if (node._next === null) { 34022 this._tail = null; 34023 } 34024 } else if (node === this._tail) { 34025 this._tail = node._prev; 34026 this._tail._next = null; 34027 } 34028 34029 node._owner = null; 34030 return this; 34031 } 34032 }, { 34033 key: 'detachAll', 34034 value: function detachAll() { 34035 var node = this._head; 34036 if (!node) { return this; } 34037 34038 this._head = this._tail = null; 34039 34040 while (node) { 34041 node._owner = null; 34042 node = node._next; 34043 } 34044 return this; 34045 } 34046 }]); 34047 34048 return MiniSignal; 34049 })(); 34050 34051 MiniSignal.MiniSignalBinding = MiniSignalBinding; 34052 34053 exports['default'] = MiniSignal; 34054 module.exports = exports['default']; 34055 }); 34056 34057 unwrapExports$1(miniSignals$2); 34058 34059 var Resource_1$1 = createCommonjsModule$1(function (module, exports
34059) { 34060 34061 exports.__esModule = true; 34062 exports.Resource = undefined; 34063 34064 var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) { descriptor.writable = true; } Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) { defineProperties(Constructor.prototype, protoProps); } if (staticProps) { defineProperties(Constructor, staticProps); } return Constructor; }; }(); 34065 34066 34067 34068 var _parseUri2 = _interopRequireDefault(parseUri$1); 34069 34070 34071 34072 var _miniSignals2 = _interopRequireDefault(miniSignals$2); 34073 34074 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 34075 34076 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 34077 34078 // tests if CORS is supported in XHR, if not we need to use XDR 34079 var useXdr = !!(window.XDomainRequest && !('withCredentials' in new XMLHttpRequest())); 34080 var tempAnchor = null; 34081 34082 // some status constants 34083 var STATUS_NONE = 0; 34084 var STATUS_OK = 200; 34085 var STATUS_EMPTY = 204; 34086 var STATUS_IE_BUG_EMPTY = 1223; 34087 var STATUS_TYPE_OK = 2; 34088 34089 // noop 34090 function _noop() {} /* empty */ 34091 34092 /** 34093 * Manages the state and loading of a resource and all child resources. 34094 * 34095 * @class 34096 */ 34097 34098 var Resource = exports.Resource = function () { 34099 /** 34100 * Sets the load type to be used for a specific extension. 34101 * 34102 * @static 34103 * @param {string} extname - The extension to set the type for, e.g. "png" or "fnt" 34104 * @param {Resource.LOAD_TYPE} loadType - The load type to set it to. 34105 */ 34106 Resource.setExtensionLoadType = function setExtensionLoadType(extname, loadType) { 34107 setExtMap(Resource._loadTypeMap, extname, loadType); 34108 }; 34109 34110 /** 34111 * Sets the load type to be used for a specific extension. 34112 * 34113 * @static 34114 * @param {string} extname - The extension to set the type for, e.g. "png" or "fnt" 34115 * @param {Resource.XHR_RESPONSE_TYPE} xhrType - The xhr type to set it to. 34116 */ 34117 34118 34119 Resource.setExtensionXhrType = function setExtensionXhrType(extname, xhrType) { 34120 setExtMap(Resource._xhrTypeMap, extname, xhrType); 34121 }; 34122 34123 /** 34124 * @param {string} name - The name of the resource to load. 34125 * @param {string|string[]} url - The url for this resource, for audio/video loads you can pass 34126 * an array of sources. 34127 * @param {object} [options] - The options for the load. 34128 * @param {string|boolean} [options.crossOrigin] - Is this request cross-origin? Default is to 34129 * determine automatically. 34130 * @param {number} [options.timeout=0] - A timeout in milliseconds for the load. If the load takes 34131 * longer than this time it is cancelled and the load is considered a failure. If this value is 34132 * set to `0` then there is no explicit timeout. 34133 * @param {Resource.LOAD_TYPE} [options.loadType=Resource.LOAD_TYPE.XHR] - How should this resource 34134 * be loaded? 34135 * @param {Resource.XHR_RESPONSE_TYPE} [options.xhrType=Resource.XHR_RESPONSE_TYPE.DEFAULT] - How 34136 * should the data being loaded be interpreted when using XHR? 34137 * @param {Resource.IMetadata} [options.metadata] - Extra configuration for middleware and the Resource object. 34138 */ 34139 34140 34141 function Resource(name, url, options) { 34142 _classCallCheck(this, Resource); 34143 34144 if (typeof name !== 'string' || typeof url !== 'string') { 34145 throw new Error('Both name and url are required for constructing a resource.'); 34146 } 34147 34148 options = options || {}; 34149 34150 /** 34151 * The state flags of this resource. 34152 * 34153 * @private 34154 * @member {number} 34155 */ 34156 this._flags = 0; 34157 34158 // set data url flag, needs to be set early for some _determineX checks to work. 34159 this._setFlag(Resource.STATUS_FLAGS.DATA_URL, url.indexOf('data:') === 0); 34160 34161 /** 34162 * The name of this resource. 34163 * 34164 * @readonly 34165 * @member {string} 34166 */ 34167 this.name = name; 34168 34169 /** 34170 * The url used to load this resource. 34171 * 34172 * @readonly 34173 * @member {string} 34174 */ 34175 this.url = url; 34176 34177 /** 34178 * The extension used to load this resource. 34179 * 34180 * @readonly 34181 * @member {string} 34182 */ 34183 this.extension = this._getExtension(); 34184 34185 /** 34186 * The data that was loaded by the resource. 34187 * 34188 * @member {any} 34189 */ 34190 this.data = null; 34191 34192 /** 34193 * Is this request cross-origin? If unset, determined automatically. 34194 * 34195 * @member {string} 34196 */ 34197 this.crossOrigin = options.crossOrigin === true ? 'anonymous' : options.crossOrigin; 34198 34199 /** 34200 * A timeout in milliseconds for the load. If the load takes longer than this time 34201 * it is cancelled and the load is considered a failure. If this value is set to `0` 34202 * then there is no explicit timeout. 34203 * 34204 * @member {number} 34205 */ 34206 this.timeout = options.timeout || 0; 34207 34208 /** 34209 * The method of loading to use for this resource. 34210 * 34211 * @member {Resource.LOAD_TYPE} 34212 */ 34213 this.loadType = options.loadType || this._determineLoadType(); 34214 34215 /** 34216 * The type used to load the resource via XHR. If unset, determined automatically. 34217 * 34218 * @member {string} 34219 */ 34220 this.xhrType = options.xhrType; 34221 34222 /** 34223 * Extra info for middleware, and controlling specifics about how the resource loads. 34224 * 34225 * Note that if you pass in a `loadElement`, the Resource class takes ownership of it. 34226 * Meaning it will modify it as it sees fit. 34227 * 34228 * @member {Resource.IMetadata} 34229 */ 34230 this.metadata = options.metadata || {}; 34231 34232 /** 34233 * The error that occurred while loading (if any). 34234 * 34235 * @readonly 34236 * @member {Error} 34237 */ 34238 this.error = null; 34239 34240 /** 34241 * The XHR object that was used to load this resource. This is only set 34242 * when `loadType` is `Resource.LOAD_TYPE.XHR`. 34243 * 34244 * @readonly 34245 * @member {XMLHttpRequest} 34246 */ 34247 this.xhr = null; 34248 34249 /** 34250 * The child resources this resource owns. 34251 * 34252 * @readonly 34253 * @member {Resource[]} 34254 */ 34255 this.children = []; 34256 34257 /** 34258 * The resource type. 34259 * 34260 * @readonly 34261 * @member {Resource.TYPE} 34262 */ 34263 this.type = Resource.TYPE.UNKNOWN; 34264 34265 /** 34266 * The progress chunk owned by this resource. 34267 * 34268 * @readonly 34269 * @member {number} 34270 */ 34271 this.progressChunk = 0; 34272 34273 /** 34274 * The `dequeue` method that will be used a storage place for the async queue dequeue method 34275 * used privately by the loader. 34276 * 34277 * @private 34278 * @member {function} 34279 */ 34280 this._dequeue = _noop; 34281 34282 /**
34283 * Used a storage place for the on load binding used privately by the loader. 34284 * 34285 * @private 34286 * @member {function} 34287 */ 34288 this._onLoadBinding = null; 34289 34290 /** 34291 * The timer for element loads to check if they timeout. 34292 * 34293 * @private 34294 * @member {number} 34295 */ 34296 this._elementTimer = 0; 34297 34298 /** 34299 * The `complete` function bound to this resource's context. 34300 * 34301 * @private 34302 * @member {function} 34303 */ 34304 this._boundComplete = this.complete.bind(this); 34305 34306 /** 34307 * The `_onError` function bound to this resource's context. 34308 * 34309 * @private 34310 * @member {function} 34311 */ 34312 this._boundOnError = this._onError.bind(this); 34313 34314 /** 34315 * The `_onProgress` function bound to this resource's context. 34316 * 34317 * @private 34318 * @member {function} 34319 */ 34320 this._boundOnProgress = this._onProgress.bind(this); 34321 34322 /** 34323 * The `_onTimeout` function bound to this resource's context. 34324 * 34325 * @private 34326 * @member {function} 34327 */ 34328 this._boundOnTimeout = this._onTimeout.bind(this); 34329 34330 // xhr callbacks 34331 this._boundXhrOnError = this._xhrOnError.bind(this); 34332 this._boundXhrOnTimeout = this._xhrOnTimeout.bind(this); 34333 this._boundXhrOnAbort = this._xhrOnAbort.bind(this); 34334 this._boundXhrOnLoad = this._xhrOnLoad.bind(this); 34335 34336 /** 34337 * Dispatched when the resource beings to load. 34338 * 34339 * The callback looks like {@link Resource.OnStartSignal}. 34340 * 34341 * @member {Signal} 34342 */ 34343 this.onStart = new _miniSignals2.default(); 34344 34345 /** 34346 * Dispatched each time progress of this resource load updates. 34347 * Not all resources types and loader systems can support this event 34348 * so sometimes it may not be available. If the resource 34349 * is being loaded on a modern browser, using XHR, and the remote server 34350 * properly sets Content-Length headers, then this will be available. 34351 * 34352 * The callback looks like {@link Resource.OnProgressSignal}. 34353 * 34354 * @member {Signal} 34355 */ 34356 this.onProgress = new _miniSignals2.default(); 34357 34358 /** 34359 * Dispatched once this resource has loaded, if there was an error it will 34360 * be in the `error` property. 34361 * 34362 * The callback looks like {@link Resource.OnCompleteSignal}. 34363 * 34364 * @member {Signal} 34365 */ 34366 this.onComplete = new _miniSignals2.default(); 34367 34368 /** 34369 * Dispatched after this resource has had all the *after* middleware run on it. 34370 * 34371 * The callback looks like {@link Resource.OnCompleteSignal}. 34372 * 34373 * @member {Signal} 34374 */ 34375 this.onAfterMiddleware = new _miniSignals2.default(); 34376 } 34377 34378 /** 34379 * When the resource starts to load. 34380 * 34381 * @memberof Resource 34382 * @callback OnStartSignal 34383 * @param {Resource} resource - The resource that the event happened on. 34384 */ 34385 34386 /** 34387 * When the resource reports loading progress. 34388 * 34389 * @memberof Resource 34390 * @callback OnProgressSignal 34391 * @param {Resource} resource - The resource that the event happened on. 34392 * @param {number} percentage - The progress of the load in the range [0, 1]. 34393 */ 34394 34395 /** 34396 * When the resource finishes loading. 34397 * 34398 * @memberof Resource 34399 * @callback OnCompleteSignal 34400 * @param {Resource} resource - The resource that the event happened on. 34401 */ 34402 34403 /** 34404 * @memberof Resource 34405 * @typedef {object} IMetadata 34406 * @property {HTMLImageElement|HTMLAudioElement|HTMLVideoElement} [loadElement=null] - The 34407 * element to use for loading, instead of creating one. 34408 * @property {boolean} [skipSource=false] - Skips adding source(s) to the load element. This 34409 * is useful if you want to pass in a `loadElement` that you already added load sources to. 34410 * @property {string|string[]} [mimeType] - The mime type to use for the source element 34411 * of a video/audio elment. If the urls are an array, you can pass this as an array as well 34412 * where each index is the mime type to use for the corresponding url index. 34413 */ 34414 34415 /** 34416 * Stores whether or not this url is a data url. 34417 * 34418 * @readonly 34419 * @member {boolean} 34420 */ 34421 34422 34423 /** 34424 * Marks the resource as complete. 34425 * 34426 */ 34427 Resource.prototype.complete = function complete() { 34428 this._clearEvents(); 34429 this._finish(); 34430 }; 34431 34432 /** 34433 * Aborts the loading of this resource, with an optional message. 34434 * 34435 * @param {string} message - The message to use for the error 34436 */ 34437 34438 34439 Resource.prototype.abort = function abort(message) { 34440 // abort can be called multiple times, ignore subsequent calls. 34441 if (this.error) { 34442 return; 34443 } 34444 34445 // store error 34446 this.error = new Error(message); 34447 34448 // clear events before calling aborts 34449 this._clearEvents(); 34450 34451 // abort the actual loading 34452 if (this.xhr) { 34453 this.xhr.abort(); 34454 } else if (this.xdr) { 34455 this.xdr.abort(); 34456 } else if (this.data) { 34457 // single source 34458 if (this.data.src) { 34459 this.data.src = Resource.EMPTY_GIF; 34460 } 34461 // multi-source 34462 else { 34463 while (this.data.firstChild) { 34464 this.data.removeChild(this.data.firstChild); 34465 } 34466 } 34467 } 34468 34469 // done now. 34470 this._finish(); 34471 }; 34472 34473 /** 34474 * Kicks off loading of this resource. This method is asynchronous. 34475 * 34476 * @param {Resource.OnCompleteSignal} [cb] - Optional callback to call once the resource is loaded. 34477 */ 34478 34479 34480 Resource.prototype.load = function load(cb) { 34481 var _this = this; 34482 34483 if (this.isLoading) { 34484 return; 34485 } 34486 34487 if (this.isComplete) { 34488 if (cb) { 34489 setTimeout(function () { 34490 return cb(_this); 34491 }, 1); 34492 } 34493 34494 return; 34495 } else if (cb) { 34496 this.onComplete.once(cb); 34497 } 34498 34499 this._setFlag(Resource.STATUS_FLAGS.LOADING, true); 34500 34501 this.onStart.dispatch(this); 34502 34503 // if unset, determine the value 34504 if (this.crossOrigin === false || typeof this.crossOrigin !== 'string') { 34505 this.crossOrigin = this._determineCrossOrigin(this.url); 34506 } 34507 34508 switch (this.loadType) { 34509 case Resource.LOAD_TYPE.IMAGE: 34510 this.type = Resource.TYPE.IMAGE; 34511 this._loadElement('image'); 34512 break; 34513 34514 case Resource.LOAD_TYPE.AUDIO: 34515 this.type = Resource.TYPE.AUDIO; 34516 this._loadSourceElement('audio'); 34517 break; 34518 34519 case Resource.LOAD_TYPE.VIDEO: 34520 this.type = Resource.TYPE.VIDEO; 34521 this._loadSourceElement('video'); 34522 break; 34523 34524 case Resource.LOAD_TYPE.XHR: 34525 /* falls through */ 34526 default: 34527 if (useXdr && this.crossOrigin) { 34528 this._loadXdr(); 34529 } else { 34530 this._loadXhr(); 34531 } 34532 break; 34533 } 34534 }; 34535 34536 /** 34537 * Checks if the flag is set. 34538 * 34539 * @private 34540 * @param {number} flag - The flag to check. 34541 * @return {boolean} True if the flag is set. 34542 */ 34543 34544 34545 Resource.prototype._hasFlag = function _hasFlag(flag) { 34546 return (this._flags & flag) !== 0; 34547 }; 34548 34549 /** 34550 * (Un)Sets the flag. 34551 * 34552 * @private 34553 * @param {number} flag - The flag to (un)set. 34554 * @param {boolean} value - Whether to set or (un)set the flag. 34555 */ 34556 34557 34558 Resource.prototype._setFlag = function _setFlag(flag, value) { 34559 this._flags = value ? this._flags | flag : this._flags & ~flag; 34560 }; 34561 34562 /** 34563 * Clears all the events from the underlying loading source. 34564 * 34565 * @private 34566 */ 34567 34568 34569 Resource.prototype._clearEvents = function _clearEvents() { 34570 clearTimeout(this._elementTimer); 34571 34572 if (this.data && this.data.removeEventListener) { 34573 this.data.removeEventListener('error', this._boundOnError, false); 34574 this.data.removeEventListener('load', this._boundComplete, false); 34575 this.data.removeEventListener('progress', this._boundOnProgress, false); 34576 this.data.removeEventListener('canplaythrough', this._boundComplete, false); 34577 } 34578 34579 if (this.xhr) { 34580 if (this.xhr.removeEventListener) { 34581 this.xhr.removeEventListener('error', this._boundXhrOnError, false); 34582 this.xhr.removeEventListener('timeout', this._boundXhrOnTimeout, false); 34583 this.xhr.removeEventListener('abort', this._boundXhrOnAbort, false); 34584 this.xhr.removeEventListener('progress', this._boundOnProgress, false); 34585 this.xhr.removeEventListener('load', this._boundXhrOnLoad, false); 34586 } else { 34587 this.xhr.onerror = null; 34588 this.xhr.ontimeout = null; 34589 this.xhr.onprogress = null; 34590 this.xhr.onload = null; 34591 } 34592 } 34593 }; 34594 34595 /** 34596 * Finalizes the load. 34597 * 34598 * @private 34599 */ 34600 34601 34602 Resource.prototype._finish = function _finish() { 34603 if (this.isComplete) { 34604 throw new Error('Complete called again for an already completed resource.'); 34605 } 34606 34607 this._setFlag(Resource.STATUS_FLAGS.COMPLETE, true); 34608 this._setFlag(Resource.STATUS_FLAGS.LOADING, false); 34609 34610 this.onComplete.dispatch(this); 34611 }; 34612 34613 /** 34614 * Loads this resources using an element that has a single source, 34615 * like an HTMLImageElement. 34616 * 34617 * @private 34618 * @param {string} type - The type of element to use. 34619 */ 34620 34621 34622 Resource.prototype._loadElement = function _loadElement(type) { 34623 if (this.metadata.loadElement) { 34624 this.data = this.metadata.loadElement; 34625 } else if (type === 'image' && typeof window.Image !== 'undefined') { 34626 this.data = new Image(); 34627 } else { 34628 this.data = document.createElement(type); 34629 } 34630 34631 if (this.crossOrigin) { 34632 this.data.crossOrigin = this.crossOrigin; 34633 } 34634 34635 if (!this.metadata.skipSource) { 34636 this.data.src = this.url; 34637 } 34638 34639 this.data.addEventListener('error', this._boundOnError, false); 34640 this.data.addEventListener('load', this._boundComplete, false); 34641 this.data.addEventListener('progress', this._boundOnProgress, false); 34642 34643 if (this.timeout) { 34644 this._elementTimer = setTimeout(this._boundOnTimeout, this.timeout); 34645 } 34646 }; 34647 34648 /** 34649 * Loads this resources using an element that has multiple sources, 34650 * like an HTMLAudioElement or HTMLVideoElement. 34651 * 34652 * @private 34653 * @param {string} type - The type of element to use. 34654 */ 34655 34656 34657 Resource.prototype._loadSourceElement = function _loadSourceElement(type) { 34658 if (this.metadata.loadElement) { 34659 this.data = this.metadata.loadElement; 34660 } else if (type === 'audio' && typeof window.Audio !== 'undefined') { 34661 this.data = new Audio(); 34662 } else { 34663 this.data = document.createElement(type); 34664 } 34665 34666 if (this.data === null) { 34667 this.abort('Unsupported element: ' + type); 34668 34669 return; 34670 } 34671 34672 if (this.crossOrigin) { 34673 this.data.crossOrigin = this.crossOrigin; 34674 } 34675 34676 if (!this.metadata.skipSource) { 34677 // support for CocoonJS Canvas+ runtime, lacks document.createElement('source') 34678 if (navigator.isCocoonJS) { 34679 this.data.src = Array.isArray(this.url) ? this.url[0] : this.url; 34680 } else if (Array.isArray(this.url)) { 34681 var mimeTypes = this.metadata.mimeType; 34682 34683 for (var i = 0; i < this.url.length; ++i) { 34684 this.data.appendChild(this._createSource(type, this.url[i], Array.isArray(mimeTypes) ? mimeTypes[i] : mimeTypes)); 34685 } 34686 } else { 34687 var _mimeTypes = this.metadata.mimeType; 34688 34689 this.data.appendChild(this._createSource(type, this.url, Array.isArray(_mimeTypes) ? _mimeTypes[0] : _mimeTypes)); 34690 } 34691 } 34692 34693 this.data.addEventListener('error', this._boundOnError, false); 34694 this.data.addEventListener('load', this._boundComplete, false); 34695 this.data.addEventListener('progress', this._boundOnProgress, false); 34696 this.data.addEventListener('canplaythrough', this._boundComplete, false); 34697 34698 this.data.load(); 34699 34700 if (this.timeout) { 34701 this._elementTimer = setTimeout(this._boundOnTimeout, this.timeout); 34702 } 34703 }; 34704 34705 /** 34706 * Loads this resources using an XMLHttpRequest. 34707 * 34708 * @private 34709 */ 34710 34711 34712 Resource.prototype._loadXhr = function _loadXhr() { 34713 // if unset, determine the value 34714 if (typeof this.xhrType !== 'string') { 34715 this.xhrType = this._determineXhrType(); 34716 } 34717 34718 var xhr = this.xhr = new XMLHttpRequest(); 34719 34720 // set the request type and url 34721 xhr.open('GET', this.url, true); 34722 34723 xhr.timeout = this.timeout; 34724 34725 // load json as text and parse it ourselves. We do this because some browsers 34726 // *cough* safari *cough* can't deal with it. 34727 if (this.xhrType === Resource.XHR_RESPONSE_TYPE.JSON || this.xhrType === Resource.XHR_RESPONSE_TYPE.DOCUMENT) { 34728 xhr.responseType = Resource.XHR_RESPONSE_TYPE.TEXT; 34729 } else { 34730 xhr.responseType = this.xhrType; 34731 } 34732 34733 xhr.addEventListener('error', this._boundXhrOnError, false); 34734 xhr.addEventListener('timeout', this._boundXhrOnTimeout, false); 34735 xhr.addEventListener('abort', this._boundXhrOnAbort, false); 34736 xhr.addEventListener('progress', this._boundOnProgress, false); 34737 xhr.addEventListener('load', this._boundXhrOnLoad, false); 34738 34739 xhr.send(); 34740 }; 34741 34742 /** 34743 * Loads this resources using an XDomainRequest. This is here because we need to support IE9 (gross). 34744 * 34745 * @private 34746 */ 34747 34748 34749 Resource.prototype._loadXdr = function _loadXdr() { 34750 // if unset, determine the value 34751 if (typeof this.xhrType !== 'string') { 34752 this.xhrType = this._determineXhrType(); 34753 } 34754 34755 var xdr = this.xhr = new XDomainRequest(); // eslint-disable-line no-undef 34756 34757 // XDomainRequest has a few quirks. Occasionally it will abort requests 34758 // A way to avoid this is to make sure ALL callbacks are set even if not used 34759 // More info here: http://stackoverflow.com/questions/15786966/xdomainrequest-aborts-post-on-ie-9 34760 xdr.timeout = this.timeout || 5000; // XDR needs a timeout value or it breaks in IE9 34761 34762 xdr.onerror = this._boundXhrOnError; 34763 xdr.ontimeout = this._boundXhrOnTimeout; 34764 xdr.onprogress = this._boundOnProgress; 34765 xdr.onload = this._boundXhrOnLoad; 34766
34767 xdr.open('GET', this.url, true); 34768 34769 // Note: The xdr.send() call is wrapped in a timeout to prevent an 34770 // issue with the interface where some requests are lost if multiple 34771 // XDomainRequests are being sent at the same time. 34772 // Some info here: https://github.com/photonstorm/phaser/issues/1248 34773 setTimeout(function () { 34774 return xdr.send(); 34775 }, 1); 34776 }; 34777 34778 /** 34779 * Creates a source used in loading via an element. 34780 * 34781 * @private 34782 * @param {string} type - The element type (video or audio). 34783 * @param {string} url - The source URL to load from. 34784 * @param {string} [mime] - The mime type of the video 34785 * @return {HTMLSourceElement} The source element. 34786 */ 34787 34788 34789 Resource.prototype._createSource = function _createSource(type, url, mime) { 34790 if (!mime) { 34791 mime = type + '/' + this._getExtension(url); 34792 } 34793 34794 var source = document.createElement('source'); 34795 34796 source.src = url; 34797 source.type = mime; 34798 34799 return source; 34800 }; 34801 34802 /** 34803 * Called if a load errors out. 34804 * 34805 * @param {Event} event - The error event from the element that emits it. 34806 * @private 34807 */ 34808 34809 34810 Resource.prototype._onError = function _onError(event) { 34811 this.abort('Failed to load element using: ' + event.target.nodeName); 34812 }; 34813 34814 /** 34815 * Called if a load progress event fires for an element or xhr/xdr. 34816 * 34817 * @private 34818 * @param {XMLHttpRequestProgressEvent|Event} event - Progress event. 34819 */ 34820 34821 34822 Resource.prototype._onProgress = function _onProgress(event) { 34823 if (event && event.lengthComputable) { 34824 this.onProgress.dispatch(this, event.loaded / event.total); 34825 } 34826 }; 34827 34828 /** 34829 * Called if a timeout event fires for an element. 34830 * 34831 * @private 34832 */ 34833 34834
34835 Resource.prototype._onTimeout = function _onTimeout() { 34836 this.abort('Load timed out.'); 34837 }; 34838 34839 /** 34840 * Called if an error event fires for xhr/xdr. 34841 * 34842 * @private 34843 */ 34844 34845 34846 Resource.prototype._xhrOnError = function _xhrOnError() { 34847 var xhr = this.xhr; 34848 34849 this.abort(reqType(xhr) + ' Request failed. Status: ' + xhr.status + ', text: "' + xhr.statusText + '"'); 34850 }; 34851 34852 /** 34853 * Called if an error event fires for xhr/xdr. 34854 * 34855 * @private 34856 */ 34857 34858 34859 Resource.prototype._xhrOnTimeout = function _xhrOnTimeout() { 34860 var xhr = this.xhr; 34861 34862 this.abort(reqType(xhr) + ' Request timed out.'); 34863 }; 34864 34865 /** 34866 * Called if an abort event fires for xhr/xdr. 34867 * 34868 * @private 34869 */ 34870 34871 34872 Resource.prototype._xhrOnAbort = function _xhrOnAbort() { 34873 var xhr = this.xhr; 34874 34875 this.abort(reqType(xhr) + ' Request was aborted by the user.'); 34876 }; 34877 34878 /** 34879 * Called when data successfully loads from an xhr/xdr request. 34880 * 34881 * @private 34882 * @param {XMLHttpRequestLoadEvent|Event} event - Load event 34883 */ 34884 34885 34886 Resource.prototype._xhrOnLoad = function _xhrOnLoad() { 34887 var xhr = this.xhr; 34888 var text = ''; 34889 var status = typeof xhr.status === 'undefined' ? STATUS_OK : xhr.status; // XDR has no `.status`, assume 200. 34890 34891 // responseText is accessible only if responseType is '' or 'text' and on older browsers 34892 if (xhr.responseType === '' || xhr.responseType === 'text' || typeof xhr.responseType === 'undefined') { 34893 text = xhr.responseText; 34894 } 34895 34896 // status can be 0 when using the `file://` protocol so we also check if a response is set. 34897 // If it has a response, we assume 200; otherwise a 0 status code with no contents is an aborted request. 34898 if (status === STATUS_NONE && (text.length > 0 || xhr.responseType === Resource.XHR_RESPONSE_TYPE.BUFFER)) { 34899 status = STATUS_OK; 34900 } 34901 // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request 34902 else if (status === STATUS_IE_BUG_EMPTY) { 34903 status = STATUS_EMPTY; 34904 } 34905 34906 var statusType = status / 100 | 0; 34907 34908 if (statusType === STATUS_TYPE_OK) { 34909 // if text, just return it 34910 if (this.xhrType === Resource.XHR_RESPONSE_TYPE.TEXT) { 34911 this.data = text; 34912 this.type = Resource.TYPE.TEXT; 34913 } 34914 // if json, parse into json object 34915 else if (this.xhrType === Resource.XHR_RESPONSE_TYPE.JSON) { 34916 try { 34917 this.data = JSON.parse(text); 34918 this.type = Resource.TYPE.JSON; 34919 } catch (e) { 34920 this.abort('Error trying to parse loaded json: ' + e); 34921 34922 return; 34923 } 34924 } 34925 // if xml, parse into an xml document or div element 34926 else if (this.xhrType === Resource.XHR_RESPONSE_TYPE.DOCUMENT) { 34927 try { 34928 if (window.DOMParser) { 34929 var domparser = new DOMParser(); 34930 34931 this.data = domparser.parseFromString(text, 'text/xml'); 34932 } else { 34933 var div = document.createElement('div'); 34934 34935 div.innerHTML = text; 34936 34937 this.data = div; 34938 } 34939 34940 this.type = Resource.TYPE.XML; 34941 } catch (e) { 34942 this.abort('Error trying to parse loaded xml: ' + e); 34943 34944 return; 34945 } 34946 } 34947 // other types just return the response 34948 else { 34949 this.data = xhr.response || text; 34950 } 34951 } else { 34952 this.abort('[' + xhr.status + '] ' + xhr.statusText + ': ' + xhr.responseURL); 34953 34954 return; 34955 } 34956 34957 this.complete(); 34958 }; 34959 34960 /** 34961 * Sets the `crossOrigin` property for this resource based on if the url 34962 * for this resource is cross-origin. If crossOrigin was manually set, this 34963 * function does nothing. 34964 * 34965 * @private 34966 * @param {string} url - The url to test. 34967 * @param {object} [loc=window.location] - The location object to test against. 34968 * @return {string} The crossOrigin value to use (or empty string for none). 34969 */ 34970 34971 34972 Resource.prototype._determineCrossOrigin = function _determineCrossOrigin(url, loc) { 34973 // data: and javascript: urls are considered same-origin 34974 if (url.indexOf('data:') === 0) { 34975 return ''; 34976 } 34977 34978 // A sandboxed iframe without the 'allow-same-origin' attribute will have a special 34979 // origin designed not to match window.location.origin, and will always require 34980 // crossOrigin requests regardless of whether the location matches. 34981 if (window.origin !== window.location.origin) { 34982 return 'anonymous'; 34983 } 34984 34985 // default is window.location 34986 loc = loc || window.location; 34987 34988 if (!tempAnchor) { 34989 tempAnchor = document.createElement('a'); 34990 } 34991 34992 // let the browser determine the full href for the url of this resource and then 34993 // parse with the node url lib, we can't use the properties of the anch
34993or element 34994 // because they don't work in IE9 :( 34995 tempAnchor.href = url; 34996 url = (0, _parseUri2.default)(tempAnchor.href, { strictMode: true }); 34997 34998 var samePort = !url.port && loc.port === '' || url.port === loc.port; 34999 var protocol = url.protocol ? url.protocol + ':' : ''; 35000 35001 // if cross origin 35002 if (url.host !== loc.hostname || !samePort || protocol !== loc.protocol) { 35003 return 'anonymous'; 35004 } 35005 35006 return ''; 35007 }; 35008 35009 /** 35010 * Determines the responseType of an XHR request based on the extension of the 35011 * resource being loaded. 35012 * 35013 * @private 35014 * @return {Resource.XHR_RESPONSE_TYPE} The responseType to use. 35015 */ 35016 35017 35018 Resource.prototype._determineXhrType = function _determineXhrType() { 35019 return Resource._xhrTypeMap[this.extension] || Resource.XHR_RESPONSE_TYPE.TEXT; 35020 }; 35021 35022 /** 35023 * Determines the loadType of a resource based on the extension of the 35024 * resource being loaded. 35025 * 35026 * @private 35027 * @return {Resource.LOAD_TYPE} The loadType to use. 35028 */ 35029 35030 35031 Resource.prototype._determineLoadType = function _determineLoadType() { 35032 return Resource._loadTypeMap[this.extension] || Resource.LOAD_TYPE.XHR; 35033 }; 35034 35035 /** 35036 * Extracts the extension (sans '.') of the file being loaded by the resource. 35037 * 35038 * @private 35039 * @return {string} The extension. 35040 */ 35041 35042 35043 Resource.prototype._getExtension = function _getExtension() { 35044 var url = this.url; 35045 var ext = ''; 35046 35047 if (this.isDataUrl) { 35048 var slashIndex = url.indexOf('/'); 35049 35050 ext = url.substring(slashIndex + 1, url.indexOf(';', slashIndex)); 35051 } else { 35052 var queryStart = url.indexOf('?'); 35053 var hashStart = url.indexOf('#'); 35054 var index = Math.min(queryStart > -1 ? queryStart : url.length, hashStart > -1 ? hashStart : url.length); 35055 35056 url = url.substring(0, index); 35057 ext = url.substring(url.lastIndexOf('.') + 1); 35058 } 35059 35060 return ext.toLowerCase(); 35061 }; 35062 35063 /** 35064 * Determines the mime type of an XHR request based on the responseType of 35065 * resource being loaded. 35066 * 35067 * @private 35068 * @param {Resource.XHR_RESPONSE_TYPE} type - The type to get a mime type for. 35069 * @return {string} The mime type to use. 35070 */ 35071 35072 35073 Resource.prototype._getMimeFromXhrType = function _getMimeFromXhrType(type) { 35074 switch (type) { 35075 case Resource.XHR_RESPONSE_TYPE.BUFFER: 35076 return 'application/octet-binary'; 35077 35078 case Resource.XHR_RESPONSE_TYPE.BLOB: 35079 return 'application/blob'; 35080 35081 case Resource.XHR_RESPONSE_TYPE.DOCUMENT: 35082 return 'application/xml'; 35083 35084 case Resource.XHR_RESPONSE_TYPE.JSON: 35085 return 'application/json'; 35086 35087 case Resource.XHR_RESPONSE_TYPE.DEFAULT: 35088 case Resource.XHR_RESPONSE_TYPE.TEXT: 35089 /* falls through */ 35090 default: 35091 return 'text/plain'; 35092 } 35093 }; 35094 35095 _createClass(Resource, [{ 35096 key: 'isDataUrl', 35097 get: function get() { 35098 return this._hasFlag(Resource.STATUS_FLAGS.DATA_URL); 35099 } 35100 35101 /** 35102 * Describes if this resource has finished loading. Is true when the resource has completely 35103 * loaded. 35104 * 35105 * @readonly 35106 * @member {boolean} 35107 */ 35108 35109 }, { 35110 key: 'isComplete', 35111 get: function get() { 35112 return this._hasFlag(Resource.STATUS_FLAGS.COMPLETE); 35113 } 35114 35115 /** 35116 * Describes if this resource is currently loading. Is true when the resource starts loading, 35117 * and is false again when complete. 35118 * 35119 * @readonly 35120 * @member {boolean} 35121 */ 35122 35123 }, { 35124 key: 'isLoading', 35125 get: function get() { 35126 return this._hasFlag(Resource.STATUS_FLAGS.LOADING); 35127 } 35128 }]); 35129 35130 return Resource; 35131 }(); 35132 35133 /** 35134 * The types of resources a resource could represent. 35135 * 35136 * @static 35137 * @readonly 35138 * @enum {number} 35139 */ 35140 35141 35142 Resource.STATUS_FLAGS = { 35143 NONE: 0, 35144 DATA_URL: 1 << 0, 35145 COMPLETE: 1 << 1, 35146 LOADING: 1 << 2 35147 }; 35148 35149 /** 35150 * The types of resources a resource could represent. 35151 * 35152 * @static 35153 * @readonly 35154 * @enum {number} 35155 */ 35156 Resource.TYPE = { 35157 UNKNOWN: 0, 35158 JSON: 1, 35159 XML: 2, 35160 IMAGE: 3, 35161 AUDIO: 4, 35162 VIDEO: 5, 35163 TEXT: 6 35164 }; 35165 35166 /** 35167 * The types of loading a resource can use. 35168 * 35169 * @static 35170 * @readonly 35171 * @enum {number} 35172 */ 35173 Resource.LOAD_TYPE = { 35174 /** Uses XMLHttpRequest to load the resource. */ 35175 XHR: 1, 35176 /** Uses an `Image` object to load the resource. */ 35177 IMAGE: 2, 35178 /** Uses an `Audio` object to load the resource. */ 35179 AUDIO: 3, 35180 /** Uses a `Video` object to load the resource. */ 35181 VIDEO: 4 35182 }; 35183 35184 /** 35185 * The XHR ready states, used internally. 35186 * 35187 * @static 35188 * @readonly 35189 * @enum {string} 35190 */ 35191 Resource.XHR_RESPONSE_TYPE = { 35192 /** string */ 35193 DEFAULT: 'text', 35194 /** ArrayBuffer */ 35195 BUFFER: 'arraybuffer', 35196 /** Blob */ 35197 BLOB: 'blob', 35198 /** Document */ 35199 DOCUMENT: 'document', 35200 /** Object */ 35201 JSON: 'json', 35202 /** String */ 35203 TEXT: 'text' 35204 }; 35205 35206 Resource._loadTypeMap = { 35207 // images 35208 gif: Resource.LOAD_TYPE.IMAGE, 35209 png: Resource.LOAD_TYPE.IMAGE, 35210 bmp: Resource.LOAD_TYPE.IMAGE, 35211 jpg: Resource.LOAD_TYPE.IMAGE, 35212 jpeg: Resource.LOAD_TYPE.IMAGE, 35213 tif: Resource.LOAD_TYPE.IMAGE, 35214 tiff: Resource.LOAD_TYPE.IMAGE, 35215 webp: Resource.LOAD_TYPE.IMAGE, 35216 tga: Resource.LOAD_TYPE.IMAGE, 35217 svg: Resource.LOAD_TYPE.IMAGE, 35218 'svg+xml': Resource.LOAD_TYPE.IMAGE, // for SVG data urls 35219 35220 // audio 35221 mp3: Resource.LOAD_TYPE.AUDIO, 35222 ogg: Resource.LOAD_TYPE.AUDIO, 35223 wav: Resource.LOAD_TYPE.AUDIO, 35224 35225 // videos 35226 mp4: Resource.LOAD_TYPE.VIDEO, 35227 webm: Resource.LOAD_TYPE.VIDEO 35228 }; 35229 35230 Resource._xhrTypeMap = { 35231 // xml 35232 xhtml: Resource.XHR_RESPONSE_TYPE.DOCUMENT, 35233 html: Resource.XHR_RESPONSE_TYPE.DOCUMENT, 35234 htm: Resource.XHR_RESPONSE_TYPE.DOCUMENT, 35235 xml: Resource.XHR_RESPONSE_TYPE.DOCUMENT, 35236 tmx: Resource.XHR_RESPONSE_TYPE.DOCUMENT, 35237 svg: Resource.XHR_RESPONSE_TYPE.DOCUMENT, 35238 35239 // This was added to handle Tiled Tileset XML, but .tsx is also a TypeScript React Component. 35240 // Since it is way less likely for people to be loading TypeScript files instead of Tiled files, 35241 // this should probably be fine. 35242 tsx: Resource.XHR_RESPONSE_TYPE.DOCUMENT, 35243 35244 // images 35245 gif: Resource.XHR_RESPONSE_TYPE.BLOB, 35246 png: Resource.XHR_RESPONSE_TYPE.BLOB, 35247 bmp: Resource.XHR_RESPONSE_TYPE.BLOB, 35248 jpg: Resource.XHR_RESPONSE_TYPE.BLOB, 35249 jpeg: Resource.XHR_RESPONSE_TYPE.BLOB, 35250 tif: Resource.XHR_RESPONSE_TYPE.BLOB, 35251 tiff: Resource.XHR_RESPONSE_TYPE.BLOB, 35252 webp: Resource.XHR_RESPONSE_TYPE.BLOB, 35253 tga: Resource.XHR_RESPONSE_TYPE.BLOB, 35254 35255 // json 35256 json: Resource.XHR_RESPONSE_TYPE.JSON, 35257 35258 // text 35259 text: Resource.XHR_RESPONSE_TYPE.TEXT, 35260 txt: Resource.XHR_RESPONSE_TYPE.TEXT, 35261 35262 // fonts 35263 ttf: Resource.XHR_RESPONSE_TYPE.BUFFER, 35264 otf: Resource.XHR_RESPONSE_TYPE.BUFFER 35265 }; 35266 35267 // We can't set the `src` attribute to empty string, so on abort we set it to this 1px transparent gif 35268 Resource.EMPTY_GIF = 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='; 35269 35270 /** 35271 * Quick helper to set a value on one of the extension maps. Ensures there is no 35272 * dot at the start of the extension. 35273 * 35274 * @ignore 35275 * @param {object} map - The map to set on. 35276 * @param {string}
35276 extname - The extension (or key) to set. 35277 * @param {number} val - The value to set. 35278 */ 35279 function setExtMap(map, extname, val) { 35280 if (extname && extname.indexOf('.') === 0) { 35281 extname = extname.substring(1); 35282 } 35283 35284 if (!extname) { 35285 return; 35286 } 35287 35288 map[extname] = val; 35289 } 35290 35291 /** 35292 * Quick helper to get string xhr type. 35293 * 35294 * @ignore 35295 * @param {XMLHttpRequest|XDomainRequest} xhr - The request to check. 35296 * @return {string} The type. 35297 */ 35298 function reqType(xhr) { 35299 return xhr.toString().replace('object ', ''); 35300 } 35301 35302 // Backwards compat 35303 { 35304 module.exports.default = Resource; // eslint-disable-line no-undef 35305 } 35306 35307 }); 35308 35309 unwrapExports$1(Resource_1$1); 35310 var Resource_2$1 = Resource_1$1.Resource; 35311 35312 var b64$2 = createCommonjsModule$1(function (module, exports) { 35313 35314 exports.__esModule = true; 35315 exports.encodeBinary = encodeBinary; 35316 var _keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; 35317 35318 /** 35319 * Encodes binary into base64. 35320 * 35321 * @param {string} input The input data to encode. 35322 * @returns {string} The encoded base64 string 35323 */ 35324 function encodeBinary(input) { 35325 var output = ''; 35326 var inx = 0; 35327 35328 while (inx < input.length) { 35329 // Fill byte buffer array 35330 var bytebuffer = [0, 0, 0]; 35331 var encodedCharIndexes = [0, 0, 0, 0]; 35332 35333 for (var jnx = 0; jnx < bytebuffer.length; ++jnx) { 35334 if (inx < input.length) { 35335 // throw away high-order byte, as documented at: 35336 // https://developer.mozilla.org/En/Using_XMLHttpRequest#Handling_binary_data 35337 bytebuffer[jnx] = input.charCodeAt(inx++) & 0xff; 35338 } else { 35339 bytebuffer[jnx] = 0; 35340 } 35341 } 35342 35343 // Get each encoded character, 6 bits at a time 35344 // index 1: first 6 bits 35345 encodedCharIndexes[0] = bytebuffer[0] >> 2; 35346 35347 // index 2: second 6 bits (2 least significant bits from input byte 1 + 4 most significant bits from byte 2) 35348 encodedCharIndexes[1] = (bytebuffer[0] & 0x3) << 4 | bytebuffer[1] >> 4; 35349 35350 // index 3: third 6 bits (4 least significant bits from input byte 2 + 2 most significant bits from byte 3) 35351 encodedCharIndexes[2] = (bytebuffer[1] & 0x0f) << 2 | bytebuffer[2] >> 6; 35352 35353 // index 3: forth 6 bits (6 least significant bits from input byte 3) 35354 encodedCharIndexes[3] = bytebuffer[2] & 0x3f; 35355 35356 // Determine whether padding happened, and adjust accordingly 35357 var paddingBytes = inx - (input.length - 1); 35358 35359 switch (paddingBytes) { 35360 case 2: 35361 // Set last 2 characters to padding char 35362 encodedCharIndexes[3] = 64; 35363 encodedCharIndexes[2] = 64; 35364 break; 35365 35366 case 1: 35367 // Set last character to padding char 35368 encodedCharIndexes[3] = 64; 35369 break; 35370 35371 default: 35372 break; // No padding - proceed 35373 } 35374 35375 // Now we will grab each appropriate character out of our keystring 35376 // based on our index array and append it to the output string 35377 for (var _jnx = 0; _jnx < encodedCharIndexes.length; ++_jnx) { 35378 output += _keyStr.charAt(encodedCharIndexes[_jnx]); 35379 } 35380 } 35381 35382 return output; 35383 } 35384 35385 // Backwards compat 35386 { 35387 module.exports.default = encodeBinary; // eslint-disable-line no-undef 35388 } 35389 35390 }); 35391 35392 unwrapExports$1(b64$2); 35393 var b64_1$1 = b64$2.encodeBinary; 35394 35395 var blob = createCommonjsModule$1(function (module, exports) { 35396 35397 exports.__esModule = true; 35398 exports.blobMiddlewareFactory = blobMiddlewareFactory; 35399 35400 35401 35402 35403 35404 var Url = window.URL || window.webkitURL; 35405 35406 // a middleware for transforming XHR loaded Blobs into more useful objects 35407 function blobMiddlewareFactory() { 35408 return function blobMiddleware(resource, next) { 35409 if (!resource.data) { 35410 next(); 35411 35412 return; 35413 } 35414 35415 // if this was an XHR load of a blob 35416 if (resource.xhr && resource.xhrType === Resource_1$1.Resource.XHR_RESPONSE_TYPE.BLOB) { 35417 // if there is no blob support we probably got a binary string back 35418 if (!window.Blob || typeof resource.data === 'string') { 35419 var type = resource.xhr.getResponseHeader('content-type'); 35420 35421 // this is an image, convert the binary string into a data url 35422 if (type && type.indexOf('image') === 0) { 35423 resource.data = new Image(); 35424 resource.data.src = 'data:' + type + ';base64,' + (0, b64$2.encodeBinary)(resource.xhr.responseText); 35425 35426 resource.type = Resource_1$1.Resource.TYPE.IMAGE; 35427 35428 // wait until the image loads and then callback 35429 resource.data.onload = function () { 35430 resource.data.onload = null; 35431 35432 next(); 35433 }; 35434 35435 // next will be called on load 35436 return; 35437 } 35438 } 35439 // if content type says this is an image, then we should transform the blob into an Image object 35440 else if (resource.data.type.indexOf('image') === 0) { 35441 var src = Url.createObjectURL(resource.data); 35442 35443 resource.blob = resource.data; 35444 resource.data = new Image(); 35445 resource.data.src = src; 35446 35447 resource.type = Resource_1$1.Resource.TYPE.IMAGE; 35448 35449 // cleanup the no longer used blob after the image loads 35450 // TODO: Is this correct? Will the image be invalid after revoking? 35451 resource.data.onload = function () { 35452 Url.revokeObjectURL(src); 35453 resource.data.onload = null; 35454 35455 next(); 35456 }; 35457 35458 // next will be called on load. 35459 return; 35460 } 35461 } 35462 35463 next(); 35464 }; 35465 } 35466 35467 }); 35468 35469 unwrapExports$1(blob); 35470 var blob_1 = blob.blobMiddlewareFactory; 35471 35472 /** 35473 * Loader plugin for handling Texture resources. 35474 * @class 35475 * @memberof PIXI 35476 * @implements PIXI.ILoaderPlugin 35477 */ 35478 var TextureLoader = function TextureLoader () {}; 35479 35480 TextureLoader.use = function use (resource, next) 35481 { 35482 // create a new texture if the data is an Image object 35483 if (resource.data && resource.type === lib_1.TYPE.IMAGE) 35484 { 35485 resource.texture = Texture.fromLoader( 35486 resource.data, 35487 resource.url, 35488 resource.name 35489 ); 35490 } 35491 next(); 35492 }; 35493 35494 /** 35495 * The new loader, extends Resource Loader by Chad Engler: https://github.com/englercj/resource-loader 35496 * 35497 * ```js 35498 * const loader = PIXI.Loader.shared; // PixiJS exposes a premade instance for you to use. 35499 * //or 35500 * const loader = new PIXI.Loader(); // you can also create your own if you want 35501 * 35502 * const sprites = {}; 35503 * 35504 * // Chainable `add` to enqueue a resource 35505 * loader.add('bunny', 'data/bunny.png') 35506 * .add('spaceship', 'assets/spritesheet.json'); 35507 * loader.add('scoreFont', 'assets/score.fnt'); 35508 * 35509 * // Chainable `pre` to add a middleware that runs for each resource, *before* loading that resource. 35510 * // This is useful to implement custom caching modules (using filesystem, indexeddb, memory, etc). 35511 * loader.pre(cachingMiddleware); 35512 * 35513 * // Chainable `use` to add a middleware that runs for each resource, *after* loading that resource. 35514 * // This is useful to implement custom parsing modules (like spritesheet parsers, spine parser, etc). 35515 * loader.use(parsingMiddleware); 35516 * 35517 * // The `load` method loads the queue of resources, and calls the passed in callback called once all 35518 * // resources have loaded. 35519 * loader.load((loader, resources) => { 35520 * // resources is an object where the key is the name of the resource loaded and the value is the resource object. 35521 * // They have a couple default properties: 35522 * // - `url`: The URL that the resource was loaded from 35523 * // - `error`: The error that happened when trying to load (if any) 35524 * // - `data`: The raw data that was loaded 35525 * // also may contain other properties based on the middleware that runs. 35526 * sprites.bunny = new PIXI.TilingSprite(resources.bunny.texture); 35527 * sprites.spaceship = new PIXI.TilingSprite(resources.space
35527ship.texture); 35528 * sprites.scoreFont = new PIXI.TilingSprite(resources.scoreFont.texture); 35529 * }); 35530 * 35531 * // throughout the process multiple signals can be dispatched. 35532 * loader.onProgress.add(() => {}); // called once per loaded/errored file 35533 * loader.onError.add(() => {}); // called once per errored file 35534 * loader.onLoad.add(() => {}); // called once per loaded file 35535 * loader.onComplete.add(() => {}); // called once when the queued resources all load. 35536 * ``` 35537 * 35538 * @see https://github.com/englercj/resource-loader 35539 * 35540 * @class Loader 35541 * @memberof PIXI 35542 * @param {string} [baseUrl=''] - The base url for all resources loaded by this loader. 35543 * @param {number} [concurrency=10] - The number of resources to load concurrently. 35544 */ 35545 var Loader$2 = /*@__PURE__*/(function (ResourceLoader) { 35546 function Loader(baseUrl, concurrency) 35547 { 35548 var this$1 = this; 35549 35550 ResourceLoader.call(this, baseUrl, concurrency); 35551 eventemitter3.call(this); 35552 35553 for (var i = 0; i < Loader._plugins.length; ++i) 35554 { 35555 var plugin = Loader._plugins[i]; 35556 var pre = plugin.pre; 35557 var use = plugin.use; 35558 35559 if (pre) 35560 { 35561 this.pre(pre); 35562 } 35563 35564 if (use) 35565 { 35566 this.use(use); 35567 } 35568 } 35569 35570 // Compat layer, translate the new v2 signals into old v1 events. 35571 this.onStart.add(function (l) { return this$1.emit('start', l); }); 35572 this.onProgress.add(function (l, r) { return this$1.emit('progress', l, r); }); 35573 this.onError.add(function (e, l, r) { return this$1.emit('error', e, l, r); }); 35574 this.onLoad.add(function (l, r) { return this$1.emit('load', l, r); }); 35575 this.onComplete.add(function (l, r) { return this$1.emit('complete', l, r); }); 35576 35577 /** 35578 * If this loader cannot be destroyed. 35579 * @member {boolean} 35580 * @default false 35581 * @private 35582 */ 35583 this._protected = false; 35584 } 35585 35586 if ( ResourceLoader ) { Loader.__proto__ = ResourceLoader; } 35587 Loader.prototype = Object.create( ResourceLoader && ResourceLoader.prototype ); 35588 Loader.prototype.constructor = Loader; 35589 35590 var staticAccessors = { shared: { configurable: true } }; 35591 35592 /** 35593 * Destroy the loader, removes references. 35594 * @private 35595 */ 35596 Loader.prototype.destroy = function destroy () 35597 { 35598 if (!this._protected) 35599 { 35600 this.removeAllListeners(); 35601 this.reset(); 35602 } 35603 }; 35604 35605 /** 35606 * A premade instance of the loader that can be used to load resources. 35607 * @name shared 35608 * @type {PIXI.Loader} 35609 * @static 35610 * @memberof PIXI.Loader 35611 */ 35612 staticAccessors.shared.get = function () 35613 { 35614 var shared = Loader._shared; 35615 35616 if (!shared) 35617 { 35618 shared = new Loader(); 35619 shared._protected = true; 35620 Loader._shared = shared; 35621 } 35622 35623 return shared; 35624 }; 35625 35626 Object.defineProperties( Loader, staticAccessors ); 35627 35628 return Loader; 35629 }(lib)); 35630 35631 // Copy EE3 prototype (mixin) 35632 Object.assign(Loader$2.prototype, eventemitter3.prototype); 35633 35634 /** 35635 * Collection of all installed `use` middleware for Loader. 35636 * 35637 * @static 35638 * @member {Array<PIXI.ILoaderPlugin>} _plugins 35639 * @memberof PIXI.Loader 35640 * @private 35641 */ 35642 Loader$2._plugins = []; 35643 35644 /** 35645 * Adds a Loader plugin for the global shared loader and all 35646 * new Loader instances created. 35647 * 35648 * @static 35649 * @method registerPlugin 35650 * @memberof PIXI.Loader 35651 * @param {PIXI.ILoaderPlugin} plugin - The plugin to add 35652 * @return {PIXI.Loader} Reference to PIXI.Loader for chaining 35653 */ 35654 Loader$2.registerPlugin = function registerPlugin(plugin) 35655 { 35656 Loader$2._plugins.push(plugin); 35657 35658 if (plugin.add) 35659 { 35660 plugin.add(); 35661 } 35662 35663 return Loader$2; 35664 }; 35665 35666 // parse any blob into more usable objects (e.g. Image) 35667 Loader$2.registerPlugin({ use: blob_1() }); 35668 35669 // parse any Image objects into textures 35670 Loader$2.registerPlugin(TextureLoader); 35671 35672 /** 35673 * Plugin to be installed for handling specific Loader resources. 35674 * 35675 * @memberof PIXI 35676 * @typedef ILoaderPlugin 35677 * @property {function} [add] - Function to call immediate after registering plugin. 35678 * @property {PIXI.Loader.loaderMiddleware} [pre] - Middleware function to run before load, the 35679 * arguments for this are `(resource, next)` 35680 * @property {PIXI.Loader.loaderMiddleware} [use] - Middleware function to run after load, the 35681 * arguments for this are `(resource, next)` 35682 */ 35683 35684 /** 35685 * @memberof PIXI.Loader 35686 * @callback loaderMiddleware 35687 * @param {PIXI.LoaderResource} resource 35688 * @param {function} next 35689 */ 35690 35691 /** 35692 * Application plugin for supporting loader option. Installing the LoaderPlugin 35693 * is not necessary if using **pixi.js** or **pixi.js-legacy**. 35694 * @example 35695 * import {AppLoaderPlugin} from '@pixi/loaders'; 35696 * import {Application} from '@pixi/app'; 35697 * Application.registerPlugin(AppLoaderPlugin); 35698 * @class 35699 * @memberof PIXI 35700 */ 35701 var AppLoaderPlugin = function AppLoaderPlugin () {}; 35702 35703 AppLoaderPlugin.init = function init (options) 35704 { 35705 options = Object.assign({ 35706 sharedLoader: false, 35707 }, options); 35708 35709 /** 35710 * Loader instance to help with asset loading. 35711 * @name PIXI.Application#loader 35712 * @type {PIXI.Loader} 35713 * @readonly 35714 */ 35715 this.loader = options.sharedLoader ? Loader$2.shared : new Loader$2(); 35716 }; 35717 35718 /** 35719 * Called when application destroyed 35720 * @private 35721 */ 35722 AppLoaderPlugin.destroy = function destroy () 35723 { 35724 if (this.loader) 35725 { 35726 this.loader.destroy(); 35727 this.loader = null; 35728 } 35729 }; 35730 35731 /** 35732 * Reference to **{@link https://github.com/englercj/resource-loader 35733 * resource-loader}**'s Resource class.
35734 * @see http://englercj.github.io/resource-loader/Resource.html 35735 * @class LoaderResource 35736 * @memberof PIXI 35737 */ 35738 var LoaderResource = lib_1; 35739 35740 /*! 35741 * @pixi/particles - v5.0.0-rc.3 35742 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 35743 * 35744 * @pixi/particles is licensed under the MIT License. 35745 * http://www.opensource.org/licenses/mit-license 35746 */ 35747 35748 /** 35749 * The ParticleContainer class is a really fast version of the Container built solely for speed, 35750 * so use when you need a lot of sprites or particles. 35751 * 35752 * The tradeoff of the ParticleContainer is that most advanced functionality will not work. 35753 * ParticleContainer implements the basic object transform (position, scale, rotation) 35754 * and some advanced functionality like tint (as of v4.5.6). 35755 * 35756 * Other more advanced functionality like masking, children, filters, etc will not work on sprites in this batch. 35757 * 35758 * It's extremely easy to use: 35759 * ```js 35760 * let container = new ParticleContainer(); 35761 * 35762 * for (let i = 0; i < 100; ++i) 35763 * { 35764 * let sprite = new PIXI.Sprite.from("myImage.png"); 35765 * container.addChild(sprite); 35766 * } 35767 * ``` 35768 * 35769 * And here you have a hundred sprites that will be rendered at the speed of light. 35770 * 35771 * @class 35772 * @extends PIXI.Container 35773 * @memberof PIXI 35774 */ 35775 var ParticleContainer = /*@__PURE__*/(function (Container) { 35776 function ParticleContainer(maxSize, properties, batchSize, autoResize) 35777 { 35778 if ( maxSize === void 0 ) { maxSize = 1500; } 35779 if ( batchSize === void 0 ) { batchSize = 16384; } 35780 if ( autoResize === void 0 ) { autoResize = false; } 35781 35782 Container.call(this); 35783 35784 // Making sure the batch size is valid 35785 // 65535 is max vertex index in the index buffer (see ParticleRenderer) 35786 // so max number of particles is 65536 / 4 = 16384 35787 var maxBatchSize = 16384; 35788 35789 if (batchSize > maxBatchSize) 35790 { 35791 batchSize = maxBatchSize; 35792 } 35793 35794 if (batchSize > maxSize) 35795 { 35796 batchSize = maxSize; 35797 } 35798 35799 /** 35800 * Set properties to be dynamic (true) / static (false) 35801 * 35802 * @member {boolean[]} 35803 * @private 35804 */
35805 this._properties = [false, true, false, false, false]; 35806 35807 /** 35808 * @member {number} 35809 * @private 35810 */ 35811 this._maxSize = maxSize; 35812 35813 /** 35814 * @member {number} 35815 * @private 35816 */ 35817 this._batchSize = batchSize; 35818 35819 /** 35820 * @member {Array<PIXI.Buffer>} 35821 * @private 35822 */ 35823 this._buffers = null; 35824 35825 /** 35826 * for every batch stores _updateID corresponding to the last change in that batch 35827 * @member {number[]} 35828 * @private 35829 */ 35830 this._bufferUpdateIDs = []; 35831 35832 /** 35833 * when child inserted, removed or changes position this number goes up 35834 * @member {number[]} 35835 * @private 35836 */ 35837 this._updateID = 0; 35838 35839 /** 35840 * @member {boolean} 35841 * 35842 */ 35843 this.interactiveChildren = false; 35844 35845 /** 35846 * The blend mode to be applied to the sprite. Apply a value of `PIXI.BLEND_MODES.NORMAL` 35847 * to reset the blend mode. 35848 * 35849 * @member {number} 35850 * @default PIXI.BLEND_MODES.NORMAL 35851 * @see PIXI.BLEND_MODES 35852 */ 35853 this.blendMode = BLEND_MODES.NORMAL; 35854 35855 /** 35856 * If true, container allocates more batches in case there are more than `maxSize` particles. 35857 * @member {boolean} 35858 * @default false 35859 */ 35860 this.autoResize = autoResize; 35861 35862 /** 35863 * If true PixiJS will Math.floor() x/y values when rendering, stopping pixel interpolation. 35864 * Advantages can include sharper image quality (like text) and faster rendering on canvas. 35865 * The main disadvantage is movement of objects may appear less smooth. 35866 * Default to true here as performance is usually the priority for particles. 35867 * 35868 * @member {boolean} 35869 * @default true 35870 */ 35871 this.roundPixels = true; 35872 35873 /** 35874 * The texture used to render the children. 35875 * 35876 * @readonly 35877 * @member {BaseTexture} 35878 */ 35879 this.baseTexture = null; 35880 35881 this.setProperties(properties); 35882 35883 /** 35884 * The tint applied to the container. 35885 * This is a hex value. A value of 0xFFFFFF will remove any tint effect. 35886 * 35887 * @private 35888 * @member {number} 35889 * @default 0xFFFFFF 35890 */ 35891 this._tint = 0; 35892 this.tintRgb = new Float32Array(4); 35893 this.tint = 0xFFFFFF; 35894 } 35895 35896 if ( Container ) { ParticleContainer.__proto__ = Container; } 35897 ParticleContainer.prototype = Object.create( Container && Container.prototype ); 35898 ParticleContainer.prototype.constructor = ParticleContainer; 35899 35900 var prototypeAccessors = { tint: { configurable: true } }; 35901 35902 /** 35903 * Sets the private properties array to dynamic / static based on the passed properties object 35904 * 35905 * @param {object} properties - The properties to be uploaded 35906 */ 35907 ParticleContainer.prototype.setProperties = function setProperties (properties) 35908 { 35909 if (properties) 35910 { 35911 this._properties[0] = 'vertices' in properties || 'scale' in properties 35912 ? !!properties.vertices || !!properties.scale : this._properties[0]; 35913 this._properties[1] = 'position' in properties ? !!properties.position : this._properties[1]; 35914 this._properties[2] = 'rotation' in properties ? !!properties.rotation : this._properties[2]; 35915 this._properties[3] = 'uvs' in properties ? !!properties.uvs : this._properties[3]; 35916 this._properties[4] = 'tint' in properties || 'alpha' in properties 35917 ? !!properties.tint || !!properties.alpha : this._properties[4]; 35918 } 35919 }; 35920 35921 /** 35922 * Updates the object transform for rendering 35923 * 35924 * @private 35925 */ 35926 ParticleContainer.prototype.updateTransform = function updateTransform () 35927 { 35928 // TODO don't need to! 35929 this.displayObjectUpdateTransform(); 35930 // PIXI.Container.prototype.updateTransform.call( this ); 35931 }; 35932 35933 /** 35934 * The tint applied to the container. This is a hex value. 35935 * A value of 0xFFFFFF will remove any tint effect. 35936 ** IMPORTANT: This is a WebGL only feature and will be ignored by the canvas renderer. 35937 * @member {number} 35938 * @default 0xFFFFFF 35939 */ 35940 prototypeAccessors.tint.get = function () 35941 { 35942 return this._tint; 35943 }; 35944 35945 prototypeAccessors.tint.set = function (value) // eslint-disable-line require-jsdoc 35946 { 35947 this._tint = value; 35948 hex2rgb(value, this.tintRgb); 35949 }; 35950 35951 /**
35952 * Renders the container using the WebGL renderer 35953 * 35954 * @private 35955 * @param {PIXI.Renderer} renderer - The webgl renderer 35956 */ 35957 ParticleContainer.prototype.render = function render (renderer) 35958 { 35959 var this$1 = this; 35960 35961 if (!this.visible || this.worldAlpha <= 0 || !this.children.length || !this.renderable) 35962 { 35963 return; 35964 } 35965 35966 if (!this.baseTexture) 35967 { 35968 this.baseTexture = this.children[0]._texture.baseTexture; 35969 if (!this.baseTexture.valid) 35970 { 35971 this.baseTexture.once('update', function () { return this$1.onChildrenChange(0); }); 35972 } 35973 } 35974 35975 renderer.batch.setObjectRenderer(renderer.plugins.particle); 35976 renderer.plugins.particle.render(this); 35977 }; 35978 35979 /** 35980 * Set the flag that static data should be updated to true 35981 * 35982 * @private 35983 * @param {number} smallestChildIndex - The smallest child index 35984 */ 35985 ParticleContainer.prototype.onChildrenChange = function onChildrenChange (smallestChildIndex) 35986 { 35987 var bufferIndex = Math.floor(smallestChildIndex / this._batchSize); 35988 35989 while (this._bufferUpdateIDs.length < bufferIndex) 35990 { 35991 this._bufferUpdateIDs.push(0); 35992 } 35993 this._bufferUpdateIDs[bufferIndex] = ++this._updateID; 35994 }; 35995 35996 ParticleContainer.prototype.dispose = function dispose () 35997 { 35998 if (this._buffers) 35999 { 36000 for (var i = 0; i < this._buffers.length; ++i) 36001 { 36002 this._buffers[i].destroy(); 36003 } 36004 36005 this._buffers = null; 36006 } 36007 }; 36008 36009 /** 36010 * Destroys the container 36011 * 36012 * @param {object|boolean} [options] - Options parameter. A boolean will act as if all options 36013 * have been set to that value 36014 * @param {boolean} [options.children=false] - if set to true, all the children will have their 36015 * destroy method called as well. 'options' will be passed on to those calls. 36016 * @param {boolean} [options.texture=false] - Only used for child Sprites if options.children is set to true 36017 * Should it destroy the texture of the child sprite 36018 * @param {boolean} [options.baseTexture=false] - Only used for child Sprites if options.children is set to true 36019 * Should it destroy the base texture of the child sprite 36020 */ 36021 ParticleContainer.prototype.destroy = function destroy (options) 36022 { 36023 Container.prototype.destroy.call(this, options); 36024 36025 this.dispose(); 36026 36027 this._properties = null; 36028 this._buffers = null; 36029 this._bufferUpdateIDs = null; 36030 }; 36031 36032 Object.defineProperties( ParticleContainer.prototype, prototypeAccessors ); 36033 36034 return ParticleContainer; 36035 }(Container)); 36036 36037 /** 36038 * @author Mat Groves 36039 * 36040 * Big thanks to the very clever Matt DesLauriers <mattdesl> https://github.com/mattdesl/ 36041 * for creating the original PixiJS version! 36042 * Also a thanks to https://github.com/bchevalier for tweaking the tint and alpha so that 36043 * they now share 4 bytes on the vertex buffer 36044 * 36045 * Heavily inspired by LibGDX's ParticleBuffer: 36046 * https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/ParticleBuffer.java 36047 */ 36048 36049 /** 36050 * The particle buffer manages the static and dynamic buffers for a particle container. 36051 * 36052 * @class 36053 * @private 36054 * @memberof PIXI 36055 */ 36056 var ParticleBuffer = function ParticleBuffer(properties, dynamicPropertyFlags, size) 36057 { 36058 this.geometry = new Geometry(); 36059 36060 this.indexBuffer = null; 36061 36062 /** 36063 * The number of particles the buffer can hold 36064 * 36065 * @private 36066 * @member {number} 36067 */ 36068 this.size = size; 36069 36070 /** 36071 * A list of the properties that are dynamic. 36072 * 36073 * @private 36074 * @member {object[]} 36075 */ 36076 this.dynamicProperties = []; 36077 36078 /** 36079 * A list of the properties that are static. 36080 * 36081 * @private 36082 * @member {object[]} 36083 */ 36084 this.staticProperties = []; 36085 36086 for (var i = 0; i < properties.length; ++i) 36087 { 36088 var property = properties[i]; 36089 36090 // Make copy of properties object so that when we edit the offset it doesn't 36091 // change all other instances of the object literal 36092 property = { 36093 attributeName: property.attributeName, 36094 size: property.size, 36095 uploadFunction: property.uploadFunction, 36096 type: property.type || TYPES.FLOAT, 36097 offset: property.offset, 36098 }; 36099 36100 if (dynamicPropertyFlags[i]) 36101 { 36102 this.dynamicProperties.push(property); 36103 } 36104 else 36105 { 36106 this.staticProperties.push(property); 36107 } 36108 } 36109
36110 this.staticStride = 0; 36111 this.staticBuffer = null; 36112 this.staticData = null; 36113 this.staticDataUint32 = null; 36114 36115 this.dynamicStride = 0; 36116 this.dynamicBuffer = null; 36117 this.dynamicData = null; 36118 this.dynamicDataUint32 = null; 36119 36120 this._updateID = 0; 36121 36122 this.initBuffers(); 36123 }; 36124 36125 /** 36126 * Sets up the renderer context and necessary buffers. 36127 * 36128 * @private 36129 */ 36130 ParticleBuffer.prototype.initBuffers = function initBuffers () 36131 { 36132 var geometry = this.geometry; 36133 36134 var dynamicOffset = 0; 36135 36136 /** 36137 * Holds the indices of the geometry (quads) to draw 36138 * 36139 * @member {Uint16Array} 36140 * @private 36141 */ 36142 this.indexBuffer = new Buffer(createIndicesForQuads(this.size), true, true); 36143 geometry.addIndex(this.indexBuffer); 36144 36145 this.dynamicStride = 0; 36146 36147 for (var i = 0; i < this.dynamicProperties.length; ++i) 36148 { 36149 var property = this.dynamicProperties[i]; 36150 36151 property.offset = dynamicOffset; 36152 dynamicOffset += property.size; 36153 this.dynamicStride += property.size; 36154 } 36155 36156 var dynBuffer = new ArrayBuffer(this.size * this.dynamicStride * 4 * 4); 36157 36158 this.dynamicData = new Float32Array(dynBuffer); 36159 this.dynamicDataUint32 = new Uint32Array(dynBuffer); 36160 this.dynamicBuffer = new Buffer(this.dynamicData, false, false); 36161 36162 // static // 36163 var staticOffset = 0; 36164 36165 this.staticStride = 0; 36166 36167 for (var i$1 = 0; i$1 < this.staticProperties.length; ++i$1) 36168 { 36169 var property$1 = this.staticProperties[i$1]; 36170 36171 property$1.offset = staticOffset; 36172 staticOffset += property$1.size; 36173 this.staticStride += property$1.size; 36174 } 36175 36176 var statBuffer = new ArrayBuffer(this.size * this.staticStride * 4 * 4); 36177 36178 this.staticData = new Float32Array(statBuffer); 36179 this.staticDataUint32 = new Uint32Array(statBuffer); 36180 this.staticBuffer = new Buffer(this.staticData, true, false); 36181 36182 for (var i$2 = 0; i$2 < this.dynamicProperties.length; ++i$2) 36183 { 36184 var property$2 = this.dynamicProperties[i$2]; 36185 36186 geometry.addAttribute( 36187 property$2.attributeName, 36188 this.dynamicBuffer, 36189 0, 36190 property$2.type === TYPES.UNSIGNED_BYTE, 36191 property$2.type, 36192 this.dynamicStride * 4, 36193 property$2.offset * 4 36194 ); 36195 } 36196 36197 for (var i$3 = 0; i$3 < this.staticProperties.length; ++i$3) 36198 { 36199 var property$3 = this.staticProperties[i$3]; 36200 36201 geometry.addAttribute( 36202 property$3.attributeName, 36203 this.staticBuffer, 36204 0, 36205 property$3.type === TYPES.UNSIGNED_BYTE, 36206 property$3.type, 36207 this.staticStride * 4, 36208 property$3.offset * 4 36209 ); 36210 } 36211 }; 36212 36213 /** 36214 * Uploads the dynamic properties. 36215 * 36216 * @private 36217 * @param {PIXI.DisplayObject[]} children - The children to upload. 36218 * @param {number} startIndex - The index to start at. 36219 * @param {number} amount - The number to upload. 36220 */ 36221 ParticleBuffer.prototype.uploadDynamic = function uploadDynamic (children, startIndex, amount) 36222 { 36223 for (var i = 0; i < this.dynamicProperties.length; i++) 36224 { 36225 var property = this.dynamicProperties[i]; 36226 36227 property.uploadFunction(children, startIndex, amount, 36228 property.type === TYPES.UNSIGNED_BYTE ? this.dynamicDataUint32 : this.dynamicData, 36229 this.dynamicStride, property.offset); 36230 } 36231 36232 this.dynamicBuffer._updateID++; 36233 }; 36234 36235 /** 36236 * Uploads the static properties. 36237 * 36238 * @private 36239 * @param {PIXI.DisplayObject[]} children - The children to upload. 36240 * @param {number} startIndex - The index to start at. 36241 * @param {number} amount - The number to upload. 36242 */ 36243 ParticleBuffer.prototype.uploadStatic = function uploadStatic (children, startIndex, amount) 36244 { 36245 for (var i = 0; i < this.staticProperties.length; i++) 36246 { 36247 var property = this.staticProperties[i]; 36248 36249 property.uploadFunction(children, startIndex, amount, 36250 property.type === TYPES.UNSIGNED_BYTE ? this.staticDataUint32 : this.staticData,
36251 this.staticStride, property.offset); 36252 } 36253 36254 this.staticBuffer._updateID++; 36255 }; 36256 36257 /** 36258 * Destroys the ParticleBuffer. 36259 * 36260 * @private 36261 */ 36262 ParticleBuffer.prototype.destroy = function destroy () 36263 { 36264 this.indexBuffer = null; 36265 36266 this.dynamicProperties = null; 36267 // this.dynamicBuffer.destroy(); 36268 this.dynamicBuffer = null; 36269 this.dynamicData = null; 36270 this.dynamicDataUint32 = null; 36271 36272 this.staticProperties = null; 36273 // this.staticBuffer.destroy(); 36274 this.staticBuffer = null; 36275 this.staticData = null; 36276 this.staticDataUint32 = null; 36277 // all buffers are destroyed inside geometry 36278 this.geometry.destroy(); 36279 }; 36280 36281 var vertex$2 = "attribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\nattribute vec4 aColor;\n\nattribute vec2 aPositionCoord;\nattribute float aRotation;\n\nuniform mat3 translationMatrix;\nuniform vec4 uColor;\n\nvarying vec2 vTextureCoord;\nvarying vec4 vColor;\n\nvoid main(void){\n float x = (aVertexPosition.x) * cos(aRotation) - (aVertexPosition.y) * sin(aRotation);\n float y = (aVertexPosition.x) * sin(aRotation) + (aVertexPosition.y) * cos(aRotation);\n\n vec2 v = vec2(x, y);\n v = v + aPositionCoord;\n\n gl_Position = vec4((translationMatrix * vec3(v, 1.0)).xy, 0.0, 1.0);\n\n vTextureCoord = aTextureCoord;\n vColor = aColor * uColor;\n}\n"; 36282 36283 var fragment$1 = "varying vec2 vTextureCoord;\nvarying vec4 vColor;\n\nuniform sampler2D uSampler;\n\nvoid main(void){\n vec4 color = texture2D(uSampler, vTextureCoord) * vColor;\n gl_FragColor = color;\n}"; 36284 36285 /** 36286 * @author Mat Groves 36287 * 36288 * Big thanks to the very clever Matt DesLauriers <mattdesl> https://github.com/mattdesl/ 36289 * for creating the original PixiJS version! 36290 * Also a thanks to https://github.com/bchevalier for tweaking the tint and alpha so that they now 36291 * share 4 bytes on the vertex buffer 36292 * 36293 * Heavily inspired by LibGDX's ParticleRenderer: 36294 * https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/ParticleRenderer.java 36295 */ 36296 36297 /** 36298 * Renderer for Particles that is designer for speed over feature set. 36299 * 36300 * @class 36301 * @memberof PIXI 36302 */ 36303 var ParticleRenderer = /*@__PURE__*/(function (ObjectRenderer) { 36304 function ParticleRenderer(renderer) 36305 { 36306 ObjectRenderer.call(this, renderer); 36307 36308 // 65535 is max vertex index in the index buffer (see ParticleRenderer) 36309 // so max number of particles is 65536 / 4 = 16384 36310 // and max number of element in the index buffer is 16384 * 6 = 98304 36311 // Creating a full index buffer, overhead is 98304 * 2 = 196Ko 36312 // let numIndices = 98304; 36313 36314 /** 36315 * The default shader that is used if a sprite doesn't have a more specific one. 36316 * 36317 * @member {PIXI.Shader} 36318 */ 36319 this.shader = null; 36320 36321 this.properties = null; 36322 36323 this.tempMatrix = new Matrix(); 36324 36325 this.properties = [ 36326 // verticesData 36327 { 36328 attributeName: 'aVertexPosition', 36329 size: 2, 36330 uploadFunction: this.uploadVertices, 36331 offset: 0, 36332 }, 36333 // positionData 36334 { 36335 attributeName: 'aPositionCoord', 36336 size: 2, 36337 uploadFunction: this.uploadPosition, 36338 offset: 0, 36339 }, 36340 // rotationData 36341 { 36342 attributeName: 'aRotation', 36343 size: 1, 36344 uploadFunction: this.uploadRotation, 36345 offset: 0, 36346 }, 36347 // uvsData 36348 { 36349 attributeName: 'aTextureCoord', 36350 size: 2, 36351 uploadFunction: this.uploadUvs, 36352 offset: 0, 36353 }, 36354 // tintData 36355 { 36356 attributeName: 'aColor', 36357 size: 1, 36358 type: TYPES.UNSIGNED_BYTE, 36359 uploadFunction: this.uploadTint, 36360 offset: 0, 36361 } ]; 36362 36363 this.shader = Shader.from(vertex$2, fragment$1, {}); 36364 } 36365 36366 if ( ObjectRenderer ) { ParticleRenderer.__proto__ = ObjectRenderer; } 36367 ParticleRenderer.prototype = Object.create( ObjectRenderer && ObjectRenderer.prototype ); 36368 ParticleRenderer.prototype.constructor = ParticleRenderer; 36369 36370 /**
36371 * Renders the particle container object. 36372 * 36373 * @param {PIXI.ParticleContainer} container - The container to render using this ParticleRenderer 36374 */ 36375 ParticleRenderer.prototype.render = function render (container) 36376 { 36377 var children = container.children; 36378 var maxSize = container._maxSize; 36379 var batchSize = container._batchSize; 36380 var renderer = this.renderer; 36381 var totalChildren = children.length; 36382 36383 if (totalChildren === 0) 36384 { 36385 return; 36386 } 36387 else if (totalChildren > maxSize) 36388 { 36389 totalChildren = maxSize; 36390 } 36391 36392 var buffers = container._buffers; 36393 36394 if (!buffers) 36395 { 36396 buffers = container._buffers = this.generateBuffers(container); 36397 } 36398 36399 var baseTexture = children[0]._texture.baseTexture; 36400 36401 // if the uvs have not updated then no point rendering just yet! 36402 this.renderer.state.setBlendMode(correctBlendMode(container.blendMode, baseTexture.premultiplyAlpha)); 36403 36404 var gl = renderer.gl; 36405 36406 var m = container.worldTransform.copyTo(this.tempMatrix); 36407 36408 m.prepend(renderer.globalUniforms.uniforms.projectionMatrix); 36409 36410 this.shader.uniforms.translationMatrix = m.toArray(true); 36411 36412 this.shader.uniforms.uColor = premultiplyRgba(container.tintRgb, 36413 container.worldAlpha, this.shader.uniforms.uColor, baseTexture.premultiplyAlpha); 36414 36415 this.shader.uniforms.uSampler = baseTexture; 36416 36417 this.renderer.shader.bind(this.shader); 36418 36419 var updateStatic = false; 36420 36421 // now lets upload and render the buffers.. 36422 for (var i = 0, j = 0; i < totalChildren; i += batchSize, j += 1) 36423 { 36424 var amount = (totalChildren - i); 36425 36426 if (amount > batchSize) 36427 { 36428 amount = batchSize; 36429 } 36430 36431 if (j >= buffers.length) 36432 { 36433 if (!container.autoResize) 36434 { 36435 break; 36436 } 36437 buffers.push(this._generateOneMoreBuffer(container)); 36438 } 36439 36440 var buffer = buffers[j]; 36441 36442 // we always upload the dynamic 36443 buffer.uploadDynamic(children, i, amount); 36444 36445 var bid = container._bufferUpdateIDs[j] || 0; 36446 36447 updateStatic = updateStatic || (buffer._updateID < bid); 36448 // we only upload the static content when we have to! 36449 if (updateStatic) 36450 { 36451 buffer._updateID = container._updateID; 36452 buffer.uploadStatic(children, i, amount); 36453 } 36454 36455 // bind the buffer 36456 renderer.geometry.bind(buffer.geometry); 36457 gl.drawElements(gl.TRIANGLES, amount * 6, gl.UNSIGNED_SHORT, 0); 36458 } 36459 }; 36460 36461 /** 36462 * Creates one particle buffer for each child in the container we want to render and updates internal properties 36463 * 36464 * @param {PIXI.ParticleContainer} container - The container to render using this ParticleRenderer 36465 * @return {PIXI.ParticleBuffer[]} The buffers 36466 * @private 36467 */ 36468 ParticleRenderer.prototype.generateBuffers = function generateBuffers (container) 36469 { 36470 var buffers = []; 36471 var size = container._maxSize; 36472 var batchSize = container._batchSize; 36473 var dynamicPropertyFlags = container._properties; 36474 36475 for (var i = 0; i < size; i += batchSize) 36476 { 36477 buffers.push(new ParticleBuffer(this.properties, dynamicPropertyFlags, batchSize)); 36478 } 36479 36480 return buffers; 36481 }; 36482 36483 /** 36484 * Creates one more particle buffer, because container has autoResize feature 36485 * 36486 * @param {PIXI.ParticleContainer} container - The container to render using this ParticleRenderer 36487 * @return {PIXI.ParticleBuffer} generated buffer 36488 * @private 36489 */ 36490 ParticleRenderer.prototype._generateOneMoreBuffer = function _generateOneMoreBuffer (container) 36491 { 36492 var batchSize = container._batchSize; 36493 var dynamicPropertyFlags = container._properties; 36494 36495 return new ParticleBuffer(this.properties, dynamicPropertyFlags, batchSize); 36496 }; 36497 36498 /** 36499 * Uploads the vertices. 36500 * 36501 * @param {PIXI.DisplayObject[]} children - the array of display objects to render 36502 * @param {number} startIndex - the index to start from in the children array 36503 * @param {number} amount - the amount of children that will have their vertices uploaded 36504 * @param {number[]} array - The vertices to upload. 36505 * @param {number} stride - Stride to use for iteration. 36506 * @param {number} offset - Offset to start at. 36507 */ 36508 ParticleRenderer.prototype.uploadVertices = function uploadVertices (children, startIndex, amount, array, stride, offset) 36509 { 36510 var w0 = 0; 36511 var w1 = 0; 36512 var h0 = 0; 36513 var h1 = 0; 36514 36515 for (var i = 0; i < amount; ++i) 36516 { 36517 var sprite = children[startIndex + i]; 36518 var texture = sprite._texture; 36519 var sx = sprite.scale.x; 36520 var sy = sprite.scale.y; 36521 var trim = texture.trim; 36522 var orig = texture.orig; 36523 36524 if (trim) 36525 {
36526 // if the sprite is trimmed and is not a tilingsprite then we need to add the 36527 // extra space before transforming the sprite coords.. 36528 w1 = trim.x - (sprite.anchor.x * orig.width); 36529 w0 = w1 + trim.width; 36530 36531 h1 = trim.y - (sprite.anchor.y * orig.height); 36532 h0 = h1 + trim.height; 36533 } 36534 else 36535 { 36536 w0 = (orig.width) * (1 - sprite.anchor.x); 36537 w1 = (orig.width) * -sprite.anchor.x; 36538 36539 h0 = orig.height * (1 - sprite.anchor.y); 36540 h1 = orig.height * -sprite.anchor.y; 36541 } 36542 36543 array[offset] = w1 * sx; 36544 array[offset + 1] = h1 * sy; 36545 36546 array[offset + stride] = w0 * sx; 36547 array[offset + stride + 1] = h1 * sy; 36548 36549 array[offset + (stride * 2)] = w0 * sx; 36550 array[offset + (stride * 2) + 1] = h0 * sy; 36551 36552 array[offset + (stride * 3)] = w1 * sx; 36553 array[offset + (stride * 3) + 1] = h0 * sy; 36554 36555 offset += stride * 4; 36556 } 36557 }; 36558 36559 /** 36560 * Uploads the position. 36561 * 36562 * @param {PIXI.DisplayObject[]} children - the array of display objects to render 36563 * @param {number} startIndex - the index to start from in the children array 36564 * @param {number} amount - the amount of children that will have their positions uploaded 36565 * @param {number[]} array - The vertices to upload. 36566 * @param {number} stride - Stride to use for iteration. 36567 * @param {number} offset - Offset to start at. 36568 */ 36569 ParticleRenderer.prototype.uploadPosition = function uploadPosition (children, startIndex, amount, array, stride, offset) 36570 { 36571 for (var i = 0; i < amount; i++) 36572 { 36573 var spritePosition = children[startIndex + i].position; 36574 36575 array[offset] = spritePosition.x; 36576 array[offset + 1] = spritePosition.y; 36577 36578 array[offset + stride] = spritePosition.x; 36579 array[offset + stride + 1] = spritePosition.y; 36580 36581 array[offset + (stride * 2)] = spritePosition.x; 36582 array[offset + (stride * 2) + 1] = spritePosition.y; 36583 36584 array[offset + (stride * 3)] = spritePosition.x; 36585 array[offset + (stride * 3) + 1] = spritePosition.y; 36586 36587 offset += stride * 4; 36588 } 36589 }; 36590 36591 /** 36592 * Uploads the rotiation. 36593 * 36594 * @param {PIXI.DisplayObject[]} children - the array of display objects to render 36595 * @param {number} startIndex - the index to start from in the children array 36596 * @param {number} amount - the amount of children that will have their rotation uploaded 36597 * @param {number[]} array - The vertices to upload. 36598 * @param {number} stride - Stride to use for iteration. 36599 * @param {number} offset - Offset to start at. 36600 */ 36601 ParticleRenderer.prototype.uploadRotation = function uploadRotation (children, startIndex, amount, array, stride, offset) 36602 { 36603 for (var i = 0; i < amount; i++) 36604 { 36605 var spriteRotation = children[startIndex + i].rotation; 36606 36607 array[offset] = spriteRotation; 36608 array[offset + stride] = spriteRotation; 36609 array[offset + (stride * 2)] = spriteRotation; 36610 array[offset + (stride * 3)] = spriteRotation; 36611 36612 offset += stride * 4; 36613 } 36614 }; 36615 36616 /** 36617 * Uploads the Uvs 36618 * 36619 * @param {PIXI.DisplayObject[]} children - the array of display objects to render 36620 * @param {number} startIndex - the index to start from in the children array 36621 * @param {number} amount - the amount of children that will have their rotation uploaded 36622 * @param {number[]} array - The vertices to upload. 36623 * @param {number} stride - Stride to use for iteration. 36624 * @param {number} offset - Offset to start at. 36625 */ 36626 ParticleRenderer.prototype.uploadUvs = function uploadUvs (children, startIndex, amount, array, stride, offset) 36627 { 36628 for (var i = 0; i < amount; ++i) 36629 { 36630 var textureUvs = children[startIndex + i]._texture._uvs; 36631 36632 if (textureUvs) 36633 { 36634 array[offset] = textureUvs.x0; 36635 array[offset + 1] = textureUvs.y0; 36636 36637 array[offset + stride] = textureUvs.x1; 36638 array[offset + stride + 1] = textureUvs.y1; 36639 36640 array[offset + (stride * 2)] = textureUvs.x2; 36641 array[offset + (stride * 2) + 1] = textureUvs.y2; 36642 36643 array[offset + (stride * 3)] = textureUvs.x3; 36644 array[offset + (stride * 3) + 1] = textureUvs.y3; 36645 36646 offset += stride * 4; 36647 } 36648 else 36649 { 36650 // TODO you know this can be easier! 36651 array[offset] = 0; 36652 array[offset + 1] = 0; 36653 36654 array[offset + stride] = 0; 36655 array[offset + stride + 1] = 0; 36656 36657 array[offset + (stride * 2)] = 0; 36658 array[offset + (stride * 2) + 1] = 0; 36659 36660 array[offset + (stride * 3)] = 0; 36661 array[offset + (stride * 3) + 1] = 0; 36662 36663 offset += stride * 4; 36664 } 36665 } 36666 }; 36667 36668 /** 36669 * Uploads the tint. 36670 * 36671 * @param {PIXI.DisplayObject[]} children - the array of display objects to render 36672 * @param {number} startIndex - the index to start from in the children array 36673 * @param {number} amount - the amount of children that will have their rotation uploaded 36674 * @param {number[]} array - The vertices to upload. 36675 * @param {number} stride - Stride to use for iteration. 36676 * @param {number} offset - Offset to start at. 36677 */ 36678 ParticleRenderer.prototype.uploadTint = function uploadTint (children, startIndex, amount, array, stride, offset) 36679 { 36680 for (var i = 0; i < amount; ++i) 36681 { 36682 var sprite = children[startIndex + i]; 36683 var premultiplied = sprite._texture.baseTexture.premultiplyAlpha; 36684 var alpha = sprite.alpha; 36685 // we dont call extra function if alpha is 1.0, that's faster 36686 var argb = alpha < 1.0 && premultiplied ? premultiplyTint(sprite._tintRGB, alpha) 36687 : sprite._tintRGB + (alpha * 255 << 24); 36688 36689 array[offset] = argb; 36690 array[offset + stride] = argb; 36691 array[offset + (stride * 2)] = argb; 36692 array[offset + (stride * 3)] = argb; 36693 36694 offset += stride * 4; 36695 } 36696 }; 36697 36698 /** 36699 * Destroys the ParticleRenderer. 36700 */ 36701 ParticleRenderer.prototype.destroy = function destroy () 36702 { 36703 ObjectRenderer.prototype.destroy.call(this); 36704 36705 if (this.shader) 36706 { 36707 this.shader.destroy(); 36708 this.shader = null; 36709 } 36710 36711 this.tempMatrix = null; 36712 }; 36713 36714 return ParticleRenderer; 36715 }(ObjectRenderer)); 36716 36717 /*! 36718 * @pixi/spritesheet - v5.0.0-rc.3 36719 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 36720 * 36721 * @pixi/spritesheet is licensed under the MIT License. 36722 * http://www.opensource.org/licenses/mit-license 36723 */ 36724 36725 /** 36726 * Utility class for maintaining reference to a collection 36727 * of Textures on a single Spritesheet. 36728 *
36729 * To access a sprite sheet from your code pass its JSON data file to Pixi's loader: 36730 * 36731 * ```js 36732 * PIXI.loader.add("images/spritesheet.json").load(setup); 36733 * 36734 * function setup() { 36735 * let sheet = PIXI.loader.resources["images/spritesheet.json"].spritesheet; 36736 * ... 36737 * } 36738 * ``` 36739 * With the `sheet.textures` you can create Sprite objects,`sheet.animations` can be used to create an AnimatedSprite. 36740 * 36741 * Sprite sheets can be packed using tools like {@link https://codeandweb.com/texturepacker|TexturePacker}, 36742 * {@link https://renderhjs.net/shoebox/|Shoebox} or {@link https://github.com/krzysztof-o/spritesheet.js|Spritesheet.js}. 36743 * Default anchor points (see {@link PIXI.Texture#defaultAnchor}) and grouping of animation sprites are currently only 36744 * supported by TexturePacker. 36745 * 36746 * @class 36747 * @memberof PIXI 36748 */ 36749 var Spritesheet = function Spritesheet(baseTexture, data, resolutionFilename) 36750 { 36751 if ( resolutionFilename === void 0 ) { resolutionFilename = null; } 36752 36753 /** 36754 * Reference to ths source texture 36755 * @type {PIXI.BaseTexture} 36756 */ 36757 this.baseTexture = baseTexture; 36758 36759 /** 36760 * A map containing all textures of the sprite sheet. 36761 * Can be used to create a {@link PIXI.Sprite|Sprite}: 36762 * ```js 36763 * new PIXI.Sprite(sheet.textures["image.png"]); 36764 * ``` 36765 * @member {Object} 36766 */ 36767 this.textures = {}; 36768 36769 /** 36770 * A map containing the textures for each animation. 36771 * Can be used to create an {@link PIXI.AnimatedSprite|AnimatedSprite}: 36772 * ```js 36773 * new PIXI.AnimatedSprite(sheet.animations["anim_name"]) 36774 * ``` 36775 * @member {Object} 36776 */ 36777 this.animations = {}; 36778 36779 /** 36780 * Reference to the original JSON data. 36781 * @type {Object} 36782 */ 36783 this.data = data; 36784 36785 /** 36786 * The resolution of the spritesheet. 36787 * @type {number} 36788 */ 36789 this.resolution = this._updateResolution( 36790 resolutionFilename 36791 || (this.baseTexture.resource ? this.baseTexture.resource.url : null) 36792 ); 36793 36794 /** 36795 * Map of spritesheet frames. 36796 * @type {Object} 36797 * @private 36798 */ 36799 this._frames = this.data.frames; 36800 36801 /** 36802 * Collection of frame names. 36803 * @type {string[]} 36804 * @private 36805 */ 36806 this._frameKeys = Object.keys(this._frames); 36807 36808 /** 36809 * Current batch index being processed. 36810 * @type {number} 36811 * @private 36812 */ 36813 this._batchIndex = 0; 36814 36815 /** 36816 * Callback when parse is completed. 36817 * @type {Function} 36818 * @private 36819 */ 36820 this._callback = null; 36821 }; 36822 36823 var staticAccessors$4 = { BATCH_SIZE: { configurable: true } }; 36824 36825 /** 36826 * Generate the resolution from the filename or fallback 36827 * to the meta.scale field of the JSON data. 36828 * 36829 * @private 36830 * @param {string} resolutionFilename - The filename to use for resolving 36831 * the default resolution. 36832 * @return {number} Resolution to use for spritesheet. 36833 */ 36834 staticAccessors$4.BATCH_SIZE.get = function () 36835 { 36836 return 1000; 36837 }; 36838 36839 Spritesheet.prototype._updateResolution = function _updateResolution (resolutionFilename) 36840 { 36841 var scale = this.data.meta.scale; 36842 36843 // Use a defaultValue of `null` to check if a url-based resolution is set 36844 var resolution = getResolutionOfUrl(resolutionFilename, null); 36845 36846 // No resolution found via URL 36847 if (resolution === null) 36848 { 36849 // Use the scale value or default to 1 36850 resolution = scale !== undefined ? parseFloat(scale) : 1; 36851 } 36852 36853 // For non-1 resolutions, update baseTexture 36854 if (resolution !== 1) 36855 { 36856 this.baseTexture.setResolution(resolution); 36857 } 36858 36859 return resolution; 36860 }; 36861 36862 /** 36863 * Parser spritesheet from loaded data. This is done asynchronously 36864 * to prevent creating too many Texture within a single process. 36865 * 36866 * @param {Function} callback - Callback when complete returns 36867 * a map of the Textures for this spritesheet. 36868 */ 36869 Spritesheet.prototype.parse = function parse (callback) 36870 { 36871 this._batchIndex = 0; 36872 this._callback = callback; 36873 36874 if (this._frameKeys.length <= Spritesheet.BATCH_SIZE) 36875 { 36876 this._processFrames(0); 36877 this._processAnimations(); 36878 this._parseComplete(); 36879 } 36880 else 36881 { 36882 this._nextBatch(); 36883 } 36884 }; 36885 36886 /** 36887 * Process a batch of frames 36888 * 36889 * @private 36890 * @param {number} initialFrameIndex - The index of frame to start. 36891 */ 36892 Spritesheet.prototype._processFrames = function _processFrames (initialFrameIndex) 36893 { 36894 var frameIndex = initialFrameIndex; 36895 var maxFrames = Spritesheet.BATCH_SIZE; 36896 36897 while (frameIndex - initialFrameIndex < maxFrames && frameIndex < this._frameKeys.length) 36898 { 36899 var i = this._frameKeys[frameIndex]; 36900 var data = this._frames[i]; 36901 var rect = data.frame; 36902 36903 if (rect) 36904 { 36905 var frame = null; 36906 var trim = null; 36907 var sourceSize = data.trimmed !== false && data.sourceSize 36908 ? data.sourceSize : data.frame; 36909 36910 var orig = new Rectangle( 36911 0, 36912 0, 36913 Math.floor(sourceSize.w) / this.resolution, 36914 Math.floor(sourceSize.h) / this.resolution 36915 ); 36916 36917 if (data.rotated) 36918 { 36919 frame = new Rectangle( 36920 Math.floor(rect.x) / this.resolution, 36921 Math.floor(rect.y) / this.resolution, 36922 Math.floor(rect.h) / this.resolution, 36923 Math.floor(rect.w) / this.resolution 36924 ); 36925 } 36926 else 36927 { 36928 frame = new Rectangle( 36929 Math.floor(rect.x) / this.resolution, 36930 Math.floor(rect.y) / this.resolution, 36931 Math.floor(rect.w) / this.resolution, 36932 Math.floor(rect.h) / this.resolution 36933 ); 36934 } 36935 36936 // Check to see if the sprite is trimmed 36937 if (data.trimmed !== false && data.spriteSourceSize) 36938 { 36939 trim = new Rectangle( 36940 Math.floor(data.spriteSourceSize.x) / this.resolution, 36941 Math.floor(data.spriteSourceSize.y) / this.resolution, 36942 Math.floor(rect.w) / this.resolution, 36943 Math.floor(rect.h) / this.resolution 36944 ); 36945 } 36946 36947 this.textures[i] = new Texture( 36948 this.baseTexture, 36949 frame, 36950 orig, 36951 trim, 36952 data.rotated ? 2 : 0, 36953 data.anchor 36954 ); 36955 36956 // lets also add the frame to pixi's global cache for fromFrame and fromImage functions 36957 Texture.addToCache(this.textures[i], i); 36958 } 36959 36960 frameIndex++; 36961 } 36962 }; 36963 36964 /** 36965 * Parse animations config 36966 * 36967 * @private 36968 */ 36969 Spritesheet.prototype._processAnimations = function _processAnimations () 36970 { 36971 var animations = this.data.animations || {}; 36972 36973 for (var animName in animations) 36974 { 36975 this.animations[animName] = []; 36976 for (var i = 0; i < animations[animName].length; i++) 36977 { 36978 var frameName = animations[animName][i]; 36979 36980 this.animations[animName].push(this.textures[frameName]); 36981 } 36982 } 36983 }; 36984 36985 /** 36986 * The parse has completed. 36987 * 36988 * @private 36989 */ 36990 Spritesheet.prototype._parseComplete = function _parseComplete () 36991 { 36992 var callback = this._callback; 36993 36994 this._callback = null; 36995 this._batchIndex = 0; 36996 callback.call(this, this.textures); 36997 }; 36998 36999 /** 37000 * Begin the next batch of textures. 37001 * 37002 * @private 37003 */ 37004 Spritesheet.prototype._nextBatch = function _nextBatch () 37005 { 37006 var this$1 = this; 37007 37008 this._processFrames(this._batchIndex * Spritesheet.BATCH_SIZE); 37009 this._batchIndex++; 37010 setTimeout(function () { 37011 if (this$1._batchIndex * Spritesheet.BATCH_SIZE < this$1._frameKeys.length) 37012 { 37013 this$1._nextBatch(); 37014 } 37015 else 37016 { 37017 this$1._processAnimations(); 37018 this$1._parseComplete(); 37019 } 37020 }, 0); 37021 }; 37022 37023 /** 37024 * Destroy Spritesheet and don't use after this. 37025 * 37026 * @param {boolean} [destroyBase=false] Whether to destroy the base texture as well 37027 */ 37028 Spritesheet.prototype.destroy = function destroy (destroyBase) 37029 { 37030 if ( destroyBase === void 0 ) { destroyBase = false; } 37031 37032 for (var i in this.textures) 37033 { 37034 this.textures[i].destroy(); 37035 } 37036 this._frames = null; 37037 this._frameKeys = null; 37038 this.data = null; 37039 this.textures = null; 37040 if (destroyBase) 37041 { 37042 this.baseTexture.destroy(); 37043 } 37044 this.baseTexture = null; 37045 }; 37046 37047 Object.defineProperties( Spritesheet, staticAccessors$4 ); 37048 37049 /** 37050 * {@link PIXI.Loader Loader} middleware for loading texture atlases that have been created with 37051 * TexturePacker or similar JSON-based spritesheet. 37052 * 37053 * This middleware automatically generates Texture resources. 37054 * 37055 * @class 37056 * @memberof PIXI 37057 * @implements PIXI.ILoaderPlugin 37058 */ 37059 var SpritesheetLoader = function SpritesheetLoader () {}; 37060 37061 SpritesheetLoader.use = function use (resource, next) 37062 { 37063 var imageResourceName = (resource.name) + "_image"; 37064 37065 // skip if no data, its not json, it isn't spritesheet data, or the image resource already exists 37066 if (!resource.data 37067 || resource.type !== LoaderResource.TYPE.JSON 37068 || !resource.data.frames 37069 || this.resources[imageResourceName] 37070 ) 37071 { 37072 next(); 37073 37074 return; 37075 } 37076 37077 var loadOptions = { 37078 crossOrigin: resource.crossOrigin, 37079 metadata: resource.metadata.imageMetadata, 37080 parentResource: resource, 37081 }; 37082 37083 var resourcePath = SpritesheetLoader.getResourcePath(resource, this.baseUrl); 37084 37085 // load the image for this sheet 37086 this.add(imageResourceName, resourcePath, loadOptions, function onImageLoad(res) 37087 { 37088 if (res.error) 37089 { 37090 next(res.error); 37091 37092 return; 37093 } 37094 37095 var spritesheet = new Spritesheet( 37096 res.texture.baseTexture, 37097 resource.data, 37098 resource.url 37099 ); 37100 37101 spritesheet.parse(function () { 37102 resource.spritesheet = spritesheet; 37103 resource.textures = spritesheet.textures; 37104 next(); 37105 }); 37106 }); 37107 }; 37108 37109 /** 37110 * Get the spritesheets root path 37111 * @param {PIXI.LoaderResource} resource - Resource to check path 37112 * @param {string} baseUrl - Base root url 37113 */ 37114 SpritesheetLoader.getResourcePath = function getResourcePath (resource, baseUrl) 37115 { 37116 // Prepend url path unless the resource image is a data url 37117 if (resource.isDataUrl) 37118 { 37119 return resource.data.meta.image; 37120 } 37121 37122 return url.resolve(resource.url.replace(baseUrl, ''), resource.data.meta.image); 37123 }; 37124 37125 /*! 37126 * @pixi/sprite-tiling - v5.0.0-rc.3 37127 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 37128 * 37129 * @pixi/sprite-tiling is licensed under the MIT License. 37130 * http://www.opensource.org/licenses/mit-license 37131 */ 37132 37133 var tempPoint$1 = new Point(); 37134 37135 /** 37136 * A tiling sprite is a fast way of rendering a tiling image 37137 * 37138 * @class 37139 * @extends PIXI.Sprite 37140 * @memberof PIXI 37141 */ 37142 var TilingSprite = /*@__PURE__*/(function (Sprite) { 37143 function TilingSprite(texture, width, height) 37144 { 37145 if ( width === void 0 ) { width = 100; } 37146 if ( height === void 0 ) { height = 100; } 37147 37148 Sprite.call(this, texture); 37149 37150 /** 37151 * Tile transform 37152 * 37153 * @member {PIXI.Transform} 37154 */ 37155 this.tileTransform = new Transform(); 37156 37157 // /// private 37158 37159 /** 37160 * The with of the tiling sprite 37161 * 37162 * @member {number} 37163 * @private 37164 */ 37165 this._width = width; 37166 37167 /** 37168 * The height of the tiling sprite 37169 * 37170 * @member {number} 37171 * @private 37172 */ 37173 this._height = height; 37174 37175 /** 37176 * Canvas pattern 37177 * 37178 * @type {CanvasPattern} 37179 * @private 37180 */ 37181 this._canvasPattern = null; 37182 37183 /** 37184 * matrix that is applied to UV to get the coords in Texture normalized space to coords in BaseTexture space 37185 * 37186 * @member {PIXI.TextureMatrix} 37187 */ 37188 this.uvMatrix = texture.uvMatrix || new TextureMatrix(texture); 37189 37190 /** 37191 * Plugin that is responsible for rendering this element. 37192 * Allows to customize the rendering process without overriding '_render' method. 37193 * 37194 * @member {string} 37195 * @default 'tilingSprite' 37196 */ 37197 this.pluginName = 'tilingSprite'; 37198 37199 /** 37200 * Whether or not anchor affects uvs 37201 * 37202 * @member {boolean} 37203 * @default false 37204 */ 37205 this.uvRespectAnchor = false;
vendor: 2,021 bytes, lines 37206-37273
37206 } 37207 37208 if ( Sprite ) { TilingSprite.__proto__ = Sprite; } 37209 TilingSprite.prototype = Object.create( Sprite && Sprite.prototype ); 37210 TilingSprite.prototype.constructor = TilingSprite; 37211 37212 var prototypeAccessors = { clampMargin: { configurable: true },tileScale: { configurable: true },tilePosition: { configurable: true },width: { configurable: true },height: { configurable: true } }; 37213 /** 37214 * Changes frame clamping in corresponding textureTransform, shortcut 37215 * Change to -0.5 to add a pixel to the edge, recommended for transparent trimmed textures in atlas 37216 * 37217 * @default 0.5 37218 * @member {number} 37219 */ 37220 prototypeAccessors.clampMargin.get = function () 37221 { 37222 return this.uvMatrix.clampMargin; 37223 }; 37224 37225 prototypeAccessors.clampMargin.set = function (value) // eslint-disable-line require-jsdoc 37226 { 37227 this.uvMatrix.clampMargin = value; 37228 this.uvMatrix.update(true); 37229 }; 37230 37231 /** 37232 * The scaling of the image that is being tiled 37233 * 37234 * @member {PIXI.ObservablePoint} 37235 */ 37236 prototypeAccessors.tileScale.get = function () 37237 { 37238 return this.tileTransform.scale; 37239 }; 37240 37241 prototypeAccessors.tileScale.set = function (value) // eslint-disable-line require-jsdoc 37242 { 37243 this.tileTransform.scale.copyFrom(value); 37244 }; 37245 37246 /** 37247 * The offset of the image that is being tiled 37248 * 37249 * @member {PIXI.ObservablePoint} 37250 */ 37251 prototypeAccessors.tilePosition.get = function () 37252 { 37253 return this.tileTransform.position; 37254 }; 37255 37256 prototypeAccessors.tilePosition.set = function (value) // eslint-disable-line require-jsdoc 37257 { 37258 this.tileTransform.position.copyFrom(value); 37259 }; 37260 37261 /** 37262 * @private 37263 */ 37264 TilingSprite.prototype._onTextureUpdate = function _onTextureUpdate () 37265 { 37266 if (this.uvMatrix) 37267 { 37268 this.uvMatrix.texture = this._texture; 37269 } 37270 this.cachedTint = 0xFFFFFF; 37271 }; 37272 37273 /**
37274 * Renders the object using the WebGL renderer 37275 * 37276 * @protected 37277 * @param {PIXI.Renderer} renderer - The renderer 37278 */ 37279 TilingSprite.prototype._render = function _render (renderer) 37280 { 37281 // tweak our texture temporarily.. 37282 var texture = this._texture; 37283 37284 if (!texture || !texture.valid) 37285 { 37286 return; 37287 } 37288 37289 this.tileTransform.updateLocalTransform(); 37290 this.uvMatrix.update(); 37291 37292 renderer.batch.setObjectRenderer(renderer.plugins[this.pluginName]); 37293 renderer.plugins[this.pluginName].render(this); 37294 }; 37295 37296 /** 37297 * Updates the bounds of the tiling sprite. 37298 * 37299 * @protected 37300 */ 37301 TilingSprite.prototype._calculateBounds = function _calculateBounds () 37302 { 37303 var minX = this._width * -this._anchor._x; 37304 var minY = this._height * -this._anchor._y; 37305 var maxX = this._width * (1 - this._anchor._x); 37306 var maxY = this._height * (1 - this._anchor._y); 37307 37308 this._bounds.addFrame(this.transform, minX, minY, maxX, maxY); 37309 }; 37310 37311 /** 37312 * Gets the local bounds of the sprite object. 37313 * 37314 * @param {PIXI.Rectangle} rect - The output rectangle. 37315 * @return {PIXI.Rectangle} The bounds. 37316 */ 37317 TilingSprite.prototype.getLocalBounds = function getLocalBounds (rect) 37318 { 37319 // we can do a fast local bounds if the sprite has no children! 37320 if (this.children.length === 0) 37321 { 37322 this._bounds.minX = this._width * -this._anchor._x; 37323 this._bounds.minY = this._height * -this._anchor._y; 37324 this._bounds.maxX = this._width * (1 - this._anchor._x); 37325 this._bounds.maxY = this._height * (1 - this._anchor._y); 37326 37327 if (!rect) 37328 { 37329 if (!this._localBoundsRect) 37330 { 37331 this._localBoundsRect = new Rectangle(); 37332 } 37333 37334 rect = this._localBoundsRect; 37335 } 37336 37337 return this._bounds.getRectangle(rect); 37338 } 37339 37340 return Sprite.prototype.getLocalBounds.call(this, rect); 37341 }; 37342 37343 /** 37344 * Checks if a point is inside this tiling sprite. 37345 * 37346 * @param {PIXI.Point} point - the point to check 37347 * @return {boolean} Whether or not the sprite contains the point. 37348 */ 37349 TilingSprite.prototype.containsPoint = function containsPoint (point) 37350 { 37351 this.worldTransform.applyInverse(point, tempPoint$1); 37352 37353 var width = this._width; 37354 var height = this._height; 37355 var x1 = -width * this.anchor._x; 37356 37357 if (tempPoint$1.x >= x1 && tempPoint$1.x < x1 + width) 37358 { 37359 var y1 = -height * this.anchor._y; 37360 37361 if (tempPoint$1.y >= y1 && tempPoint$1.y < y1 + height) 37362 { 37363 return true; 37364 } 37365 } 37366 37367 return false; 37368 }; 37369 37370 /** 37371 * Destroys this sprite and optionally its texture and children 37372 * 37373 * @param {object|boolean} [options] - Options parameter. A boolean will act as if all options 37374 * have been set to that value 37375 * @param {boolean} [options.children=false] - if set to true, all the children will have their destroy 37376 * method called as well. 'options' will be passed on to those calls. 37377 * @param {boolean} [options.texture=false] - Should it destroy the current texture of the sprite as well 37378 * @param {boolean} [options.baseTexture=false] - Should it destroy the base texture of the sprite as well 37379 */ 37380 TilingSprite.prototype.destroy = function destroy (options) 37381 { 37382 Sprite.prototype.destroy.call(this, options); 37383 37384 this.tileTransform = null; 37385 this.uvMatrix = null; 37386 }; 37387 37388 /** 37389 * Helper function that creates a new tiling sprite based on the source you provide. 37390 * The source can be - frame id, image url, video url, canvas element, video element, base texture 37391 * 37392 * @static 37393 * @param {number|string|PIXI.Texture|HTMLCanvasElement|HTMLVideoElement} source - Source to create texture from 37394 * @param {number} width - the width of the tiling sprite 37395 * @param {number} height - the height of the tiling sprite 37396 * @return {PIXI.TilingSprite} The newly created texture 37397 */ 37398 TilingSprite.from = function from (source, width, height) 37399 { 37400 return new TilingSprite(Texture.from(source), width, height); 37401 }; 37402 37403 /** 37404 * Helper function that creates a tiling sprite that will use a texture from the TextureCache based on the frameId 37405 * The frame ids are created when a Texture packer file has been loaded 37406 * 37407 * @static 37408 * @param {string} frameId - The frame Id of the texture in the cache 37409 * @param {number} width - the width of the tiling sprite 37410 * @param {number} height - the height of the tiling sprite 37411 * @return {PIXI.TilingSprite} A new TilingSprite using a texture from the texture cache matching the frameId 37412 */ 37413 TilingSprite.fromFrame = function fromFrame (frameId, width, height) 37414 { 37415 var texture = TextureCache[frameId]; 37416 37417 if (!texture) 37418 { 37419 throw new Error(("The frameId \"" + frameId + "\" does not exist in the texture cache " + (this))); 37420 } 37421 37422 return new TilingSprite(texture, width, height); 37423 }; 37424 37425 /** 37426 * Helper function that creates a sprite that will contain a texture based on an image url 37427 * If the image is not in the texture cache it will be loaded 37428 * 37429 * @static 37430 * @param {string} imageId - The image url of the texture 37431 * @param {number} width - the width of the tiling sprite 37432 * @param {number} height - the height of the tiling sprite 37433 * @param {Object} [options] - See {@link PIXI.BaseTexture}'s constructor for options. 37434 * @return {PIXI.TilingSprite} A new TilingSprite using a texture from the texture cache matching the image id 37435 */ 37436 TilingSprite.fromImage = function fromImage (imageId, width, height, options) 37437 { 37438 // Fallback support for crossorigin, scaleMode parameters 37439 if (options && typeof options !== 'object') 37440 { 37441 options = { 37442 scaleMode: arguments[4], 37443 resourceOptions: { 37444 crossorigin: arguments[3], 37445 }, 37446 }; 37447 } 37448 37449 return new TilingSprite(Texture.from(imageId, options), width, height); 37450 }; 37451 37452 /** 37453 * The width of the sprite, setting this will actually modify the scale to achieve the value set 37454 * 37455 * @member {number} 37456 */ 37457 prototypeAccessors.width.get = function () 37458 { 37459 return this._width; 37460 }; 37461 37462 prototypeAccessors.width.set = function (value) // eslint-disable-line require-jsdoc 37463 { 37464 this._width = value; 37465 }; 37466 37467 /** 37468 * The height of the TilingSprite, setting this will actually modify the scale to achieve the value set 37469 * 37470 * @member {number} 37471 */ 37472 prototypeAccessors.height.get = function () 37473 { 37474 return this._height; 37475 }; 37476 37477 prototypeAccessors.height.set = function (value) // eslint-disable-line require-jsdoc 37478 { 37479 this._height = value; 37480 }; 37481 37482 Object.defineProperties( TilingSprite.prototype, prototypeAccessors ); 37483 37484 return TilingSprite; 37485 }(Sprite)); 37486 37487 var vertex$3 = "attribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\n\nuniform mat3 projectionMatrix;\nuniform mat3 translationMatrix;\nuniform mat3 uTransform;\n\nvarying vec2 vTextureCoord;\n\nvoid main(void)\n{\n gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0
37487)).xy, 0.0, 1.0);\n\n vTextureCoord = (uTransform * vec3(aTextureCoord, 1.0)).xy;\n}\n"; 37488 37489 var fragment$2 = "varying vec2 vTextureCoord;\n\nuniform sampler2D uSampler;\nuniform vec4 uColor;\nuniform mat3 uMapCoord;\nuniform vec4 uClampFrame;\nuniform vec2 uClampOffset;\n\nvoid main(void)\n{\n vec2 coord = mod(vTextureCoord - uClampOffset, vec2(1.0, 1.0)) + uClampOffset;\n coord = (uMapCoord * vec3(coord, 1.0)).xy;\n coord = clamp(coord, uClampFrame.xy, uClampFrame.zw);\n\n vec4 sample = texture2D(uSampler, coord);\n gl_FragColor = sample * uColor;\n}\n"; 37490 37491 var fragmentSimple = "varying vec2 vTextureCoord;\n\nuniform sampler2D uSampler;\nuniform vec4 uColor;\n\nvoid main(void)\n{\n vec4 sample = texture2D(uSampler, vTextureCoord);\n gl_FragColor = sample * uColor;\n}\n"; 37492 37493 var tempMat$1 = new Matrix(); 37494 37495 /** 37496 * WebGL renderer plugin for tiling sprites 37497 * 37498 * @class 37499 * @memberof PIXI 37500 * @extends PIXI.ObjectRenderer 37501 */ 37502 var TilingSpriteRenderer = /*@__PURE__*/(function (ObjectRenderer) { 37503 function TilingSpriteRenderer(renderer) 37504 { 37505 ObjectRenderer.call(this, renderer); 37506 37507 var uniforms = { globals: this.renderer.globalUniforms }; 37508 37509 this.shader = Shader.from(vertex$3, fragment$2, uniforms); 37510 37511 this.simpleShader = Shader.from(vertex$3, fragmentSimple, uniforms); 37512 37513 this.quad = new QuadUv(); 37514 } 37515 37516 if ( ObjectRenderer ) { TilingSpriteRenderer.__proto__ = ObjectRenderer; } 37517 TilingSpriteRenderer.prototype = Object.create( ObjectRenderer && ObjectRenderer.prototype ); 37518 TilingSpriteRenderer.prototype.constructor = TilingSpriteRenderer; 37519 37520 /** 37521 * 37522 * @param {PIXI.TilingSprite} ts tilingSprite to be rendered 37523 */ 37524 TilingSpriteRenderer.prototype.render = function render (ts) 37525 { 37526 var renderer = this.renderer; 37527 var quad = this.quad; 37528 37529 var vertices = quad.vertices; 37530 37531 vertices[0] = vertices[6] = (ts._width) * -ts.anchor.x; 37532 vertices[1] = vertices[3] = ts._height * -ts.anchor.y; 37533 37534 vertices[2] = vertices[4] = (ts._width) * (1.0 - ts.anchor.x); 37535 vertices[5] = vertices[7] = ts._height * (1.0 - ts.anchor.y); 37536 37537 if (ts.uvRespectAnchor) 37538 { 37539 vertices = quad.uvs; 37540 37541 vertices[0] = vertices[6] = -ts.anchor.x; 37542 vertices[1] = vertices[3] = -ts.anchor.y; 37543 37544 vertices[2] = vertices[4] = 1.0 - ts.anchor.x; 37545 vertices[5] = vertices[7] = 1.0 - ts.anchor.y; 37546 } 37547 37548 quad.invalidate(); 37549 37550 var tex = ts._texture; 37551 var baseTex = tex.baseTexture; 37552 var lt = ts.tileTransform.localTransform; 37553 var uv = ts.uvMatrix; 37554 var isSimple = baseTex.isPowerOfTwo 37555 && tex.frame.width === baseTex.width && tex.frame.height === baseTex.height; 37556 37557 // auto, force repeat wrapMode for big tiling textures 37558 if (isSimple) 37559 { 37560 if (!baseTex._glTextures[renderer.CONTEXT_UID]) 37561 { 37562 if (baseTex.wrapMode === WRAP_MODES.CLAMP) 37563 { 37564 baseTex.wrapMode = WRAP_MODES.REPEAT; 37565 } 37566 } 37567 else 37568 { 37569 isSimple = baseTex.wrapMode !== WRAP_MODES.CLAMP; 37570 } 37571 } 37572 37573 var shader = isSimple ? this.simpleShader : this.shader; 37574 37575 var w = tex.width; 37576 var h = tex.height; 37577 var W = ts._width; 37578 var H = ts._height; 37579 37580 tempMat$1.set(lt.a * w / W, 37581 lt.b * w / H, 37582 lt.c * h / W, 37583 lt.d * h / H, 37584 lt.tx / W, 37585 lt.ty / H); 37586 37587 // that part is the same as above: 37588 // tempMat.identity(); 37589 // tempMat.scale(tex.width, tex.height); 37590 // tempMat.prepend(lt); 37591 // tempMat.scale(1.0 / ts._width, 1.0 / ts._height); 37592 37593 tempMat$1.invert(); 37594 if (isSimple) 37595 { 37596 tempMat$1.prepend(uv.mapCoord); 37597 } 37598 else 37599 { 37600 shader.uniforms.uMapCoord = uv.mapCoord.toArray(true); 37601 shader.uniforms.uClampFrame = uv.uClampFrame; 37602 shader.uniforms.uClampOffset = uv.uClampOffset; 37603 } 37604 37605 shader.uniforms.uTransform = tempMat$1.toArray(true); 37606 shader.uniforms.uColor = premultiplyTintToRgba(ts.tint, ts.worldAlpha, 37607 shader.uniforms.uColor, baseTex.premultiplyAlpha); 37608 shader.uniforms.translationMatrix = ts.transform.worldTransform.toArray(true); 37609 shader.uniforms.uSampler = tex; 37610 37611 renderer.shader.bind(shader); 37612 renderer.geometry.bind(quad);// , renderer.shader.getGLShader()); 37613 37614 renderer.state.setBlendMode(correctBlendMode(ts.blendMode, baseTex.premultiplyAlpha)); 37615 renderer.geometry.draw(this.renderer.gl.TRIANGLES, 6, 0); 37616 }; 37617 37618 return TilingSpriteRenderer; 37619 }(ObjectRenderer)); 37620 37621 /*! 37622 * @pixi/text-bitmap - v5.0.0-rc.3 37623 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 37624 * 37625 * @pixi/text-bitmap is licensed under the MIT License. 37626 * http://www.opensource.org/licenses/mit-license 37627 */ 37628 37629 /** 37630 * A BitmapText object will create a line or multiple lines of text using bitmap font. 37631 * 37632 * The primary advantage of this class over Text is that all of your textures are pre-generated and loading, 37633 * meaning that rendering is fast, and changing text has no performance implications. 37634 * 37635 * The primary disadvantage is that you need to preload the bitmap font assets, and thus the styling is set in stone. 37636 * Supporting character sets other than latin, such as CJK languages, may be impractical due to the number of characters. 37637 * 37638 * To split a line you can use '\n', '\r' or '\r\n' in your string. 37639 * 37640 * You can generate the fnt files using 37641 * http://www.angelcode.com/products/bmfont/ for Windows or 37642 * http://www.bmglyph.com/ for Mac. 37643 * 37644 * A BitmapText can only be created when the font is loaded. 37645 * 37646 * ```js 37647 * // in this case the font is in a file called 'desyrel.fnt' 37648 * let bitmapText = new PIXI.BitmapText("text using a fancy font!", {font: "35px Desyrel", align: "right"}); 37649 * ``` 37650 * 37651 * @class 37652 * @extends PIXI.Container 37653 * @memberof PIXI 37654 */ 37655 var BitmapText = /*@__PURE__*/(function (Container) { 37656 function BitmapText(text, style) 37657 { 37658 var this$1 = this; 37659 if ( style === void 0 ) { style = {}; } 37660 37661 Container.call(this); 37662 37663 /** 37664 * Private tracker for the width of the overall text 37665 * 37666 * @member {number} 37667 * @private 37668 */ 37669 this._textWidth = 0; 37670 37671 /** 37672 * Private tracker for the height of the overall text 37673 * 37674 * @member {number} 37675 * @private 37676 */ 37677 this._textHeight = 0; 37678 37679 /** 37680 * Private tracker for the letter sprite pool. 37681 * 37682 * @member {PIXI.Sprite[]} 37683 * @private 37684 */ 37685 this._glyphs = []; 37686 37687 /** 37688 * Private tracker for the current style. 37689 * 37690 * @member {object} 37691 * @private 37692 */ 37693 this._font = { 37694 tint: style.tint !== undefined ? style.tint : 0xFFFFFF, 37695 align: style.align || 'left', 37696 name: null, 37697 size: 0, 37698 }; 37699 37700 /** 37701 * Private tracker for the current font. 37702 * 37703 * @member {object} 37704 * @private 37705 */ 37706 this.font = style.font; // run font setter 37707 37708 /** 37709 * Private tracker for the current text. 37710 * 37711 * @member {string} 37712 * @private 37713 */ 37714 this._text = text; 37715 37716 /** 37717 * The max width of this bitmap text in pixels. If the text provided is longer than the 37718 * value provided, line breaks will be automatically inserted in the last whitespace. 37719 * Disable by setting value to 0 37720 * 37721 * @member {number} 37722 * @private 37723 */ 37724 this._maxWidth = 0; 37725 37726 /** 37727 * The max line height. This is useful when trying to use the total height of the Text, 37728 * ie: when trying to vertically align. 37729 * 37730 * @member {number} 37731 * @private 37732 */ 37733 this._maxLineHeight = 0; 37734 37735 /** 37736 * Letter spacing. This is useful for setting the space between characters. 37737 * @member {number} 37738 * @private 37739 */ 37740 this._letterSpacing = 0; 37741 37742 /** 37743 * Text anchor. read-only 37744 *
37745 * @member {PIXI.ObservablePoint} 37746 * @private 37747 */ 37748 this._anchor = new ObservablePoint(function () { this$1.dirty = true; }, this, 0, 0); 37749 37750 /** 37751 * The dirty state of this object. 37752 * 37753 * @member {boolean} 37754 */ 37755 this.dirty = false; 37756 37757 /** 37758 * If true PixiJS will Math.floor() x/y values when rendering, stopping pixel interpolation. 37759 * Advantages can include sharper image quality (like text) and faster rendering on canvas. 37760 * The main disadvantage is movement of objects may appear less smooth. 37761 * To set the global default, change {@link PIXI.settings.ROUND_PIXELS} 37762 * 37763 * @member {boolean} 37764 * @default false 37765 */ 37766 this.roundPixels = settings.ROUND_PIXELS; 37767 37768 this.updateText(); 37769 } 37770 37771 if ( Container ) { BitmapText.__proto__ = Container; } 37772 BitmapText.prototype = Object.create( Container && Container.prototype ); 37773 BitmapText.prototype.constructor = BitmapText; 37774 37775 var prototypeAccessors = { tint: { configurable: true },align: { configurable: true },anchor: { configurable: true },font: { configurable: true },text: { configurable: true },maxWidth: { configurable: true },maxLineHeight: { configurable: true },textWidth: { configurable: true },letterSpacing: { configurable: true },textHeight: { configurable: true } }; 37776 37777 /**
37778 * Renders text and updates it when needed 37779 * 37780 * @private 37781 */ 37782 BitmapText.prototype.updateText = function updateText () 37783 { 37784 var data = BitmapText.fonts[this._font.name]; 37785 var scale = this._font.size / data.size; 37786 var pos = new Point(); 37787 var chars = []; 37788 var lineWidths = []; 37789 var text = this._text.replace(/(?:\r\n|\r)/g, '\n') || ' '; 37790 var textLength = text.length; 37791 var maxWidth = this._maxWidth * data.size / this._font.size; 37792 37793 var prevCharCode = null; 37794 var lastLineWidth = 0; 37795 var maxLineWidth = 0; 37796 var line = 0; 37797 var lastBreakPos = -1; 37798 var lastBreakWidth = 0; 37799 var spacesRemoved = 0; 37800 var maxLineHeight = 0; 37801 37802 for (var i = 0; i < textLength; i++) 37803 { 37804 var charCode = text.charCodeAt(i); 37805 var char = text.charAt(i); 37806 37807 if ((/(?:\s)/).test(char)) 37808 { 37809 lastBreakPos = i; 37810 lastBreakWidth = lastLineWidth; 37811 } 37812 37813 if (char === '\r' || char === '\n') 37814 { 37815 lineWidths.push(lastLineWidth); 37816 maxLineWidth = Math.max(maxLineWidth, lastLineWidth); 37817 ++line; 37818 ++spacesRemoved; 37819 37820 pos.x = 0; 37821 pos.y += data.lineHeight; 37822 prevCharCode = null; 37823 continue; 37824 } 37825 37826 var charData = data.chars[charCode]; 37827 37828 if (!charData) 37829 { 37830 continue; 37831 } 37832 37833 if (prevCharCode && charData.kerning[prevCharCode]) 37834 { 37835 pos.x += charData.kerning[prevCharCode]; 37836 } 37837 37838 chars.push({ 37839 texture: charData.texture, 37840 line: line, 37841 charCode: charCode, 37842 position: new Point(pos.x + charData.xOffset + (this._letterSpacing / 2), pos.y + charData.yOffset), 37843 }); 37844 pos.x += charData.xAdvance + this._letterSpacing; 37845 lastLineWidth = pos.x; 37846 maxLineHeight = Math.max(maxLineHeight, (charData.yOffset + charData.texture.height)); 37847 prevCharCode = charCode; 37848 37849 if (lastBreakPos !== -1 && maxWidth > 0 && pos.x > maxWidth) 37850 { 37851 ++spacesRemoved; 37852 removeItems(chars, 1 + lastBreakPos - spacesRemoved, 1 + i - lastBreakPos); 37853 i = lastBreakPos; 37854 lastBreakPos = -1; 37855 37856 lineWidths.push(lastBreakWidth); 37857 maxLineWidth = Math.max(maxLineWidth, lastBreakWidth); 37858 line++; 37859 37860 pos.x = 0; 37861 pos.y += data.lineHeight; 37862 prevCharCode = null; 37863 } 37864 } 37865 37866 var lastChar = text.charAt(text.length - 1); 37867 37868 if (lastChar !== '\r' && lastChar !== '\n') 37869 { 37870 if ((/(?:\s)/).test(lastChar)) 37871 { 37872 lastLineWidth = lastBreakWidth; 37873 } 37874 37875 lineWidths.push(lastLineWidth); 37876 maxLineWidth = Math.max(maxLineWidth, lastLineWidth); 37877 } 37878 37879 var lineAlignOffsets = []; 37880 37881 for (var i$1 = 0; i$1 <= line; i$1++) 37882 { 37883 var alignOffset = 0; 37884 37885 if (this._font.align === 'right') 37886 { 37887 alignOffset = maxLineWidth - lineWidths[i$1]; 37888 } 37889 else if (this._font.align === 'center') 37890 { 37891 alignOffset = (maxLineWidth - lineWidths[i$1]) / 2; 37892 } 37893 37894 lineAlignOffsets.push(alignOffset); 37895 } 37896 37897 var lenChars = chars.length; 37898 var tint = this.tint; 37899 37900 for (var i$2 = 0; i$2 < lenChars; i$2++) 37901 { 37902 var c = this._glyphs[i$2]; // get the next glyph sprite 37903 37904 if (c) 37905 { 37906 c.texture = chars[i$2].texture; 37907 } 37908 else 37909 { 37910 c = new Sprite(chars[i$2].texture); 37911 c.roundPixels = this.roundPixels; 37912 this._glyphs.push(c); 37913 } 37914 37915 c.position.x = (chars[i$2].position.x + lineAlignOffsets[chars[i$2].line]) * scale; 37916 c.position.y = chars[i$2].position.y * scale; 37917 c.scale.x = c.scale.y = scale; 37918 c.tint = tint; 37919 37920 if (!c.parent) 37921 { 37922 this.addChild(c); 37923 } 37924 } 37925 37926 // remove unnecessary children. 37927 for (var i$3 = lenChars; i$3 < this._glyphs.length; ++i$3) 37928 { 37929 this.removeChild(this._glyphs[i$3]); 37930 } 37931 37932 this._textWidth = maxLineWidth * scale; 37933 this._textHeight = (pos.y + data.lineHeight) * scale; 37934 37935 // apply anchor 37936 if (this.anchor.x !== 0 || this.anchor.y !== 0) 37937 { 37938 for (var i$4 = 0; i$4 < lenChars; i$4++) 37939 { 37940 this._glyphs[i$4].x -= this._textWidth * this.anchor.x; 37941 this._glyphs[i$4].y -= this._textHeight * this.anchor.y; 37942 } 37943 } 37944 this._maxLineHeight = maxLineHeight * scale; 37945 }; 37946 37947 /** 37948 * Updates the transform of this object 37949 * 37950 * @private 37951 */ 37952 BitmapText.prototype.updateTransform = function updateTransform () 37953 { 37954 this.validate(); 37955 this.containerUpdateTransform(); 37956 }; 37957 37958 /** 37959 * Validates text before calling parent's getLocalBounds 37960 * 37961 * @return {PIXI.Rectangle} The rectangular bounding area 37962 */ 37963 BitmapText.prototype.getLocalBounds = function getLocalBounds () 37964 { 37965 this.validate(); 37966 37967 return Container.prototype.getLocalBounds.call(this); 37968 }; 37969 37970 /** 37971 * Updates text when needed 37972 * 37973 * @private 37974 */ 37975 BitmapText.prototype.validate = function validate () 37976 { 37977 if (this.dirty) 37978 { 37979 this.updateText(); 37980 this.dirty = false;
37981 } 37982 }; 37983 37984 /** 37985 * The tint of the BitmapText object. 37986 * 37987 * @member {number} 37988 */ 37989 prototypeAccessors.tint.get = function () 37990 { 37991 return this._font.tint; 37992 }; 37993 37994 prototypeAccessors.tint.set = function (value) // eslint-disable-line require-jsdoc 37995 { 37996 this._font.tint = (typeof value === 'number' && value >= 0) ? value : 0xFFFFFF; 37997 37998 this.dirty = true; 37999 }; 38000 38001 /** 38002 * The alignment of the BitmapText object. 38003 * 38004 * @member {string} 38005 * @default 'left' 38006 */ 38007 prototypeAccessors.align.get = function () 38008 { 38009 return this._font.align; 38010 }; 38011 38012 prototypeAccessors.align.set = function (value) // eslint-disable-line require-jsdoc 38013 { 38014 this._font.align = value || 'left'; 38015 38016 this.dirty = true; 38017 }; 38018 38019 /** 38020 * The anchor sets the origin point of the text. 38021 * 38022 * The default is `(0,0)`, this means the text's origin is the top left. 38023 * 38024 * Setting the anchor to `(0.5,0.5)` means the text's origin is centered. 38025 * 38026 * Setting the anchor to `(1,1)` would mean the text's origin point will be the bottom right corner. 38027 * 38028 * @member {PIXI.Point | number} 38029 */ 38030 prototypeAccessors.anchor.get = function () 38031 { 38032 return this._anchor; 38033 }; 38034 38035 prototypeAccessors.anchor.set = function (value) // eslint-disable-line require-jsdoc 38036 { 38037 if (typeof value === 'number') 38038 { 38039 this._anchor.set(value); 38040 } 38041 else 38042 { 38043 this._anchor.copyFrom(value); 38044 } 38045 }; 38046 38047 /** 38048 * The font descriptor of the BitmapText object. 38049 * 38050 * @member {object} 38051 */ 38052 prototypeAccessors.font.get = function () 38053 { 38054 return this._font; 38055 }; 38056 38057 prototypeAccessors.font.set = function (value) // eslint-disable-line require-jsdoc 38058 { 38059 if (!value) 38060 { 38061 return; 38062 } 38063 38064 if (typeof value === 'string') 38065 { 38066 value = value.split(' '); 38067 38068 this._font.name = value.length === 1 ? value[0] : value.slice(1).join(' '); 38069 this._font.size = value.length >= 2 ? parseInt(value[0], 10) : BitmapText.fonts[this._font.name].size; 38070 } 38071 else 38072 { 38073 this._font.name = value.name; 38074 this._font.size = typeof value.size === 'number' ? value.size : parseInt(value.size, 10); 38075 } 38076 38077 this.dirty = true; 38078 }; 38079 38080 /** 38081 * The text of the BitmapText object. 38082 * 38083 * @member {string} 38084 */ 38085 prototypeAccessors.text.get = function () 38086 { 38087 return this._text; 38088 }; 38089 38090 prototypeAccessors.text.set = function (text) // eslint-disable-line require-jsdoc 38091 { 38092 text = String(text === null || text === undefined ? '' : text); 38093 38094 if (this._text === text) 38095 { 38096 return; 38097 } 38098 this._text = text; 38099 this.dirty = true; 38100 }; 38101 38102 /** 38103 * The max width of this bitmap text in pixels. If the text provided is longer than the 38104 * value provided, line breaks will be automatically inserted in the last whitespace. 38105 * Disable by setting the value to 0. 38106 * 38107 * @member {number} 38108 */ 38109 prototypeAccessors.maxWidth.get = function () 38110 { 38111 return this._maxWidth; 38112 }; 38113 38114 prototypeAccessors.maxWidth.set = function (value) // eslint-disable-line require-jsdoc 38115 { 38116 if (this._maxWidth === value) 38117 { 38118 return; 38119 } 38120 this._maxWidth = value; 38121 this.dirty = true; 38122 }; 38123 38124 /** 38125 * The max line height. This is useful when trying to use the total height of the Text, 38126 * i.e. when trying to vertically align. 38127 * 38128 * @member {number} 38129 * @readonly 38130 */ 38131 prototypeAccessors.maxLineHeight.get = function () 38132 { 38133 this.validate(); 38134 38135 return this._maxLineHeight; 38136 }; 38137 38138 /** 38139 * The width of the overall text, different from fontSize, 38140 * which is defined in the style object. 38141 * 38142 * @member {number} 38143 * @readonly 38144 */ 38145 prototypeAccessors.textWidth.get = function () 38146 { 38147 this.validate(); 38148 38149 return this._textWidth; 38150 }; 38151 38152 /** 38153 * Additional space between characters. 38154 * 38155 * @member {number} 38156 */ 38157 prototypeAccessors.letterSpacing.get = function () 38158 { 38159 return this._letterSpacing; 38160 }; 38161 38162 prototypeAccessors.letterSpacing.set = function (value) // eslint-disable-line require-jsdoc 38163 { 38164 if (this._letterSpacing !== value) 38165 { 38166 this._letterSpacing = value; 38167 this.dirty = true; 38168 } 38169 }; 38170 38171 /** 38172 * The height of the overall text, different from fontSize, 38173 * which is defined in the style object. 38174 * 38175 * @member {number} 38176 * @readonly 38177 */ 38178 prototypeAccessors.textHeight.get = function () 38179 { 38180 this.validate(); 38181 38182 return this._textHeight; 38183 }; 38184 38185 /** 38186 * Register a bitmap font with data and a texture. 38187 * 38188 * @static 38189 * @param {XMLDocument} xml - The XML document data. 38190 * @param {Object.<string, PIXI.Texture>|PIXI.Texture|PIXI.Texture[]} textures - List of textures for each page. 38191 * If providing an object, the key is the `<page>` element's `file` attribute in the FNT file. 38192 * @return {Object} Result font object with font, size, lineHeight and char fields. 38193 */ 38194 BitmapText.registerFont = function registerFont (xml, textures) 38195 { 38196 var data = {}; 38197 var info = xml.getElementsByTagName('info')[0]; 38198 var common = xml.getElementsByTagName('common')[0]; 38199 var pages = xml.getElementsByTagName('page'); 38200 var res = getResolutionOfUrl(pages[0].getAttribute('file'), settings.RESOLUTION); 38201 var pagesTextures = {}; 38202 38203 data.font = info.getAttribute('face'); 38204 data.size = parseInt(info.getAttribute('size'), 10); 38205 data.lineHeight = parseInt(common.getAttribute('lineHeight'), 10) / res; 38206 data.chars = {}; 38207 38208 // Single texture, convert to list 38209 if (textures instanceof Texture) 38210 { 38211 textures = [textures]; 38212 } 38213 38214 // Convert the input Texture, Textures or object 38215 // into a page Texture lookup by "id" 38216 for (var i = 0; i < pages.length; i++) 38217 { 38218 var id = pages[i].getAttribute('id'); 38219 var file = pages[i].getAttribute('file'); 38220 38221 pagesTextures[id] = textures instanceof Array ? textures[i] : textures[file]; 38222 } 38223 38224 // parse letters 38225 var letters = xml.getElementsByTagName('char'); 38226 38227 for (var i$1 = 0; i$1 < letters.length; i$1++) 38228 { 38229 var letter = letters[i$1];
38230 var charCode = parseInt(letter.getAttribute('id'), 10); 38231 var page = letter.getAttribute('page') || 0; 38232 var textureRect = new Rectangle( 38233 (parseInt(letter.getAttribute('x'), 10) / res) + (pagesTextures[page].frame.x / res), 38234 (parseInt(letter.getAttribute('y'), 10) / res) + (pagesTextures[page].frame.y / res), 38235 parseInt(letter.getAttribute('width'), 10) / res, 38236 parseInt(letter.getAttribute('height'), 10) / res 38237 ); 38238 38239 data.chars[charCode] = { 38240 xOffset: parseInt(letter.getAttribute('xoffset'), 10) / res, 38241 yOffset: parseInt(letter.getAttribute('yoffset'), 10) / res, 38242 xAdvance: parseInt(letter.getAttribute('xadvance'), 10) / res, 38243 kerning: {}, 38244 texture: new Texture(pagesTextures[page].baseTexture, textureRect), 38245 page: page, 38246 }; 38247 } 38248 38249 // parse kernings 38250 var kernings = xml.getElementsByTagName('kerning'); 38251 38252 for (var i$2 = 0; i$2 < kernings.length; i$2++) 38253 { 38254 var kerning = kernings[i$2]; 38255 var first = parseInt(kerning.getAttribute('first'), 10) / res; 38256 var second = parseInt(kerning.getAttribute('second'), 10) / res; 38257 var amount = parseInt(kerning.getAttribute('amount'), 10) / res; 38258 38259 if (data.chars[second]) 38260 { 38261 data.chars[second].kerning[first] = amount; 38262 } 38263 } 38264 38265 // I'm leaving this as a temporary fix so we can test the bitmap fonts in v3 38266 // but it's very likely to change 38267 BitmapText.fonts[data.font] = data; 38268 38269 return data; 38270 }; 38271 38272 Object.defineProperties( BitmapText.prototype, prototypeAccessors ); 38273 38274 return BitmapText; 38275 }(Container)); 38276 38277 BitmapText.fonts = {}; 38278 38279 /** 38280 * {@link PIXI.Loader Loader} middleware for loading 38281 * bitmap-based fonts suitable for using with {@link PIXI.BitmapText}. 38282 * @class 38283 * @memberof PIXI 38284 * @implements PIXI.ILoaderPlugin 38285 */ 38286 var BitmapFontLoader = function BitmapFontLoader () {}; 38287 38288 BitmapFontLoader.parse = function parse (resource, texture) 38289 { 38290 resource.bitmapFont = BitmapText.registerFont(resource.data, texture); 38291 }; 38292 38293 /** 38294 * Called when the plugin is installed. 38295 * 38296 * @see PIXI.Loader.registerPlugin 38297 */ 38298 BitmapFontLoader.add = function add () 38299 { 38300 LoaderResource.setExtensionXhrType('fnt', LoaderResource.XHR_RESPONSE_TYPE.DOCUMENT); 38301 }; 38302 38303 /** 38304 * Replacement for NodeJS's path.dirname 38305 * @private 38306 * @param {string} url Path to get directory for 38307 */ 38308 BitmapFontLoader.dirname = function dirname (url) 38309 { 38310 var dir = url 38311 .replace(/\/$/, '') // replace trailing slash 38312 .replace(/\/[^\/]*$/, ''); // remove everything after the last 38313 38314 // File request is relative, use current directory 38315 if (dir === url) 38316 { 38317 return '.'; 38318 } 38319 // Started with a slash 38320 else if (dir === '') 38321 { 38322 return '/'; 38323 } 38324 38325 return dir; 38326 }; 38327 38328 /** 38329 * Called after a resource is loaded. 38330 * @see PIXI.Loader.loaderMiddleware 38331 * @param {PIXI.LoaderResource} resource 38332 * @param {function} next 38333 */ 38334 BitmapFontLoader.use = function use (resource, next) 38335 { 38336 // skip if no data or not xml data 38337 if (!resource.data || resource.type !== LoaderResource.TYPE.XML) 38338 { 38339 next(); 38340 38341 return; 38342 } 38343 38344 // skip if not bitmap font data, using some silly duck-typing 38345 if (resource.data.getElementsByTagName('page').length === 0 38346 || resource.data.getElementsByTagName('info').length === 0 38347 || resource.data.getElementsByTagName('info')[0].getAttribute('face') === null 38348 ) 38349 { 38350 next(); 38351 38352 return; 38353 } 38354 38355 var xmlUrl = !resource.isDataUrl ? BitmapFontLoader.dirname(resource.url) : ''; 38356 38357 if (resource.isDataUrl) 38358 { 38359 if (xmlUrl === '.') 38360 { 38361 xmlUrl = ''; 38362 } 38363 38364 if (this.baseUrl && xmlUrl) 38365 { 38366 // if baseurl has a trailing slash then add one to xmlUrl so the replace works below 38367 if (this.baseUrl.charAt(this.baseUrl.length - 1) === '/') 38368 { 38369 xmlUrl += '/'; 38370 } 38371 } 38372 } 38373 38374 // remove baseUrl from xmlUrl 38375 xmlUrl = xmlUrl.replace(this.baseUrl, ''); 38376 38377 // if there is an xmlUrl now, it needs a trailing slash. Ensure that it does if the string isn't empty. 38378 if (xmlUrl && xmlUrl.charAt(xmlUrl.length - 1) !== '/') 38379 { 38380 xmlUrl += '/'; 38381 } 38382 38383 var pages = resource.data.getElementsByTagName('page'); 38384 var textures = {}; 38385 38386 // Handle completed, when the number of textures 38387 // load is the same number as references in the fnt file 38388 var completed = function (page) { 38389 textures[page.metadata.pageFile] = page.texture; 38390 38391 if (Object.keys(textures).length === pages.length) 38392 { 38393 BitmapFontLoader.parse(resource, textures); 38394 next(); 38395 } 38396 }; 38397 38398 for (var i = 0; i < pages.length; ++i) 38399 { 38400 var pageFile = pages[i].getAttribute('file'); 38401 var url = xmlUrl + pageFile; 38402 var exists = false;
38403 38404 // incase the image is loaded outside 38405 // using the same loader, resource will be available 38406 for (var name in this.resources) 38407 { 38408 var bitmapResource = this.resources[name]; 38409 38410 if (bitmapResource.url === url) 38411 { 38412 bitmapResource.metadata.pageFile = pageFile; 38413 if (bitmapResource.texture) 38414 { 38415 completed(bitmapResource); 38416 } 38417 else 38418 { 38419 bitmapResource.onAfterMiddleware.add(completed); 38420 } 38421 exists = true; 38422 break; 38423 } 38424 } 38425 38426 // texture is not loaded, we'll attempt to add 38427 // it to the load and add the texture to the list 38428 if (!exists) 38429 { 38430 // Standard loading options for images 38431 var options = { 38432 crossOrigin: resource.crossOrigin, 38433 loadType: LoaderResource.LOAD_TYPE.IMAGE, 38434 metadata: Object.assign( 38435 { pageFile: pageFile }, 38436 resource.metadata.imageMetadata 38437 ), 38438 parentResource: resource, 38439 }; 38440 38441 this.add(url, options, completed); 38442 } 38443 } 38444 }; 38445 38446 /*! 38447 * @pixi/filter-alpha - v5.0.0-rc.3 38448 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 38449 * 38450 * @pixi/filter-alpha is licensed under the MIT License. 38451 * http://www.opensource.org/licenses/mit-license 38452 */ 38453 38454 var fragment$3 = "varying vec2 vTextureCoord;\n\nuniform sampler2D uSampler;\nuniform float uAlpha;\n\nvoid main(void)\n{\n gl_FragColor = texture2D(uSampler, vTextureCoord) * uAlpha;\n}\n"; 38455 38456 /** 38457 * Simplest filter - applies alpha. 38458 * 38459 * Use this instead of Container's alpha property to avoid visual layering of individual elements. 38460 * AlphaFilter applies alpha evenly across the entire display object and any opaque elements it contains. 38461 * If elements are not opaque, they will blend with each other anyway. 38462 * 38463 * Very handy if you want to use common features of all filters: 38464 * 38465 * 1. Assign a blendMode to this filter, blend all elements inside display object with background. 38466 * 38467 * 2. To use clipping in display coordinates, assign a filterArea to the same container that has this filter. 38468 * 38469 * @class 38470 * @extends PIXI.Filter 38471 * @memberof PIXI.filters 38472 */ 38473 var AlphaFilter = /*@__PURE__*/(function (Filter) { 38474 function AlphaFilter(alpha) 38475 { 38476 if ( alpha === void 0 ) { alpha = 1.0; } 38477 38478 Filter.call(this, _default, fragment$3, { uAlpha: 1 }); 38479 38480 this.alpha = alpha; 38481 } 38482 38483 if ( Filter ) { AlphaFilter.__proto__ = Filter; } 38484 AlphaFilter.prototype = Object.create( Filter && Filter.prototype ); 38485 AlphaFilter.prototype.constructor = AlphaFilter; 38486 38487 var prototypeAccessors = { alpha: { configurable: true } }; 38488 38489 /** 38490 * Coefficient for alpha multiplication 38491 * 38492 * @member {number} 38493 * @default 1 38494 */ 38495 prototypeAccessors.alpha.get = function () 38496 { 38497 return this.uniforms.uAlpha; 38498 }; 38499 38500 prototypeAccessors.alpha.set = function (value) // eslint-disable-line require-jsdoc 38501 { 38502 this.uniforms.uAlpha = value; 38503 }; 38504 38505 Object.defineProperties( AlphaFilter.prototype, prototypeAccessors ); 38506 38507 return AlphaFilter; 38508 }(Filter)); 38509 38510 /*! 38511 * @pixi/filter-blur - v5.0.0-rc.3 38512 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 38513 * 38514 * @pixi/filter-blur is licensed under the MIT License. 38515 * http://www.opensource.org/licenses/mit-license 38516 */ 38517 38518 var vertTemplate = "\n attribute vec2 aVertexPosition;\n\n uniform mat3 projectionMatrix;\n\n uniform float strength;\n\n varying vec2 vBlurTexCoords[%size%];\n\n uniform vec4 inputSize;\n uniform vec4 outputFrame;\n \n vec4 filterVertexPosition( void )\n {\n vec2 position = aVertexPosition * max(outputFrame.zw, vec2(0.)) + outputFrame.xy;\n \n return vec4((projectionMatrix * vec3(position, 1.0)).xy, 0.0, 1.0);\n }\n \n vec2 filterTextureCoord( void )\n {\n return aVertexPosition * (outputFrame.zw * inputSize.zw);\n }\n\n void main(void)\n {\n gl_Position = filterVertexPosition();\n\n vec2 textureCoord = filterTextureCoord();\n %blur%\n }"; 38519 38520 function generateBlurVertSource(kernelSize, x) 38521 { 38522 var halfLength = Math.ceil(kernelSize / 2); 38523 38524 var vertSource = vertTemplate; 38525 38526 var blurLoop = ''; 38527 var template; 38528 // let value; 38529 38530 if (x) 38531 { 38532 template = 'vBlurTexCoords[%index%] = textureCoord + vec2(%sampleIndex% * strength, 0.0);'; 38533 } 38534 else 38535 { 38536 template = 'vBlurTexCoords[%index%] = textureCoord + vec2(0.0, %sampleIndex% * strength);'; 38537 } 38538 38539 for (var i = 0; i < kernelSize; i++) 38540 { 38541 var blur = template.replace('%index%', i); 38542 38543 // value = i; 38544 38545 // if(i >= halfLength) 38546 // { 38547 // value = kernelSize - i - 1; 38548 // } 38549 38550 blur = blur.replace('%sampleIndex%', ((i - (halfLength - 1)) + ".0")); 38551 38552 blurLoop += blur; 38553 blurLoop += '\n'; 38554 } 38555 38556 vertSource = vertSource.replace('%blur%', blurLoop); 38557 vertSource = vertSource.replace('%size%', kernelSize); 38558 38559 return vertSource; 38560 } 38561 38562 var GAUSSIAN_VALUES = { 38563 5: [0.153388, 0.221461, 0.250301], 38564 7: [0.071303, 0.131514, 0.189879, 0.214607], 38565 9: [0.028532, 0.067234, 0.124009, 0.179044, 0.20236], 38566 11: [0.0093, 0.028002, 0.065984, 0.121703, 0.175713, 0.198596], 38567 13: [0.002406, 0.009255, 0.027867, 0.065666, 0.121117, 0.174868, 0.197641], 38568 15: [0.000489, 0.002403, 0.009246, 0.02784, 0.065602, 0.120999, 0.174697, 0.197448], 38569 }; 38570 38571 var fragTemplate$2 = [ 38572 'varying vec2 vBlurTexCoords[%size%];', 38573 'uniform sampler2D uSampler;', 38574 38575 'void main(void)', 38576 '{', 38577 ' gl_FragColor = vec4(0.0);', 38578 ' %blur%', 38579 '}' ].join('\n'); 38580 38581 function generateBlurFragSource(kernelSize) 38582 { 38583 var kernel = GAUSSIAN_VALUES[kernelSize]; 38584 var halfLength = kernel.length; 38585 38586 var fragSource = fragTemplate$2; 38587 38588 var blurLoop = ''; 38589 var template = 'gl_FragColor += texture2D(uSampler, vBlurTexCoords[%index%]) * %value%;'; 38590 var value; 38591 38592 for (var i = 0; i < kernelSize; i++) 38593 { 38594 var blur = template.replace('%index%', i); 38595 38596 value = i; 38597 38598 if (i >= halfLength) 38599 { 38600 value = kernelSize - i - 1; 38601 } 38602 38603 blur = blur.replace('%value%', kernel[value]); 38604 38605 blurLoop += blur; 38606 blurLoop += '\n'; 38607 } 38608 38609 fragSource = fragSource.replace('%blur%', blurLoop); 38610 fragSource = fragSource.replace('%size%', kernelSize); 38611 38612 return fragSource; 38613 } 38614 38615 /** 38616 * The BlurFilterPass applies a horizontal or vertical Gaussian blur to an object. 38617 * 38618 * @class 38619 * @extends PIXI.Filter 38620 * @memberof PIXI.filters 38621 */ 38622 var BlurFilterPass = /*@__PURE__*/(function (Filter) {
38623 function BlurFilterPass(horizontal, strength, quality, resolution, kernelSize) 38624 { 38625 kernelSize = kernelSize || 5; 38626 var vertSrc = generateBlurVertSource(kernelSize, horizontal); 38627 var fragSrc = generateBlurFragSource(kernelSize); 38628 38629 Filter.call( 38630 // vertex shader 38631 this, vertSrc, 38632 // fragment shader 38633 fragSrc 38634 ); 38635 38636 this.horizontal = horizontal; 38637 38638 this.resolution = resolution || settings.RESOLUTION; 38639 38640 this._quality = 0; 38641 38642 this.quality = quality || 4; 38643 38644 this.blur = strength || 8; 38645 } 38646 38647 if ( Filter ) { BlurFilterPass.__proto__ = Filter; } 38648 BlurFilterPass.prototype = Object.create( Filter && Filter.prototype ); 38649 BlurFilterPass.prototype.constructor = BlurFilterPass; 38650 38651 var prototypeAccessors = { blur: { configurable: true },quality: { configurable: true } }; 38652 38653 BlurFilterPass.prototype.apply = function apply (filterManager, input, output, clear) 38654 { 38655 if (output) 38656 { 38657 if (this.horizontal) 38658 { 38659 this.uniforms.strength = (1 / output.width) * (output.width / input.width); 38660 } 38661 else 38662 { 38663 this.uniforms.strength = (1 / output.height) * (output.height / input.height); 38664 } 38665 } 38666 else 38667 { 38668 if (this.horizontal) // eslint-disable-line 38669 { 38670 this.uniforms.strength = (1 / filterManager.renderer.width) * (filterManager.renderer.width / input.width); 38671 } 38672 else 38673 { 38674 this.uniforms.strength = (1 / filterManager.renderer.height) * (filterManager.renderer.height / input.height); // eslint-disable-line 38675 } 38676 } 38677 38678 // screen space! 38679 this.uniforms.strength *= this.strength; 38680 this.uniforms.strength /= this.passes; 38681 38682 if (this.passes === 1) 38683 { 38684 filterManager.applyFilter(this, input, output, clear); 38685 } 38686 else 38687 { 38688 var renderTarget = filterManager.getFilterTexture(); 38689 var renderer = filterManager.renderer; 38690 38691 var flip = input; 38692 var flop = renderTarget; 38693 38694 this.state.blend = false; 38695 filterManager.applyFilter(this, flip, flop, false); 38696 38697 for (var i = 1; i < this.passes - 1; i++) 38698 { 38699 renderer.renderTexture.bind(flip, flip.filterFrame); 38700 38701 this.uniforms.uSampler = flop; 38702 38703 var temp = flop; 38704 38705 flop = flip; 38706 flip = temp; 38707 38708 renderer.shader.bind(this); 38709 renderer.geometry.draw(5); 38710 } 38711 38712 this.state.blend = true; 38713 filterManager.applyFilter(this, flop, output, clear); 38714 filterManager.returnFilterTexture(renderTarget); 38715 } 38716 }; 38717 /** 38718 * Sets the strength of both the blur. 38719 * 38720 * @member {number} 38721 * @default 16 38722 */ 38723 prototypeAccessors.blur.get = function () 38724 { 38725 return this.strength; 38726 }; 38727 38728 prototypeAccessors.blur.set = function (value) // eslint-disable-line require-jsdoc 38729 { 38730 this.padding = 1 + (Math.abs(value) * 2); 38731 this.strength = value; 38732 }; 38733 38734 /** 38735 * Sets the quality of the blur by modifying the number of passes. More passes means higher 38736 * quaility bluring but the lower the performance. 38737 * 38738 * @member {number} 38739 * @default 4 38740 */ 38741 prototypeAccessors.quality.get = function () 38742 { 38743 return this._quality; 38744 }; 38745 38746 prototypeAccessors.quality.set = function (value) // eslint-disable-line require-jsdoc 38747 { 38748 this._quality = value; 38749 this.passes = value; 38750 }; 38751 38752 Object.defineProperties( BlurFilterPass.prototype, prototypeAccessors ); 38753 38754 return BlurFilterPass; 38755 }
38755(Filter)); 38756 38757 /** 38758 * The BlurFilter applies a Gaussian blur to an object. 38759 * 38760 * The strength of the blur can be set for the x-axis and y-axis separately. 38761 * 38762 * @class 38763 * @extends PIXI.Filter 38764 * @memberof PIXI.filters 38765 */ 38766 var BlurFilter = /*@__PURE__*/(function (Filter) { 38767 function BlurFilter(strength, quality, resolution, kernelSize) 38768 { 38769 Filter.call(this); 38770 38771 this.blurXFilter = new BlurFilterPass(true, strength, quality, resolution, kernelSize); 38772 this.blurYFilter = new BlurFilterPass(false, strength, quality, resolution, kernelSize); 38773 38774 this.resolution = resolution || settings.RESOLUTION; 38775 this.quality = quality || 4; 38776 this.blur = strength || 8; 38777 38778 this.repeatEdgePixels = false; 38779 } 38780 38781 if ( Filter ) { BlurFilter.__proto__ = Filter; } 38782 BlurFilter.prototype = Object.create( Filter && Filter.prototype ); 38783 BlurFilter.prototype.constructor = BlurFilter; 38784 38785 var prototypeAccessors = { blur: { configurable: true },quality: { configurable: true },blurX: { configurable: true },blurY: { configurable: true },blendMode: { configurable: true },repeatEdgePixels: { configurable: true } }; 38786 38787 /** 38788 * Applies the filter. 38789 * 38790 * @param {PIXI.systems.FilterSystem} filterManager - The manager. 38791 * @param {PIXI.RenderTexture} input - The input target. 38792 * @param {PIXI.RenderTexture} output - The output target. 38793 */ 38794 BlurFilter.prototype.apply = function apply (filterManager, input, output, clear) 38795 { 38796 var xStrength = Math.abs(this.blurXFilter.strength); 38797 var yStrength = Math.abs(this.blurYFilter.strength); 38798 38799 if (xStrength && yStrength) 38800 { 38801 var renderTarget = filterManager.getFilterTexture(); 38802 38803 this.blurXFilter.apply(filterManager, input, renderTarget, true); 38804 this.blurYFilter.apply(filterManager, renderTarget, output, clear); 38805 38806 filterManager.returnFilterTexture(renderTarget); 38807 } 38808 else if (yStrength) 38809 { 38810 this.blurYFilter.apply(filterManager, input, output, clear); 38811 } 38812 else 38813 { 38814 this.blurXFilter.apply(filterManager, input, output, clear); 38815 } 38816 }; 38817 38818 BlurFilter.prototype.updatePadding = function updatePadding () 38819 { 38820 if (this._repeatEdgePixels) 38821 { 38822 this.padding = 0; 38823 } 38824 else 38825 { 38826 this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2; 38827 } 38828 }; 38829 38830 /** 38831 * Sets the strength of both the blurX and blurY properties simultaneously 38832 * 38833 * @member {number} 38834 * @default 2 38835 */ 38836 prototypeAccessors.blur.get = function () 38837 { 38838 return this.blurXFilter.blur; 38839 }; 38840 38841 prototypeAccessors.blur.set = function (value) // eslint-disable-line require-jsdoc 38842 { 38843 this.blurXFilter.blur = this.blurYFilter.blur = value; 38844 this.updatePadding(); 38845 }; 38846 38847 /** 38848 * Sets the number of passes for blur. More passes means higher quaility bluring. 38849 * 38850 * @member {number} 38851 * @default 1 38852 */ 38853 prototypeAccessors.quality.get = function () 38854 { 38855 return this.blurXFilter.quality; 38856 }; 38857 38858 prototypeAccessors.quality.set = function (value) // eslint-disable-line require-jsdoc 38859 { 38860 this.blurXFilter.quality = this.blurYFilter.quality = value; 38861 }; 38862 38863 /** 38864 * Sets the strength of the blurX property 38865 * 38866 * @member {number} 38867 * @default 2 38868 */ 38869 prototypeAccessors.blurX.get = function () 38870 { 38871 return this.blurXFilter.blur; 38872 }; 38873 38874 prototypeAccessors.blurX.set = function (value) // eslint-disable-line require-jsdoc 38875 { 38876 this.blurXFilter.blur = value; 38877 this.updatePadding(); 38878 }; 38879 38880 /** 38881 * Sets the strength of the blurY property 38882 * 38883 * @member {number} 38884 * @default 2 38885 */ 38886 prototypeAccessors.blurY.get = function () 38887 { 38888 return this.blurYFilter.blur; 38889 }; 38890 38891 prototypeAccessors.blurY.set = function (value) // eslint-disable-line require-jsdoc 38892 { 38893 this.blurYFilter.blur = value; 38894 this.updatePadding(); 38895 }; 38896 38897 /** 38898 * Sets the blendmode of the filter 38899 * 38900 * @member {number} 38901 * @default PIXI.BLEND_MODES.NORMAL 38902 */ 38903 prototypeAccessors.blendMode.get = function () 38904 { 38905 return this.blurYFilter.blendMode; 38906 }; 38907 38908 prototypeAccessors.blendMode.set = function (value) // eslint-disable-line require-jsdoc 38909 { 38910 this.blurYFilter.blendMode = value; 38911 }; 38912 38913 /** 38914 * If set to true the edge of the target will be clamped 38915 * 38916 * @member {bool} 38917 * @default false 38918 */ 38919 prototypeAccessors.repeatEdgePixels.get = function () 38920 { 38921 return this._repeatEdgePixels; 38922 }; 38923 38924 prototypeAccessors.repeatEdgePixels.set = function (value) 38925 { 38926 this._repeatEdgePixels = value; 38927 this.updatePadding(); 38928 }; 38929 38930 Object.defineProperties( BlurFilter.prototype, prototypeAccessors ); 38931 38932 return BlurFilter; 38933 }(Filter)); 38934 38935 /*! 38936 * @pixi/filter-color-matrix - v5.0.0-rc.3 38937 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 38938 * 38939 * @pixi/filter-color-matrix is licensed under the MIT License. 38940 * http://www.opensource.org/licenses/mit-license 38941 */ 38942 38943 var fragment$4 = "varying vec2 vTextureCoord;\nuniform sampler2D uSampler;\nuniform float m[20];\nuniform float uAlpha;\n\nvoid main(void)\n{\n vec4 c = texture2D(uSampler, vTextureCoord);\n\n if (uAlpha == 0.0) {\n gl_FragColor = c;\n return;\n }\n\n // Un-premultiply alpha before applying the color matrix. See issue #3539.\n if (c.a > 0.0) {\n c.rgb /= c.a;\n }\n\n vec4 result;\n\n result.r = (m[0] * c.r);\n result.r += (m[1] * c.g);\n result.r += (m[2] * c.b);\n result.r += (m[3] * c.a);\n result.r += m[4];\n\n result.g = (m[5] * c.r);\n result.g += (m[6] * c.g);\n result.g += (m[7] * c.b);\n result.g += (m[8] * c.a);\n result.g += m[9];\n\n result.b = (m[10] * c.r);\n result.b += (m[11] * c.g);\n result.b += (m[12] * c.b);\n result.b += (m[13] * c.a);\n result.b += m[14];\n\n result.a = (m[15] * c.r);\n result.a += (m[16] * c.g);\n result.a += (m[17] * c.b);\n result.a += (m[18] * c.a);\n result.a += m[19];\n\n vec3 rgb = mix(c.rgb, result.rgb, uAlpha);\n\n // Premultiply alpha again.\n rgb *= result.a;\n\n gl_FragColor = vec4(rgb, result.a);\n}\n"; 38944 38945 /** 38946 * The ColorMatrixFilter class lets you apply a 5x4 matrix transformation on the RGBA 38947 * color and alpha values of every pixel on your displayObject to produce a result 38948 * with a new set of RGBA color and alpha values. It's pretty powerful! 38949 * 38950 * ```js 38951 * let colorMatrix = new PIXI.filters.ColorMatrixFilter(); 38952 * container.filters = [colorMatrix]; 38953 * colorMatrix.contrast(2); 38954 * ``` 38955 * @author Clément Chenebault <[email protected]> 38956 * @class 38957 * @extends PIXI.Filter 38958 * @memberof PIXI.filters 38959 */ 38960 var ColorMatrixFilter = /*@__PURE__*/(function (Filter) { 38961 function ColorMatrixFilter() 38962 { 38963 var uniforms = { 38964 m: new Float32Array([1, 0, 0, 0, 0, 38965 0, 1, 0, 0, 0, 38966 0, 0, 1, 0, 0, 38967 0, 0, 0, 1, 0]), 38968 uAlpha: 1, 38969 }; 38970 38971 Filter.call(this, defaultFilter, fragment$4, uniforms); 38972 38973 this.alpha = 1; 38974 } 38975 38976 if ( Filter ) { ColorMatrixFilter.__proto__ = Filter; } 38977 ColorMatrixFilter.prototype = Object.create( Filter && Filter.prototype ); 38978 ColorMatrixFilter.prototype.constructor = ColorMatrixFilter; 38979 38980 var prototypeAccessors = { matrix: { configurable: true },alpha: { configurable: true } }; 38981 38982 /** 38983 * Transforms current matrix and set the new one 38984 * 38985 * @param {number[]} matrix - 5x4 matrix 38986 * @param {boolean} multiply - if true, current matrix and matrix are multiplied. If false, 38987 * just set the current matrix with @param matrix 38988 */ 38989 ColorMatrixFilter.prototype._loadMatrix = function _loadMatrix (matrix, multiply) 38990 { 38991 if ( multiply === void 0 ) { multiply = false; } 38992 38993 var newMatrix = matrix; 38994 38995 if (multiply) 38996 {
38997 this._multiply(newMatrix, this.uniforms.m, matrix); 38998 newMatrix = this._colorMatrix(newMatrix); 38999 } 39000 39001 // set the new matrix 39002 this.uniforms.m = newMatrix; 39003 }; 39004 39005 /** 39006 * Multiplies two mat5's 39007 * 39008 * @private 39009 * @param {number[]} out - 5x4 matrix the receiving matrix 39010 * @param {number[]} a - 5x4 matrix the first operand 39011 * @param {number[]} b - 5x4 matrix the second operand 39012 * @returns {number[]} 5x4 matrix 39013 */ 39014 ColorMatrixFilter.prototype._multiply = function _multiply (out, a, b) 39015 { 39016 // Red Channel 39017 out[0] = (a[0] * b[0]) + (a[1] * b[5]) + (a[2] * b[10]) + (a[3] * b[15]); 39018 out[1] = (a[0] * b[1]) + (a[1] * b[6]) + (a[2] * b[11]) + (a[3] * b[16]); 39019 out[2] = (a[0] * b[2]) + (a[1] * b[7]) + (a[2] * b[12]) + (a[3] * b[17]); 39020 out[3] = (a[0] * b[3]) + (a[1] * b[8]) + (a[2] * b[13]) + (a[3] * b[18]); 39021 out[4] = (a[0] * b[4]) + (a[1] * b[9]) + (a[2] * b[14]) + (a[3] * b[19]) + a[4]; 39022 39023 // Green Channel 39024 out[5] = (a[5] * b[0]) + (a[6] * b[5]) + (a[7] * b[10]) + (a[8] * b[15]); 39025 out[6] = (a[5] * b[1]) + (a[6] * b[6]) + (a[7] * b[11]) + (a[8] * b[16]); 39026 out[7] = (a[5] * b[2]) + (a[6] * b[7]) + (a[7] * b[12]) + (a[8] * b[17]); 39027 out[8] = (a[5] * b[3]) + (a[6] * b[8]) + (a[7] * b[13]) + (a[8] * b[18]); 39028 out[9] = (a[5] * b[4]) + (a[6] * b[9]) + (a[7] * b[14]) + (a[8] * b[19]) + a[9]; 39029 39030 // Blue Channel 39031 out[10] = (a[10] * b[0]) + (a[11] * b[5]) + (a[12] * b[10]) + (a[13] * b[15]); 39032 out[11] = (a[10] * b[1]) + (a[11] * b[6]) + (a[12] * b[11]) + (a[13] * b[16]); 39033 out[12] = (a[10] * b[2]) + (a[11] * b[7]) + (a[12] * b[12]) + (a[13] * b[17]); 39034 out[13] = (a[10] * b[3]) + (a[11] * b[8]) + (a[12] * b[13]) + (a[13] * b[18]); 39035 out[14] = (a[10] * b[4]) + (a[11] * b[9]) + (a[12] * b[14]) + (a[13] * b[19]) + a[14]; 39036 39037 // Alpha Channel 39038 out[15] = (a[15] * b[0]) + (a[16] * b[5]) + (a[17] * b[10]) + (a[18] * b[15]); 39039 out[16] = (a[15] * b[1]) + (a[16] * b[6]) + (a[17] * b[11]) + (a[18] * b[16]); 39040 out[17] = (a[15] * b[2]) + (a[16] * b[7]) + (a[17] * b[12]) + (a[18] * b[17]); 39041 out[18] = (a[15] * b[3]) + (a[16] * b[8]) + (a[17] * b[13]) + (a[18] * b[18]); 39042 out[19] = (a[15] * b[4]) + (a[16] * b[9]) + (a[17] * b[14]) + (a[18] * b[19]) + a[19]; 39043 39044 return out; 39045 }; 39046 39047 /** 39048 * Create a Float32 Array and normalize the offset component to 0-1 39049 * 39050 * @private 39051 * @param {number[]} matrix - 5x4 matrix 39052 * @return {number[]} 5x4 matrix with all values between 0-1 39053 */ 39054 ColorMatrixFilter.prototype._colorMatrix = function _colorMatrix (matrix) 39055 { 39056 // Create a Float32 Array and normalize the offset component to 0-1 39057 var m = new Float32Array(matrix); 39058 39059 m[4] /= 255; 39060 m[9] /= 255; 39061 m[14] /= 255; 39062 m[19] /= 255; 39063 39064 return m; 39065 }; 39066 39067 /** 39068 * Adjusts brightness 39069 * 39070 * @param {number} b - value of the brigthness (0-1, where 0 is black) 39071 * @param {boolean} multiply - if true, current matrix and matrix are multiplied. If false, 39072 * just set the current matrix with @param matrix 39073 */ 39074 ColorMatrixFilter.prototype.brightness = function brightness (b, multiply) 39075 { 39076 var matrix = [ 39077 b, 0, 0, 0, 0, 39078 0, b, 0, 0, 0, 39079 0, 0, b, 0, 0, 39080 0, 0, 0, 1, 0 ]; 39081 39082 this._loadMatrix(matrix, multiply); 39083 }; 39084 39085 /** 39086 * Set the matrices in grey scales 39087 * 39088 * @param {number} scale - value of the grey (0-1, where 0 is black) 39089 * @param {boolean} multiply - if true, current matrix and matrix are multiplied. If false, 39090 * just set the current matrix with @param matrix 39091 */ 39092 ColorMatrixFilter.prototype.greyscale = function greyscale (scale, multiply) 39093 { 39094 var matrix = [ 39095 scale, scale, scale, 0, 0, 39096 scale, scale, scale, 0, 0, 39097 scale, scale, scale, 0, 0, 39098 0, 0, 0, 1, 0 ]; 39099 39100 this._loadMatrix(matrix, multiply); 39101 }; 39102 39103 /** 39104 * Set the black and white matrice. 39105 * 39106 * @param {boolean} multiply - if true, current matrix and matrix are multiplied. If false, 39107 * just set the current matrix with @param matrix 39108 */ 39109 ColorMatrixFilter.prototype.blackAndWhite = function blackAndWhite (multiply) 39110 { 39111 var matrix = [ 39112 0.3, 0.6, 0.1, 0, 0, 39113 0.3, 0.6, 0.1, 0, 0, 39114 0.3, 0.6, 0.1, 0, 0, 39115 0, 0, 0, 1, 0 ]; 39116 39117 this._loadMatrix(matrix, multiply); 39118 }; 39119 39120 /** 39121 * Set the hue property of the color 39122 * 39123 * @param {number} rotation - in degrees 39124 * @param {boolean} multiply - if true, current matrix and matrix are multiplied. If false, 39125 * just set the current matrix with @param matrix 39126 */ 39127 ColorMatrixFilter.prototype.hue = function hue (rotation, multiply) 39128 { 39129 rotation = (rotation || 0) / 180 * Math.PI; 39130 39131 var cosR = Math.cos(rotation); 39132 var sinR = Math.sin(rotation); 39133 var sqrt = Math.sqrt; 39134 39135 /* a good approximation for hue rotation 39136 This matrix is far better than the versions with magic luminance constants 39137 formerly used here, but also used in the starling framework (flash) and known from this 39138 old part of the internet: quasimondo.com/archives/000565.p
39138hp 39139 39140 This new matrix is based on rgb cube rotation in space. Look here for a more descriptive 39141 implementation as a shader not a general matrix: 39142 https://github.com/evanw/glfx.js/blob/58841c23919bd59787effc0333a4897b43835412/src/filters/adjust/huesaturation.js 39143 39144 This is the source for the code: 39145 see http://stackoverflow.com/questions/8507885/shift-hue-of-an-rgb-color/8510751#8510751 39146 */ 39147 39148 var w = 1 / 3; 39149 var sqrW = sqrt(w); // weight is 39150 39151 var a00 = cosR + ((1.0 - cosR) * w); 39152 var a01 = (w * (1.0 - cosR)) - (sqrW * sinR); 39153 var a02 = (w * (1.0 - cosR)) + (sqrW * sinR); 39154 39155 var a10 = (w * (1.0 - cosR)) + (sqrW * sinR); 39156 var a11 = cosR + (w * (1.0 - cosR)); 39157 var a12 = (w * (1.0 - cosR)) - (sqrW * sinR); 39158 39159 var a20 = (w * (1.0 - cosR)) - (sqrW * sinR); 39160 var a21 = (w * (1.0 - cosR)) + (sqrW * sinR); 39161 var a22 = cosR + (w * (1.0 - cosR)); 39162 39163 var matrix = [ 39164 a00, a01, a02, 0, 0, 39165 a10, a11, a12, 0, 0, 39166 a20, a21, a22, 0, 0, 39167 0, 0, 0, 1, 0 ]; 39168 39169 this._loadMatrix(matrix, multiply); 39170 }; 39171 39172 /** 39173 * Set the contrast matrix, increase the separation between dark and bright 39174 * Increase contrast : shadows darker and highlights brighter 39175 * Decrease contrast : bring the shadows up and the highlights down 39176 * 39177 * @param {number} amount - value of the contrast (0-1) 39178 * @param {boolean} multiply - if true, current matrix and matrix are multiplied. If false, 39179 * just set the current matrix with @param matrix 39180 */ 39181 ColorMatrixFilter.prototype.contrast = function contrast (amount, multiply) 39182 { 39183 var v = (amount || 0) + 1; 39184 var o = -0.5 * (v - 1); 39185 39186 var matrix = [ 39187 v, 0, 0, 0, o, 39188 0, v, 0, 0, o, 39189 0, 0, v, 0, o, 39190 0, 0, 0, 1, 0 ]; 39191 39192 this._loadMatrix(matrix, multiply); 39193 }; 39194 39195 /** 39196 * Set the saturation matrix, increase the separation between colors 39197 * Increase saturation : increase contrast, brightness, and sharpness 39198 * 39199 * @param {number} amount - The saturation amount (0-1) 39200 * @param {boolean} multiply - if true, current matrix and matrix are multiplied. If false, 39201 * just set the current matrix with @param matrix 39202 */ 39203 ColorMatrixFilter.prototype.saturate = function saturate (amount, multiply) 39204 { 39205 if ( amount === void 0 ) { amount = 0; } 39206 39207 var x = (amount * 2 / 3) + 1; 39208 var y = ((x - 1) * -0.5); 39209 39210 var matrix = [ 39211 x, y, y, 0, 0, 39212 y, x, y, 0, 0, 39213 y, y, x, 0, 0, 39214 0, 0, 0, 1, 0 ]; 39215 39216 this._loadMatrix(matrix, multiply); 39217 }; 39218 39219 /** 39220 * Desaturate image (remove color) 39221 * 39222 * Call the saturate function 39223 * 39224 */ 39225 ColorMatrixFilter.prototype.desaturate = function desaturate () // eslint-disable-line no-unused-vars 39226 { 39227 this.saturate(-1); 39228 }; 39229 39230 /** 39231 * Negative image (inverse of classic rgb matrix) 39232 * 39233 * @param {boolean} multiply - if true, current matrix and matrix are multiplied. If false, 39234 * just set the current matrix with @param matrix 39235 */ 39236 ColorMatrixFilter.prototype.negative = function negative (multiply) 39237 { 39238 var matrix = [ 39239 -1, 0, 0, 1, 0, 39240 0, -1, 0, 1, 0, 39241 0, 0, -1, 1, 0, 39242 0, 0, 0, 1, 0 ]; 39243 39244 this._loadMatrix(matrix, multiply); 39245 }; 39246 39247 /** 39248 * Sepia image 39249 * 39250 * @param {boolean} multiply - if true, current matrix and matrix are multiplied. If false, 39251 * just set the current matrix with @param matrix 39252 */ 39253 ColorMatrixFilter.prototype.sepia = function sepia (multiply) 39254 { 39255 var matrix = [ 39256 0.393, 0.7689999, 0.18899999, 0, 0, 39257 0.349, 0.6859999, 0.16799999, 0, 0, 39258 0.272, 0.5339999, 0.13099999, 0, 0, 39259 0, 0, 0, 1, 0 ]; 39260 39261 this._loadMatrix(matrix, multiply); 39262 }; 39263 39264 /** 39265 * Color motion picture process invented in 1916 (thanks Dominic Szablewski) 39266 * 39267 * @param {boolean} multiply - if true, current matrix and matrix are multiplied. If false, 39268 * just set the current matrix with @param matrix 39269 */ 39270 ColorMatrixFilter.prototype.technicolor = function technicolor (multiply) 39271 { 39272 var matrix = [ 39273 1.9125277891456083, -0.8545344976951645, -0.091555084827
3927355585, 0, 11.793603434377337, 39274 -0.3087833385928097, 1.7658908555458428, -0.10601743074722245, 0, -70.35205161461398, 39275 -0.231103377548616, -0.7501899197440212, 1.847597816108189, 0, 30.950940869491138, 39276 0, 0, 0, 1, 0 ]; 39277 39278 this._loadMatrix(matrix, multiply); 39279 }; 39280 39281 /** 39282 * Polaroid filter 39283 * 39284 * @param {boolean} multiply - if true, current matrix and matrix are multiplied. If false, 39285 * just set the current matrix with @param matrix 39286 */ 39287 ColorMatrixFilter.prototype.polaroid = function polaroid (multiply) 39288 { 39289 var matrix = [ 39290 1.438, -0.062, -0.062, 0, 0, 39291 -0.122, 1.378, -0.122, 0, 0, 39292 -0.016, -0.016, 1.483, 0, 0, 39293 0, 0, 0, 1, 0 ]; 39294 39295 this._loadMatrix(matrix, multiply); 39296 }; 39297 39298 /** 39299 * Filter who transforms : Red -> Blue and Blue -> Red 39300 * 39301 * @param {boolean} multiply - if true, current matrix and matrix are multiplied. If false, 39302 * just set the current matrix with @param matrix 39303 */ 39304 ColorMatrixFilter.prototype.toBGR = function toBGR (multiply) 39305 { 39306 var matrix = [ 39307 0, 0, 1, 0, 0, 39308 0, 1, 0, 0, 0, 39309 1, 0, 0, 0, 0, 39310 0, 0, 0, 1, 0 ]; 39311 39312 this._loadMatrix(matrix, multiply); 39313 }; 39314 39315 /** 39316 * Color reversal film introduced by Eastman Kodak in 1935. (thanks Dominic Szablewski) 39317 * 39318 * @param {boolean} multiply - if true, current matrix and matrix are multiplied. If false, 39319 * just set the current matrix with @param matrix 39320 */ 39321 ColorMatrixFilter.prototype.kodachrome = function kodachrome (multiply) 39322 { 39323 var matrix = [ 39324 1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502, 39325 -0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203, 39326 -0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946, 39327 0, 0, 0, 1, 0 ]; 39328 39329 this._loadMatrix(matrix, multiply); 39330 }; 39331 39332 /** 39333 * Brown delicious browni filter (thanks Dominic Szablewski) 39334 * 39335 * @param {boolean} multiply - if true, current matrix and matrix are multiplied. If false, 39336 * just set the current matrix with @param matrix 39337 */ 39338 ColorMatrixFilter.prototype.browni = function browni (multiply) 39339 { 39340 var matrix = [ 39341 0.5997023498159715, 0.34553243048391263, -0.2708298674538042, 0, 47.43192855600873, 39342 -0.037703249837783157, 0.8609577587992641, 0.15059552388459913, 0, -36.96841498319127, 39343 0.24113635128153335, -0.07441037908422492, 0.44972182064877153, 0, -7.562075277591283, 39344 0, 0, 0, 1, 0 ]; 39345 39346 this._loadMatrix(matrix, multiply); 39347 }; 39348 39349 /** 39350 * Vintage filter (thanks Dominic Szablewski) 39351 * 39352 * @param {boolean} multiply - if true, current matrix and matrix are multiplied. If false, 39353 * just set the current matrix with @param matrix 39354 */ 39355 ColorMatrixFilter.prototype.vintage = function vintage (multiply) 39356 { 39357 var matrix = [ 39358 0.6279345635605994, 0.3202183420819367, -0.03965408211312453, 0, 9.651285835294123, 39359 0.02578397704808868, 0.6441188644374771, 0.03259127616149294, 0, 7.462829176470591, 39360 0.0466055556782719, -0.0851232987247891, 0.5241648018700465, 0, 5.159190588235296, 39361 0, 0, 0, 1, 0 ]; 39362 39363 this._loadMatrix(matrix, multiply); 39364 }; 39365 39366 /** 39367 * We don't know exactly what it does, kind of gradient map, but funny to play with! 39368 * 39369 * @param {number} desaturation - Tone values. 39370 * @param {number} toned - Tone values. 39371 * @param {string} lightColor - Tone values, example: `0xFFE580` 39372 * @param {string} darkColor - Tone values, example: `0xFFE580` 39373 * @param {boolean} multiply - if true, current matrix and matrix are multiplied. If false, 39374 * just set the current matrix with @param matrix 39375 */ 39376 ColorMatrixFilter.prototype.colorTone = function colorTone (desaturation, toned, lightColor, darkColor, multiply) 39377 { 39378 desaturation = desaturation || 0.2; 39379 toned = toned || 0.15; 39380 lightColor = lightColor || 0xFFE580; 39381 darkColor = darkColor || 0x338000; 39382 39383 var lR = ((lightColor >> 16) & 0xFF) / 255; 39384 var lG = ((lightColor >> 8) & 0xFF) / 255; 39385 var lB = (lightColor & 0xFF) / 255; 39386 39387 var dR = ((darkColor >> 16) & 0xFF) / 255; 39388 var dG = ((darkColor >> 8) & 0xFF) / 255; 39389 var dB = (darkColor & 0xFF) / 255; 39390 39391 var matrix = [
39392 0.3, 0.59, 0.11, 0, 0, 39393 lR, lG, lB, desaturation, 0, 39394 dR, dG, dB, toned, 0, 39395 lR - dR, lG - dG, lB - dB, 0, 0 ]; 39396 39397 this._loadMatrix(matrix, multiply); 39398 }; 39399 39400 /** 39401 * Night effect 39402 * 39403 * @param {number} intensity - The intensity of the night effect. 39404 * @param {boolean} multiply - if true, current matrix and matrix are multiplied. If false, 39405 * just set the current matrix with @param matrix 39406 */ 39407 ColorMatrixFilter.prototype.night = function night (intensity, multiply) 39408 { 39409 intensity = intensity || 0.1; 39410 var matrix = [ 39411 intensity * (-2.0), -intensity, 0, 0, 0, 39412 -intensity, 0, intensity, 0, 0, 39413 0, intensity, intensity * 2.0, 0, 0, 39414 0, 0, 0, 1, 0 ]; 39415 39416 this._loadMatrix(matrix, multiply); 39417 }; 39418 39419 /** 39420 * Predator effect 39421 * 39422 * Erase the current matrix by setting a new indepent one 39423 * 39424 * @param {number} amount - how much the predator feels his future victim 39425 * @param {boolean} multiply - if true, current matrix and matrix are multiplied. If false, 39426 * just set the current matrix with @param matrix 39427 */ 39428 ColorMatrixFilter.prototype.predator = function predator (amount, multiply) 39429 { 39430 var matrix = [ 39431 // row 1 39432 11.224130630493164 * amount, 39433 -4.794486999511719 * amount, 39434 -2.8746118545532227 * amount, 39435 0 * amount, 39436 0.40342438220977783 * amount, 39437 // row 2 39438 -3.6330697536468506 * amount, 39439 9.193157196044922 * amount, 39440 -2.951810836791992 * amount, 39441 0 * amount, 39442 -1.316135048866272 * amount, 39443 // row 3 39444 -3.2184197902679443 * amount, 39445 -4.2375030517578125 * amount, 39446 7.476448059082031 * amount, 39447 0 * amount, 39448 0.8044459223747253 * amount, 39449 // row 4 39450 0, 0, 0, 1, 0 ]; 39451 39452 this._loadMatrix(matrix, multiply); 39453 }; 39454 39455 /** 39456 * LSD effect 39457 * 39458 * Multiply the current matrix 39459 * 39460 * @param {boolean} multiply - if true, current matrix and matrix are multiplied. If false, 39461 * just set the current matrix with @param matrix 39462 */ 39463 ColorMatrixFilter.prototype.lsd = function lsd (multiply) 39464 { 39465 var matrix = [ 39466 2, -0.4, 0.5, 0, 0, 39467 -0.5, 2, -0.4, 0, 0, 39468 -0.4, -0.5, 3, 0, 0, 39469 0, 0, 0, 1, 0 ]; 39470 39471 this._loadMatrix(matrix, multiply); 39472 }; 39473 39474 /** 39475 * Erase the current matrix by setting the default one 39476 * 39477 */ 39478 ColorMatrixFilter.prototype.reset = function reset () 39479 { 39480 var matrix = [ 39481 1, 0, 0, 0, 0, 39482 0, 1, 0, 0, 0, 39483 0, 0, 1, 0, 0, 39484 0, 0, 0, 1, 0 ]; 39485 39486 this._loadMatrix(matrix, false); 39487 }; 39488 39489 /** 39490 * The matrix of the color matrix filter 39491 * 39492 * @member {number[]} 39493 * @default [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0] 39494 */ 39495 prototypeAccessors.matrix.get = function () 39496 { 39497 return this.uniforms.m; 39498 }; 39499 39500 prototypeAccessors.matrix.set = function (value) // eslint-disable-line require-jsdoc 39501 { 39502 this.uniforms.m = value; 39503 }; 39504 39505 /** 39506 * The opacity value to use when mixing the original and resultant colors. 39507 * 39508 * When the value is 0, the original color is used without modification. 39509 * When the value is 1, the result color is used. 39510 * When in the range (0, 1) the color is interpolated between the original and result by this amount. 39511 * 39512 * @member {number} 39513 * @default 1 39514 */ 39515 prototypeAccessors.alpha.get = function () 39516 { 39517 return this.uniforms.uAlpha; 39518 }; 39519 39520 prototypeAccessors.alpha.set = function (value) // eslint-disable-line require-jsdoc 39521 { 39522 this.uniforms.uAlpha = value; 39523 }; 39524 39525 Object.defineProperties( ColorMatrixFilter.prototype, prototypeAccessors ); 39526 39527 return ColorMatrixFilter; 39528 }(Filter)); 39529 39530 // Americanized alias 39531 ColorMatrixFilter.prototype.grayscale = ColorMatrixFilter.prototype.greyscale; 39532 39533 /*! 39534 * @pixi/filter-displacement - v5.0.0-rc.3 39535 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 39536 * 39537 * @pixi/filter-displacement is licensed under the MIT License. 39538 * http://www.opensource.org/licenses/mit-license 39539 */ 39540 39541 var vertex$4 = "attribute vec2 aVertexPosition;\n\nuniform mat3 projectionMatrix;\nuniform mat3 filterMatrix;\n\nvarying vec2 vTextureCoord;\nvarying vec2 vFilterCoord;\n\nuniform vec4 inputSize;\nuniform vec4 outputFrame;\n\nvec4 filterVertexPosition( void )\n{\n vec2 position = aVertexPosition * max(outputFrame.zw, vec2(0.)) + outputFrame.xy;
39541\n\n return vec4((projectionMatrix * vec3(position, 1.0)).xy, 0.0, 1.0);\n}\n\nvec2 filterTextureCoord( void )\n{\n return aVertexPosition * (outputFrame.zw * inputSize.zw);\n}\n\nvoid main(void)\n{\n\tgl_Position = filterVertexPosition();\n\tvTextureCoord = filterTextureCoord();\n\tvFilterCoord = ( filterMatrix * vec3( vTextureCoord, 1.0) ).xy;\n}\n"; 39542 39543 var fragment$5 = "varying vec2 vFilterCoord;\nvarying vec2 vTextureCoord;\n\nuniform vec2 scale;\nuniform mat2 rotation;\nuniform sampler2D uSampler;\nuniform sampler2D mapSampler;\n\nuniform highp vec4 inputSize;\nuniform vec4 inputClamp;\n\nvoid main(void)\n{\n vec4 map = texture2D(mapSampler, vFilterCoord);\n\n map -= 0.5;\n map.xy = scale * inputSize.zw * (rotation * map.xy);\n\n gl_FragColor = texture2D(uSampler, clamp(vec2(vTextureCoord.x + map.x, vTextureCoord.y + map.y), inputClamp.xy, inputClamp.zw));\n}\n"; 39544 39545 /** 39546 * The DisplacementFilter class uses the pixel values from the specified texture 39547 * (called the displacement map) to perform a displacement of an object. 39548 * 39549 * You can use this filter to apply all manor of crazy warping effects. 39550 * Currently the `r` property of the texture is used to offset the `x` 39551 * and the `g` property of the texture is used to offset the `y`. 39552 * 39553 * The way it works is it uses the values of the displacement map to look up the 39554 * correct pixels to output. This means it's not technically moving the original. 39555 * Instead, it's starting at the output and asking "which pixel from the original goes here". 39556 * For example, if a displacement map pixel has `red = 1` and the filter scale is `20`, 39557 * this filter will output the pixel approximately 20 pixels to the right of the original. 39558 * 39559 * @class 39560 * @extends PIXI.Filter 39561 * @memberof PIXI.filters 39562 */ 39563 var DisplacementFilter = /*@__PURE__*/(function (Filter) { 39564 function DisplacementFilter(sprite, scale) 39565 { 39566 var maskMatrix = new Matrix(); 39567 39568 sprite.renderable = false; 39569 39570 Filter.call(this, vertex$4, fragment$5, { 39571 mapSampler: sprite._texture, 39572 filterMatrix: maskMatrix, 39573 scale: { x: 1, y: 1 }, 39574 rotation: new Float32Array([1, 0, 0, 1]), 39575 }); 39576 39577 this.maskSprite = sprite; 39578 this.maskMatrix = maskMatrix; 39579 39580 if (scale === null || scale === undefined) 39581 { 39582 scale = 20; 39583 } 39584 39585 /** 39586 * scaleX, scaleY for displacements 39587 * @member {PIXI.Point} 39588 */ 39589 this.scale = new Point(scale, scale); 39590 } 39591 39592 if ( Filter ) { DisplacementFilter.__proto__ = Filter; } 39593 DisplacementFilter.prototype = Object.create( Filter && Filter.prototype ); 39594 DisplacementFilter.prototype.constructor = DisplacementFilter; 39595 39596 var prototypeAccessors = { map: { configurable: true } }; 39597 39598 /** 39599 * Applies the filter. 39600 * 39601 * @param {PIXI.systems.FilterSystem} filterManager - The manager. 39602 * @param {PIXI.RenderTexture} input - The input target. 39603 * @param {PIXI.RenderTexture} output - The output target. 39604 */ 39605 DisplacementFilter.prototype.apply = function apply (filterManager, input, output) 39606 { 39607 this.uniforms.filterMatrix = filterManager.calculateSpriteMatrix(this.maskMatrix, this.maskSprite); 39608 this.uniforms.scale.x = this.scale.x; 39609 this.uniforms.scale.y = this.scale.y; 39610 39611 // Extract rotation from world transform 39612 var wt = this.maskSprite.transform.worldTransform; 39613 var lenX = Math.sqrt((wt.a * wt.a) + (wt.b * wt.b)); 39614 var lenY = Math.sqrt((wt.c * wt.c) + (wt.d * wt.d)); 39615 39616 if (lenX !== 0 && lenY !== 0) 39617 { 39618 this.uniforms.rotation[0] = wt.a / lenX; 39619 this.uniforms.rotation[1] = wt.b / lenX; 39620 this.uniforms.rotation[2] = wt.c / lenY; 39621 this.uniforms.rotation[3] = wt.d / lenY; 39622 } 39623 39624 // draw the filter... 39625 filterManager.applyFilter(this, input, output); 39626 }; 39627 39628 /** 39629 * The texture used for the displacement map. Must be power of 2 sized texture. 39630 * 39631 * @member {PIXI.Texture} 39632 */ 39633 prototypeAccessors.map.get = function () 39634 { 39635 return this.uniforms.mapSampler; 39636 }; 39637 39638 prototypeAccessors.map.set = function (value) // eslint-disable-line require-jsdoc 39639 { 39640 this.uniforms.mapSampler = value; 39641 }; 39642 39643 Object.defineProperties( DisplacementFilter.prototype, prototypeAccessors ); 39644 39645 return DisplacementFilter; 39646 }(Filter)); 39647 39648 /*!
39649 * @pixi/filter-fxaa - v5.0.0-rc.3 39650 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 39651 * 39652 * @pixi/filter-fxaa is licensed under the MIT License. 39653 * http://www.opensource.org/licenses/mit-license 39654 */ 39655 39656 var vertex$5 = "\nattribute vec2 aVertexPosition;\n\nuniform mat3 projectionMatrix;\n\nvarying vec2 v_rgbNW;\nvarying vec2 v_rgbNE;\nvarying vec2 v_rgbSW;\nvarying vec2 v_rgbSE;\nvarying vec2 v_rgbM;\n\nvarying vec2 vFragCoord;\n\nuniform vec4 inputPixel;\nuniform vec4 outputFrame;\n\nvec4 filterVertexPosition( void )\n{\n vec2 position = aVertexPosition * max(outputFrame.zw, vec2(0.)) + outputFrame.xy;\n\n return vec4((projectionMatrix * vec3(position, 1.0)).xy, 0.0, 1.0);\n}\n\nvoid texcoords(vec2 fragCoord, vec2 inverseVP,\n out vec2 v_rgbNW, out vec2 v_rgbNE,\n out vec2 v_rgbSW, out vec2 v_rgbSE,\n out vec2 v_rgbM) {\n v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP;\n v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP;\n v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP;\n v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP;\n v_rgbM = vec2(fragCoord * inverseVP);\n}\n\nvoid main(void) {\n\n gl_Position = filterVertexPosition();\n\n vFragCoord = aVertexPosition * outputFrame.zw;\n\n texcoords(vFragCoord, inputPixel.zw, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM);\n}\n"; 39657 39658 var fragment$6 = "varying vec2 v_rgbNW;\nvarying vec2 v_rgbNE;\nvarying vec2 v_rgbSW;\nvarying vec2 v_rgbSE;\nvarying vec2 v_rgbM;\n\nvarying vec2 vFragCoord;\nuniform sampler2D uSampler;\nuniform highp vec4 inputPixel;\n\n\n/**\n Basic FXAA implementation based on the code on geeks3d.com with the\n modification that the texture2DLod stuff was removed since it's\n unsupported by WebGL.\n\n --\n\n From:\n https://github.com/mitsuhiko/webgl-meincraft\n\n Copyright (c) 2011 by Armin Ronacher.\n\n Some rights reserved.\n\n Redistribution and use in source and binary forms, with or without\n modification, are permitted provided that the following conditions are\n met:\n\n * Redistributions of source code must retain the above copyright\n notice, this list of conditions and the following disclaimer.\n\n * Redistributions in binary form must reproduce the above\n copyright notice, this list of conditions and the following\n disclaimer in the documentation and/or other materials provided\n with the distribution.\n\n * The names of the contributors may not be used to endorse or\n promote products derived from this software without specific\n prior written permission.\n\n THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifndef FXAA_REDUCE_MIN\n#define FXAA_REDUCE_MIN (1.0/ 128.0)\n#endif\n#ifndef FXAA_REDUCE_MUL\n#define FXAA_REDUCE_MUL (1.0 / 8.0)\n#endif\n#ifndef FXAA_SPAN_MAX\n#define FXAA_SPAN_MAX 8.0\n#endif\n\n//optimized version for mobile, where dependent\n//texture reads can be a bottleneck\nvec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 inverseVP,\n vec2 v_rgbNW, vec2 v_rgbNE,\n vec2 v_rgbSW, vec2 v_rgbSE,\n vec2 v_rgbM) {\n vec4 color;\n vec3 rgbNW = texture2D(tex, v_rgbNW).xyz;\n vec3 rgbNE = texture2D(tex, v_rgbNE).xyz;\n vec3 rgbSW = texture2D(tex, v_rgbSW).xyz;\n vec3 rgbSE = texture2D(tex, v_rgbSE).xyz;\n vec4 texColor = texture2D(tex, v_rgbM);\n vec3 rgbM = texColor.xyz;\n vec3 luma = vec3(0.299, 0.587, 0.114);\n float lumaNW = dot(rgbNW, luma);\n float lumaNE = dot(rgbNE, luma);\n float lumaSW = dot(rgbSW, luma);\n float lumaSE = dot(rgbSE, luma);\n float lumaM = dot(rgbM, luma);\n float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));\n float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));\n\n mediump vec2 dir;\n dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\n dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
39658\n\n float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *\n (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);\n\n float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);\n dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),\n max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),\n dir * rcpDirMin)) * inverseVP;\n\n vec3 rgbA = 0.5 * (\n texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz +\n texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz);\n vec3 rgbB = rgbA * 0.5 + 0.25 * (\n texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz +\n texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz);\n\n float lumaB = dot(rgbB, luma);\n if ((lumaB < lumaMin) || (lumaB > lumaMax))\n color = vec4(rgbA, texColor.a);\n else\n color = vec4(rgbB, texColor.a);\n return color;\n}\n\nvoid main() {\n\n vec4 color;\n\n color = fxaa(uSampler, vFragCoord, inputPixel.zw, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM);\n\n gl_FragColor = color;\n}\n"; 39659 39660 /** 39661 * Basic FXAA (Fast Approximate Anti-Aliasing) implementation based on the code on geeks3d.com 39662 * with the modification that the texture2DLod stuff was removed since it is unsupported by WebGL. 39663 * 39664 * @see https://github.com/mitsuhiko/webgl-meincraft 39665 * 39666 * @class 39667 * @extends PIXI.Filter 39668 * @memberof PIXI.filters 39669 * 39670 */ 39671 var FXAAFilter = /*@__PURE__*/(function (Filter) { 39672 function FXAAFilter() 39673 { 39674 // TODO - needs work 39675 Filter.call(this, vertex$5, fragment$6); 39676 } 39677 39678 if ( Filter ) { FXAAFilter.__proto__ = Filter; } 39679 FXAAFilter.prototype = Object.create( Filter && Filter.prototype ); 39680 FXAAFilter.prototype.constructor = FXAAFilter; 39681 39682 return FXAAFilter; 39683 }(Filter)); 39684 39685 /*! 39686 * @pixi/filter-noise - v5.0.0-rc.3 39687 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 39688 * 39689 * @pixi/filter-noise is licensed under the MIT License. 39690 * http://www.opensource.org/licenses/mit-license 39691 */ 39692 39693 var fragment$7 = "precision highp float;\n\nvarying vec2 vTextureCoord;\nvarying vec4 vColor;\n\nuniform float uNoise;\nuniform float uSeed;\nuniform sampler2D uSampler;\n\nfloat rand(vec2 co)\n{\n return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453);\n}\n\nvoid main()\n{\n vec4 color = texture2D(uSampler, vTextureCoord);\n float randomValue = rand(gl_FragCoord.xy * uSeed);\n float diff = (randomValue - 0.5) * uNoise;\n\n // Un-premultiply alpha before applying the color matrix. See issue #3539.\n if (color.a > 0.0) {\n color.rgb /= color.a;\n }\n\n color.r += diff;\n color.g += diff;\n color.b += diff;\n\n // Premultiply alpha again.\n color.rgb *= color.a;\n\n gl_FragColor = color;\n}\n"; 39694 39695 /** 39696 * @author Vico @vicocotea 39697 * original filter: https://github.com/evanw/glfx.js/blob/master/src/filters/adjust/noise.js 39698 */ 39699 39700 /** 39701 * A Noise effect filter. 39702 * 39703 * @class 39704 * @extends PIXI.Filter 39705 * @memberof PIXI.filters 39706 */ 39707 var NoiseFilter = /*@__PURE__*/(function (Filter) { 39708 function NoiseFilter(noise, seed) 39709 { 39710 if ( noise === void 0 ) { noise = 0.5; } 39711 if ( seed === void 0 ) { seed = Math.random(); } 39712 39713 Filter.call(this, defaultFilter, fragment$7, { 39714 uNoise: 0, 39715 uSeed: 0, 39716 }); 39717 39718 this.noise = noise; 39719 this.seed = seed; 39720 } 39721 39722 if ( Filter ) { NoiseFilter.__proto__ = Filter; } 39723 NoiseFilter.prototype = Object.create( Filter && Filter.prototype ); 39724 NoiseFilter.prototype.constructor = NoiseFilter; 39725 39726 var prototypeAccessors = { noise: { configurable: true },seed: { configurable: true } }; 39727 39728 /** 39729 * The amount of noise to apply, this value should be in the range (0, 1]. 39730 * 39731 * @member {number} 39732 * @default 0.5 39733 */ 39734 prototypeAccessors.noise.get = function () 39735 { 39736 return this.uniforms.uNoise; 39737 }; 39738 39739 prototypeAccessors.noise.set = function (value) // eslint-disable-line require-jsdoc 39740 { 39741 this.uniforms.uNoise = value; 39742 }; 39743 39744 /** 39745 * A seed value to apply to the random noise generation. `Math.random()` is a good value to use. 39746 * 39747 * @member {number} 39748 */ 39749 prototypeAccessors.seed.get = function () 39750 { 39751 return this.uniforms.uSeed; 39752 }; 39753 39754 prototypeAccessors.seed.set = function (value) // eslint-disable-line require-jsdoc 39755 { 39756 this.uniforms.uSeed = value; 39757 }; 39758 39759 Object.defineProperties( NoiseFilter.prototype, prototypeAccessors ); 39760 39761 return NoiseFilter; 39762 }(Filter)); 39763 39764 /*! 39765 * @pixi/mixin-cache-as-bitmap - v5.0.0-rc.3 39766 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 39767 * 39768 * @pixi/mixin-cache-as-bitmap is licensed under the MIT License. 39769 * http://www.opensource.org/licenses/mit-license 39770 */ 39771 39772 var _tempMatrix = new Matrix(); 39773 39774 DisplayObject.prototype._cacheAsBitmap = false;
39775 DisplayObject.prototype._cacheData = false; 39776 39777 // figured theres no point adding ALL the extra variables to prototype. 39778 // this model can hold the information needed. This can also be generated on demand as 39779 // most objects are not cached as bitmaps. 39780 /** 39781 * @class 39782 * @ignore 39783 */ 39784 var CacheData = function CacheData() 39785 { 39786 this.textureCacheId = null; 39787 39788 this.originalRender = null; 39789 this.originalRenderCanvas = null; 39790 this.originalCalculateBounds = null; 39791 this.originalGetLocalBounds = null; 39792 39793 this.originalUpdateTransform = null; 39794 this.originalHitTest = null; 39795 this.originalDestroy = null; 39796 this.originalMask = null; 39797 this.originalFilterArea = null; 39798 this.sprite = null; 39799 }; 39800 39801 Object.defineProperties(DisplayObject.prototype, { 39802 /** 39803 * Set this to true if you want this display object to be cached as a bitmap. 39804 * This basically takes a snap shot of the display object as it is at that moment. It can 39805 * provide a performance benefit for complex static displayObjects. 39806 * To remove simply set this property to `false` 39807 * 39808 * IMPORTANT GOTCHA - Make sure that all your textures are preloaded BEFORE setting this property to true 39809 * as it will take a snapshot of what is currently there. If the textures have not loaded then they will not appear. 39810 * 39811 * @member {boolean} 39812 * @memberof PIXI.DisplayObject# 39813 */ 39814 cacheAsBitmap: { 39815 get: function get() 39816 { 39817 return this._cacheAsBitmap; 39818 }, 39819 set: function set(value) 39820 { 39821 if (this._cacheAsBitmap === value) 39822 { 39823 return; 39824 } 39825 39826 this._cacheAsBitmap = value; 39827 39828 var data; 39829 39830 if (value) 39831 { 39832 if (!this._cacheData) 39833 { 39834 this._cacheData = new CacheData(); 39835 } 39836 39837 data = this._cacheData; 39838 39839 data.originalRender = this.render; 39840 data.originalRenderCanvas = this.renderCanvas; 39841 39842 data.originalUpdateTransform = this.updateTransform; 39843 data.originalCalculateBounds = this.calculateBounds; 39844 data.originalGetLocalBounds = this.getLocalBounds; 39845 39846 data.originalDestroy = this.destroy; 39847 39848 data.originalContainsPoint = this.containsPoint; 39849 39850 data.originalMask = this._mask; 39851 data.originalFilterArea = this.filterArea; 39852 39853 this.render = this._renderCached; 39854 this.renderCanvas = this._renderCachedCanvas; 39855 39856 this.destroy = this._cacheAsBitmapDestroy; 39857 } 39858 else 39859 { 39860 data = this._cacheData; 39861 39862 if (data.sprite) 39863 { 39864 this._destroyCachedDisplayObject(); 39865 } 39866 39867 this.render = data.originalRender; 39868 this.renderCanvas = data.originalRenderCanvas; 39869 this.calculateBounds = data.originalCalculateBounds; 39870 this.getLocalBounds = data.originalGetLocalBounds; 39871 39872 this.destroy = data.originalDestroy; 39873 39874 this.updateTransform = data.originalUpdateTransform; 39875 this.containsPoint = data.originalContainsPoint; 39876 39877 this._mask = data.originalMask; 39878 this.filterArea = data.originalFilterArea; 39879 } 39880 }, 39881 }, 39882 }); 39883 39884 /** 39885 * Renders a cached version of the sprite with WebGL 39886 * 39887 * @private 39888 * @function _renderCached 39889 * @memberof PIXI.DisplayObject# 39890 * @param {PIXI.Renderer} renderer - the WebGL renderer 39891 */ 39892 DisplayObject.prototype._renderCached = function _renderCached(renderer) 39893 { 39894 if (!this.visible || this.worldAlpha <= 0 || !this.renderable) 39895 { 39896 return; 39897 } 39898 39899 this._initCachedDisplayObject(renderer); 39900 39901 this._cacheData.sprite.transform._worldID = this.transform._worldID; 39902 this._cacheData.sprite.worldAlpha = this.worldAlpha; 39903 this._cacheData.sprite._render(renderer); 39904 }; 39905 39906 /** 39907 * Prepares the WebGL renderer to cache the sprite 39908 * 39909 * @private 39910 * @function _initCachedDisplayObject 39911 * @memberof PIXI.DisplayObject# 39912 * @param {PIXI.Renderer} renderer - the WebGL renderer 39913 */ 39914 DisplayObject.prototype._initCachedDisplayObject = function _initCachedDisplayObject(renderer) 39915 { 39916 if (this._cacheData && this._cacheData.sprite) 39917 { 39918 return; 39919 } 39920 39921 // make sure alpha is set to 1 otherwise it will get rendered as invisible! 39922 var cacheAlpha = this.alpha; 39923 39924 this.alpha = 1; 39925 39926 // first we flush anything left in the renderer (otherwise it would get rendered to the cached texture) 39927 renderer.batch.flush(); 39928 // this.filters= []; 39929 39930 // next we find the dimensions of the untransformed object 39931 // this function also calls updatetransform on all its children as part of the measuring. 39932 // This means we don't need to update the transform again in this function 39933 // TODO pass an object to clone too? saves having to create a new one each time! 39934 var bounds = this.getLocalBounds().clone(); 39935 39936 // add some padding! 39937 if (this.filters) 39938 { 39939 var padding = this.filters[0].padding; 39940 39941 bounds.pad(padding); 39942 } 39943 39944 bounds.ceil(settings.RESOLUTION); 39945 39946 // for now we cache the current renderTarget that the WebGL renderer is currently using. 39947 // this could be more elegant.. 39948 var cachedRenderTarget = renderer._activeRenderTarget; 39949 // We also store the filter stack - I will definitely look to change how this works a little later down the line.
39950 // const stack = renderer.filterManager.filterStack; 39951 39952 // this renderTexture will be used to store the cached DisplayObject 39953 var renderTexture = RenderTexture.create(bounds.width, bounds.height); 39954 39955 var textureCacheId = "cacheAsBitmap_" + (uid()); 39956 39957 this._cacheData.textureCacheId = textureCacheId; 39958 39959 BaseTexture.addToCache(renderTexture.baseTexture, textureCacheId); 39960 Texture.addToCache(renderTexture, textureCacheId); 39961 39962 // need to set // 39963 var m = _tempMatrix; 39964 39965 m.tx = -bounds.x; 39966 m.ty = -bounds.y; 39967 39968 // reset 39969 this.transform.worldTransform.identity(); 39970 39971 // set all properties to there original so we can render to a texture 39972 this.render = this._cacheData.originalRender; 39973 39974 renderer.render(this, renderTexture, true, m, true); 39975 // now restore the state be setting the new properties 39976 39977 renderer.renderTexture.bind(cachedRenderTarget); 39978 39979 // renderer.filterManager.filterStack = stack; 39980 39981 this.render = this._renderCached; 39982 // the rest is the same as for Canvas 39983 this.updateTransform = this.displayObjectUpdateTransform; 39984 this.calculateBounds = this._calculateCachedBounds; 39985 this.getLocalBounds = this._getCachedLocalBounds; 39986 39987 this._mask = null; 39988 this.filterArea = null; 39989 39990 // create our cached sprite 39991 var cachedSprite = new Sprite(renderTexture); 39992 39993 cachedSprite.transform.worldTransform = this.transform.worldTransform; 39994 cachedSprite.anchor.x = -(bounds.x / bounds.width); 39995 cachedSprite.anchor.y = -(bounds.y / bounds.height); 39996 cachedSprite.alpha = cacheAlpha; 39997 cachedSprite._bounds = this._bounds; 39998 39999 this._cacheData.sprite = cachedSprite; 40000 40001 this.transform._parentID = -1; 40002 // restore the transform of the cached sprite to avoid the nasty flicker.. 40003 if (!this.parent) 40004 { 40005 this.parent = renderer._tempDisplayObjectParent; 40006 this.updateTransform(); 40007 this.parent = null; 40008 } 40009 else 40010 { 40011 this.updateTransform(); 40012 } 40013 40014 // map the hit test.. 40015 this.containsPoint = cachedSprite.containsPoint.bind(cachedSprite); 40016 }; 40017 40018 /** 40019 * Renders a cached version of the sprite with canvas 40020 * 40021 * @private 40022 * @function _renderCachedCanvas 40023 * @memberof PIXI.DisplayObject# 40024 * @param {PIXI.Renderer} renderer - the WebGL renderer 40025 */ 40026 DisplayObject.prototype._renderCachedCanvas = function _renderCachedCanvas(renderer) 40027 { 40028 if (!this.visible || this.worldAlpha <= 0 || !this.renderable) 40029 { 40030 return; 40031 } 40032 40033 this._initCachedDisplayObjectCanvas(renderer); 40034 40035 this._cacheData.sprite.worldAlpha = this.worldAlpha; 40036 this._cacheData.sprite._renderCanvas(renderer); 40037 }; 40038 40039 // TODO this can be the same as the WebGL version.. will need to do a little tweaking first though.. 40040 /** 40041 * Prepares the Canvas renderer to cache the sprite 40042 * 40043 * @private 40044 * @function _initCachedDisplayObjectCanvas 40045 * @memberof PIXI.DisplayObject# 40046 * @param {PIXI.Renderer} renderer - the WebGL renderer 40047 */ 40048 DisplayObject.prototype._initCachedDisplayObjectCanvas = function _initCachedDisplayObjectCanvas(renderer) 40049 { 40050 if (this._cacheData && this._cacheData.sprite) 40051 { 40052 return; 40053 } 40054 40055 // get bounds actually transforms the object for us already! 40056 var bounds = this.getLocalBounds(); 40057 40058 var cacheAlpha = this.alpha; 40059 40060 this.alpha = 1; 40061 40062 var cachedRenderTarget = renderer.context; 40063 40064 bounds.ceil(settings.RESOLUTION); 40065 40066 var renderTexture = RenderTexture.create(bounds.width, bounds.height); 40067 40068 var textureCacheId = "cacheAsBitmap_" + (uid()); 40069 40070 this._cacheData.textureCacheId = textureCacheId; 40071 40072 BaseTexture.addToCache(renderTexture.baseTexture, textureCacheId); 40073 Texture.addToCache(renderTexture, textureCacheId); 40074 40075 // need to set // 40076 var m = _tempMatrix; 40077 40078 this.transform.localTransform.copyTo(m); 40079 m.invert(); 40080 40081 m.tx -= bounds.x; 40082 m.ty -= bounds.y; 40083 40084 // m.append(this.transform.worldTransform.) 40085 // set all properties to there original so we can render to a texture 40086 this.renderCanvas = this._cacheData.originalRenderCanvas; 40087 40088 // renderTexture.render(this, m, true); 40089 renderer.render(this, renderTexture, true, m, false); 40090 40091 // now restore the state be setting the new properties 40092 renderer.context = cachedRenderTarget; 40093 40094 this.renderCanvas = this._renderCachedCanvas; 40095 // the rest is the same as for WebGL 40096 this.updateTransform = this.displayObjectUpdateTransform; 40097 this.calculateBounds = this._calculateCachedBounds; 40098 this.getLocalBounds = this._getCachedLocalBounds; 40099 40100 this._mask = null; 40101 this.filterArea = null; 40102 40103 // create our cached sprite 40104 var cachedSprite = new Sprite(renderTexture); 40105 40106 cachedSprite.transform.worldTransform = this.transform.worldTransform;
40107 cachedSprite.anchor.x = -(bounds.x / bounds.width); 40108 cachedSprite.anchor.y = -(bounds.y / bounds.height); 40109 cachedSprite.alpha = cacheAlpha; 40110 cachedSprite._bounds = this._bounds; 40111 40112 this._cacheData.sprite = cachedSprite; 40113 40114 this.transform._parentID = -1; 40115 // restore the transform of the cached sprite to avoid the nasty flicker.. 40116 if (!this.parent) 40117 { 40118 this.parent = renderer._tempDisplayObjectParent; 40119 this.updateTransform(); 40120 this.parent = null; 40121 } 40122 else 40123 { 40124 this.updateTransform(); 40125 } 40126 40127 // map the hit test.. 40128 this.containsPoint = cachedSprite.containsPoint.bind(cachedSprite); 40129 }; 40130 40131 /** 40132 * Calculates the bounds of the cached sprite 40133 * 40134 * @private 40135 */ 40136 DisplayObject.prototype._calculateCachedBounds = function _calculateCachedBounds() 40137 { 40138 this._bounds.clear(); 40139 this._cacheData.sprite.transform._worldID = this.transform._worldID; 40140 this._cacheData.sprite._calculateBounds(); 40141 this._lastBoundsID = this._boundsID; 40142 }; 40143 40144 /** 40145 * Gets the bounds of the cached sprite. 40146 * 40147 * @private 40148 * @return {Rectangle} The local bounds. 40149 */ 40150 DisplayObject.prototype._getCachedLocalBounds = function _getCachedLocalBounds() 40151 { 40152 return this._cacheData.sprite.getLocalBounds(); 40153 }; 40154 40155 /** 40156 * Destroys the cached sprite. 40157 * 40158 * @private 40159 */ 40160 DisplayObject.prototype._destroyCachedDisplayObject = function _destroyCachedDisplayObject() 40161 { 40162 this._cacheData.sprite._texture.destroy(true); 40163 this._cacheData.sprite = null; 40164 40165 BaseTexture.removeFromCache(this._cacheData.textureCacheId); 40166 Texture.removeFromCache(this._cacheData.textureCacheId); 40167 40168 this._cacheData.textureCacheId = null; 40169 }; 40170 40171 /** 40172 * Destroys the cached object. 40173 * 40174 * @private 40175 * @param {object|boolean} [options] - Options parameter. A boolean will act as if all options 40176 * have been set to that value. 40177 * Used when destroying containers, see the Container.destroy method. 40178 */ 40179 DisplayObject.prototype._cacheAsBitmapDestroy = function _cacheAsBitmapDestroy(options) 40180 { 40181 this.cacheAsBitmap = false; 40182 this.destroy(options); 40183 }; 40184 40185 /*! 40186 * @pixi/mixin-get-child-by-name - v5.0.0-rc.3 40187 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 40188 * 40189 * @pixi/mixin-get-child-by-name is licensed under the MIT License. 40190 * http://www.opensource.org/licenses/mit-license 40191 */ 40192 40193 /** 40194 * The instance name of the object. 40195 * 40196 * @memberof PIXI.DisplayObject# 40197 * @member {string} name 40198 */ 40199 DisplayObject.prototype.name = null; 40200 40201 /** 40202 * Returns the display object in the container. 40203 * 40204 * @method getChildByName 40205 * @memberof PIXI.Container# 40206 * @param {string} name - Instance name. 40207 * @return {PIXI.DisplayObject} The child with the specified name. 40208 */ 40209 Container.prototype.getChildByName = function getChildByName(name) 40210 { 40211 for (var i = 0; i < this.children.length; i++) 40212 { 40213 if (this.children[i].name === name) 40214 { 40215 return this.children[i]; 40216 } 40217 } 40218 40219 return null; 40220 }; 40221 40222 /*! 40223 * @pixi/mixin-get-global-position - v5.0.0-rc.3 40224 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 40225 * 40226 * @pixi/mixin-get-global-position is licensed under the MIT License. 40227 * http://www.opensource.org/licenses/mit-license 40228 */ 40229 40230 /** 40231 * Returns the global position of the displayObject. Does not depend on object scale, rotation and pivot. 40232 * 40233 * @method getGlobalPosition 40234 * @memberof PIXI.DisplayObject# 40235 * @param {Point} point - The point to write the global value to. If null a new point will be returned 40236 * @param {boolean} skipUpdate - Setting to true will stop the transforms of the scene graph from 40237 * being updated. This means the calculation returned MAY be out of date BUT will give you a 40238 * nice performance boost. 40239 * @return {Point} The updated point. 40240 */ 40241 DisplayObject.prototype.getGlobalPosition = function getGlobalPosition(point, skipUpdate) 40242 { 40243 if ( point === void 0 ) { point = new Point(); } 40244 if ( skipUpdate === void 0 ) { skipUpdate = false; } 40245 40246 if (this.parent) 40247 { 40248 this.parent.toGlobal(this.position, point, skipUpdate); 40249 } 40250 else 40251 { 40252 point.x = this.position.x; 40253 point.y = this.position.y; 40254 } 40255 40256 return point; 40257 }; 40258 40259 /*! 40260 * @pixi/mesh - v5.0.0-rc.3 40261 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 40262 * 40263 * @pixi/mesh is licensed under the MIT License. 40264 * http://www.opensource.org/licenses/mit-license 40265 */ 40266 40267 /**
40268 * Class controls cache for UV mapping from Texture normal space to BaseTexture normal space. 40269 * 40270 * @class 40271 * @memberof PIXI 40272 */ 40273 var MeshBatchUvs = function MeshBatchUvs(uvBuffer, uvMatrix) 40274 { 40275 /** 40276 * Buffer with normalized UV's 40277 * @member {PIXI.Buffer} 40278 */ 40279 this.uvBuffer = uvBuffer; 40280 40281 /** 40282 * Material UV matrix 40283 * @member {PIXI.TextureMatrix} 40284 */ 40285 this.uvMatrix = uvMatrix; 40286 40287 /** 40288 * UV Buffer data 40289 * @member {Float32Array} 40290 * @readonly 40291 */ 40292 this.data = null; 40293 40294 this._bufferUpdateId = -1; 40295 40296 this._textureUpdateId = -1; 40297 40298 this._updateID = 0; 40299 }; 40300 40301 /** 40302 * updates 40303 * 40304 * @param {boolean} forceUpdate - force the update 40305 */ 40306 MeshBatchUvs.prototype.update = function update (forceUpdate) 40307 { 40308 if (!forceUpdate 40309 && this._bufferUpdateId === this.uvBuffer._updateID 40310 && this._textureUpdateId === this.uvMatrix._updateID) 40311 { 40312 return; 40313 } 40314 40315 this._bufferUpdateId = this.uvBuffer._updateID; 40316 this._textureUpdateId = this.uvMatrix._updateID; 40317 40318 var data = this.uvBuffer.data; 40319 40320 if (!this.data || this.data.length !== data.length) 40321 { 40322 this.data = new Float32Array(data.length); 40323 } 40324 40325 this.uvMatrix.multiplyUvs(data, this.data); 40326 40327 this._updateID++; 40328 }; 40329 40330 var tempPoint$2 = new Point(); 40331 var tempPolygon = new Polygon(); 40332 40333 /** 40334 * Base mesh class. 40335 * 40336 * This class empowers you to have maximum flexibility to render any kind of WebGL visuals you can think of. 40337 * This class assumes a certain level of WebGL knowledge. 40338 * If you know a bit this should abstract enough away to make you life easier! 40339 * 40340 * Pretty much ALL WebGL can be broken down into the following: 40341 * - Geometry - The structure and data for the mesh. This can include anything from positions, uvs, normals, colors etc.. 40342 * - Shader - This is the shader that PixiJS will render the geometry with (attributes in the shader must match the geometry) 40343 * - State - This is the state of WebGL required to render the mesh. 40344 * 40345 * Through a combination of the above elements you can render anything you want, 2D or 3D! 40346 * 40347 * @class 40348 * @extends PIXI.Container 40349 * @memberof PIXI 40350 */ 40351 var Mesh = /*@__PURE__*/(function (Container) { 40352 function Mesh(geometry, shader, state, drawMode)// vertices, uvs, indices, drawMode) 40353 { 40354 if ( drawMode === void 0 ) { drawMode = DRAW_MODES.TRIANGLES; } 40355 40356 Container.call(this); 40357 40358 /** 40359 * Includes vertex positions, face indices, normals, colors, UVs, and 40360 * custom attributes within buffers, reducing the cost of passing all 40361 * this data to the GPU. Can be shared between multiple Mesh objects. 40362 * @member {PIXI.Geometry} 40363 * @readonly 40364 */ 40365 this.geometry = geometry; 40366 40367 geometry.refCount++; 40368 40369 /** 40370 * Represents the vertex and fragment shaders that processes the geometry and runs on the GPU. 40371 * Can be shared between multiple Mesh objects. 40372 * @member {PIXI.Shader|PIXI.MeshMaterial} 40373 */ 40374 this.shader = shader; 40375 40376 /** 40377 * Represents the WebGL state the Mesh required to render, excludes shader and geometry. E.g., 40378 * blend mode, culling, depth testing, direction of rendering triangles, backface, etc. 40379 * @member {PIXI.State} 40380 */ 40381 this.state = state || State.for2d(); 40382 40383 /** 40384 * The way the Mesh should be drawn, can be any of the {@link PIXI.DRAW_MODES} constants. 40385 * 40386 * @member {number} 40387 * @see PIXI.DRAW_MODES 40388 */ 40389 this.drawMode = drawMode; 40390 40391 /** 40392 * Typically the index of the IndexBuffer where to start drawing. 40393 * @member {number} 40394 * @default 0 40395 */ 40396 this.start = 0; 40397 40398 /** 40399 * How much of the geometry to draw, by default `0` renders everything. 40400 * @member {number} 40401 * @default 0 40402 */ 40403 this.size = 0; 40404 40405 /** 40406 * thease are used as easy access for batching 40407 * @member {Float32Array} 40408 * @private 40409 */ 40410 this.uvs = null; 40411 40412 /** 40413 * thease are used as easy access for batching 40414 * @member {Uint16Array} 40415 * @private 40416 */ 40417 this.indices = null; 40418 40419 /** 40420 * this is the caching layer used by the batcher 40421 * @member {Float32Array} 40422 * @private 40423 */ 40424 this.vertexData = new Float32Array(1); 40425 40426 /** 40427 * If geometry is changed used to decide to re-transform 40428 * the vertexData. 40429 * @member {number} 40430 * @private 40431 */ 40432 this.vertexDirty = 0; 40433
40434 this._transformID = -1; 40435 40436 // Inherited from DisplayMode, set defaults 40437 this.tint = 0xFFFFFF; 40438 this.blendMode = BLEND_MODES.NORMAL; 40439 40440 /** 40441 * Internal roundPixels field 40442 * 40443 * @member {boolean} 40444 * @private 40445 */ 40446 this._roundPixels = settings.ROUND_PIXELS; 40447 40448 /** 40449 * Batched UV's are cached for atlas textures 40450 * @member {PIXI.MeshBatchUvs} 40451 * @private 40452 */ 40453 this.batchUvs = null; 40454 } 40455 40456 if ( Container ) { Mesh.__proto__ = Container; } 40457 Mesh.prototype = Object.create( Container && Container.prototype ); 40458 Mesh.prototype.constructor = Mesh; 40459 40460 var prototypeAccessors = { uvBuffer: { configurable: true },verticesBuffer: { configurable: true },material: { configurable: true },blendMode: { configurable: true },roundPixels: { configurable: true },tint: { configurable: true },texture: { configurable: true } }; 40461 40462 /** 40463 * To change mesh uv's, change its uvBuffer data and increment its _updateID. 40464 * @member {PIXI.Buffer} 40465 * @readonly 40466 */ 40467 prototypeAccessors.uvBuffer.get = function () 40468 { 40469 return this.geometry.buffers[1].data; 40470 }; 40471 40472 /** 40473 * To change mesh vertices, change its uvBuffer data and increment its _updateID. 40474 * Incrementing _updateID is optional because most of Mesh objects do it anyway. 40475 * @member {PIXI.Buffer} 40476 * @readonly 40477 */ 40478 prototypeAccessors.verticesBuffer.get = function () 40479 { 40480 return this.geometry.buffers[0].data; 40481 }; 40482 40483 /** 40484 * Alias for {@link PIXI.Mesh#shader}. 40485 * @member {PIXI.Shader|PIXI.MeshMaterial} 40486 */ 40487 prototypeAccessors.material.set = function (value) 40488 { 40489 this.shader = value; 40490 }; 40491 40492 prototypeAccessors.material.get = function () 40493 { 40494 return this.shader; 40495 }; 40496 40497 /** 40498 * The blend mode to be applied to the Mesh. Apply a value of 40499 * `PIXI.BLEND_MODES.NORMAL` to reset the blend mode. 40500 * 40501 * @member {number} 40502 * @default PIXI.BLEND_MODES.NORMAL; 40503 * @see PIXI.BLEND_MODES 40504 */ 40505 prototypeAccessors.blendMode.set = function (value) 40506 { 40507 this.state.blendMode = value; 40508 }; 40509 40510 prototypeAccessors.blendMode.get = function () 40511 { 40512 return this.state.blendMode; 40513 }; 40514 40515 /** 40516 * If true PixiJS will Math.floor() x/y values when rendering, stopping pixel interpolation. 40517 * Advantages can include sharper image quality (like text) and faster rendering on canvas. 40518 * The main disadvantage is movement of objects may appear less smooth. 40519 * To set the global default, change {@link PIXI.settings.ROUND_PIXELS} 40520 * 40521 * @member {boolean} 40522 * @default false 40523 */ 40524 prototypeAccessors.roundPixels.set = function (value) 40525 { 40526 if (this._roundPixels !== value) 40527 { 40528 this._transformID = -1; 40529 } 40530 this._roundPixels = value; 40531 }; 40532 40533 prototypeAccessors.roundPixels.get = function () 40534 { 40535 return this._roundPixels; 40536 }; 40537 40538 /** 40539 * The multiply tint applied to the Mesh. This is a hex value. A value of 40540 * `0xFFFFFF` will remove any tint effect. 40541 * 40542 * @member {number} 40543 * @default 0xFFFFFF 40544 */ 40545 prototypeAccessors.tint.get = function () 40546 { 40547 return this.shader.tint; 40548 }; 40549 40550 prototypeAccessors.tint.set = function (value) 40551 { 40552 this.shader.tint = value; 40553 }; 40554 40555 /** 40556 * The texture that the Mesh uses. 40557 * 40558 * @member {PIXI.Texture} 40559 */ 40560 prototypeAccessors.texture.get = function () 40561 { 40562 return this.shader.texture; 40563 }; 40564 40565 prototypeAccessors.texture.set = function (value) 40566 { 40567 this.shader.texture = value; 40568 }; 40569 40570 /** 40571 * Standard renderer draw. 40572 * @protected 40573 */ 40574 Mesh.prototype._render = function _render (renderer) 40575 { 40576 // set properties for batching.. 40577 // TODO could use a different way to grab verts? 40578 var vertices = this.geometry.buffers[0].data; 40579 40580 // TODO benchmark check for attribute size.. 40581 if (this.shader.batchable && this.drawMode === DRAW_MODES.TRIANGLES && vertices.length < Mesh.BATCHABLE_SIZE * 2) 40582 { 40583 this._renderToBatch(renderer); 40584 } 40585 else 40586 { 40587 this._renderDefault(renderer); 40588 } 40589 }; 40590 40591 /** 40592 * Standard non-batching way of rendering. 40593 * @protected 40594 * @param {PIXI.Renderer} renderer - Instance to renderer. 40595 */ 40596 Mesh.prototype._renderDefault = function _renderDefault (renderer) 40597 { 40598 var shader = this.shader; 40599 40600 shader.alpha = this.worldAlpha; 40601 if (shader.update) 40602 {
40603 shader.update(); 40604 } 40605 40606 renderer.batch.flush(); 40607 40608 if (shader.program.uniformData.translationMatrix) 40609 { 40610 shader.uniforms.translationMatrix = this.transform.worldTransform.toArray(true); 40611 } 40612 40613 // bind and sync uniforms.. 40614 renderer.shader.bind(shader); 40615 40616 // set state.. 40617 renderer.state.setState(this.state); 40618 40619 // bind the geometry... 40620 renderer.geometry.bind(this.geometry, shader); 40621 40622 // then render it 40623 renderer.geometry.draw(this.drawMode, this.size, this.start, this.geometry.instanceCount); 40624 }; 40625 40626 /** 40627 * Rendering by using the Batch system. 40628 * @protected 40629 * @param {PIXI.Renderer} renderer - Instance to renderer. 40630 */ 40631 Mesh.prototype._renderToBatch = function _renderToBatch (renderer) 40632 { 40633 var geometry = this.geometry; 40634 40635 if (this.shader.uvMatrix) 40636 { 40637 this.shader.uvMatrix.update(); 40638 this.calculateUvs(); 40639 } 40640 40641 // set properties for batching.. 40642 this.calculateVertices(); 40643 this.indices = geometry.indexBuffer.data; 40644 this._tintRGB = this.shader._tintRGB; 40645 this._texture = this.shader.texture; 40646 40647 var pluginName = this.material.pluginName; 40648 40649 renderer.batch.setObjectRenderer(renderer.plugins[pluginName]); 40650 renderer.plugins[pluginName].render(this); 40651 }; 40652 40653 /** 40654 * Updates vertexData field based on transform and vertices 40655 */ 40656 Mesh.prototype.calculateVertices = function calculateVertices () 40657 { 40658 var geometry = this.geometry; 40659 var vertices = geometry.buffers[0].data; 40660 40661 if (geometry.vertexDirtyId === this.vertexDirty && this._transformID === this.transform._worldID) 40662 { 40663 return; 40664 } 40665 40666 this._transformID = this.transform._worldID; 40667 40668 if (this.vertexData.length !== vertices.length) 40669 { 40670 this.vertexData = new Float32Array(vertices.length); 40671 } 40672 40673 var wt = this.transform.worldTransform; 40674 var a = wt.a; 40675 var b = wt.b; 40676 var c = wt.c; 40677 var d = wt.d; 40678 var tx = wt.tx; 40679 var ty = wt.ty; 40680 40681 var vertexData = this.vertexData; 40682 40683 for (var i = 0; i < vertexData.length / 2; i++) 40684 { 40685 var x = vertices[(i * 2)]; 40686 var y = vertices[(i * 2) + 1]; 40687 40688 vertexData[(i * 2)] = (a * x) + (c * y) + tx; 40689 vertexData[(i * 2) + 1] = (b * x) + (d * y) + ty; 40690 } 40691 40692 if (this._roundPixels) 40693 { 40694 for (var i$1 = 0; i$1 < vertexData.length; i$1++) 40695 { 40696 vertexData[i$1] = Math.round(vertexData[i$1]); 40697 } 40698 } 40699 40700 this.vertexDirty = geometry.vertexDirtyId; 40701 }; 40702 40703 /** 40704 * Updates uv field based on from geometry uv's or batchUvs 40705 */ 40706 Mesh.prototype.calculateUvs = function calculateUvs () 40707 { 40708 var geomUvs = this.geometry.buffers[1]; 40709 40710 if (!this.shader.uvMatrix.isSimple) 40711 { 40712 if (!this.batchUvs) 40713 { 40714 this.batchUvs = new MeshBatchUvs(geomUvs, this.shader.uvMatrix); 40715 } 40716 this.batchUvs.update(); 40717 this.uvs = this.batchUvs.data; 40718 } 40719 else 40720 { 40721 this.uvs = geomUvs.data; 40722 } 40723 }; 40724 40725 /** 40726 * Updates the bounds of the mesh as a rectangle. The bounds calculation takes the worldTransform into account. 40727 * there must be a aVertexPosition attribute present in the geometry for bounds to be calculated correctly. 40728 * 40729 * @protected 40730 */ 40731 Mesh.prototype._calculateBounds = function _calculateBounds () 40732 { 40733 this.calculateVertices(); 40734 40735 this._bounds.addVertexData(this.vertexData, 0, this.vertexData.length); 40736 }; 40737 40738 /** 40739 * Tests if a point is inside this mesh. Works only for PIXI.DRAW_MODES.TRIANGLES. 40740 * 40741 * @param {PIXI.Point} point the point to test 40742 * @return {boolean} the result of the test 40743 */ 40744 Mesh.prototype.containsPoint = function containsPoint (point) 40745 { 40746 if (!this.getBounds().contains(point.x, point.y)) 40747 { 40748 return false;
40749 } 40750 40751 this.worldTransform.applyInverse(point, tempPoint$2); 40752 40753 var vertices = this.geometry.getAttribute('aVertexPosition').data; 40754 40755 var points = tempPolygon.points; 40756 var indices = this.geometry.getIndex().data; 40757 var len = indices.length; 40758 var step = this.drawMode === 4 ? 3 : 1; 40759 40760 for (var i = 0; i + 2 < len; i += step) 40761 { 40762 var ind0 = indices[i] * 2; 40763 var ind1 = indices[i + 1] * 2; 40764 var ind2 = indices[i + 2] * 2; 40765 40766 points[0] = vertices[ind0]; 40767 points[1] = vertices[ind0 + 1]; 40768 points[2] = vertices[ind1]; 40769 points[3] = vertices[ind1 + 1]; 40770 points[4] = vertices[ind2]; 40771 points[5] = vertices[ind2 + 1]; 40772 40773 if (tempPolygon.contains(tempPoint$2.x, tempPoint$2.y)) 40774 { 40775 return true; 40776 } 40777 } 40778 40779 return false; 40780 }; 40781 /** 40782 * Destroys the Mesh object. 40783 * 40784 * @param {object|boolean} [options] - Options parameter. A boolean will act as if all 40785 * options have been set to that value 40786 * @param {boolean} [options.children=false] - if set to true, all the children will have 40787 * their destroy method called as well. 'options' will be passed on to those calls. 40788 */ 40789 Mesh.prototype.destroy = function destroy (options) 40790 { 40791 Container.prototype.destroy.call(this, options); 40792 40793 this.geometry.refCount--; 40794 if (this.geometry.refCount === 0) 40795 { 40796 this.geometry.dispose(); 40797 } 40798 40799 this.geometry = null; 40800 this.shader = null; 40801 this.state = null; 40802 this.uvs = null; 40803 this.indices = null; 40804 this.vertexData = null; 40805 }; 40806 40807 Object.defineProperties( Mesh.prototype, prototypeAccessors ); 40808 40809 return Mesh; 40810 }(Container)); 40811 40812 /** 40813 * The maximum number of vertices to consider batchable. Generally, the complexity 40814 * of the geometry. 40815 * @memberof PIXI.Mesh 40816 * @static 40817 * @member {number} BATCHABLE_SIZE 40818 */ 40819 Mesh.BATCHABLE_SIZE = 100; 40820 40821 var vertex$6 = "attribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\n\nuniform mat3 projectionMatrix;\nuniform mat3 translationMatrix;\nuniform mat3 uTextureMatrix;\n\nvarying vec2 vTextureCoord;\n\nvoid main(void)\n{\n gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0
40821)).xy, 0.0, 1.0);\n\n vTextureCoord = (uTextureMatrix * vec3(aTextureCoord, 1.0)).xy;\n}\n"; 40822 40823 var fragment$8 = "varying vec2 vTextureCoord;\nuniform vec4 uColor;\n\nuniform sampler2D uSampler;\n\nvoid main(void)\n{\n gl_FragColor = texture2D(uSampler, vTextureCoord) * uColor;\n}\n"; 40824 40825 /** 40826 * Slightly opinionated default shader for PixiJS 2D objects. 40827 * @class 40828 * @memberof PIXI 40829 * @extends PIXI.Shader 40830 */ 40831 var MeshMaterial = /*@__PURE__*/(function (Shader) { 40832 function MeshMaterial(uSampler, options) 40833 { 40834 var uniforms = { 40835 uSampler: uSampler, 40836 alpha: 1, 40837 uTextureMatrix: Matrix.IDENTITY, 40838 uColor: new Float32Array([1, 1, 1, 1]), 40839 }; 40840 40841 // Set defaults 40842 options = Object.assign({ 40843 tint: 0xFFFFFF, 40844 alpha: 1, 40845 pluginName: 'batch', 40846 }, options); 40847 40848 if (options.uniforms) 40849 { 40850 Object.assign(uniforms, options.uniforms); 40851 } 40852 40853 Shader.call(this, options.program || Program.from(vertex$6, fragment$8), uniforms); 40854 40855 /** 40856 * Only do update if tint or alpha changes. 40857 * @member {boolean} 40858 * @private 40859 * @default false 40860 */ 40861 this._colorDirty = false; 40862 40863 /** 40864 * TextureMatrix instance for this Mesh, used to track Texture changes 40865 * 40866 * @member {PIXI.TextureMatrix} 40867 * @readonly 40868 */ 40869 this.uvMatrix = new TextureMatrix(uSampler); 40870 40871 /** 40872 * `true` if shader can be batch with the renderer's batch system. 40873 * @member {boolean} 40874 * @default true 40875 */ 40876 this.batchable = options.program === undefined; 40877 40878 /** 40879 * Renderer plugin for batching 40880 * 40881 * @member {string} 40882 * @default 'batch' 40883 */ 40884 this.pluginName = options.pluginName; 40885 40886 this.tint = options.tint; 40887 this.alpha = options.alpha; 40888 } 40889 40890 if ( Shader ) { MeshMaterial.__proto__ = Shader; } 40891 MeshMaterial.prototype = Object.create( Shader && Shader.prototype ); 40892 MeshMaterial.prototype.constructor = MeshMaterial; 40893 40894 var prototypeAccessors = { texture: { configurable: true },alpha: { configurable: true },tint: { configurable: true } }; 40895 40896 /** 40897 * Reference to the texture being rendered. 40898 * @member {PIXI.Texture} 40899 */ 40900 prototypeAccessors.texture.get = function () 40901 { 40902 return this.uniforms.uSampler; 40903 }; 40904 prototypeAccessors.texture.set = function (value) 40905 { 40906 if (this.uniforms.uSampler !== value) 40907 { 40908 this.uniforms.uSampler = value; 40909 this.uvMatrix.texture = value; 40910 } 40911 }; 40912 40913 /** 40914 * This gets automatically set by the object using this. 40915 * 40916 * @default 1 40917 * @member {number} 40918 */ 40919 prototypeAccessors.alpha.set = function (value) 40920 { 40921 if (value === this._alpha) { return; } 40922 40923 this._alpha = value; 40924 this._colorDirty = true; 40925 }; 40926 prototypeAccessors.alpha.get = function () 40927 { 40928 return this._alpha; 40929 }; 40930 40931 /** 40932 * Multiply tint for the material. 40933 * @member {number} 40934 * @default 0xFFFFFF 40935 */ 40936 prototypeAccessors.tint.set = function (value) 40937 { 40938 if (value === this._tint) { return; } 40939 40940 this._tint = value; 40941 this._tintRGB = (value >> 16) + (value & 0xff00) + ((value & 0xff) << 16); 40942 this._colorDirty = true; 40943 }; 40944 prototypeAccessors.tint.get = function () 40945 { 40946 return this._tint; 40947 }; 40948 40949 /** 40950 * Gets called automatically by the Mesh. Intended to be overridden for custom 40951 * MeshMaterial objects. 40952 */ 40953 MeshMaterial.prototype.update = function update () 40954 { 40955 if (this._colorDirty) 40956 { 40957 this._colorDirty = false; 40958 var baseTexture = this.texture.baseTexture; 40959 40960 premultiplyTintToRgba(this._tint, this._alpha, this.uniforms.uColor, baseTexture.premultiplyAlpha); 40961 } 40962 if (this.uvMatrix.update()) 40963 { 40964 this.uniforms.uTextureMatrix = this.uvMatrix.mapCoord; 40965 } 40966 }; 40967 40968 Object.defineProperties( MeshMaterial.prototype, prototypeAccessors ); 40969 40970 return MeshMaterial; 40971 }(Shader)); 40972 40973 /** 40974 * Standard 2D geometry used in PixiJS. 40975 * 40976 * Geometry can be defined without passing in a style or data if required. 40977 * 40978 * ```js 40979 * const geometry = new PIXI.Geometry(); 40980 * 40981 * geometry.addAttribute('positions', [0, 0, 100, 0, 100, 100, 0, 100], 2); 40982 * geometry.addAttribute('uvs', [0,0,1,0,1,1,0,1], 2); 40983 * geometry.addIndex([0,1,2,1,3,2]); 40984 * 40985 * ``` 40986 * @class 40987 * @memberof PIXI 40988 * @extends PIXI.Geometry 40989 */ 40990 var MeshGeometry = /*@__PURE__*/(function (Geometry) { 40991 function MeshGeometry(vertices, uvs, index) 40992 { 40993 Geometry.call(this); 40994 40995 var verticesBuffer = new Buffer(vertices); 40996 var uvsBuffer = new Buffer(uvs, true); 40997 var indexBuffer = new Buffer(index, true, true); 40998 40999 this.addAttribute('aVertexPosition', verticesBuffer, 2, false, TYPES.FLOAT) 41000 .addAttribute('aTextureCoord', uvsBuffer, 2, false, TYPES.FLOAT) 41001 .addIndex(indexBuffer); 41002 41003 /** 41004 * Dirty flag to limit update calls on Mesh. For example, 41005 * limiting updates on a single Mesh instance with a shared Geometry 41006 * within the render loop. 41007 * @private 41008 * @member {number} 41009 * @default -1 41010 */ 41011 this._updateId = -1; 41012 } 41013 41014 if ( Geometry ) { MeshGeometry.__proto__ = Geometry; } 41015 MeshGeometry.prototype = Object.create( Geometry && Geometry.prototype ); 41016 MeshGeometry.prototype.constructor = MeshGeometry; 41017 41018 var prototypeAccessors = { vertexDirtyId: { configurable: true } }; 41019 41020 /** 41021 * If the vertex position is updated. 41022 * @member {number} 41023 * @readonly 41024 * @private 41025 */ 41026 prototypeAccessors.vertexDirtyId.get = function () 41027 { 41028 return this.buffers[0]._updateID; 41029 }; 41030 41031 Object.defineProperties( MeshGeometry.prototype, prototypeAccessors ); 41032 41033 return MeshGeometry; 41034 }(Geometry)); 41035 41036 /*! 41037 * @pixi/mesh-extras - v5.0.0-rc.3 41038 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 41039 * 41040 * @pixi/mesh-extras is licensed under the MIT License. 41041 * http://www.opensource.org/licenses/mit-license 41042 */ 41043 41044 var PlaneGeometry = /*@__PURE__*/(function (MeshGeometry) { 41045 function PlaneGeometry(width, height, segWidth, segHeight) 41046 { 41047 if ( width === void 0 ) { width = 100; } 41048 if ( height === void 0 ) { height = 100; } 41049 if ( segWidth === void 0 ) { segWidth = 10; } 41050 if ( segHeight === void 0 ) { segHeight = 10; } 41051 41052 MeshGeometry.call(this); 41053 41054 this.segWidth = segWidth; 41055 this.segHeight = segHeight; 41056 41057 this.width = width; 41058 this.height = height; 41059 41060 this.build(); 41061 } 41062 41063 if ( MeshGeometry ) { PlaneGeometry.__proto__ = MeshGeometry; } 41064 PlaneGeometry.prototype = Object.create( MeshGeometry && MeshGeometry.prototype ); 41065 PlaneGeometry.prototype.constructor = PlaneGeometry; 41066 41067 /** 41068 * Refreshes plane coordinates 41069 * @private 41070 */ 41071 PlaneGeometry.prototype.build = function build () 41072 { 41073 var total = this.segWidth * this.segHeight; 41074 var verts = []; 41075 var uvs = []; 41076 var indices = []; 41077 41078 var segmentsX = this.segWidth - 1; 41079 var segmentsY = this.segHeight - 1; 41080 41081 var sizeX = (this.width) / segmentsX; 41082 var sizeY = (this.height) / segmentsY; 41083 41084 for (var i = 0; i < total; i++) 41085 { 41086 var x = (i % this.segWidth); 41087 var y = ((i / this.segWidth) | 0); 41088
41089 verts.push(x * sizeX, y * sizeY); 41090 uvs.push(x / segmentsX, y / segmentsY); 41091 } 41092 41093 var totalSub = segmentsX * segmentsY; 41094 41095 for (var i$1 = 0; i$1 < totalSub; i$1++) 41096 { 41097 var xpos = i$1 % segmentsX; 41098 var ypos = (i$1 / segmentsX) | 0; 41099 41100 var value = (ypos * this.segWidth) + xpos; 41101 var value2 = (ypos * this.segWidth) + xpos + 1; 41102 var value3 = ((ypos + 1) * this.segWidth) + xpos; 41103 var value4 = ((ypos + 1) * this.segWidth) + xpos + 1; 41104 41105 indices.push(value, value2, value3, 41106 value2, value4, value3); 41107 } 41108 41109 this.buffers[0].data = new Float32Array(verts); 41110 this.buffers[1].data = new Float32Array(uvs); 41111 this.indexBuffer.data = new Uint16Array(indices); 41112 41113 // ensure that the changes are uploaded 41114 this.buffers[0].update(); 41115 this.buffers[1].update(); 41116 this.indexBuffer.update(); 41117 }; 41118 41119 return PlaneGeometry; 41120 }(MeshGeometry)); 41121 41122 /** 41123 * RopeGeometry allows you to draw a geometry across several points and then manipulate these points. 41124 * 41125 * ```js 41126 * for (let i = 0; i < 20; i++) { 41127 * points.push(new PIXI.Point(i * 50, 0)); 41128 * }; 41129 * const rope = new PIXI.RopeGeometry(100, points); 41130 * ``` 41131 * 41132 * @class 41133 * @extends PIXI.MeshGeometry 41134 * @memberof PIXI 41135 * 41136 */ 41137 var RopeGeometry = /*@__PURE__*/(function (MeshGeometry) { 41138 function RopeGeometry(width, points) 41139 { 41140 if ( width === void 0 ) { width = 200; } 41141 41142 MeshGeometry.call(this, new Float32Array(points.length * 4), 41143 new Float32Array(points.length * 4), 41144 new Uint16Array((points.length - 1) * 6)); 41145 41146 /** 41147 * An array of points that determine the rope 41148 * @member {PIXI.Point[]} 41149 */ 41150 this.points = points; 41151 41152 /** 41153 * The width (i.e., thickness) of the rope. 41154 * @member {number} 41155 * @readOnly 41156 */ 41157 this.width = width; 41158 41159 this.build(); 41160 } 41161 41162 if ( MeshGeometry ) { RopeGeometry.__proto__ = MeshGeometry; } 41163 RopeGeometry.prototype = Object.create( MeshGeometry && MeshGeometry.prototype ); 41164 RopeGeometry.prototype.constructor = RopeGeometry; 41165 /** 41166 * Refreshes Rope indices and uvs 41167 * @private 41168 */ 41169 RopeGeometry.prototype.build = function build () 41170 { 41171 var points = this.points; 41172 41173 if (!points) { return; } 41174 41175 var vertexBuffer = this.getAttribute('aVertexPosition'); 41176 var uvBuffer = this.getAttribute('aTextureCoord'); 41177 var indexBuffer = this.getIndex(); 41178 41179 // if too little points, or texture hasn't got UVs set yet just move on. 41180 if (points.length < 1) 41181 { 41182 return; 41183 } 41184 41185 // if the number of points has changed we will need to recreate the arraybuffers 41186 if (vertexBuffer.data.length / 4 !== points.length) 41187 { 41188 vertexBuffer.data = new Float32Array(points.length * 4); 41189 uvBuffer.data = new Float32Array(points.length * 4); 41190 indexBuffer.data = new Uint16Array((points.length - 1) * 6); 41191 } 41192 41193 var uvs = uvBuffer.data; 41194 var indices = indexBuffer.data; 41195 41196 uvs[0] = 0; 41197 uvs[1] = 0; 41198 uvs[2] = 0; 41199 uvs[3] = 1; 41200 41201 // indices[0] = 0; 41202 // indices[1] = 1; 41203 41204 var total = points.length; // - 1; 41205 41206 for (var i = 0; i < total; i++) 41207 { 41208 // time to do some smart drawing! 41209 var index = i * 4; 41210 var amount = i / (total - 1); 41211 41212 uvs[index] = amount; 41213 uvs[index + 1] = 0; 41214 41215 uvs[index + 2] = amount; 41216 uvs[index + 3] = 1; 41217 } 41218 41219 var indexCount = 0; 41220 41221 for (var i$1 = 0; i$1 < total - 1; i$1++) 41222 { 41223 var index$1 = i$1 * 2; 41224 41225 indices[indexCount++] = index$1; 41226 indices[indexCount++] = index$1 + 1; 41227 indices[indexCount++] = index$1 + 2; 41228 41229 indices[indexCount++] = index$1 + 2; 41230 indices[indexCount++] = index$1 + 1; 41231 indices[indexCount++] = index$1 + 3; 41232 } 41233 41234 // ensure that the changes are uploaded
41235 uvBuffer.update(); 41236 indexBuffer.update(); 41237 41238 this.updateVertices(); 41239 }; 41240 41241 /** 41242 * refreshes vertices of Rope mesh 41243 */ 41244 RopeGeometry.prototype.updateVertices = function updateVertices () 41245 { 41246 var points = this.points; 41247 41248 if (points.length < 1) 41249 { 41250 return; 41251 } 41252 41253 var lastPoint = points[0]; 41254 var nextPoint; 41255 var perpX = 0; 41256 var perpY = 0; 41257 41258 // this.count -= 0.2; 41259 41260 var vertices = this.buffers[0].data; 41261 var total = points.length; 41262 41263 for (var i = 0; i < total; i++) 41264 { 41265 var point = points[i]; 41266 var index = i * 4; 41267 41268 if (i < points.length - 1) 41269 { 41270 nextPoint = points[i + 1]; 41271 } 41272 else 41273 { 41274 nextPoint = point; 41275 } 41276 41277 perpY = -(nextPoint.x - lastPoint.x); 41278 perpX = nextPoint.y - lastPoint.y; 41279 41280 var perpLength = Math.sqrt((perpX * perpX) + (perpY * perpY)); 41281 var num = this.width / 2; // (20 + Math.abs(Math.sin((i + this.count) * 0.3) * 50) )* ratio; 41282 41283 perpX /= perpLength; 41284 perpY /= perpLength; 41285 41286 perpX *= num; 41287 perpY *= num; 41288 41289 vertices[index] = point.x + perpX; 41290 vertices[index + 1] = point.y + perpY; 41291 vertices[index + 2] = point.x - perpX; 41292 vertices[index + 3] = point.y - perpY; 41293 41294 lastPoint = point; 41295 } 41296 41297 this.buffers[0].update(); 41298 }; 41299 41300 RopeGeometry.prototype.update = function update () 41301 { 41302 this.updateVertices(); 41303 }; 41304 41305 return RopeGeometry; 41306 }(MeshGeometry)); 41307 41308 /** 41309 * The rope allows you to draw a texture across several points and then manipulate these points 41310 * 41311 *```js 41312 * for (let i = 0; i < 20; i++) { 41313 * points.push(new PIXI.Point(i * 50, 0)); 41314 * }; 41315 * let rope = new PIXI.Rope(PIXI.Texture.from("snake.png"), points); 41316 * ``` 41317 * 41318 * @class 41319 * @extends PIXI.Mesh 41320 * @memberof PIXI 41321 * 41322 */ 41323 var SimpleRope = /*@__PURE__*/(function (Mesh) { 41324 function SimpleRope(texture, points) 41325 { 41326 var ropeGeometry = new RopeGeometry(texture.height, points); 41327 var meshMaterial = new MeshMaterial(texture); 41328 41329 Mesh.call(this, ropeGeometry, meshMaterial); 41330 41331 /** 41332 * re-calculate vertices by rope points each frame 41333 * 41334 * @member {boolean} 41335 */ 41336 this.autoUpdate = true; 41337 } 41338 41339 if ( Mesh ) { SimpleRope.__proto__ = Mesh; } 41340 SimpleRope.prototype = Object.create( Mesh && Mesh.prototype ); 41341 SimpleRope.prototype.constructor = SimpleRope; 41342 41343 SimpleRope.prototype._render = function _render (renderer) 41344 { 41345 if (this.autoUpdate 41346 || this.geometry.width !== this.shader.texture.height) 41347 { 41348 this.geometry.width = this.shader.texture.height; 41349 this.geometry.update(); 41350 } 41351 41352 Mesh.prototype._render.call(this, renderer); 41353 }; 41354 41355 return SimpleRope; 41356 }(Mesh)); 41357 41358 /** 41359 * The Plane allows you to draw a texture across several points and then manipulate these points 41360 * 41361 *```js 41362 * for (let i = 0; i < 20; i++) { 41363 * points.push(new PIXI.Point(i * 50, 0)); 41364 * }; 41365 * let Plane = new PIXI.Plane(PIXI.Texture.from("snake.png"), points); 41366 * ``` 41367 * 41368 * @class 41369 * @extends PIXI.Mesh 41370 * @memberof PIXI 41371 * 41372 */ 41373 var SimplePlane = /*@__PURE__*/(function (Mesh) { 41374 function SimplePlane(texture, verticesX, verticesY) 41375 { 41376 var planeGeometry = new PlaneGeometry(texture.width, texture.height, verticesX, verticesY); 41377 var meshMaterial = new MeshMaterial(Texture.WHITE); 41378 41379 Mesh.call(this, planeGeometry, meshMaterial); 41380 41381 // lets call the setter to ensure all necessary updates are performed 41382 this.texture = texture; 41383 } 41384 41385 if ( Mesh ) { SimplePlane.__proto__ = Mesh; } 41386 SimplePlane.prototype = Object.create( Mesh && Mesh.prototype ); 41387 SimplePlane.prototype.constructor = SimplePlane; 41388 41389 var prototypeAccessors = { texture: { configurable: true } }; 41390 41391 /** 41392 * Method used for overrides, to do something in case texture frame was changed. 41393 * Meshes based on plane can override it and change more details based on texture. 41394 */ 41395 SimplePlane.prototype.textureUpdated = function textureUpdated () 41396 { 41397 this._textureID = this.shader.texture._updateID; 41398 41399 this.geometry.width = this.shader.texture.width; 41400 this.geometry.height = this.shader.texture.height; 41401 41402 this.geometry.build(); 41403 }; 41404 41405 prototypeAccessors.texture.set = function (value) 41406 { 41407 // Track texture same way sprite does. 41408 // For generated meshes like NineSlicePlane it can change the geometry. 41409 // Unfortunately, this method might not work if you directly change texture in material. 41410 41411 if (this.shader.texture === value) 41412 { 41413 return; 41414 } 41415 41416 this.shader.texture = value; 41417 this._textureID = -1; 41418 41419 if (value.baseTexture.valid) 41420 { 41421 this.textureUpdated(); 41422 } 41423 else 41424 { 41425 value.once('update', this.textureUpdated, this); 41426 } 41427 }; 41428 41429 prototypeAccessors.texture.get = function () 41430 { 41431 return this.shader.texture; 41432 }; 41433 41434 SimplePlane.prototype._render = function _render (renderer) 41435 { 41436 if (this._textureID !== this.shader.texture._updateID) 41437 { 41438 this.textureUpdated(); 41439 } 41440 41441 Mesh.prototype._render.call(this, renderer); 41442 }; 41443 41444 Object.defineProperties( SimplePlane.prototype, prototypeAccessors ); 41445 41446 return SimplePlane; 41447 }(Mesh)); 41448 41449 /** 41450 * The Simple Mesh class mimics Mesh in PixiJS v4, providing easy-to-use constructor arguments. 41451 * For more robust customization, use {@link PIXI.Mesh}. 41452 * 41453 * @class 41454 * @extends PIXI.Mesh 41455 * @memberof PIXI 41456 */ 41457 var SimpleMesh = /*@__PURE__*/(function (Mesh) { 41458 function SimpleMesh(texture, vertices, uvs, indices, drawMode) 41459 { 41460 if ( texture === void 0 ) { texture = Texture.EMPTY; } 41461 41462 var geometry = new MeshGeometry(vertices, uvs, indices); 41463 41464 geometry.getAttribute('aVertexPosition').static = false;
41465 41466 var meshMaterial = new MeshMaterial(texture); 41467 41468 Mesh.call(this, geometry, meshMaterial, null, drawMode); 41469 41470 /** 41471 * upload vertices buffer each frame 41472 * @member {boolean} 41473 */ 41474 this.autoUpdate = true; 41475 } 41476 41477 if ( Mesh ) { SimpleMesh.__proto__ = Mesh; } 41478 SimpleMesh.prototype = Object.create( Mesh && Mesh.prototype ); 41479 SimpleMesh.prototype.constructor = SimpleMesh; 41480 41481 var prototypeAccessors = { vertices: { configurable: true } }; 41482 41483 /** 41484 * Collection of vertices data. 41485 * @member {Float32Array} 41486 */ 41487 prototypeAccessors.vertices.get = function () 41488 { 41489 return this.geometry.getAttribute('aVertexPosition').data; 41490 }; 41491 prototypeAccessors.vertices.set = function (value) 41492 { 41493 this.geometry.getAttribute('aVertexPosition').data = value; 41494 }; 41495 41496 SimpleMesh.prototype._render = function _render (renderer) 41497 { 41498 if (this.autoUpdate) 41499 { 41500 this.geometry.getAttribute('aVertexPosition').update(); 41501 } 41502 41503 Mesh.prototype._render.call(this, renderer); 41504 }; 41505 41506 Object.defineProperties( SimpleMesh.prototype, prototypeAccessors ); 41507 41508 return SimpleMesh; 41509 }(Mesh)); 41510 41511 var DEFAULT_BORDER_SIZE = 10; 41512 41513 /** 41514 * The NineSlicePlane allows you to stretch a texture using 9-slice scaling. The corners will remain unscaled (useful 41515 * for buttons with rounded corners for example) and the other areas will be scaled horizontally and or vertically 41516 * 41517 *```js 41518 * let Plane9 = new PIXI.NineSlicePlane(PIXI.Texture.from('BoxWithRoundedCorners.png'), 15, 15, 15, 15); 41519 * ``` 41520 * <pre> 41521 * A B 41522 * +---+----------------------+---+ 41523 * C | 1 | 2 | 3 | 41524 * +---+----------------------+---+ 41525 * | | | | 41526 * | 4 | 5 | 6 | 41527 * | | | | 41528 * +---+----------------------+---+ 41529 * D | 7 | 8 | 9 | 41530 * +---+----------------------+---+ 41531 41532 * When changing this objects width and/or height: 41533 * areas 1 3 7 and 9 will remain unscaled. 41534 * areas 2 and 8 will be stretched horizontally 41535 * areas 4 and 6 will be stretched vertically 41536 * area 5 will be stretched both horizontally and vertically 41537 * </pre> 41538 * 41539 * @class 41540 * @extends PIXI.SimplePlane 41541 * @memberof PIXI 41542 * 41543 */ 41544 var NineSlicePlane = /*@__PURE__*/(function (SimplePlane) { 41545 function NineSlicePlane(texture, leftWidth, topHeight, rightWidth, bottomHeight) 41546 { 41547 SimplePlane.call(this, Texture.WHITE, 4, 4); 41548 41549 this._origWidth = texture.orig.width; 41550 this._origHeight = texture.orig.height; 41551 41552 /** 41553 * The width of the NineSlicePlane, setting this will actually modify the vertices and UV's of this plane 41554 * 41555 * @member {number} 41556 * @override 41557 */ 41558 this._width = this._origWidth; 41559 41560 /** 41561 * The height of the NineSlicePlane, setting this will actually modify the vertices and UV's of this plane 41562 * 41563 * @member {number} 41564 * @override 41565 */ 41566 this._height = this._origHeight; 41567 41568 /** 41569 * The width of the left column (a) 41570 * 41571 * @member {number} 41572 * @private 41573 */ 41574 this._leftWidth = typeof leftWidth !== 'undefined' ? leftWi
41574dth : DEFAULT_BORDER_SIZE; 41575 41576 /** 41577 * The width of the right column (b) 41578 * 41579 * @member {number} 41580 * @private 41581 */ 41582 this._rightWidth = typeof rightWidth !== 'undefined' ? rightWidth : DEFAULT_BORDER_SIZE; 41583 41584 /** 41585 * The height of the top row (c) 41586 * 41587 * @member {number} 41588 * @private 41589 */ 41590 this._topHeight = typeof topHeight !== 'undefined' ? topHeight : DEFAULT_BORDER_SIZE; 41591 41592 /** 41593 * The height of the bottom row (d) 41594 * 41595 * @member {number} 41596 * @private 41597 */ 41598 this._bottomHeight = typeof bottomHeight !== 'undefined' ? bottomHeight : DEFAULT_BORDER_SIZE; 41599 41600 // lets call the setter to ensure all necessary updates are performed 41601 this.texture = texture; 41602 } 41603 41604 if ( SimplePlane ) { NineSlicePlane.__proto__ = SimplePlane; } 41605 NineSlicePlane.prototype = Object.create( SimplePlane && SimplePlane.prototype ); 41606 NineSlicePlane.prototype.constructor = NineSlicePlane; 41607 41608 var prototypeAccessors = { vertices: { configurable: true },width: { configurable: true },height: { configurable: true },leftWidth: { configurable: true },rightWidth: { configurable: true },topHeight: { configurable: true },bottomHeight: { configurable: true } }; 41609 41610 NineSlicePlane.prototype.textureUpdated = function textureUpdated () 41611 { 41612 this._textureID = this.shader.texture._updateID; 41613 this._refresh(); 41614 }; 41615 41616 prototypeAccessors.vertices.get = function () 41617 { 41618 return this.geometry.getAttribute('aVertexPosition').data; 41619 }; 41620 41621 prototypeAccessors.vertices.set = function (value) 41622 { 41623 this.geometry.getAttribute('aVertexPosition').data = value; 41624 }; 41625 41626 /** 41627 * Updates the horizontal vertices. 41628 * 41629 */ 41630 NineSlicePlane.prototype.updateHorizontalVertices = function updateHorizontalVertices () 41631 { 41632 var vertices = this.vertices; 41633 41634 var h = this._topHeight + this._bottomHeight; 41635 var scale = this._height > h ? 1.0 : this._height / h; 41636 41637 vertices[9] = vertices[11] = vertices[13] = vertices[15] = this._topHeight * scale; 41638 vertices[17] = vertices[19] = vertices[21] = vertices[23] = this._height - (this._bottomHeight * scale); 41639 vertices[25] = vertices[27] = vertices[29] = vertices[31] = this._height; 41640 }; 41641 41642 /** 41643 * Updates the vertical vertices. 41644 * 41645 */ 41646 NineSlicePlane.prototype.updateVerticalVertices = function updateVerticalVertices () 41647 { 41648 var vertices = this.vertices; 41649 41650 var w = this._leftWidth + this._rightWidth; 41651 var scale = this._width > w ? 1.0 : this._width / w; 41652 41653 vertices[2] = vertices[10] = vertices[18] = vertices[26] = this._leftWidth * scale; 41654 vertices[4] = vertices[12] = vertices[20] = vertices[28] = this._width - (this._rightWidth * scale); 41655 vertices[6] = vertices[14] = vertices[22] = vertices[30] = this._width; 41656 }; 41657 41658 /** 41659 * The width of the NineSlicePlane, setting this will actually modify the vertices and UV's of this plane 41660 * 41661 * @member {number} 41662 */ 41663 prototypeAccessors.width.get = function () 41664 { 41665 return this._width; 41666 }; 41667 41668 prototypeAccessors.width.set = function (value) // eslint-disable-line require-jsdoc 41669 { 41670 this._width = value; 41671 this._refresh(); 41672 }; 41673 41674 /** 41675 * The height of the NineSlicePlane, setting this will actually modify the vertices and UV's of this plane 41676 * 41677 * @member {number} 41678 */ 41679 prototypeAccessors.height.get = function () 41680 { 41681 return this._height; 41682 }; 41683 41684 prototypeAccessors.height.set = function (value) // eslint-disable-line require-jsdoc 41685 { 41686 this._height = value; 41687 this._refresh(); 41688 }; 41689 41690 /** 41691 * The width of the left column 41692 * 41693 * @member {number} 41694 */ 41695 prototypeAccessors.leftWidth.get = function () 41696 { 41697 return this._leftWidth; 41698 }; 41699 41700 prototypeAccessors.leftWidth.set = function (value) // eslint-disable-line require-jsdoc 41701 {
41702 this._leftWidth = value; 41703 this._refresh(); 41704 }; 41705 41706 /** 41707 * The width of the right column 41708 * 41709 * @member {number} 41710 */ 41711 prototypeAccessors.rightWidth.get = function () 41712 { 41713 return this._rightWidth; 41714 }; 41715 41716 prototypeAccessors.rightWidth.set = function (value) // eslint-disable-line require-jsdoc 41717 { 41718 this._rightWidth = value; 41719 this._refresh(); 41720 }; 41721 41722 /** 41723 * The height of the top row 41724 * 41725 * @member {number} 41726 */ 41727 prototypeAccessors.topHeight.get = function () 41728 { 41729 return this._topHeight; 41730 }; 41731 41732 prototypeAccessors.topHeight.set = function (value) // eslint-disable-line require-jsdoc 41733 { 41734 this._topHeight = value; 41735 this._refresh(); 41736 }; 41737 41738 /** 41739 * The height of the bottom row 41740 * 41741 * @member {number} 41742 */ 41743 prototypeAccessors.bottomHeight.get = function () 41744 { 41745 return this._bottomHeight; 41746 }; 41747 41748 prototypeAccessors.bottomHeight.set = function (value) // eslint-disable-line require-jsdoc 41749 { 41750 this._bottomHeight = value; 41751 this._refresh(); 41752 }; 41753 41754 /** 41755 * Refreshes NineSlicePlane coords. All of them. 41756 */ 41757 NineSlicePlane.prototype._refresh = function _refresh () 41758 { 41759 var texture = this.texture; 41760 41761 var uvs = this.geometry.buffers[1].data; 41762 41763 this._origWidth = texture.orig.width; 41764 this._origHeight = texture.orig.height; 41765 41766 var _uvw = 1.0 / this._origWidth; 41767 var _uvh = 1.0 / this._origHeight; 41768 41769 uvs[0] = uvs[8] = uvs[16] = uvs[24] = 0; 41770 uvs[1] = uvs[3] = uvs[5] = uvs[7] = 0; 41771 uvs[6] = uvs[14] = uvs[22] = uvs[30] = 1; 41772 uvs[25] = uvs[27] = uvs[29] = uvs[31] = 1; 41773 41774 uvs[2] = uvs[10] = uvs[18] = uvs[26] = _uvw * this._leftWidth; 41775 uvs[4] = uvs[12] = uvs[20] = uvs[28] = 1 - (_uvw * this._rightWidth); 41776 uvs[9] = uvs[11] = uvs[13] = uvs[15] = _uvh * this._topHeight; 41777 uvs[17] = uvs[19] = uvs[21] = uvs[23] = 1 - (_uvh * this._bottomHeight); 41778 41779 this.updateHorizontalVertices(); 41780 this.updateVerticalVertices(); 41781 41782 this.geometry.buffers[0].update(); 41783 this.geometry.buffers[1].update(); 41784 }; 41785 41786 Object.defineProperties( NineSlicePlane.prototype, prototypeAccessors ); 41787 41788 return NineSlicePlane; 41789 }(SimplePlane)); 41790 41791 /*! 41792 * @pixi/sprite-animated - v5.0.0-rc.3 41793 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 41794 * 41795 * @pixi/sprite-animated is licensed under the MIT License. 41796 * http://www.opensource.org/licenses/mit-license 41797 */ 41798 41799 /** 41800 * An AnimatedSprite is a simple way to display an animation depicted by a list of textures. 41801 * 41802 * ```js 41803 * let alienImages = ["image_sequence_01.png","image_sequence_02.png","image_sequence_03.png","image_sequence_04.png"]; 41804 * let textureArray = []; 41805 * 41806 * for (let i=0; i < 4; i++) 41807 * { 41808 * let texture = PIXI.Texture.from(alienImages[i]); 41809 * textureArray.push(texture); 41810 * }; 41811 * 41812 * let animatedSprite = new PIXI.AnimatedSprite(textureArray); 41813 * ``` 41814 * 41815 * The more efficient and simpler way to create an animated sprite is using a {@link PIXI.Spritesheet} 41816 * containing the animation definitions: 41817 * 41818 * ```js 41819 * PIXI.loader.add("assets/spritesheet.json").load(setup); 41820 * 41821 * function setup() { 41822 * let sheet = PIXI.loader.resources["assets/spritesheet.json"].spritesheet; 41823 * animatedSprite = new PIXI.AnimatedSprite(sheet.animations["image_sequence"]); 41824 * ... 41825 * } 41826 * ``` 41827 * 41828 * @class 41829 * @extends PIXI.Sprite 41830 * @memberof PIXI 41831 */ 41832 var AnimatedSprite = /*@__PURE__*/(function (Sprite) { 41833 function AnimatedSprite(textures, autoUpdate) 41834 { 41835 Sprite.call(this, textures[0] instanceof Texture ? textures[0] : textures[0].texture); 41836 41837 /** 41838 * @type {PIXI.Texture[]} 41839 * @private 41840 */ 41841 this._textures = null; 41842 41843 /** 41844 * @type {number[]} 41845 * @private 41846 */ 41847 this._durations = null; 41848 41849 this.textures = textures; 41850 41851 /** 41852 * `true` uses PIXI.Ticker.shared to auto update animation time. 41853 * @type {boolean} 41854 * @default true 41855 * @private 41856 */ 41857 this._autoUpdate = autoUpdate !== false; 41858 41859 /** 41860 * The speed that the AnimatedSprite will play at. Higher is faster, lower is slower. 41861 * 41862 * @member {number} 41863 * @default 1 41864 */ 41865 this.animationSpeed = 1; 41866 41867 /** 41868 * Whether or not the animate sprite repeats after playing. 41869 * 41870 * @member {boolean} 41871 * @default true 41872 */ 41873 this.loop = true; 41874 41875 /** 41876 * Update anchor to [Texture's defaultAnchor]{@link PIXI.Texture#defaultAnchor} when frame changes. 41877 * 41878 * Useful with [sprite sheet animations]{@link PIXI.Spritesheet#animations} created with tools. 41879 * Changing anchor for each frame allows to pin sprite origin to certain moving feature 41880 * of the frame (e.g. left foot). 41881 * 41882 * Note: Enabling this will override any previously set `anchor` on each frame change. 41883 * 41884 * @member {boolean} 41885 * @default false 41886 */ 41887 this.updateAnchor = false;
41888 41889 /** 41890 * Function to call when a AnimatedSprite finishes playing. 41891 * 41892 * @member {Function} 41893 */ 41894 this.onComplete = null; 41895 41896 /** 41897 * Function to call when a AnimatedSprite changes which texture is being rendered. 41898 * 41899 * @member {Function} 41900 */ 41901 this.onFrameChange = null; 41902 41903 /** 41904 * Function to call when `loop` is true, and an AnimatedSprite is played and loops around to start again. 41905 * 41906 * @member {Function} 41907 */ 41908 this.onLoop = null; 41909 41910 /** 41911 * Elapsed time since animation has been started, used internally to display current texture. 41912 * 41913 * @member {number} 41914 * @private 41915 */ 41916 this._currentTime = 0; 41917 41918 /** 41919 * Indicates if the AnimatedSprite is currently playing. 41920 * 41921 * @member {boolean} 41922 * @readonly 41923 */ 41924 this.playing = false; 41925 } 41926 41927 if ( Sprite ) { AnimatedSprite.__proto__ = Sprite; } 41928 AnimatedSprite.prototype = Object.create( Sprite && Sprite.prototype ); 41929 AnimatedSprite.prototype.constructor = AnimatedSprite; 41930 41931 var prototypeAccessors = { totalFrames: { configurable: true },textures: { configurable: true },currentFrame: { configurable: true } }; 41932 41933 /** 41934 * Stops the AnimatedSprite. 41935 * 41936 */ 41937 AnimatedSprite.prototype.stop = function stop () 41938 { 41939 if (!this.playing) 41940 { 41941 return; 41942 } 41943 41944 this.playing = false; 41945 if (this._autoUpdate) 41946 { 41947 Ticker.shared.remove(this.update, this); 41948 } 41949 }; 41950 41951 /** 41952 * Plays the AnimatedSprite. 41953 * 41954 */ 41955 AnimatedSprite.prototype.play = function play () 41956 { 41957 if (this.playing) 41958 { 41959 return; 41960 } 41961 41962 this.playing = true; 41963 if (this._autoUpdate) 41964 { 41965 Ticker.shared.add(this.update, this, UPDATE_PRIORITY.HIGH); 41966 } 41967 }; 41968 41969 /** 41970 * Stops the AnimatedSprite and goes to a specific frame. 41971 * 41972 * @param {number} frameNumber - Frame index to stop at. 41973 */ 41974 AnimatedSprite.prototype.gotoAndStop = function gotoAndStop (frameNumber) 41975 { 41976 this.stop(); 41977 41978 var previousFrame = this.currentFrame; 41979 41980 this._currentTime = frameNumber; 41981 41982 if (previousFrame !== this.currentFrame) 41983 { 41984 this.updateTexture(); 41985 } 41986 }; 41987 41988 /** 41989 * Goes to a specific frame and begins playing the AnimatedSprite. 41990 * 41991 * @param {number} frameNumber - Frame index to start at. 41992 */ 41993 AnimatedSprite.prototype.gotoAndPlay = function gotoAndPlay (frameNumber) 41994 { 41995 var previousFrame = this.currentFrame; 41996 41997 this._currentTime = frameNumber; 41998 41999 if (previousFrame !== this.currentFrame) 42000 { 42001 this.updateTexture(); 42002 } 42003 42004 this.play(); 42005 }; 42006 42007 /** 42008 * Updates the object transform for rendering. 42009 * 42010 * @private 42011 * @param {number} deltaTime - Time since last tick. 42012 */ 42013 AnimatedSprite.prototype.update = function update (deltaTime) 42014 { 42015 var elapsed = this.animationSpeed * deltaTime; 42016 var previousFrame = this.currentFrame; 42017 42018 if (this._durations !== null) 42019 { 42020 var lag = this._currentTime % 1 * this._durations[this.currentFrame]; 42021 42022 lag += elapsed / 60 * 1000; 42023 42024 while (lag < 0) 42025 { 42026 this._currentTime--; 42027 lag += this._durations[this.currentFrame]; 42028 } 42029 42030 var sign = Math.sign(this.animationSpeed * deltaTime); 42031 42032 this._currentTime = Math.floor(this._currentTime); 42033 42034 while (lag >= this._durations[this.currentFrame]) 42035 { 42036 lag -= this._durations[this.currentFrame] * sign; 42037 this._currentTime += sign; 42038 } 42039 42040 this._currentTime += lag / this._durations[this.currentFrame]; 42041 } 42042 else 42043 { 42044 this._currentTime += elapsed; 42045 } 42046 42047 if (this._currentTime < 0 && !this.loop) 42048 { 42049 this.gotoAndStop(0); 42050 42051 if (this.onComplete) 42052 { 42053 this.onComplete(); 42054 } 42055 } 42056 else if (this._currentTime >= this._textures.length && !this.loop) 42057 { 42058 this.gotoAndStop(this._textures.length - 1); 42059 42060 if (this.onComplete) 42061 { 42062 this.onComplete(); 42063 } 42064 } 42065 else if (previousFrame !== this.currentFrame) 42066 { 42067 if (this.loop && this.onLoop) 42068 { 42069 if (this.animationSpeed > 0 && this.currentFrame < previousFrame) 42070 { 42071 this.onLoop(); 42072 } 42073 else if (this.animationSpeed < 0 && this.currentFrame > previousFrame) 42074 { 42075 this.onLoop(); 42076 } 42077 } 42078 42079 this.updateTexture(); 42080 } 42081 }; 42082 42083 /** 42084 * Updates the displayed texture to match the current frame index. 42085 * 42086 * @private 42087 */ 42088 AnimatedSprite.prototype.updateTexture = function updateTexture () 42089 { 42090 this._texture = this._textures[this.currentFrame]; 42091 this._textureID = -1; 42092 this._textureTrimmedID = -1; 42093 this.cachedTint = 0xFFFFFF; 42094 this.uvs = this._texture._uvs.uvsFloat32; 42095 42096 if (this.updateAnchor) 42097 { 42098 this._anchor.copy(this._texture.defaultAnchor); 42099 } 42100 42101 if (this.onFrameChange) 42102 { 42103 this.onFrameChange(this.currentFrame); 42104 } 42105 }; 42106 42107 /** 42108 * Stops the AnimatedSprite and destroys it. 42109 * 42110 * @param {object|boolean} [options] - Options parameter. A boolean will act as if all options 42111 * have been set to that value. 42112 * @param {boolean} [options.children=false] - If set to true, all the children will have their destroy 42113 * method called as well. 'options' will be passed on to those calls. 42114 * @param {boolean} [options.texture=false] - Should it destroy the current texture of the sprite as well. 42115 * @param {boolean} [options.baseTexture=false] - Should it destroy the base texture of the sprite as well. 42116 */ 42117 AnimatedSprite.prototype.destroy = function destroy (options) 42118 { 42119 this.stop(); 42120 Sprite.prototype.destroy.call(this, options); 42121 42122 this.onComplete = null; 42123 this.onFrameChange = null; 42124 this.onLoop = null; 42125 }; 42126 42127 /** 42128 * A short hand way of creating a movieclip from an array of frame ids. 42129 * 42130 * @static 42131 * @param {string[]}
42131 frames - The array of frames ids the movieclip will use as its texture frames. 42132 * @return {AnimatedSprite} The new animated sprite with the specified frames. 42133 */ 42134 AnimatedSprite.fromFrames = function fromFrames (frames) 42135 { 42136 var textures = []; 42137 42138 for (var i = 0; i < frames.length; ++i) 42139 { 42140 textures.push(Texture.from(frames[i])); 42141 } 42142 42143 return new AnimatedSprite(textures); 42144 }; 42145 42146 /** 42147 * A short hand way of creating a movieclip from an array of image ids. 42148 * 42149 * @static 42150 * @param {string[]} images - The array of image urls the movieclip will use as its texture frames. 42151 * @return {AnimatedSprite} The new animate sprite with the specified images as frames. 42152 */ 42153 AnimatedSprite.fromImages = function fromImages (images) 42154 { 42155 var textures = []; 42156 42157 for (var i = 0; i < images.length; ++i) 42158 { 42159 textures.push(Texture.from(images[i])); 42160 } 42161 42162 return new AnimatedSprite(textures); 42163 }; 42164 42165 /** 42166 * The total number of frames in the AnimatedSprite. This is the same as number of textures 42167 * assigned to the AnimatedSprite. 42168 * 42169 * @readonly 42170 * @member {number} 42171 * @default 0 42172 */ 42173 prototypeAccessors.totalFrames.get = function () 42174 { 42175 return this._textures.length; 42176 }; 42177 42178 /** 42179 * The array of textures used for this AnimatedSprite. 42180 * 42181 * @member {PIXI.Texture[]} 42182 */ 42183 prototypeAccessors.textures.get = function () 42184 { 42185 return this._textures; 42186 }; 42187 42188 prototypeAccessors.textures.set = function (value) // eslint-disable-line require-jsdoc 42189 { 42190 if (value[0] instanceof Texture) 42191 { 42192 this._textures = value; 42193 this._durations = null; 42194 } 42195 else 42196 { 42197 this._textures = []; 42198 this._durations = []; 42199 42200 for (var i = 0; i < value.length; i++) 42201 { 42202 this._textures.push(value[i].texture); 42203 this._durations.push(value[i].time); 42204 } 42205 } 42206 this.gotoAndStop(0); 42207 this.updateTexture(); 42208 }; 42209 42210 /** 42211 * The AnimatedSprites current frame index. 42212 * 42213 * @member {number} 42214 * @readonly 42215 */ 42216 prototypeAccessors.currentFrame.get = function () 42217 { 42218 var currentFrame = Math.floor(this._currentTime) % this._textures.length; 42219 42220 if (currentFrame < 0) 42221 { 42222 currentFrame += this._textures.length; 42223 } 42224 42225 return currentFrame; 42226 }; 42227 42228 Object.defineProperties( AnimatedSprite.prototype, prototypeAccessors ); 42229 42230 return AnimatedSprite; 42231 }(Sprite)); 42232 42233 /*! 42234 * pixi.js - v5.0.0-rc.3 42235 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 42236 * 42237 * pixi.js is licensed under the MIT License. 42238 * http://www.opensource.org/licenses/mit-license 42239 */ 42240 42241 var v5 = '5.0.0'; 42242 42243 /** 42244 * Deprecations (backward compatibilities) are automatically applied for browser bundles 42245 * in the UMD module format. If using Webpack or Rollup, you'll need to apply these 42246 * deprecations manually by doing something like this: 42247 * @example 42248 * import * as PIXI from 'pixi.js'; 42249 * PIXI.useDeprecated(); // MUST be bound to namespace 42250 * @memberof PIXI 42251 * @function useDeprecated 42252 */ 42253 function useDeprecated() 42254 { 42255 var PIXI = this; 42256 42257 Object.defineProperties(PIXI, { 42258 /** 42259 * @constant {RegExp|string} SVG_SIZE 42260 * @memberof PIXI 42261 * @see PIXI.resources.SVGResource.SVG_SIZE 42262 * @deprecated since 5.0.0 42263 */ 42264 SVG_SIZE: { 42265 get: function get() 42266 { 42267 deprecation(v5, 'PIXI.utils.SVG_SIZE has moved to PIXI.SVGResource.SVG_SIZE'); 42268 42269 return PIXI.SVGResource.SVG_SIZE; 42270 }, 42271 }, 42272 42273 /** 42274 * @class PIXI.TransformStatic 42275 * @deprecated since 5.0.0 42276 * @see PIXI.Transform 42277 */ 42278 TransformStatic: { 42279 get: function get() 42280 { 42281 deprecation(v5, 'PIXI.TransformStatic has been removed, use PIXI.Transform'); 42282 42283 return PIXI.Transform; 42284 }, 42285 }, 42286 42287 /** 42288 * @class PIXI.TransformBase 42289 * @deprecated since 5.0.0 42290 * @see PIXI.Transform 42291 */ 42292 TransformBase: { 42293 get: function get() 42294 { 42295 deprecation(v5, 'PIXI.TransformBase has been removed, use PIXI.Transform'); 42296 42297 return PIXI.Transform; 42298 }, 42299 }, 42300 42301 /** 42302 * Constants that specify the transform type. 42303 * 42304 * @static 42305 * @constant 42306 * @name TRANSFORM_MODE 42307 * @memberof PIXI 42308 * @enum {number} 42309 * @deprecated since 5.0.0 42310 * @property {number} STATIC 42311 * @property {number} DYNAMIC 42312 */ 42313 TRANSFORM_MODE: { 42314 get: function get() 42315 { 42316 deprecation(v5, 'PIXI.TRANSFORM_MODE has been removed'); 42317 42318 return { STATIC: 0, DYNAMIC: 1 }; 42319 }, 42320 }, 42321 42322 /** 42323 * @class PIXI.WebGLRenderer 42324 * @see PIXI.Renderer 42325 * @deprecated since 5.0.0 42326 */ 42327 WebGLRenderer: { 42328 get: function get() 42329 { 42330 deprecation(v5, 'PIXI.WebGLRenderer has moved to PIXI.Renderer'); 42331 42332 return PIXI.Renderer; 42333 }, 42334 }, 42335 42336 /** 42337 * @class PIXI.CanvasRenderTarget 42338 * @see PIXI.utils.CanvasRenderTarget 42339 * @deprecated since 5.0.0 42340 */ 42341 CanvasRenderTarget: { 42342 get: function get() 42343 { 42344 deprecation(v5, 'PIXI.CanvasRenderTarget has moved to PIXI.utils.CanvasRenderTarget'); 42345 42346 return PIXI.utils.CanvasRenderTarget; 42347 }, 42348 }, 42349 42350 /** 42351 * @memberof PIXI 42352 * @name loader 42353 * @type {PIXI.Loader} 42354 * @see PIXI.Loader.shared 42355 * @deprecated since 5.0.0 42356 */ 42357 loader: { 42358 get: function get() 42359 { 42360 deprecation(v5, 'PIXI.loader has moved to PIXI.Loader.shared'); 42361 42362 return PIXI.Loader.shared; 42363 }, 42364 }, 42365 42366 /** 42367 * @class PIXI.FilterManager 42368 * @see PIXI.systems.FilterSystem 42369 * @deprecated since 5.0.0 42370 */ 42371 FilterManager: { 42372 get: function get() 42373 { 42374 deprecation(v5, 'PIXI.FilterManager has moved to PIXI.systems.FilterSystem'); 42375 42376 return PIXI.systems.FilterManager; 42377 }, 42378 }, 42379 }); 42380 42381 /** 42382 * This namespace has been removed. All classes previous nested 42383 * under this namespace have been moved to the top-level `PIXI` object. 42384 * @namespace PIXI.extras 42385 * @deprecated since 5.0.0 42386 */ 42387 PIXI.extras = {}; 42388 42389 Object.defineProperties(PIXI.extras, { 42390 /** 42391 * @class PIXI.extras.TilingSprite 42392 * @see PIXI.TilingSprite 42393 * @deprecated since 5.0.0 42394 */ 42395 TilingSprite: { 42396 get: function get() 42397 { 42398 deprecation(v5, 'PIXI.extras.TilingSprite has moved to PIXI.TilingSprite'); 42399 42400 return PIXI.TilingSprite; 42401 }, 42402 }, 42403 /** 42404 * @class PIXI.extras.TilingSpriteRenderer 42405 * @see PIXI.TilingSpriteRenderer 42406 * @deprecated since 5.0.0 42407 */ 42408 TilingSpriteRenderer: { 42409 get: function get() 42410 { 42411 deprecation(v5, 'PIXI.extras.TilingSpriteRenderer has moved to PIXI.TilingSpriteRenderer'); 42412 42413 return PIXI.TilingSpriteRenderer; 42414 }, 42415 }, 42416 /** 42417 * @class PIXI.extras.AnimatedSprite 42418 * @see PIXI.AnimatedSprite 42419 * @deprecated since 5.0.0 42420 */ 42421 AnimatedSprite: { 42422 get: function get() 42423 { 42424 deprecation(v5, 'PIXI.extras.AnimatedSprite has moved to PIXI.AnimatedSprite'); 42425 42426 return PIXI.AnimatedSprite; 42427 }, 42428 }, 42429 /** 42430 * @class PIXI.extras.BitmapText 42431 * @see PIXI.BitmapText 42432 * @deprecated since 5.0.0 42433 */ 42434 BitmapText: { 42435 get: function get() 42436 { 42437 deprecation(v5, 'PIXI.extras.BitmapText has moved to PIXI.BitmapText'); 42438 42439 return PIXI.BitmapText; 42440 }, 42441 }, 42442 }); 42443 42444 Object.defineProperties(PIXI.utils, { 42445 /** 42446 * @function PIXI.utils.getSvgSize 42447 * @see PIXI.resources.SVGResource.getSize 42448 * @deprecated since 5.0.0 42449 */ 42450 getSvgSize: { 42451 get: function get() 42452 { 42453 deprecation(v5, 'PIXI.utils.getSvgSize has moved to PIXI.SVGResource.getSize'); 42454 42455 return PIXI.SVGResource.getSize; 42456 }, 42457 }, 42458 }); 42459 42460 /** 42461 * All classes on this namespace have moved to the high-level `PIXI` object. 42462 * @namespace PIXI.mesh 42463 * @deprecated since 5.0.0 42464 */ 42465 PIXI.mesh = {}; 42466 42467 Object.defineProperties(PIXI.mesh, { 42468 /** 42469 * @class PIXI.mesh.Mesh 42470 * @see PIXI.SimpleMesh 42471 * @deprecated since 5.0.0 42472 */ 42473 Mesh: { 42474 get: function get() 42475 { 42476 deprecation(v5, 'PIXI.mesh.Mesh has moved to PIXI.SimpleMesh'); 42477 42478 return PIXI.SimpleMesh; 42479 }, 42480 }, 42481 /** 42482 * @class PIXI.mesh.NineSlicePlane 42483 * @see PIXI.NineSlicePlane 42484 * @deprecated since 5.0.0 42485 */ 42486 NineSlicePlane: { 42487 get: function get() 42488 { 42489 deprecation(v5, 'PIXI.mesh.NineSlicePlane has moved to PIXI.NineSlicePlane'); 42490 42491 return PIXI.NineSlicePlane; 42492 }, 42493 }, 42494 /** 42495 * @class PIXI.mesh.Plane 42496 * @see PIXI.SimplePlane 42497 * @deprecated since 5.0.0 42498 */ 42499 Plane: { 42500 get: function get() 42501 { 42502 deprecation(v5, 'PIXI.mesh.Plane has moved to PIXI.SimplePlane'); 42503 42504 return PIXI.SimplePlane; 42505 }, 42506 }, 42507 /** 42508 * @class PIXI.mesh.Rope 42509 * @see PIXI.SimpleRope 42510 * @deprecated since 5.0.0 42511 */ 42512 Rope: { 42513 get: function get() 42514 { 42515 deprecation(v5, 'PIXI.mesh.Rope has moved to PIXI.SimpleRope'); 42516 42517 return PIXI.SimpleRope; 42518 }, 42519 }, 42520 /** 42521 * @class PIXI.mesh.RawMesh 42522 * @see PIXI.Mesh 42523 * @deprecated since 5.0.0 42524 */ 42525 RawMesh: { 42526 get: function get() 42527 { 42528 deprecation(v5, 'PIXI.mesh.RawMesh has moved to PIXI.Mesh'); 42529 42530 return PIXI.Mesh; 42531 }, 42532 }, 42533 /**
42534 * @class PIXI.mesh.CanvasMeshRenderer 42535 * @see PIXI.CanvasMeshRenderer 42536 * @deprecated since 5.0.0 42537 */ 42538 CanvasMeshRenderer: { 42539 get: function get() 42540 { 42541 deprecation(v5, 'PIXI.mesh.CanvasMeshRenderer has moved to PIXI.CanvasMeshRenderer'); 42542 42543 return PIXI.CanvasMeshRenderer; 42544 }, 42545 }, 42546 /** 42547 * @class PIXI.mesh.MeshRenderer 42548 * @see PIXI.MeshRenderer 42549 * @deprecated since 5.0.0 42550 */ 42551 MeshRenderer: { 42552 get: function get() 42553 { 42554 deprecation(v5, 'PIXI.mesh.MeshRenderer has moved to PIXI.MeshRenderer'); 42555 42556 return PIXI.MeshRenderer; 42557 }, 42558 }, 42559 }); 42560 42561 /** 42562 * This namespace has been removed and items have been moved to 42563 * the top-level `PIXI` object. 42564 * @namespace PIXI.particles 42565 * @deprecated since 5.0.0 42566 */ 42567 PIXI.particles = {}; 42568 42569 Object.defineProperties(PIXI.particles, { 42570 /** 42571 * @class PIXI.particles.ParticleContainer 42572 * @deprecated since 5.0.0 42573 * @see PIXI.ParticleContainer 42574 */ 42575 ParticleContainer: { 42576 get: function get() 42577 { 42578 deprecation(v5, 'PIXI.particles.ParticleContainer has moved to PIXI.ParticleContainer'); 42579 42580 return PIXI.ParticleContainer; 42581 }, 42582 }, 42583 /** 42584 * @class PIXI.particles.ParticleRenderer 42585 * @deprecated since 5.0.0 42586 * @see PIXI.ParticleRenderer 42587 */ 42588 ParticleRenderer: { 42589 get: function get() 42590 { 42591 deprecation(v5, 'PIXI.particles.ParticleRenderer has moved to PIXI.ParticleRenderer'); 42592 42593 return PIXI.ParticleRenderer; 42594 }, 42595 }, 42596 }); 42597 42598 /** 42599 * This namespace has been removed and items have been moved to 42600 * the top-level `PIXI` object. 42601 * @namespace PIXI.ticker 42602 * @deprecated since 5.0.0 42603 */ 42604 PIXI.ticker = {}; 42605 42606 Object.defineProperties(PIXI.ticker, { 42607 /** 42608 * @class PIXI.ticker.Ticker 42609 * @deprecated since 5.0.0 42610 * @see PIXI.Ticker 42611 */ 42612 Ticker: { 42613 get: function get() 42614 { 42615 deprecation(v5, 'PIXI.ticker.Ticker has moved to PIXI.Ticker'); 42616 42617 return PIXI.Ticker; 42618 }, 42619 }, 42620 /** 42621 * @name PIXI.ticker.shared 42622 * @type {PIXI.Ticker} 42623 * @deprecated since 5.0.0 42624 * @see PIXI.Ticker.shared 42625 */ 42626 shared: { 42627 get: function get() 42628 { 42629 deprecation(v5, 'PIXI.ticker.shared has moved to PIXI.Ticker.shared'); 42630 42631 return PIXI.Ticker.shared; 42632 }, 42633 }, 42634 }); 42635 42636 /** 42637 * All classes on this namespace have moved to the high-level `PIXI` object. 42638 * @namespace PIXI.loaders 42639 * @deprecated since 5.0.0 42640 */ 42641 PIXI.loaders = {}; 42642 42643 Object.defineProperties(PIXI.loaders, { 42644 /** 42645 * @class PIXI.loaders.Loader 42646 * @see PIXI.Loader 42647 * @deprecated since 5.0.0 42648 */ 42649 Loader: { 42650 get: function get() 42651 { 42652 deprecation(v5, 'PIXI.loaders.Loader has moved to PIXI.Loader'); 42653 42654 return PIXI.Loader; 42655 }, 42656 }, 42657 /** 42658 * @class PIXI.loaders.Resource 42659 * @see PIXI.LoaderResource 42660 * @deprecated since 5.0.0 42661 */ 42662 Resource: { 42663 get: function get() 42664 { 42665 deprecation(v5, 'PIXI.loaders.Resource has moved to PIXI.LoaderResource'); 42666 42667 return PIXI.LoaderResource; 42668 }, 42669 }, 42670 /** 42671 * @function PIXI.loaders.bitmapFontParser 42672 * @see PIXI.BitmapFontLoader.use 42673 * @deprecated since 5.0.0 42674 */ 42675 bitmapFontParser: { 42676 get: function get() 42677 { 42678 deprecation(v5, 'PIXI.loaders.bitmapFontParser has moved to PIXI.BitmapFontLoader.use'); 42679 42680 return PIXI.BitmapFontLoader.use; 42681 }, 42682 }, 42683 /** 42684 * @function PIXI.loaders.parseBitmapFontData 42685 * @see PIXI.BitmapFontLoader.parse 42686 * @deprecated since 5.0.0 42687 */ 42688 parseBitmapFontData: { 42689 get: function get() 42690 { 42691 deprecation(v5, 'PIXI.loaders.parseBitmapFontData has moved to PIXI.BitmapFontLoader.parse'); 42692 42693 return PIXI.BitmapFontLoader.parse; 42694 }, 42695 }, 42696 /** 42697 * @function PIXI.loaders.spritesheetParser 42698 * @see PIXI.SpritesheetLoader.use 42699 * @deprecated since 5.0.0 42700 */ 42701 spritesheetParser: { 42702 get: function get() 42703 { 42704 deprecation(v5, 'PIXI.loaders.spritesheetParser has moved to PIXI.SpritesheetLoader.use'); 42705 42706 return PIXI.SpritesheetLoader.use; 42707 }, 42708 }, 42709 /** 42710 * @function PIXI.loaders.getResourcePath 42711 * @see PIXI.SpritesheetLoader.getResourcePath 42712 * @deprecated since 5.0.0 42713 */ 42714 getResourcePath: { 42715 get: function get() 42716 { 42717 deprecation(v5, 'PIXI.loaders.getResourcePath has moved to PIXI.SpritesheetLoader.getResourcePath'); 42718 42719 return PIXI.SpritesheetLoader.getResourcePath; 42720 }, 42721 }, 42722 }); 42723 42724 /** 42725 * @function PIXI.loaders.Loader.addPixiMiddleware 42726 * @see PIXI.Loader.registerPlugin 42727 * @deprecated since 5.0.0 42728 * @param {function} middleware 42729 */ 42730 PIXI.Loader.addPixiMiddleware = function addPixiMiddleware(middleware) 42731 { 42732 deprecation(v5, 'PIXI.loaders.Loader.addPixiMiddleware is deprecated, use PIXI.loaders.Loader.registerPlugin'); 42733 42734 return PIXI.loaders.Loader.registerPlugin({ use: middleware() }); 42735 }; 42736 42737 /** 42738 * @class PIXI.extract.WebGLExtract 42739 * @deprecated since 5.0.0 42740 * @see PIXI.extract.Extract 42741 */ 42742 Object.defineProperty(PIXI.extract, 'WebGLExtract', { 42743 get: function get() 42744 { 42745 deprecation(v5, 'PIXI.extract.WebGLExtract has moved to PIXI.extract.Extract'); 42746 42747 return PIXI.extract.Extract; 42748 }, 42749 }); 42750 42751 /** 42752 * @class PIXI.prepare.WebGLPrepare 42753 * @deprecated since 5.0.0 42754 * @see PIXI.prepare.Prepare 42755 */ 42756 Object.defineProperty(PIXI.prepare, 'WebGLPrepare', { 42757 get: function get() 42758 { 42759 deprecation(v5, 'PIXI.prepare.WebGLPrepare has moved to PIXI.prepare.Prepare'); 42760 42761 return PIXI.prepare.Prepare; 42762 }, 42763 }); 42764 42765 /** 42766 * @method PIXI.Container#_renderWebGL 42767 * @private 42768 * @deprecated since 5.0.0
42769 * @see PIXI.Container#render 42770 * @param {PIXI.Renderer} renderer Instance of renderer 42771 */ 42772 PIXI.Container.prototype._renderWebGL = function _renderWebGL(renderer) 42773 { 42774 deprecation(v5, 'PIXI.Container#_renderWebGL has moved to PIXI.Container#_render'); 42775 42776 this._render(renderer); 42777 }; 42778 42779 /** 42780 * @method PIXI.Container#renderWebGL 42781 * @deprecated since 5.0.0 42782 * @see PIXI.Container#render 42783 * @param {PIXI.Renderer} renderer Instance of renderer 42784 */ 42785 PIXI.Container.prototype.renderWebGL = function renderWebGL(renderer) 42786 { 42787 deprecation(v5, 'PIXI.Container#renderWebGL has moved to PIXI.Container#render'); 42788 42789 this.render(renderer); 42790 }; 42791 42792 /** 42793 * @method PIXI.DisplayObject#renderWebGL 42794 * @deprecated since 5.0.0 42795 * @see PIXI.DisplayObject#render 42796 * @param {PIXI.Renderer} renderer Instance of renderer 42797 */ 42798 PIXI.DisplayObject.prototype.renderWebGL = function renderWebGL(renderer) 42799 { 42800 deprecation(v5, 'PIXI.DisplayObject#renderWebGL has moved to PIXI.DisplayObject#render'); 42801 42802 this.render(renderer); 42803 }; 42804 42805 /** 42806 * @method PIXI.Container#renderAdvancedWebGL 42807 * @deprecated since 5.0.0
42808 * @see PIXI.Container#renderAdvanced 42809 * @param {PIXI.Renderer} renderer Instance of renderer 42810 */ 42811 PIXI.Container.prototype.renderAdvancedWebGL = function renderAdvancedWebGL(renderer) 42812 { 42813 deprecation(v5, 'PIXI.Container#renderAdvancedWebGL has moved to PIXI.Container#renderAdvanced'); 42814 42815 this.renderAdvanced(renderer); 42816 }; 42817 42818 Object.defineProperties(PIXI.settings, { 42819 /** 42820 * Default transform type. 42821 * 42822 * @static 42823 * @deprecated since 5.0.0 42824 * @memberof PIXI.settings 42825 * @type {PIXI.TRANSFORM_MODE} 42826 * @default PIXI.TRANSFORM_MODE.STATIC 42827 */ 42828 TRANSFORM_MODE: { 42829 get: function get() 42830 { 42831 deprecation(v5, 'PIXI.settings.TRANSFORM_MODE has been removed.'); 42832 42833 return 0; 42834 }, 42835 set: function set() 42836 { 42837 deprecation(v5, 'PIXI.settings.TRANSFORM_MODE has been removed.'); 42838 }, 42839 }, 42840 }); 42841 42842 var BaseTexture = PIXI.BaseTexture; 42843 42844 /** 42845 * @method fromImage 42846 * @static 42847 * @memberof PIXI.BaseTexture 42848 * @deprecated since 5.0.0 42849 * @see PIXI.BaseTexture.from 42850 */ 42851 BaseTexture.fromImage = function fromImage(canvas, crossorigin, scaleMode, scale) 42852 { 42853 deprecation(v5, 'PIXI.BaseTexture.fromImage has been replaced with PIXI.BaseTexture.from'); 42854 42855 var resourceOptions = { scale: scale, crossorigin: crossorigin }; 42856 42857 return BaseTexture.from(canvas, { scaleMode: scaleMode, resourceOptions: resourceOptions }); 42858 }; 42859 42860 /** 42861 * @method fromCanvas 42862 * @static 42863 * @memberof PIXI.BaseTexture 42864 * @deprecated since 5.0.0 42865 * @see PIXI.BaseTexture.from 42866 */ 42867 BaseTexture.fromCanvas = function fromCanvas(canvas, scaleMode) 42868 { 42869 deprecation(v5, 'PIXI.BaseTexture.fromCanvas has been replaced with PIXI.BaseTexture.from'); 42870 42871 return BaseTexture.from(canvas, { scaleMode: scaleMode }); 42872 }; 42873 42874 /** 42875 * @method fromSVG 42876 * @static 42877 * @memberof PIXI.BaseTexture 42878 * @deprecated since 5.0.0 42879 * @see PIXI.BaseTexture.from 42880 */ 42881 BaseTexture.fromSVG = function fromSVG(canvas, crossorigin, scaleMode, scale) 42882 { 42883 deprecation(v5, 'PIXI.BaseTexture.fromSVG has been replaced with PIXI.BaseTexture.from'); 42884 42885 var resourceOptions = { scale: scale, crossorigin: crossorigin }; 42886 42887 return BaseTexture.from(canvas, { scaleMode: scaleMode, resourceOptions: resourceOptions }); 42888 }; 42889 42890 /** 42891 * @method PIXI.Point#copy 42892 * @deprecated since 5.0.0 42893 * @see PIXI.Point#copyFrom 42894 */ 42895 PIXI.Point.prototype.copy = function copy(p) 42896 { 42897 deprecation(v5, 'PIXI.Point.copy has been replaced with PIXI.Point#copyFrom'); 42898 42899 return this.copyFrom(p); 42900 }; 42901 42902 /** 42903 * @method PIXI.ObservablePoint#copy 42904 * @deprecated since 5.0.0 42905 * @see PIXI.ObservablePoint#copyFrom 42906 */
42907 PIXI.ObservablePoint.prototype.copy = function copy(p) 42908 { 42909 deprecation(v5, 'PIXI.ObservablePoint.copy has been replaced with PIXI.ObservablePoint#copyFrom'); 42910 42911 return this.copyFrom(p); 42912 }; 42913 42914 /** 42915 * @method PIXI.Rectangle#copy 42916 * @deprecated since 5.0.0 42917 * @see PIXI.Rectangle#copyFrom 42918 */ 42919 PIXI.Rectangle.prototype.copy = function copy(p) 42920 { 42921 deprecation(v5, 'PIXI.Rectangle.copy has been replaced with PIXI.Rectangle#copyFrom'); 42922 42923 return this.copyFrom(p); 42924 }; 42925 42926 /** 42927 * @method PIXI.Matrix#copy 42928 * @deprecated since 5.0.0 42929 * @see PIXI.Matrix#copyTo 42930 */ 42931 PIXI.Matrix.prototype.copy = function copy(p) 42932 { 42933 deprecation(v5, 'PIXI.Matrix.copy has been replaced with PIXI.Matrix#copyTo'); 42934 42935 return this.copyTo(p); 42936 }; 42937 42938 Object.assign(PIXI.systems.FilterSystem.prototype, { 42939 /** 42940 * @method PIXI.FilterManager#getRenderTarget 42941 * @deprecated since 5.0.0 42942 * @see PIXI.systems.FilterSystem#getFilterTexture 42943 */ 42944 getRenderTarget: function getRenderTarget(clear, resolution) 42945 { 42946 deprecation(v5, 'FilterManager#getRenderTarget has been replaced with FilterSystem#getFilterTexture'); 42947 42948 return this.getFilterTexture(resolution); 42949 }, 42950 42951 /** 42952 * @method PIXI.FilterManager#returnRenderTarget 42953 * @deprecated since 5.0.0 42954 * @see PIXI.systems.FilterSystem#returnFilterTexture 42955 */ 42956 returnRenderTarget: function returnRenderTarget(renderTexture) 42957 { 42958 deprecation(v5, 'FilterManager#returnRenderTarget has been replaced with FilterSystem#returnFilterTexture'); 42959 42960 this.returnFilterTexture(renderTexture); 42961 }, 42962 }); 42963 42964 Object.defineProperties(PIXI.RenderTexture.prototype, { 42965 /** 42966 * @name PIXI.RenderTexture#sourceFrame 42967 * @type {PIXI.Rectangle} 42968 * @deprecated since 5.0.0 42969 * @readonly 42970 */ 42971 sourceFrame: { 42972 get: function get() 42973 { 42974 deprecation(v5, 'PIXI.RenderTexture#sourceFrame has been removed'); 42975 42976 return this.filterFrame; 42977 }, 42978 }, 42979 /** 42980 * @name PIXI.RenderTexture#size 42981 * @type {PIXI.Rectangle} 42982 * @deprecated since 5.0.0 42983 * @readonly 42984 */ 42985 size: { 42986 get: function get() 42987 { 42988 deprecation(v5, 'PIXI.RenderTexture#size has been removed'); 42989 42990 return this._frame; 42991 }, 42992 }, 42993 }); 42994 42995 /** 42996 * @class BlurXFilter 42997 * @memberof PIXI.filters 42998 * @deprecated since 5.0.0 42999 * @see PIXI.filters.BlurFilterPass 43000 */ 43001 var BlurXFilter = /*@__PURE__*/(function (superclass) { 43002 function BlurXFilter(strength, quality, resolution, kernelSize) 43003 { 43004 deprecation(v5, 'PIXI.filters.BlurXFilter is deprecated, use PIXI.filters.BlurFilterPass'); 43005 43006 superclass.call(this, true, strength, quality, resolution, kernelSize); 43007 } 43008 43009 if ( superclass ) { BlurXFilter.__proto__ = superclass; } 43010 BlurXFilter.prototype = Object.create( superclass && superclass.prototype ); 43011 BlurXFilter.prototype.constructor = BlurXFilter; 43012 43013 return BlurXFilter; 43014 }(PIXI.filters.BlurFilterPass)); 43015 43016 /** 43017 * @class BlurYFilter 43018 * @memberof PIXI.filters 43019 * @deprecated since 5.0.0 43020 * @see PIXI.filters.BlurFilterPass 43021 */ 43022 var BlurYFilter = /*@__PURE__*/(function (superclass) { 43023 function BlurYFilter(strength, quality, resolution, kernelSize) 43024 { 43025 deprecation(v5, 'PIXI.filters.BlurYFilter is deprecated, use PIXI.filters.BlurFilterPass'); 43026 43027 superclass.call(this, false, strength, quality, resolution, kernelSize); 43028 } 43029 43030 if ( superclass ) { BlurYFilter.__proto__ = superclass; } 43031 BlurYFilter.prototype = Object.create( superclass && superclass.prototype ); 43032 BlurYFilter.prototype.constructor = BlurYFilter; 43033 43034 return BlurYFilter; 43035 }(PIXI.filters.BlurFilterPass)); 43036 43037 Object.assign(PIXI.filters, { 43038 BlurXFilter: BlurXFilter, 43039 BlurYFilter: BlurYFilter, 43040 }); 43041 43042 var Sprite = PIXI.Sprite; 43043 var Texture = PIXI.Texture; 43044 var Graphics = PIXI.Graphics; 43045
43046 // Support for pixi.js-legacy bifurcation 43047 // give users a friendly assist to use legacy 43048 if (!Graphics.prototype.generateCanvasTexture) 43049 { 43050 Graphics.prototype.generateCanvasTexture = function generateCanvasTexture() 43051 { 43052 deprecation(v5, 'PIXI.Graphics#generateCanvasTexture is only available in "pixi.js-legacy"'); 43053 }; 43054 } 43055 43056 // Use these to deprecate all the Sprite from* methods 43057 function spriteFrom(name, source, crossorigin, scaleMode) 43058 { 43059 deprecation(v5, ("PIXI.Sprite." + name + " is deprecated, use PIXI.Sprite.from")); 43060 43061 return Sprite.from(source, { 43062 resourceOptions: { 43063 scale: scaleMode, 43064 crossorigin: crossorigin, 43065 }, 43066 }); 43067 } 43068 43069 /** 43070 * @deprecated since 5.0.0 43071 * @see PIXI.Sprite.from 43072 * @method PIXI.Sprite.fromImage 43073 * @return {PIXI.Sprite} 43074 */ 43075 Sprite.fromImage = spriteFrom.bind(null, 'fromImage'); 43076 43077 /** 43078 * @deprecated since 5.0.0 43079 * @method PIXI.Sprite.fromSVG 43080 * @see PIXI.Sprite.from 43081 * @return {PIXI.Sprite} 43082 */ 43083 Sprite.fromSVG = spriteFrom.bind(null, 'fromSVG'); 43084 43085 /** 43086 * @deprecated since 5.0.0 43087 * @method PIXI.Sprite.fromCanvas 43088 * @see PIXI.Sprite.from 43089 * @return {PIXI.Sprite} 43090 */ 43091 Sprite.fromCanvas = spriteFrom.bind(null, 'fromCanvas'); 43092 43093 /** 43094 * @deprecated since 5.0.0 43095 * @method PIXI.Sprite.fromVideo 43096 * @see PIXI.Sprite.from 43097 * @return {PIXI.Sprite} 43098 */ 43099 Sprite.fromVideo = spriteFrom.bind(null, 'fromVideo'); 43100 43101 /** 43102 * @deprecated since 5.0.0 43103 * @method PIXI.Sprite.fromFrame 43104 * @see PIXI.Sprite.from 43105 * @return {PIXI.Sprite} 43106 */ 43107 Sprite.fromFrame = spriteFrom.bind(null, 'fromFrame'); 43108 43109 // Use these to deprecate all the Texture from* methods 43110 function textureFrom(name, source, crossorigin, scaleMode) 43111 { 43112 deprecation(v5, ("PIXI.Texture." + name + " is deprecated, use PIXI.Texture.from")); 43113 43114 return Texture.from(source, { 43115 resourceOptions: { 43116 scale: scaleMode, 43117 crossorigin: crossorigin, 43118 }, 43119 }); 43120 } 43121 43122 /** 43123 * @deprecated since 5.0.0 43124 * @method PIXI.Texture.fromImage 43125 * @see PIXI.Texture.from 43126 * @return {PIXI.Texture} 43127 */ 43128 Texture.fromImage = textureFrom.bind(null, 'fromImage'); 43129 43130 /** 43131 * @deprecated since 5.0.0 43132 * @method PIXI.Texture.fromSVG 43133 * @see PIXI.Texture.from 43134 * @return {PIXI.Texture} 43135 */ 43136 Texture.fromSVG = textureFrom.bind(null, 'fromSVG'); 43137 43138 /** 43139 * @deprecated since 5.0.0 43140 * @method PIXI.Texture.fromCanvas 43141 * @see PIXI.Texture.from 43142 * @return {PIXI.Texture} 43143 */ 43144 Texture.fromCanvas = textureFrom.bind(null, 'fromCanvas'); 43145 43146 /** 43147 * @deprecated since 5.0.0 43148 * @method PIXI.Texture.fromVideo 43149 * @see PIXI.Texture.from 43150 * @return {PIXI.Texture} 43151 */ 43152 Texture.fromVideo = textureFrom.bind(null, 'fromVideo'); 43153 43154 /** 43155 * @deprecated since 5.0.0 43156 * @method PIXI.Texture.fromFrame 43157 * @see PIXI.Texture.from 43158 * @return {PIXI.Texture} 43159 */ 43160 Texture.fromFrame = textureFrom.bind(null, 'fromFrame'); 43161 43162 /** 43163 * @deprecated since 5.0.0 43164 * @member {boolean} PIXI.AbstractRenderer#autoResize 43165 * @see PIXI.AbstractRenderer#autoDensity 43166 */ 43167 Object.defineProperty(PIXI.AbstractRenderer.prototype, 'autoResize', { 43168 get: function get() 43169 { 43170 deprecation(v5, 'PIXI.AbstractRenderer autoResize is deprecated, use autoDensity'); 43171 43172 return this.autoDensity; 43173 }, 43174 set: function set(value) 43175 { 43176 deprecation(v5, 'PIXI.AbstractRenderer autoResize is deprecated, use autoDensity'); 43177 43178 this.autoDensity = value; 43179 }, 43180 }); 43181 43182 /** 43183 * @namespace PIXI.utils.mixins 43184 * @deprecated since 5.0.0 43185 */ 43186 PIXI.utils.mixins = { 43187 /** 43188 * @memberof PIXI.utils.mixins 43189 * @function mixin 43190 * @deprecated since 5.0.0 43191 */ 43192 mixin: function mixin() 43193 { 43194 deprecation(v5, 'PIXI.utils.mixins.mixin no longer available'); 43195 }, 43196 /** 43197 * @memberof PIXI.utils.mixins 43198 * @function delayMixin 43199 * @deprecated since 5.0.0 43200 */ 43201 delayMixin: function delayMixin() 43202 { 43203 deprecation(v5, 'PIXI.utils.mixins.delayMixin no longer available'); 43204 }, 43205 /** 43206 * @memberof PIXI.utils.mixins 43207 * @function performMixins 43208 * @deprecated since 5.0.0 43209 */ 43210 performMixins: function performMixins() 43211 { 43212 deprecation(v5, 'PIXI.utils.mixins.performMixins no longer available'); 43213 }, 43214 }; 43215 } 43216 43217 // Install renderer plugins
43218 Renderer.registerPlugin('accessibility', AccessibilityManager); 43219 Renderer.registerPlugin('extract', Extract); 43220 Renderer.registerPlugin('interaction', InteractionManager); 43221 Renderer.registerPlugin('particle', ParticleRenderer); 43222 Renderer.registerPlugin('prepare', Prepare); 43223 Renderer.registerPlugin('batch', BatchRenderer); 43224 Renderer.registerPlugin('tilingSprite', TilingSpriteRenderer); 43225 43226 Loader$2.registerPlugin(BitmapFontLoader); 43227 Loader$2.registerPlugin(SpritesheetLoader); 43228 43229 Application.registerPlugin(TickerPlugin); 43230 Application.registerPlugin(AppLoaderPlugin); 43231 43232 /** 43233 * String of the current PIXI version. 43234 * 43235 * @static 43236 * @constant 43237 * @memberof PIXI 43238 * @name VERSION 43239 * @type {string} 43240 */ 43241 var VERSION$1 = '5.0.0-rc.3'; 43242 43243 /** 43244 * @namespace PIXI 43245 */ 43246 43247 /** 43248 * This namespace contains WebGL-only display filters that can be applied 43249 * to DisplayObjects using the {@link PIXI.DisplayObject#filters filters} property. 43250 * 43251 * Since PixiJS only had a handful of built-in filters, additional filters 43252 * can be downloaded {@link https://github.com/pixijs/pixi-filters here} from the 43253 * PixiJS Filters repository. 43254 * 43255 * All filters must extend {@link PIXI.Filter}. 43256 * 43257 * @example 43258 * // Create a new application 43259 * const app = new PIXI.Application(); 43260 * 43261 * // Draw a green rectangle 43262 * const rect = new PIXI.Graphics() 43263 * .beginFill(0x00ff00) 43264 * .drawRect(40, 40, 200, 200); 43265 * 43266 * // Add a blur filter 43267 * rect.filters = [new PIXI.filters.BlurFilter()]; 43268 * 43269 * // Display rectangle 43270 * app.stage.addChild(rect); 43271 * document.body.appendChild(app.view); 43272 * @namespace PIXI.filters 43273 */ 43274 var filters = { 43275 AlphaFilter: AlphaFilter, 43276 BlurFilter: BlurFilter, 43277 BlurFilterPass: BlurFilterPass, 43278 ColorMatrixFilter: ColorMatrixFilter, 43279 DisplacementFilter: DisplacementFilter, 43280 FXAAFilter: FXAAFilter, 43281 NoiseFilter: NoiseFilter, 43282 }; 43283 43284 /*! 43285 * @pixi/canvas-renderer - v5.0.0-rc.3 43286 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 43287 * 43288 * @pixi/canvas-renderer is licensed under the MIT License. 43289 * http://www.opensource.org/licenses/mit-license 43290 */ 43291 43292 /** 43293 * A set of functions used to handle masking. 43294 * 43295 * Sprite masking is not supported on the CanvasRenderer. 43296 * 43297 * @class 43298 * @memberof PIXI 43299 */ 43300 var CanvasMaskManager = function CanvasMaskManager(renderer) 43301 { 43302 this.renderer = renderer; 43303 }; 43304 43305 /** 43306 * This method adds it to the current stack of masks. 43307 * 43308 * @param {object} maskData - the maskData that will be pushed 43309 */ 43310 CanvasMaskManager.prototype.pushMask = function pushMask (maskData) 43311 { 43312 var renderer = this.renderer; 43313 43314 renderer.context.save(); 43315 43316 var cacheAlpha = maskData.alpha; 43317 var transform = maskData.transform.worldTransform; 43318 var resolution = renderer.resolution; 43319 43320 renderer.context.setTransform( 43321 transform.a * resolution, 43322 transform.b * resolution, 43323 transform.c * resolution, 43324 transform.d * resolution, 43325 transform.tx * resolution, 43326 transform.ty * resolution 43327 ); 43328 43329 // TODO support sprite alpha masks?? 43330 // lots of effort required. If demand is great enough.. 43331 if (!maskData._texture) 43332 { 43333 this.renderGraphicsShape(maskData); 43334 renderer.context.clip(); 43335 } 43336 43337 maskData.worldAlpha = cacheAlpha; 43338 }; 43339 43340 /** 43341 * Renders a PIXI.Graphics shape. 43342 * 43343 * @param {PIXI.Graphics} graphics - The object to render. 43344 */ 43345 CanvasMaskManager.prototype.renderGraphicsShape = function renderGraphicsShape (graphics) 43346 { 43347 var context = this.renderer.context; 43348 var graphicsData = graphics.geometry.graphicsData; 43349 var len = graphicsData.length; 43350 43351 if (len === 0) 43352 { 43353 return; 43354 } 43355 43356 context.beginPath(); 43357 43358 for (var i = 0; i < len; i++) 43359 { 43360 var data = graphicsData[i]; 43361 var shape = data.shape; 43362 43363 if (data.type === SHAPES.POLY) 43364 { 43365 var points = shape.points; 43366 43367 context.moveTo(points[0], points[1]); 43368 43369 for (var j = 1; j < points.length / 2; j++) 43370 { 43371 context.lineTo(points[j * 2], points[(j * 2) + 1]); 43372 } 43373 43374 // if the first and last point are the same close the path - much neater :) 43375 if (points[0] === points[points.length - 2] && points[1] === points[points.length - 1]) 43376 { 43377 context.closePath(); 43378 } 43379 } 43380 else if (data.type === SHAPES.RECT) 43381 { 43382 context.rect(shape.x, shape.y, shape.width, shape.height); 43383 context.closePath(); 43384 } 43385 else if (data.type === SHAPES.CIRC) 43386 {
43387 // TODO - need to be Undefined! 43388 context.arc(shape.x, shape.y, shape.radius, 0, 2 * Math.PI); 43389 context.closePath(); 43390 } 43391 else if (data.type === SHAPES.ELIP) 43392 { 43393 // ellipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas 43394 43395 var w = shape.width * 2; 43396 var h = shape.height * 2; 43397 43398 var x = shape.x - (w / 2); 43399 var y = shape.y - (h / 2); 43400 43401 var kappa = 0.5522848; 43402 var ox = (w / 2) * kappa; // control point offset horizontal 43403 var oy = (h / 2) * kappa; // control point offset vertical 43404 var xe = x + w; // x-end 43405 var ye = y + h; // y-end 43406 var xm = x + (w / 2); // x-middle 43407 var ym = y + (h / 2); // y-middle 43408 43409 context.moveTo(x, ym); 43410 context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y); 43411 context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym); 43412 context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye); 43413 context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym); 43414 context.closePath(); 43415 } 43416 else if (data.type === SHAPES.RREC) 43417 { 43418 var rx = shape.x; 43419 var ry = shape.y; 43420 var width = shape.width; 43421 var height = shape.height; 43422 var radius = shape.radius; 43423 43424 var maxRadius = Math.min(width, height) / 2 | 0; 43425 43426 radius = radius > maxRadius ? maxRadius : radius; 43427 43428 context.moveTo(rx, ry + radius); 43429 context.lineTo(rx, ry + height - radius); 43430 context.quadraticCurveTo(rx, ry + height, rx + radius, ry + height); 43431 context.lineTo(rx + width - radius, ry + height); 43432 context.quadraticCurveTo(rx + width, ry + height, rx + width, ry + height - radius); 43433 context.lineTo(rx + width, ry + radius); 43434 context.quadraticCurveTo(rx + width, ry, rx + width - radius, ry); 43435 context.lineTo(rx + radius, ry); 43436 context.quadraticCurveTo(rx, ry, rx, ry + radius); 43437 context.closePath(); 43438 } 43439 } 43440 }; 43441 43442 /** 43443 * Restores the current drawing context to the state it was before the mask was applied. 43444 * 43445 * @param {PIXI.CanvasRenderer} renderer - The renderer context to use. 43446 */ 43447 CanvasMaskManager.prototype.popMask = function popMask (renderer) 43448 { 43449 renderer.context.restore(); 43450 renderer.invalidateBlendMode(); 43451 }; 43452 43453 /** 43454 * Destroys this canvas mask manager. 43455 * 43456 */ 43457 CanvasMaskManager.prototype.destroy = function destroy () 43458 { 43459 /* empty */ 43460 }; 43461 43462 /** 43463 * Creates a little colored canvas 43464 * 43465 * @ignore 43466 * @param {string} color - The color to make the canvas 43467 * @return {canvas} a small canvas element 43468 */ 43469 function createColoredCanvas(color) 43470 { 43471 var canvas = document.createElement('canvas'); 43472 43473 canvas.width = 6; 43474 canvas.height = 1; 43475 43476 var context = canvas.getContext('2d'); 43477 43478 context.fillStyle = color; 43479 context.fillRect(0, 0, 6, 1); 43480 43481 return canvas; 43482 } 43483 43484 /** 43485 * Checks whether the Canvas BlendModes are supported by the current browser 43486 * 43487 * @private 43488 * @return {boolean} whether they are supported 43489 */ 43490 function canUseNewCanvasBlendModes() 43491 { 43492 if (typeof document === 'undefined') 43493 { 43494 return false; 43495 } 43496 43497 var magenta = createColoredCanvas('#ff00ff'); 43498 var yellow = createColoredCanvas('#ffff00'); 43499 43500 var canvas = document.createElement('canvas'); 43501 43502 canvas.width = 6; 43503 canvas.height = 1; 43504 43505 var context = canvas.getContext('2d'); 43506 43507 context.globalCompositeOperation = 'multiply'; 43508 context.drawImage(magenta, 0, 0); 43509 context.drawImage(yellow, 2, 0); 43510 43511 var imageData = context.getImageData(2, 0, 1, 1); 43512 43513 if (!imageData) 43514 { 43515 return false; 43516 } 43517 43518 var data = imageData.data; 43519 43520 return (data[0] === 255 && data[1] === 0 && data[2] === 0); 43521 } 43522 43523 /** 43524 * Maps blend combinations to Canvas. 43525 * 43526 * @memberof PIXI 43527 * @function mapCanvasBlendModesToPixi 43528 * @private 43529 * @param {string[]} [array=[]] - The array to output into. 43530 * @return {string[]} Mapped modes. 43531 */ 43532 function mapCanvasBlendModesToPixi(array) 43533 { 43534 if ( array === void 0 ) { array = []; } 43535 43536 if (canUseNewCanvasBlendModes()) 43537 {
43538 array[BLEND_MODES.NORMAL] = 'source-over'; 43539 array[BLEND_MODES.ADD] = 'lighter'; // IS THIS OK??? 43540 array[BLEND_MODES.MULTIPLY] = 'multiply'; 43541 array[BLEND_MODES.SCREEN] = 'screen'; 43542 array[BLEND_MODES.OVERLAY] = 'overlay'; 43543 array[BLEND_MODES.DARKEN] = 'darken'; 43544 array[BLEND_MODES.LIGHTEN] = 'lighten'; 43545 array[BLEND_MODES.COLOR_DODGE] = 'color-dodge'; 43546 array[BLEND_MODES.COLOR_BURN] = 'color-burn'; 43547 array[BLEND_MODES.HARD_LIGHT] = 'hard-light'; 43548 array[BLEND_MODES.SOFT_LIGHT] = 'soft-light'; 43549 array[BLEND_MODES.DIFFERENCE] = 'difference'; 43550 array[BLEND_MODES.EXCLUSION] = 'exclusion'; 43551 array[BLEND_MODES.HUE] = 'hue'; 43552 array[BLEND_MODES.SATURATION] = 'saturate'; 43553 array[BLEND_MODES.COLOR] = 'color'; 43554 array[BLEND_MODES.LUMINOSITY] = 'luminosity'; 43555 } 43556 else 43557 { 43558 // this means that the browser does not support the cool new blend modes in canvas 'cough' ie 'cough' 43559 array[BLEND_MODES.NORMAL] = 'source-over'; 43560 array[BLEND_MODES.ADD] = 'lighter'; // IS THIS OK??? 43561 array[BLEND_MODES.MULTIPLY] = 'source-over'; 43562 array[BLEND_MODES.SCREEN] = 'source-over'; 43563 array[BLEND_MODES.OVERLAY] = 'source-over'; 43564 array[BLEND_MODES.DARKEN] = 'source-over'; 43565 array[BLEND_MODES.LIGHTEN] = 'source-over'; 43566 array[BLEND_MODES.COLOR_DODGE] = 'source-over'; 43567 array[BLEND_MODES.COLOR_BURN] = 'source-over'; 43568 array[BLEND_MODES.HARD_LIGHT] = 'source-over'; 43569 array[BLEND_MODES.SOFT_LIGHT] = 'source-over'; 43570 array[BLEND_MODES.DIFFERENCE] = 'source-over'; 43571 array[BLEND_MODES.EXCLUSION] = 'source-over'; 43572 array[BLEND_MODES.HUE] = 'source-over'; 43573 array[BLEND_MODES.SATURATION] = 'source-over'; 43574 array[BLEND_MODES.COLOR] = 'source-over'; 43575 array[BLEND_MODES.LUMINOSITY] = 'source-over'; 43576 } 43577 // not-premultiplied, only for webgl 43578 array[BLEND_MODES.NORMAL_NPM] = array[BLEND_MODES.NORMAL]; 43579 array[BLEND_MODES.ADD_NPM] = array[BLEND_MODES.ADD]; 43580 array[BLEND_MODES.SCREEN_NPM] = array[BLEND_MODES.SCREEN]; 43581 43582 // composite operations 43583 array[BLEND_MODES.SRC_IN] = 'source-in'; 43584 array[BLEND_MODES.SRC_OUT] = 'source-out'; 43585 array[BLEND_MODES.SRC_ATOP] = 'source-atop'; 43586 array[BLEND_MODES.DST_OVER] = 'destination-over'; 43587 array[BLEND_MODES.DST_IN] = 'destination-in'; 43588 array[BLEND_MODES.DST_OUT] = 'destination-out'; 43589 array[BLEND_MODES.DST_ATOP] = 'destination-atop'; 43590 43591 // SUBTRACT from flash, does not exist in canvas 43592 array[BLEND_MODES.SUBTRACT] = 'source-over'; 43593 43594 return array; 43595 } 43596 43597 /** 43598 * The CanvasRenderer draws the scene and all its content onto a 2d canvas. 43599 * 43600 * This renderer should be used for browsers that do not support WebGL. 43601 * Don't forget to add the CanvasRenderer.view to your DOM or you will not see anything! 43602 * 43603 * @class 43604 * @memberof PIXI 43605 * @extends PIXI.AbstractRenderer 43606 */ 43607 var CanvasRenderer = /*@__PURE__*/(function (AbstractRenderer) { 43608 function CanvasRenderer(options, arg2, arg3) 43609 { 43610 AbstractRenderer.call(this, 'Canvas', options, arg2, arg3); 43611 43612 this.type = RENDERER_TYPE.CANVAS; 43613 43614 /** 43615 * The root canvas 2d context that everything is drawn with. 43616 * 43617 * @member {CanvasRenderingContext2D} 43618 */ 43619 this.rootContext = this.view.getContext('2d', { alpha: this.transparent }); 43620 43621 /** 43622 * The currently active canvas 2d context (could change with renderTextures) 43623 * 43624 * @member {CanvasRenderingContext2D} 43625 */ 43626 this.context = this.rootContext; 43627 43628 /** 43629 * Boolean flag controlling canvas refresh. 43630 * 43631 * @member {boolean} 43632 */ 43633 this.refresh = true; 43634 43635 /** 43636 * Instance of a CanvasMaskManager, handles masking when using the canvas renderer. 43637 * 43638 * @member {PIXI.CanvasMaskManager} 43639 */ 43640 this.maskManager = new CanvasMaskManager(this); 43641 43642 /** 43643 * The canvas property used to set the canvas smoothing property. 43644 * 43645 * @member {string} 43646 */ 43647 this.smoothProperty = 'imageSmoothingEnabled'; 43648
43649 if (!this.rootContext.imageSmoothingEnabled) 43650 { 43651 if (this.rootContext.webkitImageSmoothingEnabled) 43652 { 43653 this.smoothProperty = 'webkitImageSmoothingEnabled'; 43654 } 43655 else if (this.rootContext.mozImageSmoothingEnabled) 43656 { 43657 this.smoothProperty = 'mozImageSmoothingEnabled'; 43658 } 43659 else if (this.rootContext.oImageSmoothingEnabled) 43660 { 43661 this.smoothProperty = 'oImageSmoothingEnabled'; 43662 } 43663 else if (this.rootContext.msImageSmoothingEnabled) 43664 { 43665 this.smoothProperty = 'msImageSmoothingEnabled'; 43666 } 43667 } 43668 43669 this.initPlugins(CanvasRenderer.__plugins); 43670 43671 /** 43672 * Tracks the blend modes useful for this renderer. 43673 * 43674 * @member {object<number, string>} 43675 */ 43676 this.blendModes = mapCanvasBlendModesToPixi(); 43677 this._activeBlendMode = null; 43678 this._outerBlend = false; 43679 43680 this.renderingToScreen = false; 43681 43682 sayHello('Canvas'); 43683 43684 /** 43685 * Fired after rendering finishes. 43686 * 43687 * @event PIXI.CanvasRenderer#postrender 43688 */ 43689 43690 /** 43691 * Fired before rendering starts. 43692 * 43693 * @event PIXI.CanvasRenderer#prerender 43694 */ 43695 43696 this.resize(this.options.width, this.options.height); 43697 } 43698 43699 if ( AbstractRenderer ) { CanvasRenderer.__proto__ = AbstractRenderer; } 43700 CanvasRenderer.prototype = Object.create( AbstractRenderer && AbstractRenderer.prototype ); 43701 CanvasRenderer.prototype.constructor = CanvasRenderer; 43702 43703 /**
43704 * Renders the object to this canvas view 43705 * 43706 * @param {PIXI.DisplayObject} displayObject - The object to be rendered 43707 * @param {PIXI.RenderTexture} [renderTexture] - A render texture to be rendered to. 43708 * If unset, it will render to the root context. 43709 * @param {boolean} [clear=false] - Whether to clear the canvas before drawing 43710 * @param {PIXI.Matrix} [transform] - A transformation to be applied 43711 * @param {boolean} [skipUpdateTransform=false] - Whether to skip the update transform 43712 */ 43713 CanvasRenderer.prototype.render = function render (displayObject, renderTexture, clear, transform, skipUpdateTransform) 43714 { 43715 if (!this.view) 43716 { 43717 return; 43718 } 43719 43720 // can be handy to know! 43721 this.renderingToScreen = !renderTexture; 43722 43723 this.emit('prerender'); 43724 43725 var rootResolution = this.resolution; 43726 43727 if (renderTexture) 43728 { 43729 renderTexture = renderTexture.baseTexture || renderTexture; 43730 43731 if (!renderTexture._canvasRenderTarget) 43732 { 43733 renderTexture._canvasRenderTarget = new CanvasRenderTarget( 43734 renderTexture.width, 43735 renderTexture.height, 43736 renderTexture.resolution 43737 ); 43738 renderTexture.source = renderTexture._canvasRenderTarget.canvas; 43739 renderTexture.valid = true; 43740 } 43741 43742 this.context = renderTexture._canvasRenderTarget.context; 43743 this.resolution = renderTexture._canvasRenderTarget.resolution; 43744 } 43745 else 43746 { 43747 this.context = this.rootContext; 43748 } 43749 43750 var context = this.context; 43751 43752 if (!renderTexture) 43753 { 43754 this._lastObjectRendered = displayObject; 43755 } 43756 43757 if (!skipUpdateTransform) 43758 { 43759 // update the scene graph 43760 var cacheParent = displayObject.parent; 43761 var tempWt = this._tempDisplayObjectParent.transform.worldTransform; 43762 43763 if (transform) 43764 { 43765 transform.copyTo(tempWt); 43766 43767 // lets not forget to flag the parent transform as dirty... 43768 this._tempDisplayObjectParent.transform._worldID = -1; 43769 } 43770 else 43771 { 43772 tempWt.identity(); 43773 } 43774 43775 displayObject.parent = this._tempDisplayObjectParent; 43776 43777 displayObject.updateTransform(); 43778 displayObject.parent = cacheParent; 43779 // displayObject.hitArea = //TODO add a temp hit area 43780 } 43781 43782 context.save(); 43783 context.setTransform(1, 0, 0, 1, 0, 0); 43784 context.globalAlpha = 1; 43785 this._activeBlendMode = BLEND_MODES.NORMAL; 43786 this._outerBlend = false; 43787 context.globalCompositeOperation = this.blendModes[BLEND_MODES.NORMAL]; 43788 43789 if (clear !== undefined ? clear : this.clearBeforeRender) 43790 { 43791 if (this.renderingToScreen) 43792 { 43793 if (this.transparent) 43794 { 43795 context.clearRect(0, 0, this.width, this.height); 43796 } 43797 else 43798 { 43799 context.fillStyle = this._backgroundColorString; 43800 context.fillRect(0, 0, this.width, this.height); 43801 } 43802 } // else { 43803 // TODO: implement background for CanvasRenderTarget or RenderTexture? 43804 // } 43805 } 43806 43807 // TODO RENDER TARGET STUFF HERE.. 43808 var tempContext = this.context; 43809 43810 this.context = context; 43811 displayObject.renderCanvas(this); 43812 this.context = tempContext; 43813 43814 context.restore(); 43815 43816 this.resolution = rootResolution; 43817 43818 this.emit('postrender'); 43819 }; 43820 43821 /** 43822 * Clear the canvas of renderer. 43823 * 43824 * @param {string} [clearColor] - Clear the canvas with this color, except the canvas is transparent. 43825 */ 43826 CanvasRenderer.prototype.clear = function clear (clearColor) 43827 { 43828 var context = this.context; 43829 43830 clearColor = clearColor || this._backgroundColorString; 43831 43832 if (!this.transparent && clearColor) 43833 { 43834 context.fillStyle = clearColor; 43835 context.fillRect(0, 0, this.width, this.height); 43836 } 43837 else 43838 { 43839 context.clearRect(0, 0, this.width, this.height); 43840 } 43841 }; 43842 43843 /** 43844 * Sets the blend mode of the renderer. 43845 * 43846 * @param {number} blendMode - See {@link PIXI.BLEND_MODES} for valid values. 43847 * @param {boolean} [readyForOuterBlend=false] - Some blendModes are dangerous, they affect outer space of sprite. 43848 * Pass `true` only if you are ready to use them. 43849 */ 43850 CanvasRenderer.prototype.setBlendMode = function setBlendMode (blendMode, readyForOuterBlend) 43851 { 43852 var outerBlend = blendMode === BLEND_MODES.SRC_IN 43853 || blendMode === BLEND_MODES.SRC_OUT 43854 || blendMode === BLEND_MODES.DST_IN 43855 || blendMode === BLEND_MODES.DST_ATOP; 43856 43857 if (!readyForOuterBlend && outerBlend) 43858 { 43859 blendMode = BLEND_MODES.NORMAL; 43860 } 43861 43862 if (this._activeBlendMode === blendMode) 43863 { 43864 return; 43865 } 43866 43867 this._activeBlendMode = blendMode; 43868 this._outerBlend = outerBlend; 43869 this.context.globalCompositeOperation = this.blendModes[blendMode]; 43870 }; 43871 43872 /** 43873 * Removes everything from the renderer and optionally removes the Canvas DOM element. 43874 * 43875 * @param {boolean} [removeView=false] - Removes the Canvas element from the DOM. 43876 */ 43877 CanvasRenderer.prototype.destroy = function destroy (removeView) 43878 { 43879 // call the base destroy 43880 AbstractRenderer.prototype.destroy.call(this, removeView); 43881 43882 this.context = null; 43883 43884 this.refresh = true; 43885 43886 this.maskManager.destroy(); 43887 this.maskManager = null; 43888 43889 this.smoothProperty = null; 43890 }; 43891 43892 /** 43893 * Resizes the canvas view to the specified width and height. 43894 * 43895 * @extends PIXI.AbstractRenderer#resize 43896 * 43897 * @param {number} screenWidth - the new width of the screen 43898 * @param {number} screenHeight - the new height of the screen 43899 */ 43900 CanvasRenderer.prototype.resize = function resize (screenWidth, screenHeight) 43901 { 43902 AbstractRenderer.prototype.resize.call(this, screenWidth, screenHeight); 43903
43904 // reset the scale mode.. oddly this seems to be reset when the canvas is resized. 43905 // surely a browser bug?? Let PixiJS fix that for you.. 43906 if (this.smoothProperty) 43907 { 43908 this.rootContext[this.smoothProperty] = (settings.SCALE_MODE === SCALE_MODES.LINEAR); 43909 } 43910 }; 43911 43912 /** 43913 * Checks if blend mode has changed. 43914 */ 43915 CanvasRenderer.prototype.invalidateBlendMode = function invalidateBlendMode () 43916 { 43917 this._activeBlendMode = this.blendModes.indexOf(this.context.globalCompositeOperation); 43918 }; 43919 43920 /** 43921 * Collection of installed plugins. These are included by default in PIXI, but can be excluded 43922 * by creating a custom build. Consult the README for more information about creating custom 43923 * builds and excluding plugins. 43924 * @name PIXI.CanvasRenderer#plugins 43925 * @type {object} 43926 * @readonly 43927 * @property {PIXI.accessibility.AccessibilityManager} accessibility Support tabbing interactive elements. 43928 * @property {PIXI.extract.CanvasExtract} extract Extract image data from renderer. 43929 * @property {PIXI.interaction.InteractionManager} interaction Handles mouse, touch and pointer events. 43930 * @property {PIXI.prepare.CanvasPrepare} prepare Pre-render display objects. 43931 */ 43932 43933 /** 43934 * Adds a plugin to the renderer. 43935 * 43936 * @method 43937 * @param {string} pluginName - The name of the plugin. 43938 * @param {Function} ctor - The constructor function or class for the plugin. 43939 */ 43940 CanvasRenderer.registerPlugin = function registerPlugin (pluginName, ctor) 43941 { 43942 CanvasRenderer.__plugins = CanvasRenderer.__plugins || {}; 43943 CanvasRenderer.__plugins[pluginName] = ctor; 43944 }; 43945 43946 return CanvasRenderer; 43947 }(AbstractRenderer)); 43948 43949 /** 43950 * Utility methods for Sprite/Texture tinting. 43951 * 43952 * Tinting with the CanvasRenderer involves creating a new canvas to use as a texture, 43953 * so be aware of the performance implications. 43954 * 43955 * @class 43956 * @memberof PIXI 43957 */ 43958 var CanvasTinter = { 43959 /** 43960 * Basically this method just needs a sprite and a color and tints the sprite with the given color. 43961 * 43962 * @memberof PIXI.CanvasTinter 43963 * @param {PIXI.Sprite} sprite - the sprite to tint 43964 * @param {number} color - the color to use to tint the sprite with 43965 * @return {HTMLCanvasElement} The tinted canvas 43966 */ 43967 getTintedCanvas: function (sprite, color) { 43968 var texture = sprite._texture; 43969 43970 color = CanvasTinter.roundColor(color); 43971 43972 var stringColor = "#" + ((("00000" + ((color | 0).toString(16)))).substr(-6)); 43973 43974 texture.tintCache = texture.tintCache || {}; 43975 43976 var cachedCanvas = texture.tintCache[stringColor]; 43977 43978 var canvas; 43979 43980 if (cachedCanvas) 43981 { 43982 if (cachedCanvas.tintId === texture._updateID) 43983 { 43984 return texture.tintCache[stringColor]; 43985 } 43986 43987 canvas = texture.tintCache[stringColor]; 43988 } 43989 else 43990 { 43991 canvas = CanvasTinter.canvas || document.createElement('canvas'); 43992 } 43993 43994 CanvasTinter.tintMethod(texture, color, canvas); 43995 43996 canvas.tintId = texture._updateID; 43997 43998 if (CanvasTinter.convertTintToImage) 43999 { 44000 // is this better? 44001 var tintImage = new Image(); 44002 44003 tintImage.src = canvas.toDataURL(); 44004 44005 texture.tintCache[stringColor] = tintImage; 44006 } 44007 else 44008 { 44009 texture.tintCache[stringColor] = canvas; 44010 // if we are not converting the texture to an image then we need to lose the reference to the canvas 44011 CanvasTinter.canvas = null; 44012 } 44013 44014 return canvas; 44015 }, 44016 44017 /** 44018 * Tint a texture using the 'multiply' operation. 44019 * 44020 * @memberof PIXI.CanvasTinter 44021 * @param {PIXI.Texture} texture - the texture to tint 44022 * @param {number} color - the color to use to tint the sprite with 44023 * @param {HTMLCanvasElement} canvas - the current canvas 44024 */ 44025 tintWithMultiply: function (texture, color, canvas) { 44026 var context = canvas.getContext('2d'); 44027 var crop = texture._frame.clone(); 44028 var resolution = texture.baseTexture.resolution; 44029 44030 crop.x *= resolution; 44031 crop.y *= resolution; 44032 crop.width *= resolution; 44033 crop.height *= resolution; 44034 44035 canvas.width = Math.ceil(crop.width);
44036 canvas.height = Math.ceil(crop.height); 44037 44038 context.save(); 44039 context.fillStyle = "#" + ((("00000" + ((color | 0).toString(16)))).substr(-6)); 44040 44041 context.fillRect(0, 0, crop.width, crop.height); 44042 44043 context.globalCompositeOperation = 'multiply'; 44044 44045 var source = texture.baseTexture.getDrawableSource(); 44046 44047 context.drawImage( 44048 source, 44049 crop.x, 44050 crop.y, 44051 crop.width, 44052 crop.height, 44053 0, 44054 0, 44055 crop.width, 44056 crop.height 44057 ); 44058 44059 context.globalCompositeOperation = 'destination-atop'; 44060 44061 context.drawImage( 44062 source, 44063 crop.x, 44064 crop.y, 44065 crop.width, 44066 crop.height, 44067 0, 44068 0, 44069 crop.width, 44070 crop.height 44071 ); 44072 context.restore(); 44073 }, 44074 44075 /** 44076 * Tint a texture using the 'overlay' operation. 44077 * 44078 * @memberof PIXI.CanvasTinter 44079 * @param {PIXI.Texture} texture - the texture to tint 44080 * @param {number} color - the color to use to tint the sprite with 44081 * @param {HTMLCanvasElement} canvas - the current canvas 44082 */ 44083 tintWithOverlay: function tintWithOverlay(texture, color, canvas) 44084 { 44085 var context = canvas.getContext('2d'); 44086 var crop = texture._frame.clone(); 44087 var resolution = texture.baseTexture.resolution; 44088 44089 crop.x *= resolution; 44090 crop.y *= resolution; 44091 crop.width *= resolution; 44092 crop.height *= resolution; 44093 44094 canvas.width = Math.ceil(crop.width); 44095 canvas.height = Math.ceil(crop.height); 44096 44097 context.save(); 44098 context.globalCompositeOperation = 'copy'; 44099 context.fillStyle = "#" + ((("00000" + ((color | 0).toString(16)))).substr(-6)); 44100 context.fillRect(0, 0, crop.width, crop.height); 44101 44102 context.globalCompositeOperation = 'destination-atop'; 44103 context.drawImage( 44104 texture.baseTexture.getDrawableSource(), 44105 crop.x, 44106 crop.y, 44107 crop.width, 44108 crop.height, 44109 0, 44110 0, 44111 crop.width, 44112 crop.height 44113 ); 44114 44115 // context.globalCompositeOperation = 'copy'; 44116 context.restore(); 44117 }, 44118 44119 /** 44120 * Tint a texture pixel per pixel. 44121 * 44122 * @memberof PIXI.CanvasTinter 44123 * @param {PIXI.Texture} texture - the texture to tint 44124 * @param {number} color - the color to use to tint the sprite with 44125 * @param {HTMLCanvasElement} canvas - the current canvas 44126 */ 44127 tintWithPerPixel: function (texture, color, canvas) { 44128 var context = canvas.getContext('2d'); 44129 var crop = texture._frame.clone(); 44130 var resolution = texture.baseTexture.resolution; 44131 44132 crop.x *= resolution; 44133 crop.y *= resolution; 44134 crop.width *= resolution; 44135 crop.height *= resolution; 44136 44137 canvas.width = Math.ceil(crop.width); 44138 canvas.height = Math.ceil(crop.height); 44139 44140 context.save(); 44141 context.globalCompositeOperation = 'copy'; 44142 context.drawImage( 44143 texture.baseTexture.getDrawableSource(), 44144 crop.x, 44145 crop.y, 44146 crop.width, 44147 crop.height, 44148 0, 44149 0, 44150 crop.width, 44151 crop.height 44152 ); 44153 context.restore(); 44154 44155 var rgbValues = hex2rgb(color); 44156 var r = rgbValues[0]; 44157 var g = rgbValues[1]; 44158 var b = rgbValues[2]; 44159 44160 var pixelData = context.getImageData(0, 0, crop.width, crop.height); 44161 44162 var pixels = pixelData.data; 44163 44164 for (var i = 0; i < pixels.length; i += 4) 44165 { 44166 pixels[i + 0] *= r; 44167 pixels[i + 1] *= g; 44168 pixels[i + 2] *= b; 44169 } 44170 44171 context.putImageData(pixelData, 0, 0); 44172 }, 44173 44174 /** 44175 * Rounds the specified color according to the CanvasTinter.cacheStepsPerColorChannel. 44176 * 44177 * @memberof PIXI.CanvasTinter 44178 * @param {number} color - the color to round, should be a hex color 44179 * @return {number} The rounded color. 44180 */ 44181 roundColor: function (color) { 44182 var step = CanvasTinter.cacheStepsPerColorChannel; 44183 44184 var rgbValues = hex2rgb(color); 44185 44186 rgbValues[0] = Math.min(255, (rgbValues[0] / step) * step); 44187 rgbValues[1] = Math.min(255, (rgbValues[1] / step) * step); 44188 rgbValues[2] = Math.min(255, (rgbValues[2] / step) * step); 44189 44190 return rgb2hex(rgbValues); 44191 }, 44192 44193 /** 44194 * Number of steps which will be used as a cap when rounding colors. 44195 * 44196 * @memberof PIXI.CanvasTinter 44197 * @type {number} 44198 */ 44199 cacheStepsPerColorChannel: 8, 44200 44201 /** 44202 * Tint cache boolean flag. 44203 * 44204 * @memberof PIXI.CanvasTinter 44205 * @type {boolean} 44206 */ 44207 convertTintToImage: false, 44208 44209 /** 44210 * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method. 44211 * 44212 * @memberof PIXI.CanvasTinter 44213 * @type {boolean} 44214 */ 44215 canUseMultiply: canUseNewCanvasBlendModes(), 44216 44217 /** 44218 * The tinting method that will be used. 44219 * 44220 * @memberof PIXI.CanvasTinter 44221 * @type {Function} 44222 */ 44223 tintMethod: function () { // jslint-disable no-empty-function 44224 44225 }, 44226 }; 44227 44228 CanvasTinter.tintMethod = CanvasTinter.canUseMultiply ? CanvasTinter.tintWithMultiply : CanvasTinter.tintWithPerP
44228ixel; 44229 44230 // Reference to Renderer.create static function 44231 var parentCreate = Renderer.create; 44232 44233 /** 44234 * Override the Renderer.create to fallback to use CanvasRenderer. 44235 * Also supports forceCanvas option with Application or autoDetectRenderer. 44236 * @private 44237 */ 44238 Renderer.create = function create(options) 44239 { 44240 var forceCanvas = options && options.forceCanvas; 44241 44242 if (!forceCanvas) 44243 { 44244 try 44245 { 44246 return parentCreate(options); 44247 } 44248 catch (err) 44249 { 44250 // swallow WebGL-unsupported error 44251 } 44252 } 44253 44254 return new CanvasRenderer(options); 44255 }; 44256 44257 /** 44258 * Get the drawable source, such as HTMLCanvasElement or HTMLImageElement suitable 44259 * for rendering with CanvasRenderer. Provided by **@pixi/canvas-renderer** package. 44260 * @method getDrawableSource 44261 * @memberof PIXI.BaseTexture# 44262 * @return {PIXI.ICanvasImageSource} Source to render with CanvasRenderer 44263 */ 44264 BaseTexture.prototype.getDrawableSource = function getDrawableSource() 44265 { 44266 var resource = this.resource; 44267 44268 return resource ? (resource.bitmap || resource.source) : this.source; 44269 }; 44270 44271 /*! 44272 * @pixi/canvas-mesh - v5.0.0-rc.3 44273 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 44274 * 44275 * @pixi/canvas-mesh is licensed under the MIT License. 44276 * http://www.opensource.org/licenses/mit-license 44277 */ 44278 44279 /** 44280 * Renderer dedicated to meshes. 44281 * 44282 * @class 44283 * @protected 44284 * @memberof PIXI 44285 */ 44286 var CanvasMeshRenderer = function CanvasMeshRenderer(renderer) 44287 { 44288 this.renderer = renderer; 44289 }; 44290 44291 /** 44292 * Renders the Mesh 44293 * 44294 * @param {PIXI.Mesh} mesh - the Mesh to render 44295 */ 44296 CanvasMeshRenderer.prototype.render = function render (mesh) 44297 { 44298 var renderer = this.renderer; 44299 var context = renderer.context; 44300 44301 var transform = mesh.worldTransform; 44302 var res = renderer.resolution; 44303 44304 if (mesh.roundPixels) 44305 { 44306 context.setTransform( 44307 transform.a * res, 44308 transform.b * res, 44309 transform.c * res, 44310 transform.d * res, 44311 (transform.tx * res) | 0, 44312 (transform.ty * res) | 0 44313 ); 44314 } 44315 else 44316 { 44317 context.setTransform( 44318 transform.a * res, 44319 transform.b * res, 44320 transform.c * res, 44321 transform.d * res, 44322 transform.tx * res, 44323 transform.ty * res 44324 ); 44325 } 44326 44327 renderer.context.globalAlpha = mesh.worldAlpha; 44328 renderer.setBlendMode(mesh.blendMode); 44329 44330 if (mesh.drawMode !== DRAW_MODES.TRIANGLES) 44331 { 44332 this._renderTriangleMesh(mesh); 44333 } 44334 else 44335 { 44336 this._renderTriangles(mesh); 44337 } 44338 }; 44339 44340 /** 44341 * Draws the object in Triangle Mesh mode 44342 * 44343 * @private 44344 * @param {PIXI.RawMesh} mesh - the Mesh to render 44345 */ 44346 CanvasMeshRenderer.prototype._renderTriangleMesh = function _renderTriangleMesh (mesh) 44347 { 44348 // draw triangles!! 44349 var length = mesh.geometry.buffers[0].data.length; 44350 44351 for (var i = 0; i < length - 2; i++) 44352 { 44353 // draw some triangles! 44354 var index = i * 2; 44355 44356 this._renderDrawTriangle(mesh, index, (index + 2), (index + 4)); 44357 } 44358 }; 44359 44360 /** 44361 * Draws the object in triangle mode using canvas 44362 * 44363 * @private 44364 * @param {PIXI.RawMesh} mesh - the current mesh 44365 */ 44366 CanvasMeshRenderer.prototype._renderTriangles = function _renderTriangles (mesh) 44367 { 44368 // draw triangles!! 44369 var indices = mesh.geometry.getIndex().data; 44370 var length = indices.length; 44371 44372 for (var i = 0; i < length; i += 3) 44373 { 44374 // draw some triangles! 44375 var index0 = indices[i] * 2; 44376 var index1 = indices[i + 1] * 2; 44377 var index2 = indices[i + 2] * 2; 44378 44379 this._renderDrawTriangle(mesh, index0, index1, index2); 44380 } 44381 }; 44382 44383 /** 44384 * Draws one of the triangles that from the Mesh 44385 * 44386 * @private 44387 * @param {PIXI.RawMesh} mesh - the current mesh 44388 * @param {number} index0 - the index of the first vertex 44389 * @param {number} index1 - the index of the second vertex 44390 * @param {number} index2 - the index of the third vertex 44391 */ 44392 CanvasMeshRenderer.prototype._renderDrawTriangle = function _renderDrawTriangle (mesh, index0, index1, index2) 44393 { 44394 var context = this.renderer.context; 44395 var vertices = mesh.geometry.buffers[0].data; 44396 var uvs = mesh.uvs; 44397 var texture = mesh.texture; 44398 44399 if (!texture.valid) 44400 { 44401 return; 44402 } 44403 44404 var base = texture.baseTexture; 44405 var textureSource = base.getDrawableSource(); 44406 var textureWidth = base.width; 44407 var textureHeight = base.height; 44408 44409 var u0 = uvs[index0] * base.width; 44410 var u1 = uvs[index1] * base.width; 44411 var u2 = uvs[index2] * base.width; 44412 var v0 = uvs[index0 + 1] * base.height; 44413 var v1 = uvs[index1 + 1] * base.height; 44414 var v2 = uvs[index2 + 1] * base.height; 44415 44416 var x0 = vertices[index0]; 44417 var x1 = vertices[index1]; 44418 var x2 = vertices[index2]; 44419 var y0 = vertices[index0 + 1]; 44420 var y1 = vertices[index1 + 1]; 44421 var y2 = vertices[index2 + 1]; 44422 44423 var canvasPadding = mesh.canvasPadding / this.renderer.resolution; 44424 44425 if (canvasPadding > 0) 44426 { 44427 var paddingX = canvasPadding / Math.abs(mesh.worldTransform.a); 44428 var paddingY = canvasPadding / Math.abs(mesh.worldTransform.d); 44429 var centerX = (x0 + x1 + x2) / 3; 44430 var centerY = (y0 + y1 + y2) / 3; 44431 44432 var normX = x0 - centerX;
44433 var normY = y0 - centerY; 44434 44435 var dist = Math.sqrt((normX * normX) + (normY * normY)); 44436 44437 x0 = centerX + ((normX / dist) * (dist + paddingX)); 44438 y0 = centerY + ((normY / dist) * (dist + paddingY)); 44439 44440 // 44441 44442 normX = x1 - centerX; 44443 normY = y1 - centerY; 44444 44445 dist = Math.sqrt((normX * normX) + (normY * normY)); 44446 x1 = centerX + ((normX / dist) * (dist + paddingX)); 44447 y1 = centerY + ((normY / dist) * (dist + paddingY)); 44448 44449 normX = x2 - centerX; 44450 normY = y2 - centerY; 44451 44452 dist = Math.sqrt((normX * normX) + (normY * normY)); 44453 x2 = centerX + ((normX / dist) * (dist + paddingX)); 44454 y2 = centerY + ((normY / dist) * (dist + paddingY)); 44455 } 44456 44457 context.save(); 44458 context.beginPath(); 44459 44460 context.moveTo(x0, y0); 44461 context.lineTo(x1, y1); 44462 context.lineTo(x2, y2); 44463 44464 context.closePath(); 44465 44466 context.clip(); 44467 44468 // Compute matrix transform 44469 var delta = (u0 * v1) + (v0 * u2) + (u1 * v2) - (v1 * u2) - (v0 * u1) - (u0 * v2); 44470 var deltaA = (x0 * v1) + (v0 * x2) + (x1 * v2) - (v1 * x2) - (v0 * x1) - (x0 * v2); 44471 var deltaB = (u0 * x1) + (x0 * u2) + (u1 * x2) - (x1 * u2) - (x0 * u1) - (u0 * x2); 44472 var deltaC = (u0 * v1 * x2) + (v0 * x1 * u2) + (x0 * u1 * v2) - (x0 * v1 * u2) - (v0 * u1 * x2) - (u0 * x1 * v2); 44473 var deltaD = (y0 * v1) + (v0 * y2) + (y1 * v2) - (v1 * y2) - (v0 * y1) - (y0 * v2); 44474 var deltaE = (u0 * y1) + (y0 * u2) + (u1 * y2) - (y1 * u2) - (y0 * u1) - (u0 * y2); 44475 var deltaF = (u0 * v1 * y2) + (v0 * y1 * u2) + (y0 * u1 * v2) - (y0 * v1 * u2) - (v0 * u1 * y2) - (u0 * y1 * v2); 44476 44477 context.transform( 44478 deltaA / delta, 44479 deltaD / delta, 44480 deltaB / delta, 44481 deltaE / delta, 44482 deltaC / delta, 44483 deltaF / delta 44484 ); 44485 44486 context.drawImage( 44487 textureSource, 44488 0, 44489 0, 44490 textureWidth * base.resolution, 44491 textureHeight * base.resolution, 44492 0, 44493 0, 44494 textureWidth, 44495 textureHeight 44496 ); 44497 44498 context.restore(); 44499 this.renderer.invalidateBlendMode(); 44500 }; 44501 44502 /** 44503 * Renders a flat Mesh 44504 * 44505 * @private 44506 * @param {PIXI.RawMesh} mesh - The Mesh to render 44507 */ 44508 CanvasMeshRenderer.prototype.renderMeshFlat = function renderMeshFlat (mesh) 44509 { 44510 var context = this.renderer.context; 44511 var vertices = mesh.geometry.getAttribute('aVertexPosition').data; 44512 var length = vertices.length / 2; 44513 44514 // this.count++; 44515 44516 context.beginPath(); 44517 44518 for (var i = 1; i < length - 2; ++i) 44519 { 44520 // draw some triangles! 44521 var index = i * 2; 44522 44523 var x0 = vertices[index]; 44524 var y0 = vertices[index + 1]; 44525 44526 var x1 = vertices[index + 2]; 44527 var y1 = vertices[index + 3]; 44528 44529 var x2 = vertices[index + 4]; 44530 var y2 = vertices[index + 5]; 44531 44532 context.moveTo(x0, y0); 44533 context.lineTo(x1, y1); 44534 context.lineTo(x2, y2); 44535 } 44536 44537 context.fillStyle = '#FF0000'; 44538 context.fill(); 44539 context.closePath(); 44540 }; 44541 44542 /** 44543 * destroy the the renderer. 44544 * 44545 */ 44546 CanvasMeshRenderer.prototype.destroy = function destroy () 44547 { 44548 this.renderer = null; 44549 }; 44550 44551 /** 44552 * Default `canvasPadding` for canvas-based Mesh rendering. 44553 * 44554 * @see PIXI.Mesh2d#canvasPadding 44555 * @static 44556 * @name MESH_CANVAS_PADDING 44557 * @memberof PIXI.settings 44558 * @type {number} 44559 * @default 0 44560 */ 44561 settings.MESH_CANVAS_PADDING = 0; 44562 44563 /** 44564 * Renders the mesh using the Canvas renderer 44565 * 44566 * @protected 44567 * @method render 44568 * @memberof PIXI.MeshMaterial# 44569 * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. 44570 * @param {PIXI.Mesh} mesh - Mesh to render. 44571 */ 44572 MeshMaterial.prototype._renderCanvas = function _renderCanvas(renderer, mesh) 44573 { 44574 renderer.plugins.mesh.render(mesh); 44575 }; 44576 44577 /** 44578 * Cached tint value so we can tell when the tint is changed. 44579 * @memberof PIXI.NineSlicePlane# 44580 * @member {number} _cachedTint 44581 * @protected 44582 */ 44583 NineSlicePlane.prototype._cachedTint = 0xFFFFFF; 44584 44585 /** 44586 * Cached tinted texture. 44587 * @memberof PIXI.NineSlicePlane# 44588 * @member {HTMLCanvasElement} _tintedCanvas 44589 * @protected 44590 */ 44591 NineSlicePlane.prototype._tintedCanvas = null; 44592 44593 /** 44594 * Temporary storage for canvas source coords 44595 * @memberof PIXI.NineSlicePlane# 44596 * @member {number[]} _canvasUvs 44597 * @private 44598 */ 44599 NineSlicePlane.prototype._canvasUvs = null; 44600 44601 /** 44602 * Renders the object using the Canvas renderer 44603 * 44604 * @private 44605 * @method _renderCanvas 44606 * @memberof PIXI.NineSlicePlane# 44607 * @param {PIXI.CanvasRenderer} renderer - The canvas renderer to render with. 44608 */ 44609 NineSlicePlane.prototype._renderCanvas = function _renderCanvas(renderer) 44610 { 44611 var context = renderer.context; 44612 var transform = this.worldTransform; 44613 var res = renderer.resolution; 44614 var isTinted = this.tint !== 0xFFFFFF; 44615 var texture = this._texture; 44616 44617 // Work out tinting 44618 if (isTinted) 44619 { 44620 if (this._cachedTint !== this.tint) 44621 { 44622 // Tint has changed, need to update the tinted texture and use that instead 44623 44624 this._cachedTint = this.tint; 44625 44626 this._tintedCanvas = CanvasTinter.getTintedCanvas(this, this.tint); 44627 } 44628 } 44629 44630 var textureSource = !isTinted ? texture.baseTexture.source : this._tintedCanvas; 44631 44632 if (!this._canvasUvs) 44633 { 44634 this._canvasUvs = [0, 0, 0, 0, 0, 0, 0, 0]; 44635 } 44636 44637 var vertices = this.vertices; 44638 var uvs = this._canvasUvs; 44639 var u0 = isTinted ? 0 : texture.frame.x; 44640 var v0 = isTinted ? 0 : texture.frame.y; 44641 var u1 = u0 + texture.frame.width; 44642 var v1 = v0 + texture.frame.height; 44643 44644 uvs[0] = u0;
44645 uvs[1] = u0 + this._leftWidth; 44646 uvs[2] = u1 - this._rightWidth; 44647 uvs[3] = u1; 44648 uvs[4] = v0; 44649 uvs[5] = v0 + this._topHeight; 44650 uvs[6] = v1 - this._bottomHeight; 44651 uvs[7] = v1; 44652 44653 for (var i = 0; i < 8; i++) 44654 { 44655 uvs[i] *= texture.baseTexture.resolution; 44656 } 44657 44658 context.globalAlpha = this.worldAlpha; 44659 renderer.setBlendMode(this.blendMode); 44660 44661 if (this.roundPixels) 44662 { 44663 context.setTransform( 44664 transform.a * res, 44665 transform.b * res, 44666 transform.c * res, 44667 transform.d * res, 44668 (transform.tx * res) | 0, 44669 (transform.ty * res) | 0 44670 ); 44671 } 44672 else 44673 { 44674 context.setTransform( 44675 transform.a * res, 44676 transform.b * res, 44677 transform.c * res, 44678 transform.d * res, 44679 transform.tx * res, 44680 transform.ty * res 44681 ); 44682 } 44683 44684 for (var row = 0; row < 3; row++) 44685 { 44686 for (var col = 0; col < 3; col++) 44687 { 44688 var ind = (col * 2) + (row * 8); 44689 var sw = Math.max(1, uvs[col + 1] - uvs[col]); 44690 var sh = Math.max(1, uvs[row + 5] - uvs[row + 4]); 44691 var dw = Math.max(1, vertices[ind + 10] - vertices[ind]); 44692 var dh = Math.max(1, vertices[ind + 11] - vertices[ind + 1]); 44693 44694 context.drawImage(textureSource, uvs[col], uvs[row + 4], sw, sh, 44695 vertices[ind], vertices[ind + 1], dw, dh); 44696 } 44697 } 44698 }; 44699 44700 /** 44701 * Renders the object using the Canvas renderer 44702 * 44703 * @private 44704 * @method _renderCanvas 44705 * @memberof PIXI.Mesh# 44706 * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. 44707 */ 44708 Mesh.prototype._renderCanvas = function _renderCanvas(renderer) 44709 { 44710 if (this.shader.uvMatrix) 44711 { 44712 this.shader.uvMatrix.update(); 44713 this.calculateUvs(); 44714 } 44715 44716 this.material._renderCanvas(renderer, this); 44717 }; 44718 44719 // IMPORTANT: Please do NOT use this as a precedent to use `settings` after the object is created 44720 // this was merely created to completely decouple canvas from the base Mesh class and we are 44721 // unable to add `canvasPadding` in the constructor anymore, as the case was for PixiJS v4. 44722 44723 /** 44724 * Internal variable for `canvasPadding`. 44725 * 44726 * @private 44727 * @memberof PIXI.Mesh 44728 * @member {number} 44729 * @default null 44730 */ 44731 Mesh.prototype._canvasPadding = null; 44732 44733 /** 44734 * Triangles in canvas mode are automatically antialiased, use this value to force triangles 44735 * to overlap a bit with each other. To set the global default, set {@link PIXI.settings.MESH_CANVAS_PADDING} 44736 * 44737 * @see PIXI.settings.MESH_CANVAS_PADDING 44738 * @member {number} canvasPadding 44739 * @memberof PIXI.SimpleMesh# 44740 * @default 0 44741 */ 44742 Object.defineProperty(Mesh.prototype, 'canvasPadding', { 44743 get: function get() 44744 { 44745 return this._canvasPadding !== null ? this._canvasPadding : settings.MESH_CANVAS_PADDING; 44746 }, 44747 set: function set(value) 44748 { 44749 this._canvasPadding = value; 44750 }, 44751 }); 44752 44753 /** 44754 * Renders the object using the Canvas renderer 44755 * 44756 * @private 44757 * @method _renderCanvas 44758 * @memberof PIXI.Mesh# 44759 * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. 44760 */ 44761 SimpleMesh.prototype._renderCanvas = function _renderCanvas(renderer) 44762 { 44763 if (this.autoUpdate) 44764 { 44765 this.geometry.getAttribute('aVertexPosition').update(); 44766 } 44767 44768 if (this.shader.update) 44769 { 44770 this.shader.update(); 44771 } 44772 44773 this.calculateUvs(); 44774 44775 this.material._renderCanvas(renderer, this); 44776 }; 44777 44778 /** 44779 * Renders the object using the Canvas renderer 44780 * 44781 * @protected 44782 * @method _renderCanvas 44783 * @memberof PIXI.Mesh# 44784 * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. 44785 */ 44786 SimpleRope.prototype._renderCanvas = function _renderCanvas(renderer) 44787 { 44788 if (this.autoUpdate 44789 || this.geometry.width !== this.shader.texture.height) 44790 { 44791 this.geometry.width = this.shader.texture.height; 44792 this.geometry.update(); 44793 } 44794 44795 if (this.shader.update) 44796 {
44797 this.shader.update(); 44798 } 44799 44800 this.calculateUvs(); 44801 44802 this.material._renderCanvas(renderer, this); 44803 }; 44804 44805 /*! 44806 * @pixi/canvas-graphics - v5.0.0-rc.3 44807 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 44808 * 44809 * @pixi/canvas-graphics is licensed under the MIT License. 44810 * http://www.opensource.org/licenses/mit-license 44811 */ 44812 44813 /** 44814 * @author Mat Groves 44815 * 44816 * Big thanks to the very clever Matt DesLauriers <mattdesl> https://github.com/mattdesl/ 44817 * for creating the original PixiJS version! 44818 * Also a thanks to https://github.com/bchevalier for tweaking the tint and alpha so that they 44819 * now share 4 bytes on the vertex buffer 44820 * 44821 * Heavily inspired by LibGDX's CanvasGraphicsRenderer: 44822 * https://github.com/libgdx/libgdx/blob/1.0.0/gdx/src/com/badlogic/gdx/graphics/glutils/ShapeRenderer.java 44823 */ 44824 44825 /** 44826 * Renderer dedicated to drawing and batching graphics objects. 44827 * 44828 * @class 44829 * @protected 44830 * @memberof PIXI 44831 */ 44832 var CanvasGraphicsRenderer = function CanvasGraphicsRenderer(renderer) 44833 { 44834 this.renderer = renderer; 44835 }; 44836 44837 /** 44838 * Renders a Graphics object to a canvas. 44839 * 44840 * @param {PIXI.Graphics} graphics - the actual graphics object to render 44841 */ 44842 CanvasGraphicsRenderer.prototype.render = function render (graphics) 44843 { 44844 var renderer = this.renderer; 44845 var context = renderer.context; 44846 var worldAlpha = graphics.worldAlpha; 44847 var transform = graphics.transform.worldTransform; 44848 var resolution = renderer.resolution; 44849 44850 context.setTransform( 44851 transform.a * resolution, 44852 transform.b * resolution, 44853 transform.c * resolution, 44854 transform.d * resolution, 44855 transform.tx * resolution, 44856 transform.ty * resolution 44857 ); 44858 44859 // update tint if graphics was dirty 44860 if (graphics.canvasTintDirty !== graphics.dirty 44861 || graphics._prevTint !== graphics.tint) 44862 { ; } 44863 44864 renderer.setBlendMode(graphics.blendMode); 44865 44866 var graphicsData = graphics.geometry.graphicsData; 44867 44868 for (var i = 0; i < graphicsData.length; i++) 44869 { 44870 var data = graphicsData[i]; 44871 var shape = data.shape; 44872 var fillStyle = data.fillStyle; 44873 var lineStyle = data.lineStyle; 44874 44875 var fillColor = fillStyle.color;// data._fillTint; 44876 var lineColor = lineStyle.color;// data._lineTint; 44877 44878 context.lineWidth = lineStyle.width; 44879 44880 if (data.type === SHAPES.POLY) 44881 { 44882 context.beginPath(); 44883 44884 var points = shape.points; 44885 var holes = data.holes; 44886 var outerArea = (void 0); 44887 var innerArea = (void 0); 44888 44889 context.moveTo(points[0], points[1]); 44890 44891 for (var j = 2; j < points.length; j += 2) 44892 { 44893 context.lineTo(points[j], points[j + 1]); 44894 } 44895 44896 if (shape.closeStroke) 44897 { 44898 context.closePath(); 44899 } 44900 44901 if (holes.length > 0) 44902 { 44903 outerArea = 0; 44904 for (var j$1 = 0; j$1 < points.length; j$1 += 2) 44905 { 44906 outerArea += (points[j$1] * points[j$1 + 3]) - (points[j$1 + 1] * points[j$1 + 2]); 44907 } 44908 44909 for (var k = 0; k < holes.length; k++) 44910 { 44911 points = holes[k].points; 44912 44913 innerArea = 0; 44914 for (var j$2 = 0; j$2 < points.length; j$2 += 2) 44915 { 44916 innerArea += (points[j$2] * points[j$2 + 3]) - (points[j$2 + 1] * points[j$2 + 2]); 44917 } 44918 44919 if (innerArea * outerArea < 0) 44920 { 44921 context.moveTo(points[0], points[1]); 44922 44923 for (var j$3 = 2; j$3 < points.length; j$3 += 2) 44924 { 44925 context.lineTo(points[j$3], points[j$3 + 1]); 44926 } 44927 } 44928 else 44929 { 44930 context.moveTo(points[points.length - 2], points[points.length - 1]); 44931 44932 for (var j$4 = points.length - 4; j$4 >= 0; j$4 -= 2) 44933 { 44934 context.lineTo(points[j$4], points[j$4 + 1]); 44935 } 44936 } 44937 44938 if (holes[k].shape.closeStroke) 44939 { 44940 context.closePath(); 44941 } 44942 } 44943 } 44944 44945 if (fillStyle.visible) 44946 { 44947 context.globalAlpha = fillStyle.alpha * worldAlpha; 44948 44949 context.fillStyle = "#" + ((("00000" + ((fillColor | 0
44949).toString(16)))).substr(-6)); 44950 context.fill(); 44951 } 44952 44953 if (lineStyle.visible) 44954 { 44955 context.globalAlpha = lineStyle.alpha * worldAlpha; 44956 context.strokeStyle = "#" + ((("00000" + ((lineColor | 0).toString(16)))).substr(-6)); 44957 context.stroke(); 44958 } 44959 } 44960 else if (data.type === SHAPES.RECT) 44961 { 44962 if (fillStyle.visible) 44963 { 44964 context.globalAlpha = fillStyle.alpha * worldAlpha; 44965 context.fillStyle = "#" + ((("00000" + ((fillColor | 0).toString(16)))).substr(-6)); 44966 context.fillRect(shape.x, shape.y, shape.width, shape.height); 44967 } 44968 if (lineStyle.visible) 44969 { 44970 context.globalAlpha = lineStyle.alpha * worldAlpha; 44971 context.strokeStyle = "#" + ((("00000" + ((lineColor | 0).toString(16)))).substr(-6)); 44972 context.strokeRect(shape.x, shape.y, shape.width, shape.height); 44973 } 44974 } 44975 else if (data.type === SHAPES.CIRC) 44976 { 44977 // TODO - need to be Undefined! 44978 context.beginPath(); 44979 context.arc(shape.x, shape.y, shape.radius, 0, 2 * Math.PI); 44980 context.closePath(); 44981 44982 if (fillStyle.visible) 44983 { 44984 context.globalAlpha = fillStyle.alpha * worldAlpha; 44985 context.fillStyle = "#" + ((("00000" + ((fillColor | 0).toString(16)))).substr(-6)); 44986 context.fill(); 44987 } 44988 44989 if (lineStyle.visible) 44990 { 44991 context.globalAlpha = lineStyle.alpha * worldAlpha; 44992 context.strokeStyle = "#" + ((("00000" + ((lineColor | 0).toString(16)))).substr(-6)); 44993 context.stroke(); 44994 } 44995 } 44996 else if (data.type === SHAPES.ELIP) 44997 { 44998 // ellipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas 44999 45000 var w = shape.width * 2; 45001 var h = shape.height * 2; 45002 45003 var x = shape.x - (w / 2); 45004 var y = shape.y - (h / 2); 45005 45006 context.beginPath(); 45007 45008 var kappa = 0.5522848; 45009 var ox = (w / 2) * kappa; // control point offset horizontal 45010 var oy = (h / 2) * kappa; // control point offset vertical 45011 var xe = x + w; // x-end 45012 var ye = y + h; // y-end 45013 var xm = x + (w / 2); // x-middle 45014 var ym = y + (h / 2); // y-middle 45015 45016 context.moveTo(x, ym); 45017 context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y); 45018 context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym); 45019 context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye); 45020 context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym); 45021 45022 context.closePath(); 45023 45024 if (fillStyle.visible) 45025 { 45026 context.globalAlpha = fillStyle.alpha * worldAlpha; 45027 context.fillStyle = "#" + ((("00000" + ((fillColor | 0).toString(16)))).substr(-6)); 45028 context.fill(); 45029 } 45030 if (lineStyle.visible) 45031 { 45032 context.globalAlpha = lineStyle.alpha * worldAlpha; 45033 context.strokeStyle = "#" + ((("00000" + ((lineColor | 0).toString(16)))).substr(-6)); 45034 context.stroke(); 45035 } 45036 } 45037 else if (data.type === SHAPES.RREC) 45038 { 45039 var rx = shape.x; 45040 var ry = shape.y; 45041 var width = shape.width; 45042 var height = shape.height; 45043 var radius = shape.radius; 45044 45045 var maxRadius = Math.min(width, height) / 2 | 0; 45046 45047 radius = radius > maxRadius ? maxRadius : radius; 45048 45049 context.beginPath(); 45050 context.moveTo(rx, ry + radius); 45051 context.lineTo(rx, ry + height - radius); 45052 context.quadraticCurveTo(rx, ry + height, rx + radius, ry + height);
45053 context.lineTo(rx + width - radius, ry + height); 45054 context.quadraticCurveTo(rx + width, ry + height, rx + width, ry + height - radius); 45055 context.lineTo(rx + width, ry + radius); 45056 context.quadraticCurveTo(rx + width, ry, rx + width - radius, ry); 45057 context.lineTo(rx + radius, ry); 45058 context.quadraticCurveTo(rx, ry, rx, ry + radius); 45059 context.closePath(); 45060 45061 if (fillStyle.visible) 45062 { 45063 context.globalAlpha = fillStyle.alpha * worldAlpha; 45064 context.fillStyle = "#" + ((("00000" + ((fillColor | 0).toString(16)))).substr(-6)); 45065 context.fill(); 45066 } 45067 if (lineStyle.visible) 45068 { 45069 context.globalAlpha = lineStyle.alpha * worldAlpha; 45070 context.strokeStyle = "#" + ((("00000" + ((lineColor | 0).toString(16)))).substr(-6)); 45071 context.stroke(); 45072 } 45073 } 45074 } 45075 }; 45076 45077 /** 45078 * Updates the tint of a graphics object 45079 * 45080 * @protected 45081 * @param {PIXI.Graphics} graphics - the graphics that will have its tint updated 45082 */ 45083 CanvasGraphicsRenderer.prototype.updateGraphicsTint = function updateGraphicsTint (graphics) 45084 { 45085 graphics._prevTint = graphics.tint; 45086 graphics.canvasTintDirty = graphics.dirty; 45087 45088 var tintR = ((graphics.tint >> 16) & 0xFF) / 255; 45089 var tintG = ((graphics.tint >> 8) & 0xFF) / 255; 45090 var tintB = (graphics.tint & 0xFF) / 255; 45091 45092 for (var i = 0; i < graphics.graphicsData.length; ++i) 45093 { 45094 var data = graphics.graphicsData[i]; 45095 45096 var fillColor = data.fillColor | 0; 45097 var lineColor = data.lineColor | 0; 45098 45099 // super inline, cos optimization :) 45100 data._fillTint = ( 45101 (((fillColor >> 16) & 0xFF) / 255 * tintR * 255 << 16) 45102 + (((fillColor >> 8) & 0xFF) / 255 * tintG * 255 << 8) 45103 + (((fillColor & 0xFF) / 255) * tintB * 255) 45104 ); 45105 45106 data._lineTint = ( 45107 (((lineColor >> 16) & 0xFF) / 255 * tintR * 255 << 16) 45108 + (((lineColor >> 8) & 0xFF) / 255 * tintG * 255 << 8) 45109 + (((lineColor & 0xFF) / 255) * tintB * 255) 45110 ); 45111 } 45112 }; 45113 45114 /** 45115 * destroy graphics object 45116 * 45117 */ 45118 CanvasGraphicsRenderer.prototype.destroy = function destroy () 45119 { 45120 this.renderer = null; 45121 }; 45122 45123 var canvasRenderer; 45124 var tempMatrix$1 = new Matrix(); 45125 45126 /** 45127 * Generates a canvas texture. Only available with **pixi.js-legacy** bundle 45128 * or the **@pixi/canvas-graphics** package. 45129 * @method generateCanvasTexture 45130 * @memberof PIXI.Graphics# 45131 * @param {number} scaleMode - The scale mode of the texture. 45132 * @param {number} resolution - The resolution of the texture. 45133 * @return {PIXI.Texture} The new texture. 45134 */ 45135 Graphics.prototype.generateCanvasTexture = function generateCanvasTexture(scaleMode, resolution) 45136 { 45137 if ( resolution === void 0 ) { resolution = 1; } 45138 45139 var bounds = this.getLocalBounds(); 45140 45141 var canvasBuffer = RenderTexture.create(bounds.width, bounds.height, scaleMode, resolution); 45142 45143 if (!canvasRenderer) 45144 { 45145 canvasRenderer = new CanvasRenderer(); 45146 } 45147 45148 this.transform.updateLocalTransform(); 45149 this.transform.localTransform.copyTo(tempMatrix$1); 45150 45151 tempMatrix$1.invert(); 45152 45153 tempMatrix$1.tx -= bounds.x; 45154 tempMatrix$1.ty -= bounds.y; 45155 45156 canvasRenderer.render(this, canvasBuffer, true, tempMatrix$1); 45157 45158 var texture = Texture.from(canvasBuffer.baseTexture._canvasRenderTarget.canvas, { 45159 scaleMode: scaleMode, 45160 }); 45161 45162 texture.baseTexture.resolution = resolution; 45163 texture.baseTexture.update(); 45164 45165 return texture; 45166 }; 45167 45168 Graphics.prototype.cachedGraphicsData = []; 45169 45170 /** 45171 * Renders the object using the Canvas renderer 45172 * 45173 * @method _renderCanvas 45174 * @memberof PIXI.Graphics# 45175 * @private 45176 * @param {PIXI.CanvasRenderer} renderer - The renderer 45177 */ 45178 Graphics.prototype._renderCanvas = function _renderCanvas(renderer) 45179 { 45180 if (this.isMask === true) 45181 { 45182 return; 45183 } 45184 45185 this.finishPoly(); 45186 renderer.plugins.graphics.render(this); 45187 }; 45188 45189 /*! 45190 * @pixi/canvas-sprite - v5.0.0-rc.3 45191 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 45192 * 45193 * @pixi/canvas-sprite is licensed under the MIT License. 45194 * http://www.opensource.org/licenses/mit-license 45195 */ 45196 45197 var canvasRenderWorldTransform = new Matrix(); 45198 45199 /** 45200 * Types that can be passed to drawImage 45201 * @typedef {HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | ImageBitmap} ICanvasImageSource 45202 * @memberof PIXI 45203 */ 45204 45205 /** 45206 * @author Mat Groves 45207 * 45208 * Big thanks to the very clever Matt DesLauriers <mattdesl> https://github.com/mattdesl/ 45209 * for creating the original PixiJS version! 45210 * Also a thanks to https://github.com/bchevalier for tweaking the tint and alpha so that they now 45211 * share 4 bytes on the vertex buffer 45212 * 45213 * Heavily inspired by LibGDX's CanvasSpriteRenderer: 45214 * https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/CanvasSpriteRenderer.java 45215 */ 45216 45217 /** 45218 * Renderer dedicated to drawing and batching sprites. 45219 * 45220 * @class 45221 * @protected 45222 * @memberof PIXI 45223 */ 45224 var CanvasSpriteRenderer = function CanvasSpriteRenderer(renderer) 45225 { 45226 this.renderer = renderer; 45227 }; 45228 45229 /** 45230 * Renders the sprite object. 45231 * 45232 * @param {PIXI.Sprite} sprite - the sprite to render when using this spritebatch 45233 */ 45234 CanvasSpriteRenderer.prototype.render = function render (sprite) 45235 { 45236 var texture = sprite._texture; 45237 var renderer = this.renderer; 45238 var context = renderer.context; 45239 45240 var width = texture._frame.width; 45241 var height = texture._frame.height; 45242 45243 var wt = sprite.transform.worldTransform; 45244 var dx = 0; 45245 var dy = 0; 45246 45247 var source = texture.baseTexture.getDrawableSource(); 45248 45249 if (texture.orig.width <= 0 || texture.orig.height <= 0 || !source) 45250 { 45251 return; 45252 } 45253 45254 if (!texture.valid) 45255 { 45256 return; 45257 } 45258 45259 renderer.setBlendMode(sprite.blendMode, true); 45260 45261 renderer.context.globalAlpha = sprite.worldAlpha; 45262 45263 // If smoothingEnabled is supported and we need to change the smoothing property for sprite texture 45264 var smoothingEnabled = texture.baseTexture.scaleMode === SCALE_MODES.LINEAR; 45265 45266 if (renderer.smoothProperty && renderer.context[renderer.smoothProperty] !== smoothingEnabled) 45267 { 45268 context[renderer.smoothProperty] = smoothingEnabled; 45269 } 45270 45271 if (texture.trim) 45272 { 45273 dx = (texture.trim.width / 2) + texture.trim.x - (sprite.anchor.x * texture.orig.width); 45274 dy = (texture.trim.height / 2) + texture.trim.y - (sprite.anchor.y * texture.orig.height); 45275 } 45276 else 45277 { 45278 dx = (0.5 - sprite.anchor.x) * texture.orig.width; 45279 dy = (0.5 - sprite.anchor.y) * texture.orig.height; 45280 } 45281 45282 if (texture.rotate) 45283 { 45284 wt.copyTo(canvasRenderWorldTransform); 45285 wt = canvasRenderWorldTransform; 45286 GroupD8.matrixAppendRotationInv(wt, texture.rotate, dx, dy);
45287 // the anchor has already been applied above, so lets set it to zero 45288 dx = 0; 45289 dy = 0; 45290 } 45291 45292 dx -= width / 2; 45293 dy -= height / 2; 45294 45295 // Allow for pixel rounding 45296 if (sprite.roundPixels) 45297 { 45298 renderer.context.setTransform( 45299 wt.a, 45300 wt.b, 45301 wt.c, 45302 wt.d, 45303 (wt.tx * renderer.resolution) | 0, 45304 (wt.ty * renderer.resolution) | 0 45305 ); 45306 45307 dx = dx | 0; 45308 dy = dy | 0; 45309 } 45310 else 45311 { 45312 renderer.context.setTransform( 45313 wt.a, 45314 wt.b, 45315 wt.c, 45316 wt.d, 45317 wt.tx * renderer.resolution, 45318 wt.ty * renderer.resolution 45319 ); 45320 } 45321 45322 var resolution = texture.baseTexture.resolution; 45323 var outerBlend = renderer._outerBlend; 45324 45325 if (outerBlend) 45326 { 45327 context.save(); 45328 context.beginPath(); 45329 context.rect( 45330 dx * renderer.resolution, 45331 dy * renderer.resolution, 45332 width * renderer.resolution, 45333 height * renderer.resolution 45334 ); 45335 context.clip(); 45336 } 45337 45338 if (sprite.tint !== 0xFFFFFF) 45339 { 45340 if (sprite._cachedTint !== sprite.tint || sprite._tintedCanvas.tintId !== sprite._texture._updateID) 45341 { 45342 sprite._cachedTint = sprite.tint; 45343 45344 // TODO clean up caching - how to clean up the caches? 45345 sprite._tintedCanvas = CanvasTinter.getTintedCanvas(sprite, sprite.tint); 45346 } 45347 45348 context.drawImage( 45349 source, 45350 0, 45351 0, 45352 width * resolution, 45353 height * resolution, 45354 dx * renderer.resolution, 45355 dy * renderer.resolution, 45356 width * renderer.resolution, 45357 height * renderer.resolution 45358 ); 45359 } 45360 else 45361 { 45362 context.drawImage( 45363 source, 45364 texture._frame.x * resolution, 45365 texture._frame.y * resolution, 45366 width * resolution, 45367 height * resolution, 45368 dx * renderer.resolution, 45369 dy * renderer.resolution, 45370 width * renderer.resolution, 45371 height * renderer.resolution 45372 ); 45373 } 45374 45375 if (outerBlend) 45376 { 45377 context.restore(); 45378 } 45379 // just in case, leaking outer blend here will be catastrophic! 45380 renderer.setBlendMode(BLEND_MODES.NORMAL); 45381 }; 45382 45383 /** 45384 * destroy the sprite object. 45385 * 45386 */ 45387 CanvasSpriteRenderer.prototype.destroy = function destroy () 45388 { 45389 this.renderer = null; 45390 }; 45391 45392 /** 45393 * Cached tinted texture. 45394 * @memberof PIXI.Sprite# 45395 * @member {HTMLCanvasElement} _tintedCanvas 45396 * @protected 45397 */ 45398 Sprite.prototype._tintedCanvas = null; 45399 45400 /** 45401 * Cached tint value so we can tell when the tint is changed. 45402 * @memberof PIXI.Sprite# 45403 * @member {number} _cachedTint 45404 * @protected 45405 */ 45406 Sprite.prototype._cachedTint = 0xFFFFFF; 45407 45408 /** 45409 * Renders the object using the Canvas renderer 45410 * 45411 * @private 45412 * @method _renderCanvas 45413 * @memberof PIXI.Sprite# 45414 * @param {PIXI.CanvasRenderer} renderer - The renderer 45415 */ 45416 Sprite.prototype._renderCanvas = function _renderCanvas(renderer) 45417 { 45418 renderer.plugins.sprite.render(this); 45419 }; 45420 45421 /*! 45422 * @pixi/canvas-extract - v5.0.0-rc.3 45423 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 45424 * 45425 * @pixi/canvas-extract is licensed under the MIT License. 45426 * http://www.opensource.org/licenses/mit-license 45427 */ 45428 45429 var TEMP_RECT$1 = new Rectangle(); 45430 45431 /** 45432 * The extract manager provides functionality to export content from the renderers. 45433 * 45434 * An instance of this class is automatically created by default, and can be found at `renderer.plugins.extract` 45435 * 45436 * @class 45437 * @memberof PIXI.extract 45438 */ 45439 var CanvasExtract = function CanvasExtract(renderer) 45440 { 45441 this.renderer = renderer; 45442 /** 45443 * Collection of methods for extracting data (image, pixels, etc.) from a display object or render texture 45444 * 45445 * @member {PIXI.extract.CanvasExtract} extract 45446 * @memberof PIXI.CanvasRenderer# 45447 * @see PIXI.extract.CanvasExtract 45448 */ 45449 renderer.extract = this; 45450 }; 45451 45452 /** 45453 * Will return a HTML Image of the target 45454 * 45455 * @param {PIXI.DisplayObject|PIXI.RenderTexture} target - A displayObject or renderTexture 45456 * to convert. If left empty will use the main renderer 45457 * @return {HTMLImageElement} HTML Image of the target 45458 */ 45459 CanvasExtract.prototype.image = function image (target) 45460 { 45461 var image = new Image(); 45462 45463 image.src = this.base64(target); 45464 45465 return image; 45466 }; 45467 45468 /** 45469 * Will return a a base64 encoded string of this target. It works by calling 45470 * `CanvasExtract.getCanvas` and then running toDataURL on that. 45471 * 45472 * @param {PIXI.DisplayObject|PIXI.RenderTexture} target - A displayObject or renderTexture 45473 * to convert. If left empty will use the main renderer 45474 * @return {string} A base64 encoded string of the texture. 45475 */ 45476 CanvasExtract.prototype.base64 = function base64 (target) 45477 { 45478 return this.canvas(target).toDataURL(); 45479 }; 45480 45481 /** 45482 * Creates a Canvas element, renders this target to it and then returns it. 45483 * 45484 * @param {PIXI.DisplayObject|PIXI.RenderTexture} target - A displayObject or renderTexture 45485 * to convert. If left empty will use the main renderer 45486 * @return {HTMLCanvasElement} A Canvas element with the texture rendered on. 45487 */ 45488 CanvasExtract.prototype.canvas = function canvas (target) 45489 { 45490 var renderer = this.renderer; 45491 var context; 45492 var resolution; 45493 var frame; 45494 var renderTexture; 45495 45496 if (target) 45497 { 45498 if (target instanceof RenderTexture) 45499 { 45500 renderTexture = target; 45501 } 45502 else 45503 { 45504 renderTexture = renderer.generateTexture(target); 45505 } 45506 } 45507 45508 if (renderTexture) 45509 { 45510 context = renderTexture.baseTexture._canvasRenderTarget.context; 45511 resolution = renderTexture.baseTexture._canvasRenderTarget.resolution; 45512 frame = renderTexture.frame; 45513 } 45514 else 45515 { 45516 context = renderer.rootContext; 45517 resolution = renderer.resolution; 45518 frame = TEMP_RECT$1; 45519 frame.width = this.renderer.width; 45520 frame.height = this.renderer.height; 45521 } 45522 45523 var width = frame.width * resolution; 45524 var height = frame.height * resolution; 45525 45526 var canvasBuffer = new CanvasRenderTarget(width, height, 1); 45527 var canvasData = context.getImageData(frame.x * resolution, frame.y * resolution, width, height); 45528 45529 canvasBuffer.context.putImageData(canvasData, 0, 0); 45530 45531 // send the canvas back.. 45532 return canvasBuffer.canvas; 45533 }; 45534 45535 /** 45536 * Will return a one-dimensional array containing the pixel data of the entire texture in RGBA 45537 * order, with integer values between 0 and 255 (included). 45538 * 45539 * @param {PIXI.DisplayObject|PIXI.RenderTexture} target - A displayObject or renderTexture 45540 * to convert. If left empty will use the main renderer 45541 * @return {Uint8ClampedArray} One-dimensional array containing the pixel data of the entire texture 45542 */ 45543 CanvasExtract.prototype.pixels = function pixels (target) 45544 { 45545 var renderer = this.renderer; 45546 var context; 45547 var resolution; 45548 var frame; 45549 var renderTexture; 45550 45551 if (target) 45552 { 45553 if (target instanceof RenderTexture) 45554 { 45555 renderTexture = target; 45556 } 45557 else 45558 { 45559 renderTexture = renderer.generateTexture(target); 45560 } 45561 } 45562 45563 if (renderTexture) 45564 { 45565 context = renderTexture.baseTexture._canvasRenderTarget.context; 45566 resolution = renderTexture.baseTexture._canvasRenderTarget.resolution; 45567 frame = renderTexture.frame; 45568 } 45569 else 45570 { 45571 context = renderer.rootContext; 45572 45573 frame = TEMP_RECT$1; 45574 frame.width = renderer.width; 45575 frame.height = renderer.height; 45576 } 45577 45578 return context.getImageData(0, 0, frame.width * resolution, frame.height * resolution).data; 45579 }; 45580 45581 /** 45582 * Destroys the extract 45583 * 45584 */ 45585 CanvasExtract.prototype.destroy = function destroy () 45586 { 45587 this.renderer.extract = null; 45588 this.renderer = null; 45589 }; 45590 45591 var canvasExtract = ({ 45592 CanvasExtract: CanvasExtract 45593 }); 45594 45595 /*! 45596 * @pixi/canvas-prepare - v5.0.0-rc.3 45597 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 45598 * 45599 * @pixi/canvas-prepare is licensed under the MIT License. 45600 * http://www.opensource.org/licenses/mit-license 45601 */ 45602 45603 var CANVAS_START_SIZE = 16; 45604 45605 /** 45606 * The prepare manager provides functionality to upload content to the GPU. 45607 * 45608 * This cannot be done directly for Canvas like in WebGL, but the effect can be achieved by drawing 45609 * textures to an offline canvas. This draw call will force the texture to be moved onto the GPU. 45610 * 45611 * An instance of this class is automatically created by default, and can be found at `renderer.plugins.prepare` 45612 * 45613 * @class 45614 * @extends PIXI.prepare.BasePrepare 45615 * @memberof PIXI.prepare 45616 */ 45617 var CanvasPrepare = /*@__PURE__*/(function (BasePrepare) { 45618 function CanvasPrepare(renderer) 45619 { 45620 BasePrepare.call(this, renderer); 45621 45622 this.uploadHookHelper = this; 45623 45624 /** 45625 * An offline canvas to render textures to 45626 * @type {HTMLCanvasElement} 45627 * @private 45628 */ 45629 this.canvas = document.createElement('canvas'); 45630 this.canvas.width = CANVAS_START_SIZE; 45631 this.canvas.height = CANVAS_START_SIZE; 45632 45633 /** 45634 * The context to the canvas 45635 * @type {CanvasRenderingContext2D} 45636 * @private 45637 */ 45638 this.ctx = this.canvas.getContext('2d'); 45639 45640 // Add textures to upload 45641 this.registerUploadHook(uploadBaseTextures$1); 45642 } 45643 45644 if ( BasePrepare ) { CanvasPrepare.__proto__ = BasePrepare; } 45645 CanvasPrepare.prototype = Object.create( BasePrepare && BasePrepare.prototype ); 45646 CanvasPrepare.prototype.constructor = CanvasPrepare; 45647 45648 /** 45649 * Destroys the plugin, don't use after this. 45650 * 45651 */ 45652 CanvasPrepare.prototype.destroy = function destroy () 45653 { 45654 BasePrepare.prototype.destroy.call(this); 45655 this.ctx = null; 45656 this.canvas = null; 45657 }; 45658 45659 return CanvasPrepare; 45660 }(BasePrepare)); 45661 45662 /** 45663 * Built-in hook to upload PIXI.Texture objects to the GPU. 45664 * 45665 * @private 45666 * @param {*} prepare - Instance of CanvasPrepare 45667 * @param {*} item - Item to check 45668 * @return {boolean} If item was uploaded.
45669 */ 45670 function uploadBaseTextures$1(prepare, item) 45671 { 45672 if (item instanceof BaseTexture) 45673 { 45674 var image = item.source; 45675 45676 // Sometimes images (like atlas images) report a size of zero, causing errors on windows phone. 45677 // So if the width or height is equal to zero then use the canvas size 45678 // Otherwise use whatever is smaller, the image dimensions or the canvas dimensions. 45679 var imageWidth = image.width === 0 ? prepare.canvas.width : Math.min(prepare.canvas.width, image.width); 45680 var imageHeight = image.height === 0 ? prepare.canvas.height : Math.min(prepare.canvas.height, image.height); 45681 45682 // Only a small subsections is required to be drawn to have the whole texture uploaded to the GPU 45683 // A smaller draw can be faster. 45684 prepare.ctx.drawImage(image, 0, 0, imageWidth, imageHeight, 0, 0, prepare.canvas.width, prepare.canvas.height); 45685 45686 return true; 45687 } 45688 45689 return false; 45690 } 45691 45692 var canvasPrepare = ({ 45693 CanvasPrepare: CanvasPrepare 45694 }); 45695 45696 /*! 45697 * @pixi/canvas-sprite-tiling - v5.0.0-rc.3 45698 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 45699 * 45700 * @pixi/canvas-sprite-tiling is licensed under the MIT License. 45701 * http://www.opensource.org/licenses/mit-license 45702 */ 45703 45704 /** 45705 * Renders the object using the Canvas renderer 45706 * 45707 * @protected 45708 * @function _renderCanvas 45709 * @memberof PIXI.TilingSprite# 45710 * @param {PIXI.CanvasRenderer} renderer - a reference to the canvas renderer 45711 */ 45712 TilingSprite.prototype._renderCanvas = function _renderCanvas(renderer) 45713 { 45714 var texture = this._texture; 45715 45716 if (!texture.baseTexture.valid) 45717 { 45718 return; 45719 } 45720 45721 var context = renderer.context; 45722 var transform = this.worldTransform; 45723 var resolution = renderer.resolution; 45724 var baseTexture = texture.baseTexture; 45725 var source = baseTexture.getDrawableSource(); 45726 var baseTextureResolution = baseTexture.resolution; 45727 var modX = ((this.tilePosition.x / this.tileScale.x) % texture._frame.width) * baseTextureResolution; 45728 var modY = ((this.tilePosition.y / this.tileScale.y) % texture._frame.height) * baseTextureResolution; 45729 45730 // create a nice shiny pattern! 45731 if (this._textureID !== this._texture._updateID || this.cachedTint !== this.tint) 45732 { 45733 this._textureID = this._texture._updateID; 45734 // cut an object from a spritesheet.. 45735 var tempCanvas = new CanvasRenderTarget(texture._frame.width, 45736 texture._frame.height, 45737 baseTextureResolution); 45738 45739 // Tint the tiling sprite 45740 if (this.tint !== 0xFFFFFF) 45741 { 45742 this._tintedCanvas = CanvasTinter.getTintedCanvas(this, this.tint); 45743 tempCanvas.context.drawImage(this._tintedCanvas, 0, 0); 45744 } 45745 else 45746 { 45747 tempCanvas.context.drawImage(source, 45748 -texture._frame.x * baseTextureResolution, -texture._frame.y * baseTextureResolution); 45749 } 45750 this.cachedTint = this.tint; 45751 this._canvasPattern = tempCanvas.context.createPattern(tempCanvas.canvas, 'repeat'); 45752 } 45753 45754 // set context state.. 45755 context.globalAlpha = this.worldAlpha; 45756 context.setTransform(transform.a * resolution, 45757 transform.b * resolution, 45758 transform.c * resolution, 45759 transform.d * resolution, 45760 transform.tx * resolution, 45761 transform.ty * resolution); 45762 45763 renderer.setBlendMode(this.blendMode); 45764 45765 // fill the pattern! 45766 context.fillStyle = this._canvasPattern; 45767 45768 // TODO - this should be rolled into the setTransform above.. 45769 context.scale(this.tileScale.x / baseTextureResolution, this.tileScale.y / baseTextureResolution); 45770 45771 var anchorX = this.anchor.x * -this._width; 45772 var anchorY = this.anchor.y * -this._height; 45773 45774 if (this.uvRespectAnchor) 45775 { 45776 context.translate(modX, modY); 45777 45778 context.fillRect(-modX + anchorX, -modY + anchorY, 45779 this._width / this.tileScale.x * baseTextureResolution, 45780 this._height / this.tileScale.y * baseTextureResolution); 45781 } 45782 else 45783 { 45784 context.translate(modX + anchorX, modY + anchorY); 45785 45786 context.fillRect(-modX, -modY, 45787 this._width / this.tileScale.x * baseTextureResolution, 45788 this._height / this.tileScale.y * baseTextureResolution); 45789 } 45790 }; 45791 45792 /*! 45793 * @pixi/canvas-particles - v5.0.0-rc.3 45794 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 45795 * 45796 * @pixi/canvas-particles is licensed under the MIT License. 45797 * http://www.opensource.org/licenses/mit-license 45798 */ 45799 45800 /** 45801 * Renders the object using the Canvas renderer 45802 * @method renderCanvas 45803 * @memberof PIXI.ParticleContainer# 45804 * @private 45805 * @param {PIXI.CanvasRenderer} renderer - a reference to the canvas renderer 45806 */ 45807 ParticleContainer.prototype.renderCanvas = function renderCanvas(renderer) 45808 { 45809 if (!this.visible || this.worldAlpha <= 0 || !this.children.length || !this.renderable) 45810 { 45811 return; 45812 } 45813 45814 var context = renderer.context; 45815 var transform = this.worldTransform; 45816 var isRotated = true; 45817 45818 var positionX = 0; 45819 var positionY = 0; 45820 45821 var finalWidth = 0; 45822 var finalHeight = 0; 45823 45824 renderer.setBlendMode(this.blendMode); 45825 45826 context.globalAlpha = this.worldAlpha; 45827 45828 this.displayObjectUpdateTransform(); 45829 45830 for (var i = 0; i < this.children.length; ++i) 45831 { 45832 var child = this.children[i]; 45833 45834 if (!child.visible) 45835 { 45836 continue; 45837 } 45838 45839 var frame = child._texture.frame; 45840 45841 context.globalAlpha = this.worldAlpha * child.alpha; 45842 45843 if (child.rotation % (Math.PI * 2) === 0) 45844 { 45845 // this is the fastest way to optimise! - if rotation is 0 then we can avoid any kind of setTransform call 45846 if (isRotated) 45847 { 45848 context.setTransform( 45849 transform.a, 45850 transform.b, 45851 transform.c, 45852 transform.d, 45853 transform.tx * renderer.resolution, 45854 transform.ty * renderer.resolution 45855 ); 45856 45857 isRotated = false;
45858 } 45859 45860 positionX = ((child.anchor.x) * (-frame.width * child.scale.x)) + child.position.x + 0.5; 45861 positionY = ((child.anchor.y) * (-frame.height * child.scale.y)) + child.position.y + 0.5; 45862 45863 finalWidth = frame.width * child.scale.x; 45864 finalHeight = frame.height * child.scale.y; 45865 } 45866 else 45867 { 45868 if (!isRotated) 45869 { 45870 isRotated = true; 45871 } 45872 45873 child.displayObjectUpdateTransform(); 45874 45875 var childTransform = child.worldTransform; 45876 45877 if (this.roundPixels) 45878 { 45879 context.setTransform( 45880 childTransform.a, 45881 childTransform.b, 45882 childTransform.c, 45883 childTransform.d, 45884 (childTransform.tx * renderer.resolution) | 0, 45885 (childTransform.ty * renderer.resolution) | 0 45886 ); 45887 } 45888 else 45889 { 45890 context.setTransform( 45891 childTransform.a, 45892 childTransform.b, 45893 childTransform.c, 45894 childTransform.d, 45895 childTransform.tx * renderer.resolution, 45896 childTransform.ty * renderer.resolution 45897 ); 45898 } 45899 45900 positionX = ((child.anchor.x) * (-frame.width)) + 0.5; 45901 positionY = ((child.anchor.y) * (-frame.height)) + 0.5; 45902 45903 finalWidth = frame.width; 45904 finalHeight = frame.height; 45905 } 45906 45907 var resolution = child._texture.baseTexture.resolution; 45908 45909 context.drawImage( 45910 child._texture.baseTexture.source, 45911 frame.x * resolution, 45912 frame.y * resolution, 45913 frame.width * resolution, 45914 frame.height * resolution, 45915 positionX * renderer.resolution, 45916 positionY * renderer.resolution, 45917 finalWidth * renderer.resolution, 45918 finalHeight * renderer.resolution 45919 ); 45920 } 45921 }; 45922 45923 /*! 45924 * @pixi/canvas-display - v5.0.0-rc.3 45925 * Compiled Fri, 22 Mar 2019 16:39:26 UTC 45926 * 45927 * @pixi/canvas-display is licensed under the MIT License. 45928 * http://www.opensource.org/licenses/mit-license 45929 */ 45930 45931 /** 45932 * To be overridden by the subclass 45933 * @method _renderCanvas 45934 * @memberof PIXI.Container# 45935 * @protected 45936 * @param {PIXI.CanvasRenderer} renderer - The renderer 45937 */ 45938 Container.prototype._renderCanvas = function _renderCanvas(renderer) // eslint-disable-line no-unused-vars 45939 { 45940 // this is where content itself gets rendered... 45941 }; 45942 45943 /** 45944 * Renders the object using the Canvas renderer 45945 * @method renderCanvas 45946 * @memberof PIXI.Container# 45947 * @param {PIXI.CanvasRenderer} renderer - The renderer 45948 */ 45949 Container.prototype.renderCanvas = function renderCanvas(renderer) 45950 { 45951 // if not visible or the alpha is 0 then no need to render this 45952 if (!this.visible || this.worldAlpha <= 0 || !this.renderable) 45953 { 45954 return; 45955 } 45956 45957 if (this._mask) 45958 { 45959 renderer.maskManager.pushMask(this._mask); 45960 } 45961 45962 this._renderCanvas(renderer); 45963 for (var i = 0, j = this.children.length; i < j; ++i) 45964 { 45965 this.children[i].renderCanvas(renderer); 45966 } 45967 45968 if (this._mask) 45969 { 45970 renderer.maskManager.popMask(renderer); 45971 } 45972 }; 45973 45974 /** 45975 * Renders the object using the Canvas renderer 45976 * @method renderCanvas 45977 * @memberof PIXI.Container# 45978 * @param {PIXI.CanvasRenderer} renderer - The renderer 45979 */ 45980 DisplayObject.prototype.renderCanvas = function renderCanvas(renderer) // eslint-disable-line no-unused-vars 45981 { 45982 // OVERWRITE; 45983 }; 45984 45985 CanvasRenderer.registerPlugin('accessibility', AccessibilityManager); 45986 CanvasRenderer.registerPlugin('extract', CanvasExtract); 45987 CanvasRenderer.registerPlugin('graphics', CanvasGraphicsRenderer); 45988 CanvasRenderer.registerPlugin('interaction', InteractionManager); 45989 CanvasRenderer.registerPlugin('mesh', CanvasMeshRenderer); 45990 CanvasRenderer.registerPlugin('prepare', CanvasPrepare); 45991 CanvasRenderer.registerPlugin('sprite', CanvasSpriteRenderer); 45992 45993 Object.assign(prepare, canvasPrepare); 45994 Object.assign(extract, canvasExtract); 45995 45996 exports.AbstractRenderer = AbstractRenderer; 45997 exports.AnimatedSprite = AnimatedSprite; 45998 exports.AppLoaderPlugin = AppLoaderPlugin; 45999 exports.Application = Application; 46000 exports.Attribute = Attribute; 46001 exports.BLEND_MODES = BLEND_MODES; 46002 exports.BaseRenderTexture = BaseRenderTexture; 46003 exports.BaseTexture = BaseTexture; 46004 exports.BatchDrawCall = BatchDrawCall; 46005 exports.BatchGeometry = BatchGeometry; 46006 exports.BatchRenderer = BatchRenderer; 46007 exports.BitmapFontLoader = BitmapFontLoader;
46008 exports.BitmapText = BitmapText; 46009 exports.Bounds = Bounds; 46010 exports.Buffer = Buffer; 46011 exports.CanvasGraphicsRenderer = CanvasGraphicsRenderer; 46012 exports.CanvasMeshRenderer = CanvasMeshRenderer; 46013 exports.CanvasRenderer = CanvasRenderer; 46014 exports.CanvasSpriteRenderer = CanvasSpriteRenderer; 46015 exports.CanvasTinter = CanvasTinter; 46016 exports.Circle = Circle; 46017 exports.Container = Container; 46018 exports.CubeTexture = CubeTexture; 46019 exports.DEG_TO_RAD = DEG_TO_RAD; 46020 exports.DRAW_MODES = DRAW_MODES; 46021 exports.DisplayObject = DisplayObject; 46022 exports.ENV = ENV; 46023 exports.Ellipse = Ellipse; 46024 exports.FORMATS = FORMATS; 46025 exports.Filter = Filter; 46026 exports.Framebuffer = Framebuffer; 46027 exports.GC_MODES = GC_MODES; 46028 exports.GLProgram = GLProgram; 46029 exports.GLTexture = BaseTexture; 46030 exports.GRAPHICS_CURVES = GRAPHICS_CURVES; 46031 exports.Geometry = Geometry; 46032 exports.Graphics = Graphics; 46033 exports.GraphicsData = GraphicsData; 46034 exports.GraphicsGeometry = GraphicsGeometry; 46035 exports.GroupD8 = GroupD8; 46036 exports.Loader = Loader$2; 46037 exports.LoaderResource = LoaderResource; 46038 exports.MIPMAP_MODES = MIPMAP_MODES; 46039 exports.Matrix = Matrix; 46040 exports.Mesh = Mesh; 46041 exports.MeshBatchUvs = MeshBatchUvs; 46042 exports.MeshGeometry = MeshGeometry; 46043 exports.MeshMaterial = MeshMaterial; 46044 exports.NineSlicePlane = NineSlicePlane; 46045 exports.ObjectRenderer = ObjectRenderer; 46046 exports.ObservablePoint = ObservablePoint; 46047 exports.PI_2 = PI_2; 46048 exports.PRECISION = PRECISION; 46049 exports.ParticleContainer = ParticleContainer; 46050 exports.ParticleRenderer = ParticleRenderer; 46051 exports.PlaneGeometry = PlaneGeometry; 46052 exports.Point = Point; 46053 exports.Polygon = Polygon; 46054 exports.Program = Program; 46055 exports.Quad = Quad; 46056 exports.QuadUv = QuadUv; 46057 exports.RAD_TO_DEG = RAD_TO_DEG; 46058 exports.RENDERER_TYPE = RENDERER_TYPE; 46059 exports.Rectangle = Rectangle; 46060 exports.RenderTexture = RenderTexture; 46061 exports.Renderer = Renderer; 46062 exports.RopeGeometry = RopeGeometry; 46063 exports.RoundedRectangle = RoundedRectangle; 46064 exports.Runner = Runner; 46065 exports.SCALE_MODES = SCALE_MODES; 46066 exports.SHAPES = SHAPES; 46067 exports.Shader = Shader; 46068 exports.SimpleMesh = SimpleMesh; 46069 exports.SimplePlane = SimplePlane; 46070 exports.SimpleRope = SimpleRope; 46071 exports.Sprite = Sprite; 46072 exports.SpriteMaskFilter = SpriteMaskFilter; 46073 exports.Spritesheet = Spritesheet; 46074 exports.SpritesheetLoader = SpritesheetLoader; 46075 exports.State = State; 46076 exports.System = System; 46077 exports.TARGETS = TARGETS; 46078 exports.TEXT_GRADIENT = TEXT_GRADIENT; 46079 exports.TYPES = TYPES; 46080 exports.Text = Text; 46081 exports.TextMetrics = TextMetrics; 46082 exports.TextStyle = TextStyle; 46083 exports.Texture = Texture; 46084 exports.TextureLoader = TextureLoader; 46085 exports.TextureMatrix = TextureMatrix; 46086 exports.TextureUvs = TextureUvs; 46087 exports.Ticker = Ticker; 46088 exports.TickerPlugin = TickerPlugin; 46089 exports.TilingSprite = TilingSprite; 46090 exports.TilingSpriteRenderer = TilingSpriteRenderer; 46091 exports.Transform = Transform; 46092 exports.UPDATE_PRIORITY = UPDATE_PRIORITY; 46093 exports.UniformGroup = UniformGroup; 46094 exports.VERSION = VERSION$1; 46095 exports.WRAP_MODES = WRAP_MODES; 46096 exports.accessibility = accessibility_es; 46097 exports.autoDetectRenderer = autoDetectRenderer; 46098 exports.checkMaxIfStatementsInShader = checkMaxIfStatementsInShader; 46099 exports.defaultFilterVertex = defaultFilter; 46100 exports.defaultVertex = _default; 46101 exports.extract = extract; 46102 exports.filters = filters; 46103 exports.generateMultiTextureShader = generateMultiTextureShader; 46104 exports.interaction = interaction_es; 46105 exports.isMobile = isMobile_min; 46106 exports.prepare = prepare; 46107 exports.resources = index; 46108 exports.settings = settings; 46109 exports.systems = systems; 46110 exports.useDeprecated = useDeprecated; 46111 exports.utils = utils_es; 46112 46113 return exports; 46114 46115}({})); 46116PIXI.useDeprecated(); 46117//# sourceMappingURL=pixi-legacy.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.