UNPKG

pixi.js

Version:

<p align="center"> <a href="https://pixijs.com" target="_blank" rel="noopener noreferrer"> <img height="150" src="https://files.pixijs.download/branding/pixijs-logo-transparent-dark.svg?v=1" alt="PixiJS logo"> </a> </p> <br/> <p align="center">

1,289 lines (1,228 loc) 1.78 MB
/*! * PixiJS - v8.10.1 * Compiled Thu, 05 Jun 2025 17:35:59 UTC * * PixiJS is licensed under the MIT License. * http://www.opensource.org/licenses/mit-license */ "use strict"; var __defProp$1d = Object.defineProperty; var __defProps$r = Object.defineProperties; var __getOwnPropDescs$r = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols$1d = Object.getOwnPropertySymbols; var __hasOwnProp$1d = Object.prototype.hasOwnProperty; var __propIsEnum$1d = Object.prototype.propertyIsEnumerable; var __defNormalProp$1d = (obj, key, value) => key in obj ? __defProp$1d(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues$1d = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp$1d.call(b, prop)) __defNormalProp$1d(a, prop, b[prop]); if (__getOwnPropSymbols$1d) for (var prop of __getOwnPropSymbols$1d(b)) { if (__propIsEnum$1d.call(b, prop)) __defNormalProp$1d(a, prop, b[prop]); } return a; }; var __spreadProps$r = (a, b) => __defProps$r(a, __getOwnPropDescs$r(b)); var ExtensionType = /* @__PURE__ */ ((ExtensionType2) => { ExtensionType2["Application"] = "application"; ExtensionType2["WebGLPipes"] = "webgl-pipes"; ExtensionType2["WebGLPipesAdaptor"] = "webgl-pipes-adaptor"; ExtensionType2["WebGLSystem"] = "webgl-system"; ExtensionType2["WebGPUPipes"] = "webgpu-pipes"; ExtensionType2["WebGPUPipesAdaptor"] = "webgpu-pipes-adaptor"; ExtensionType2["WebGPUSystem"] = "webgpu-system"; ExtensionType2["CanvasSystem"] = "canvas-system"; ExtensionType2["CanvasPipesAdaptor"] = "canvas-pipes-adaptor"; ExtensionType2["CanvasPipes"] = "canvas-pipes"; ExtensionType2["Asset"] = "asset"; ExtensionType2["LoadParser"] = "load-parser"; ExtensionType2["ResolveParser"] = "resolve-parser"; ExtensionType2["CacheParser"] = "cache-parser"; ExtensionType2["DetectionParser"] = "detection-parser"; ExtensionType2["MaskEffect"] = "mask-effect"; ExtensionType2["BlendMode"] = "blend-mode"; ExtensionType2["TextureSource"] = "texture-source"; ExtensionType2["Environment"] = "environment"; ExtensionType2["ShapeBuilder"] = "shape-builder"; ExtensionType2["Batcher"] = "batcher"; return ExtensionType2; })(ExtensionType || {}); const normalizeExtension = (ext) => { if (typeof ext === "function" || typeof ext === "object" && ext.extension) { if (!ext.extension) { throw new Error("Extension class must have an extension object"); } const metadata = typeof ext.extension !== "object" ? { type: ext.extension } : ext.extension; ext = __spreadProps$r(__spreadValues$1d({}, metadata), { ref: ext }); } if (typeof ext === "object") { ext = __spreadValues$1d({}, ext); } else { throw new Error("Invalid extension type"); } if (typeof ext.type === "string") { ext.type = [ext.type]; } return ext; }; const normalizeExtensionPriority = (ext, defaultPriority) => { var _a; return (_a = normalizeExtension(ext).priority) != null ? _a : defaultPriority; }; const extensions = { /** @ignore */ _addHandlers: {}, /** @ignore */ _removeHandlers: {}, /** @ignore */ _queue: {}, /** * Remove extensions from PixiJS. * @param extensions - Extensions to be removed. Can be: * - Extension class with static `extension` property * - Extension format object with `type` and `ref` * - Multiple extensions as separate arguments * @returns {extensions} this for chaining * @example * ```ts * // Remove a single extension * extensions.remove(MyRendererPlugin); * * // Remove multiple extensions * extensions.remove( * MyRendererPlugin, * MySystemPlugin * ); * ``` * @see {@link ExtensionType} For available extension types * @see {@link ExtensionFormat} For extension format details */ remove(...extensions2) { extensions2.map(normalizeExtension).forEach((ext) => { ext.type.forEach((type) => { var _a, _b; return (_b = (_a = this._removeHandlers)[type]) == null ? void 0 : _b.call(_a, ext); }); }); return this; }, /** * Register new extensions with PixiJS. Extensions can be registered in multiple formats: * - As a class with a static `extension` property * - As an extension format object * - As multiple extensions passed as separate arguments * @param extensions - Extensions to add to PixiJS. Each can be: * - A class with static `extension` property * - An extension format object with `type` and `ref` * - Multiple extensions as separate arguments * @returns This extensions instance for chaining * @example * ```ts * // Register a simple extension * extensions.add(MyRendererPlugin); * * // Register multiple extensions * extensions.add( * MyRendererPlugin, * MySystemPlugin, * }); * ``` * @see {@link ExtensionType} For available extension types * @see {@link ExtensionFormat} For extension format details * @see {@link extensions.remove} For removing registered extensions */ add(...extensions2) { extensions2.map(normalizeExtension).forEach((ext) => { ext.type.forEach((type) => { var _a, _b; const handlers = this._addHandlers; const queue = this._queue; if (!handlers[type]) { queue[type] = queue[type] || []; (_a = queue[type]) == null ? void 0 : _a.push(ext); } else { (_b = handlers[type]) == null ? void 0 : _b.call(handlers, ext); } }); }); return this; }, /** * Internal method to handle extensions by name. * @param type - The extension type. * @param onAdd - Function handler when extensions are added/registered {@link StrictExtensionFormat}. * @param onRemove - Function handler when extensions are removed/unregistered {@link StrictExtensionFormat}. * @returns this for chaining. * @internal * @ignore */ handle(type, onAdd, onRemove) { var _a; const addHandlers = this._addHandlers; const removeHandlers = this._removeHandlers; if (addHandlers[type] || removeHandlers[type]) { throw new Error(`Extension type ${type} already has a handler`); } addHandlers[type] = onAdd; removeHandlers[type] = onRemove; const queue = this._queue; if (queue[type]) { (_a = queue[type]) == null ? void 0 : _a.forEach((ext) => onAdd(ext)); delete queue[type]; } return this; }, /** * Handle a type, but using a map by `name` property. * @param type - Type of extension to handle. * @param map - The object map of named extensions. * @returns this for chaining. * @ignore */ handleByMap(type, map) { return this.handle( type, (extension) => { if (extension.name) { map[extension.name] = extension.ref; } }, (extension) => { if (extension.name) { delete map[extension.name]; } } ); }, /** * Handle a type, but using a list of extensions with a `name` property. * @param type - Type of extension to handle. * @param map - The array of named extensions. * @param defaultPriority - Fallback priority if none is defined. * @returns this for chaining. * @ignore */ handleByNamedList(type, map, defaultPriority = -1) { return this.handle( type, (extension) => { const index = map.findIndex((item) => item.name === extension.name); if (index >= 0) return; map.push({ name: extension.name, value: extension.ref }); map.sort((a, b) => normalizeExtensionPriority(b.value, defaultPriority) - normalizeExtensionPriority(a.value, defaultPriority)); }, (extension) => { const index = map.findIndex((item) => item.name === extension.name); if (index !== -1) { map.splice(index, 1); } } ); }, /** * Handle a type, but using a list of extensions. * @param type - Type of extension to handle. * @param list - The list of extensions. * @param defaultPriority - The default priority to use if none is specified. * @returns this for chaining. * @ignore */ handleByList(type, list, defaultPriority = -1) { return this.handle( type, (extension) => { if (list.includes(extension.ref)) { return; } list.push(extension.ref); list.sort((a, b) => normalizeExtensionPriority(b, defaultPriority) - normalizeExtensionPriority(a, defaultPriority)); }, (extension) => { const index = list.indexOf(extension.ref); if (index !== -1) { list.splice(index, 1); } } ); }, /** * Mixin the source object(s) properties into the target class's prototype. * Copies all property descriptors from source objects to the target's prototype. * @param Target - The target class to mix properties into * @param sources - One or more source objects containing properties to mix in * @example * ```ts * // Create a mixin with shared properties * const moveable = { * x: 0, * y: 0, * move(x: number, y: number) { * this.x += x; * this.y += y; * } * }; * * // Create a mixin with computed properties * const scalable = { * scale: 1, * get scaled() { * return this.scale > 1; * } * }; * * // Apply mixins to a class * extensions.mixin(Sprite, moveable, scalable); * * // Use mixed-in properties * const sprite = new Sprite(); * sprite.move(10, 20); * console.log(sprite.x, sprite.y); // 10, 20 * ``` * @remarks * - Copies all properties including getters/setters * - Does not modify source objects * - Preserves property descriptors * @see {@link Object.defineProperties} For details on property descriptors * @see {@link Object.getOwnPropertyDescriptors} For details on property copying */ mixin(Target, ...sources) { for (const source of sources) { Object.defineProperties(Target.prototype, Object.getOwnPropertyDescriptors(source)); } } }; var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; function getDefaultExportFromCjs (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } function getDefaultExportFromNamespaceIfPresent (n) { return n && Object.prototype.hasOwnProperty.call(n, 'default') ? n['default'] : n; } function getDefaultExportFromNamespaceIfNotNamed (n) { return n && Object.prototype.hasOwnProperty.call(n, 'default') && Object.keys(n).length === 1 ? n['default'] : n; } function getAugmentedNamespace(n) { if (n.__esModule) return n; var f = n.default; if (typeof f == "function") { var a = function a () { if (this instanceof a) { return Reflect.construct(f, arguments, this.constructor); } return f.apply(this, arguments); }; a.prototype = f.prototype; } else a = {}; Object.defineProperty(a, '__esModule', {value: true}); Object.keys(n).forEach(function (k) { var d = Object.getOwnPropertyDescriptor(n, k); Object.defineProperty(a, k, d.get ? d : { enumerable: true, get: function () { return n[k]; } }); }); return a; } var eventemitter3$1 = {exports: {}}; var eventemitter3 = eventemitter3$1.exports; (function (module) { 'use strict'; var has = Object.prototype.hasOwnProperty , prefix = '~'; /** * Constructor to create a storage for our `EE` objects. * An `Events` instance is a plain object whose properties are event names. * * @constructor * @private */ function Events() {} // // We try to not inherit from `Object.prototype`. In some engines creating an // instance in this way is faster than calling `Object.create(null)` directly. // If `Object.create(null)` is not supported we prefix the event names with a // character to make sure that the built-in object properties are not // overridden or used as an attack vector. // if (Object.create) { Events.prototype = Object.create(null); // // This hack is needed because the `__proto__` property is still inherited in // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5. // if (!new Events().__proto__) prefix = false; } /** * Representation of a single event listener. * * @param {Function} fn The listener function. * @param {*} context The context to invoke the listener with. * @param {Boolean} [once=false] Specify if the listener is a one-time listener. * @constructor * @private */ function EE(fn, context, once) { this.fn = fn; this.context = context; this.once = once || false; } /** * Add a listener for a given event. * * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. * @param {(String|Symbol)} event The event name. * @param {Function} fn The listener function. * @param {*} context The context to invoke the listener with. * @param {Boolean} once Specify if the listener is a one-time listener. * @returns {EventEmitter} * @private */ function addListener(emitter, event, fn, context, once) { if (typeof fn !== 'function') { throw new TypeError('The listener must be a function'); } var listener = new EE(fn, context || emitter, once) , evt = prefix ? prefix + event : event; if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++; else if (!emitter._events[evt].fn) emitter._events[evt].push(listener); else emitter._events[evt] = [emitter._events[evt], listener]; return emitter; } /** * Clear event by name. * * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. * @param {(String|Symbol)} evt The Event name. * @private */ function clearEvent(emitter, evt) { if (--emitter._eventsCount === 0) emitter._events = new Events(); else delete emitter._events[evt]; } /** * Minimal `EventEmitter` interface that is molded against the Node.js * `EventEmitter` interface. * * @constructor * @public */ function EventEmitter() { this._events = new Events(); this._eventsCount = 0; } /** * Return an array listing the events for which the emitter has registered * listeners. * * @returns {Array} * @public */ EventEmitter.prototype.eventNames = function eventNames() { var names = [] , events , name; if (this._eventsCount === 0) return names; for (name in (events = this._events)) { if (has.call(events, name)) names.push(prefix ? name.slice(1) : name); } if (Object.getOwnPropertySymbols) { return names.concat(Object.getOwnPropertySymbols(events)); } return names; }; /** * Return the listeners registered for a given event. * * @param {(String|Symbol)} event The event name. * @returns {Array} The registered listeners. * @public */ EventEmitter.prototype.listeners = function listeners(event) { var evt = prefix ? prefix + event : event , handlers = this._events[evt]; if (!handlers) return []; if (handlers.fn) return [handlers.fn]; for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) { ee[i] = handlers[i].fn; } return ee; }; /** * Return the number of listeners listening to a given event. * * @param {(String|Symbol)} event The event name. * @returns {Number} The number of listeners. * @public */ EventEmitter.prototype.listenerCount = function listenerCount(event) { var evt = prefix ? prefix + event : event , listeners = this._events[evt]; if (!listeners) return 0; if (listeners.fn) return 1; return listeners.length; }; /** * Calls each of the listeners registered for a given event. * * @param {(String|Symbol)} event The event name. * @returns {Boolean} `true` if the event had listeners, else `false`. * @public */ EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) { var evt = prefix ? prefix + event : event; if (!this._events[evt]) return false; var listeners = this._events[evt] , len = arguments.length , args , i; if (listeners.fn) { if (listeners.once) this.removeListener(event, listeners.fn, undefined, true); switch (len) { case 1: return listeners.fn.call(listeners.context), true; case 2: return listeners.fn.call(listeners.context, a1), true; case 3: return listeners.fn.call(listeners.context, a1, a2), true; case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true; case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true; case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true; } for (i = 1, args = new Array(len -1); i < len; i++) { args[i - 1] = arguments[i]; } listeners.fn.apply(listeners.context, args); } else { var length = listeners.length , j; for (i = 0; i < length; i++) { if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true); switch (len) { case 1: listeners[i].fn.call(listeners[i].context); break; case 2: listeners[i].fn.call(listeners[i].context, a1); break; case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break; case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break; default: if (!args) for (j = 1, args = new Array(len -1); j < len; j++) { args[j - 1] = arguments[j]; } listeners[i].fn.apply(listeners[i].context, args); } } } return true; }; /** * Add a listener for a given event. * * @param {(String|Symbol)} event The event name. * @param {Function} fn The listener function. * @param {*} [context=this] The context to invoke the listener with. * @returns {EventEmitter} `this`. * @public */ EventEmitter.prototype.on = function on(event, fn, context) { return addListener(this, event, fn, context, false); }; /** * Add a one-time listener for a given event. * * @param {(String|Symbol)} event The event name. * @param {Function} fn The listener function. * @param {*} [context=this] The context to invoke the listener with. * @returns {EventEmitter} `this`. * @public */ EventEmitter.prototype.once = function once(event, fn, context) { return addListener(this, event, fn, context, true); }; /** * Remove the listeners of a given event. * * @param {(String|Symbol)} event The event name. * @param {Function} fn Only remove the listeners that match this function. * @param {*} context Only remove the listeners that have this context. * @param {Boolean} once Only remove one-time listeners. * @returns {EventEmitter} `this`. * @public */ EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) { var evt = prefix ? prefix + event : event; if (!this._events[evt]) return this; if (!fn) { clearEvent(this, evt); return this; } var listeners = this._events[evt]; if (listeners.fn) { if ( listeners.fn === fn && (!once || listeners.once) && (!context || listeners.context === context) ) { clearEvent(this, evt); } } else { for (var i = 0, events = [], length = listeners.length; i < length; i++) { if ( listeners[i].fn !== fn || (once && !listeners[i].once) || (context && listeners[i].context !== context) ) { events.push(listeners[i]); } } // // Reset the array, or remove it completely if we have no more listeners. // if (events.length) this._events[evt] = events.length === 1 ? events[0] : events; else clearEvent(this, evt); } return this; }; /** * Remove all listeners, or those of the specified event. * * @param {(String|Symbol)} [event] The event name. * @returns {EventEmitter} `this`. * @public */ EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) { var evt; if (event) { evt = prefix ? prefix + event : event; if (this._events[evt]) clearEvent(this, evt); } else { this._events = new Events(); this._eventsCount = 0; } return this; }; // // Alias methods names because people roll like that. // EventEmitter.prototype.off = EventEmitter.prototype.removeListener; EventEmitter.prototype.addListener = EventEmitter.prototype.on; // // Expose the prefix. // EventEmitter.prefixed = prefix; // // Allow `EventEmitter` to be imported as module namespace. // EventEmitter.EventEmitter = EventEmitter; // // Expose the module. // if ('undefined' !== 'object') { module.exports = EventEmitter; } } (eventemitter3$1)); var eventemitter3Exports = eventemitter3$1.exports; var EventEmitter = /*@__PURE__*/getDefaultExportFromCjs(eventemitter3Exports); var r={grad:.9,turn:360,rad:360/(2*Math.PI)},t=function(r){return "string"==typeof r?r.length>0:"number"==typeof r},n=function(r,t,n){return void 0===t&&(t=0),void 0===n&&(n=Math.pow(10,t)),Math.round(n*r)/n+0},e=function(r,t,n){return void 0===t&&(t=0),void 0===n&&(n=1),r>n?n:r>t?r:t},u=function(r){return (r=isFinite(r)?r%360:0)>0?r:r+360},a=function(r){return {r:e(r.r,0,255),g:e(r.g,0,255),b:e(r.b,0,255),a:e(r.a)}},o=function(r){return {r:n(r.r),g:n(r.g),b:n(r.b),a:n(r.a,3)}},i=/^#([0-9a-f]{3,8})$/i,s=function(r){var t=r.toString(16);return t.length<2?"0"+t:t},h=function(r){var t=r.r,n=r.g,e=r.b,u=r.a,a=Math.max(t,n,e),o=a-Math.min(t,n,e),i=o?a===t?(n-e)/o:a===n?2+(e-t)/o:4+(t-n)/o:0;return {h:60*(i<0?i+6:i),s:a?o/a*100:0,v:a/255*100,a:u}},b=function(r){var t=r.h,n=r.s,e=r.v,u=r.a;t=t/360*6,n/=100,e/=100;var a=Math.floor(t),o=e*(1-n),i=e*(1-(t-a)*n),s=e*(1-(1-t+a)*n),h=a%6;return {r:255*[e,i,o,o,s,e][h],g:255*[s,e,e,i,o,o][h],b:255*[o,o,s,e,e,i][h],a:u}},g=function(r){return {h:u(r.h),s:e(r.s,0,100),l:e(r.l,0,100),a:e(r.a)}},d=function(r){return {h:n(r.h),s:n(r.s),l:n(r.l),a:n(r.a,3)}},f=function(r){return b((n=(t=r).s,{h:t.h,s:(n*=((e=t.l)<50?e:100-e)/100)>0?2*n/(e+n)*100:0,v:e+n,a:t.a}));var t,n,e;},c=function(r){return {h:(t=h(r)).h,s:(u=(200-(n=t.s))*(e=t.v)/100)>0&&u<200?n*e/100/(u<=100?u:200-u)*100:0,l:u/2,a:t.a};var t,n,e,u;},l=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s*,\s*([+-]?\d*\.?\d+)%\s*,\s*([+-]?\d*\.?\d+)%\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,p=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s+([+-]?\d*\.?\d+)%\s+([+-]?\d*\.?\d+)%\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,v=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,m=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,y={string:[[function(r){var t=i.exec(r);return t?(r=t[1]).length<=4?{r:parseInt(r[0]+r[0],16),g:parseInt(r[1]+r[1],16),b:parseInt(r[2]+r[2],16),a:4===r.length?n(parseInt(r[3]+r[3],16)/255,2):1}:6===r.length||8===r.length?{r:parseInt(r.substr(0,2),16),g:parseInt(r.substr(2,2),16),b:parseInt(r.substr(4,2),16),a:8===r.length?n(parseInt(r.substr(6,2),16)/255,2):1}:null:null},"hex"],[function(r){var t=v.exec(r)||m.exec(r);return t?t[2]!==t[4]||t[4]!==t[6]?null:a({r:Number(t[1])/(t[2]?100/255:1),g:Number(t[3])/(t[4]?100/255:1),b:Number(t[5])/(t[6]?100/255:1),a:void 0===t[7]?1:Number(t[7])/(t[8]?100:1)}):null},"rgb"],[function(t){var n=l.exec(t)||p.exec(t);if(!n)return null;var e,u,a=g({h:(e=n[1],u=n[2],void 0===u&&(u="deg"),Number(e)*(r[u]||1)),s:Number(n[3]),l:Number(n[4]),a:void 0===n[5]?1:Number(n[5])/(n[6]?100:1)});return f(a)},"hsl"]],object:[[function(r){var n=r.r,e=r.g,u=r.b,o=r.a,i=void 0===o?1:o;return t(n)&&t(e)&&t(u)?a({r:Number(n),g:Number(e),b:Number(u),a:Number(i)}):null},"rgb"],[function(r){var n=r.h,e=r.s,u=r.l,a=r.a,o=void 0===a?1:a;if(!t(n)||!t(e)||!t(u))return null;var i=g({h:Number(n),s:Number(e),l:Number(u),a:Number(o)});return f(i)},"hsl"],[function(r){var n=r.h,a=r.s,o=r.v,i=r.a,s=void 0===i?1:i;if(!t(n)||!t(a)||!t(o))return null;var h=function(r){return {h:u(r.h),s:e(r.s,0,100),v:e(r.v,0,100),a:e(r.a)}}({h:Number(n),s:Number(a),v:Number(o),a:Number(s)});return b(h)},"hsv"]]},N=function(r,t){for(var n=0;n<t.length;n++){var e=t[n][0](r);if(e)return [e,t[n][1]]}return [null,void 0]},x=function(r){return "string"==typeof r?N(r.trim(),y.string):"object"==typeof r&&null!==r?N(r,y.object):[null,void 0]},I=function(r){return x(r)[1]},M=function(r,t){var n=c(r);return {h:n.h,s:e(n.s+100*t,0,100),l:n.l,a:n.a}},H=function(r){return (299*r.r+587*r.g+114*r.b)/1e3/255},$=function(r,t){var n=c(r);return {h:n.h,s:n.s,l:e(n.l+100*t,0,100),a:n.a}},j=function(){function r(r){this.parsed=x(r)[0],this.rgba=this.parsed||{r:0,g:0,b:0,a:1};}return r.prototype.isValid=function(){return null!==this.parsed},r.prototype.brightness=function(){return n(H(this.rgba),2)},r.prototype.isDark=function(){return H(this.rgba)<.5},r.prototype.isLight=function(){return H(this.rgba)>=.5},r.prototype.toHex=function(){return r=o(this.rgba),t=r.r,e=r.g,u=r.b,i=(a=r.a)<1?s(n(255*a)):"","#"+s(t)+s(e)+s(u)+i;var r,t,e,u,a,i;},r.prototype.toRgb=function(){return o(this.rgba)},r.prototype.toRgbString=function(){return r=o(this.rgba),t=r.r,n=r.g,e=r.b,(u=r.a)<1?"rgba("+t+", "+n+", "+e+", "+u+")":"rgb("+t+", "+n+", "+e+")";var r,t,n,e,u;},r.prototype.toHsl=function(){return d(c(this.rgba))},r.prototype.toHslString=function(){return r=d(c(this.rgba)),t=r.h,n=r.s,e=r.l,(u=r.a)<1?"hsla("+t+", "+n+"%, "+e+"%, "+u+")":"hsl("+t+", "+n+"%, "+e+"%)";var r,t,n,e,u;},r.prototype.toHsv=function(){return r=h(this.rgba),{h:n(r.h),s:n(r.s),v:n(r.v),a:n(r.a,3)};var r;},r.prototype.invert=function(){return w({r:255-(r=this.rgba).r,g:255-r.g,b:255-r.b,a:r.a});var r;},r.prototype.saturate=function(r){return void 0===r&&(r=.1),w(M(this.rgba,r))},r.prototype.desaturate=function(r){return void 0===r&&(r=.1),w(M(this.rgba,-r))},r.prototype.grayscale=function(){return w(M(this.rgba,-1))},r.prototype.lighten=function(r){return void 0===r&&(r=.1),w($(this.rgba,r))},r.prototype.darken=function(r){return void 0===r&&(r=.1),w($(this.rgba,-r))},r.prototype.rotate=function(r){return void 0===r&&(r=15),this.hue(this.hue()+r)},r.prototype.alpha=function(r){return "number"==typeof r?w({r:(t=this.rgba).r,g:t.g,b:t.b,a:r}):n(this.rgba.a,3);var t;},r.prototype.hue=function(r){var t=c(this.rgba);return "number"==typeof r?w({h:r,s:t.s,l:t.l,a:t.a}):n(t.h)},r.prototype.isEqual=function(r){return this.toHex()===w(r).toHex()},r}(),w=function(r){return r instanceof j?r:new j(r)},S=[],k=function(r){r.forEach(function(r){S.indexOf(r)<0&&(r(j,y),S.push(r));});},E=function(){return new j({r:255*Math.random(),g:255*Math.random(),b:255*Math.random()})}; function namesPlugin(e,f){var a={white:"#ffffff",bisque:"#ffe4c4",blue:"#0000ff",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",antiquewhite:"#faebd7",aqua:"#00ffff",azure:"#f0ffff",whitesmoke:"#f5f5f5",papayawhip:"#ffefd5",plum:"#dda0dd",blanchedalmond:"#ffebcd",black:"#000000",gold:"#ffd700",goldenrod:"#daa520",gainsboro:"#dcdcdc",cornsilk:"#fff8dc",cornflowerblue:"#6495ed",burlywood:"#deb887",aquamarine:"#7fffd4",beige:"#f5f5dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkkhaki:"#bdb76b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",peachpuff:"#ffdab9",darkmagenta:"#8b008b",darkred:"#8b0000",darkorchid:"#9932cc",darkorange:"#ff8c00",darkslateblue:"#483d8b",gray:"#808080",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",deeppink:"#ff1493",deepskyblue:"#00bfff",wheat:"#f5deb3",firebrick:"#b22222",floralwhite:"#fffaf0",ghostwhite:"#f8f8ff",darkviolet:"#9400d3",magenta:"#ff00ff",green:"#008000",dodgerblue:"#1e90ff",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",blueviolet:"#8a2be2",forestgreen:"#228b22",lawngreen:"#7cfc00",indianred:"#cd5c5c",indigo:"#4b0082",fuchsia:"#ff00ff",brown:"#a52a2a",maroon:"#800000",mediumblue:"#0000cd",lightcoral:"#f08080",darkturquoise:"#00ced1",lightcyan:"#e0ffff",ivory:"#fffff0",lightyellow:"#ffffe0",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",linen:"#faf0e6",mediumaquamarine:"#66cdaa",lemonchiffon:"#fffacd",lime:"#00ff00",khaki:"#f0e68c",mediumseagreen:"#3cb371",limegreen:"#32cd32",mediumspringgreen:"#00fa9a",lightskyblue:"#87cefa",lightblue:"#add8e6",midnightblue:"#191970",lightpink:"#ffb6c1",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",mintcream:"#f5fffa",lightslategray:"#778899",lightslategrey:"#778899",navajowhite:"#ffdead",navy:"#000080",mediumvioletred:"#c71585",powderblue:"#b0e0e6",palegoldenrod:"#eee8aa",oldlace:"#fdf5e6",paleturquoise:"#afeeee",mediumturquoise:"#48d1cc",mediumorchid:"#ba55d3",rebeccapurple:"#663399",lightsteelblue:"#b0c4de",mediumslateblue:"#7b68ee",thistle:"#d8bfd8",tan:"#d2b48c",orchid:"#da70d6",mediumpurple:"#9370db",purple:"#800080",pink:"#ffc0cb",skyblue:"#87ceeb",springgreen:"#00ff7f",palegreen:"#98fb98",red:"#ff0000",yellow:"#ffff00",slateblue:"#6a5acd",lavenderblush:"#fff0f5",peru:"#cd853f",palevioletred:"#db7093",violet:"#ee82ee",teal:"#008080",slategray:"#708090",slategrey:"#708090",aliceblue:"#f0f8ff",darkseagreen:"#8fbc8f",darkolivegreen:"#556b2f",greenyellow:"#adff2f",seagreen:"#2e8b57",seashell:"#fff5ee",tomato:"#ff6347",silver:"#c0c0c0",sienna:"#a0522d",lavender:"#e6e6fa",lightgreen:"#90ee90",orange:"#ffa500",orangered:"#ff4500",steelblue:"#4682b4",royalblue:"#4169e1",turquoise:"#40e0d0",yellowgreen:"#9acd32",salmon:"#fa8072",saddlebrown:"#8b4513",sandybrown:"#f4a460",rosybrown:"#bc8f8f",darksalmon:"#e9967a",lightgoldenrodyellow:"#fafad2",snow:"#fffafa",lightgrey:"#d3d3d3",lightgray:"#d3d3d3",dimgray:"#696969",dimgrey:"#696969",olivedrab:"#6b8e23",olive:"#808000"},r={};for(var d in a)r[a[d]]=d;var l={};e.prototype.toName=function(f){if(!(this.rgba.a||this.rgba.r||this.rgba.g||this.rgba.b))return "transparent";var d,i,n=r[this.toHex()];if(n)return n;if(null==f?void 0:f.closest){var o=this.toRgb(),t=1/0,b="black";if(!l.length)for(var c in a)l[c]=new e(a[c]).toRgb();for(var g in a){var u=(d=o,i=l[g],Math.pow(d.r-i.r,2)+Math.pow(d.g-i.g,2)+Math.pow(d.b-i.b,2));u<t&&(t=u,b=g);}return b}};f.string.push([function(f){var r=f.toLowerCase(),d="transparent"===r?"#0000":a[r];return d?new e(d).toRgb():null},"name"]);} "use strict"; var __defProp$1c = Object.defineProperty; var __getOwnPropSymbols$1c = Object.getOwnPropertySymbols; var __hasOwnProp$1c = Object.prototype.hasOwnProperty; var __propIsEnum$1c = Object.prototype.propertyIsEnumerable; var __defNormalProp$1c = (obj, key, value) => key in obj ? __defProp$1c(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues$1c = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp$1c.call(b, prop)) __defNormalProp$1c(a, prop, b[prop]); if (__getOwnPropSymbols$1c) for (var prop of __getOwnPropSymbols$1c(b)) { if (__propIsEnum$1c.call(b, prop)) __defNormalProp$1c(a, prop, b[prop]); } return a; }; k([namesPlugin]); const _Color = class _Color { /** * @param {ColorSource} value - Optional value to use, if not provided, white is used. */ constructor(value = 16777215) { this._value = null; this._components = new Float32Array(4); this._components.fill(1); this._int = 16777215; this.value = value; } /** * Get the red component of the color, normalized between 0 and 1. * @example * ```ts * const color = new Color('red'); * console.log(color.red); // 1 * * const green = new Color('#00ff00'); * console.log(green.red); // 0 * ``` */ get red() { return this._components[0]; } /** * Get the green component of the color, normalized between 0 and 1. * @example * ```ts * const color = new Color('lime'); * console.log(color.green); // 1 * * const red = new Color('#ff0000'); * console.log(red.green); // 0 * ``` */ get green() { return this._components[1]; } /** * Get the blue component of the color, normalized between 0 and 1. * @example * ```ts * const color = new Color('blue'); * console.log(color.blue); // 1 * * const yellow = new Color('#ffff00'); * console.log(yellow.blue); // 0 * ``` */ get blue() { return this._components[2]; } /** * Get the alpha component of the color, normalized between 0 and 1. * @example * ```ts * const color = new Color('red'); * console.log(color.alpha); // 1 (fully opaque) * * const transparent = new Color('rgba(255, 0, 0, 0.5)'); * console.log(transparent.alpha); // 0.5 (semi-transparent) * ``` */ get alpha() { return this._components[3]; } /** * Sets the color value and returns the instance for chaining. * * This is a chainable version of setting the `value` property. * @param value - The color to set. Accepts various formats: * - Hex strings/numbers (e.g., '#ff0000', 0xff0000) * - RGB/RGBA values (arrays, objects) * - CSS color names * - HSL/HSLA values * - HSV/HSVA values * @returns The Color instance for chaining * @example * ```ts * // Basic usage * const color = new Color(); * color.setValue('#ff0000') * .setAlpha(0.5) * .premultiply(0.8); * * // Different formats * color.setValue(0xff0000); // Hex number * color.setValue('#ff0000'); // Hex string * color.setValue([1, 0, 0]); // RGB array * color.setValue([1, 0, 0, 0.5]); // RGBA array * color.setValue({ r: 1, g: 0, b: 0 }); // RGB object * * // Copy from another color * const red = new Color('red'); * color.setValue(red); * ``` * @throws {Error} If the color value is invalid or null * @see {@link Color.value} For the underlying value property */ setValue(value) { this.value = value; return this; } /** * The current color source. This property allows getting and setting the color value * while preserving the original format where possible. * @remarks * When setting: * - Setting to a `Color` instance copies its source and components * - Setting to other valid sources normalizes and stores the value * - Setting to `null` throws an Error * - The color remains unchanged if normalization fails * * When getting: * - Returns `null` if color was modified by {@link Color.multiply} or {@link Color.premultiply} * - Otherwise returns the original color source * @example * ```ts * // Setting different color formats * const color = new Color(); * * color.value = 0xff0000; // Hex number * color.value = '#ff0000'; // Hex string * color.value = [1, 0, 0]; // RGB array * color.value = [1, 0, 0, 0.5]; // RGBA array * color.value = { r: 1, g: 0, b: 0 }; // RGB object * * // Copying from another color * const red = new Color('red'); * color.value = red; // Copies red's components * * // Getting the value * console.log(color.value); // Returns original format * * // After modifications * color.multiply([0.5, 0.5, 0.5]); * console.log(color.value); // Returns null * ``` * @throws {Error} When attempting to set `null` */ set value(value) { if (value instanceof _Color) { this._value = this._cloneSource(value._value); this._int = value._int; this._components.set(value._components); } else if (value === null) { throw new Error("Cannot set Color#value to null"); } else if (this._value === null || !this._isSourceEqual(this._value, value)) { this._value = this._cloneSource(value); this._normalize(this._value); } } get value() { return this._value; } /** * Copy a color source internally. * @param value - Color source */ _cloneSource(value) { if (typeof value === "string" || typeof value === "number" || value instanceof Number || value === null) { return value; } else if (Array.isArray(value) || ArrayBuffer.isView(value)) { return value.slice(0); } else if (typeof value === "object" && value !== null) { return __spreadValues$1c({}, value); } return value; } /** * Equality check for color sources. * @param value1 - First color source * @param value2 - Second color source * @returns `true` if the color sources are equal, `false` otherwise. */ _isSourceEqual(value1, value2) { const type1 = typeof value1; const type2 = typeof value2; if (type1 !== type2) { return false; } else if (type1 === "number" || type1 === "string" || value1 instanceof Number) { return value1 === value2; } else if (Array.isArray(value1) && Array.isArray(value2) || ArrayBuffer.isView(value1) && ArrayBuffer.isView(value2)) { if (value1.length !== value2.length) { return false; } return value1.every((v, i) => v === value2[i]); } else if (value1 !== null && value2 !== null) { const keys1 = Object.keys(value1); const keys2 = Object.keys(value2); if (keys1.length !== keys2.length) { return false; } return keys1.every((key) => value1[key] === value2[key]); } return value1 === value2; } /** * Convert to a RGBA color object with normalized components (0-1). * @example * ```ts * import { Color } from 'pixi.js'; * * // Convert colors to RGBA objects * new Color('white').toRgba(); // returns { r: 1, g: 1, b: 1, a: 1 } * new Color('#ff0000').toRgba(); // returns { r: 1, g: 0, b: 0, a: 1 } * * // With transparency * new Color('rgba(255,0,0,0.5)').toRgba(); // returns { r: 1, g: 0, b: 0, a: 0.5 } * ``` * @returns An RGBA object with normalized components */ toRgba() { const [r, g, b, a] = this._components; return { r, g, b, a }; } /** * Convert to a RGB color object with normalized components (0-1). * * Alpha component is omitted in the output. * @example * ```ts * import { Color } from 'pixi.js'; * * // Convert colors to RGB objects * new Color('white').toRgb(); // returns { r: 1, g: 1, b: 1 } * new Color('#ff0000').toRgb(); // returns { r: 1, g: 0, b: 0 } * * // Alpha is ignored * new Color('rgba(255,0,0,0.5)').toRgb(); // returns { r: 1, g: 0, b: 0 } * ``` * @returns An RGB object with normalized components */ toRgb() { const [r, g, b] = this._components; return { r, g, b }; } /** * Convert to a CSS-style rgba string representation. * * RGB components are scaled to 0-255 range, alpha remains 0-1. * @example * ```ts * import { Color } from 'pixi.js'; * * // Convert colors to RGBA strings * new Color('white').toRgbaString(); // returns "rgba(255,255,255,1)" * new Color('#ff0000').toRgbaString(); // returns "rgba(255,0,0,1)" * * // With transparency * new Color([1, 0, 0, 0.5]).toRgbaString(); // returns "rgba(255,0,0,0.5)" * ``` * @returns A CSS-compatible rgba string */ toRgbaString() { const [r, g, b] = this.toUint8RgbArray(); return `rgba(${r},${g},${b},${this.alpha})`; } /** * Convert to an [R, G, B] array of clamped uint8 values (0 to 255). * @param {number[]|Uint8Array|Uint8ClampedArray} [out] - Optional output array. If not provided, * a cached array will be used and returned. * @returns Array containing RGB components as integers between 0-255 * @example * ```ts * // Basic usage * new Color('white').toUint8RgbArray(); // returns [255, 255, 255] * new Color('#ff0000').toUint8RgbArray(); // returns [255, 0, 0] * * // Using custom output array * const rgb = new Uint8Array(3); * new Color('blue').toUint8RgbArray(rgb); // rgb is now [0, 0, 255] * * // Using different array types * new Color('red').toUint8RgbArray(new Uint8ClampedArray(3)); // [255, 0, 0] * new Color('red').toUint8RgbArray([]); // [255, 0, 0] * ``` * @remarks * - Output values are always clamped between 0-255 * - Alpha component is not included in output * - Reuses internal cache array if no output array provided */ toUint8RgbArray(out) { const [r, g, b] = this._components; if (!this._arrayRgb) { this._arrayRgb = []; } out || (out = this._arrayRgb); out[0] = Math.round(r * 255); out[1] = Math.round(g * 255); out[2] = Math.round(b * 255); return out; } /** * Convert to an [R, G, B, A] array of normalized floats (numbers from 0.0 to 1.0). * @param {number[]|Float32Array} [out] - Optional output array. If not provided, * a cached array will be used and returned. * @returns Array containing RGBA components as floats between 0-1 * @example * ```ts * // Basic usage * new Color('white').toArray(); // returns [1, 1, 1, 1] * new Color('red').toArray(); // returns [1, 0, 0, 1] * * // With alpha * new Color('rgba(255,0,0,0.5)').toArray(); // returns [1, 0, 0, 0.5] * * // Using custom output array * const rgba = new Float32Array(4); * new Color('blue').toArray(rgba); // rgba is now [0, 0, 1, 1] * ``` * @remarks * - Output values are normalized between 0-1 * - Includes alpha component as the fourth value * - Reuses internal cache array if no output array provided */ toArray(out) { if (!this._arrayRgba) { this._arrayRgba = []; } out || (out = this._arrayRgba); const [r, g, b, a] = this._components; out[0] = r; out[1] = g; out[2] = b; out[3] = a; return out; } /** * Convert to an [R, G, B] array of normalized floats (numbers from 0.0 to 1.0). * @param {number[]|Float32Array} [out] - Optional output array. If not provided, * a cached array will be used and returned. * @returns Array containing RGB components as floats between 0-1 * @example * ```ts * // Basic usage * new Color('white').toRgbArray(); // returns [1, 1, 1] * new Color('red').toRgbArray(); // returns [1, 0, 0] * * // Using custom output array * const rgb = new Float32Array(3); * new Color('blue').toRgbArray(rgb); // rgb is now [0, 0, 1] * ``` * @remarks * - Output values are normalized between 0-1 * - Alpha component is omitted from output * - Reuses internal cache array if no output array provided */ toRgbArray(out) { if (!this._arrayRgb) { this._arrayRgb = []; } out || (out = this._arrayRgb); const [r, g, b] = this._components; out[0] = r; out[1] = g; out[2] = b; return out; } /** * Convert to a hexadecimal number. * @returns The color as a 24-bit RGB integer * @example * ```ts * // Basic usage * new Color('white').toNumber(); // returns 0xffffff * new Color('red').toNumber(); // returns 0xff0000 * * // Store as hex * const color = new Color('blue'); * const hex = color.toNumber(); // 0x0000ff * ``` */ toNumber() { return this._int; } /** * Convert to a BGR number. * * Useful for platforms that expect colors in BGR format. * @returns The color as a 24-bit BGR integer * @example * ```ts * // Convert RGB to BGR * new Color(0xffcc99).toBgrNumber(); // returns 0x99ccff * * // Common use case: platform-specific color format * const color = new Color('orange'); * const bgrColor = color.toBgrNumber(); // Color with swapped R/B channels * ``` * @remarks * This swaps the red and blue channels compared to the normal RGB format: * - RGB 0xRRGGBB becomes BGR 0xBBGGRR */ toBgrNumber() { const [r, g, b] = this.toUint8RgbArray(); return (b << 16) + (g << 8) + r; } /** * Convert to a hexadecimal number in little endian format (e.g., BBGGRR). * * Useful for platforms that expect colors in little endian byte order. * @example * ```ts * import { Color } from 'pixi.js'; * * // Convert RGB color to little endian format * new Color(0xffcc99).toLittleEndianNumber(); // returns 0x99ccff * * // Common use cases: * const color = new Color('orange'); * const leColor = color.toLittleEndianNumber(); // Swaps byte order for LE systems * * // Multiple conversions * const colors = { * normal: 0xffcc99, * littleEndian: new Color(0xffcc99).toLittleEndianNumber(), // 0x99ccff * backToNormal: new Color(0x99ccff).toLittleEndianNumber() // 0xffcc99 * }; * ``` * @remarks * - Swaps R and B channels in the color value * - RGB 0xRRGGBB becomes 0xBBGGRR * - Useful for systems that use little endian byte order * - Can be used to convert back and forth between formats * @returns The color as a number in little endian format (BBGGRR) * @see {@link Color.toBgrNumber} For BGR format without byte swapping */ toLittleEndianNumber() { const value = this._int; return (value >> 16) + (value & 65280) + ((value & 255) << 16); } /** * Multiply with another color. * * This action is destructive and modifies the original color. * @param {ColorSource} value - The color to multiply by. Accepts any valid color format: * - Hex strings/numbers (e.g., '#ff0000', 0xff0000) * - RGB/RGBA arrays ([1, 0, 0], [1, 0, 0, 1]) * - Color objects ({ r: 1, g: 0, b: 0 }) * - CSS color names ('red', 'blue') * @returns this - The Color instance for chaining * @example * ```ts * // Basic multiplication * const color = new Color('#ff0000'); * color.multiply(0x808080); // 50% darker red * * // With transparency * color.multiply([1, 1, 1, 0.5]); // 50% transparent * * // Chain operations * color * .multiply('#808080') * .multiply({ r: 1, g: 1, b: 1, a: 0.5 }); * ``` * @remarks * - Multiplies each RGB component and alpha separately * - Values are clamped between 0-1 * - Original color format is lost (value becomes null) * - Operation cannot be undone */ multiply(value) { const [r, g, b, a] = _Color._temp.setValue(value)._components; this._components[0] *= r; this._components[1] *= g; this._components[2] *= b; this._components[3] *= a; this._refreshInt(); this._value = null; return this; } /** * Converts color to a premultiplied alpha format. * * This action is destructive and modifies the original color. * @param alpha - The alpha value to multiply by (0-1) * @param {boolean} [applyToRGB=true] - Whether to premultiply RGB channels * @returns {Color} The Color instance for chaining * @example * ```ts * // Basic premultiplication * const color = new Color('red'); * color.premultiply(0.5); // 50% transparent red with premultiplied RGB * * // Alpha only (RGB unchanged) * color.premultiply(0.5, false); // 50% transparent, original RGB * * // Chain with other operations * color * .multiply(0x808080) * .premultiply(0.5) * .toNumber(); * ``` * @remarks * - RGB channels are multiplied by alpha when applyToRGB is true * - Alpha is always set to the provided value * - Values are clamped between 0-1 * - Original color format is lost (value becomes null) * - Operation cannot be undone */ premultiply(alpha, applyToRGB = true) { if (applyToRGB) { this._components[0] *= alpha; this._components[1] *= alpha; this._components[2] *= alpha; } this._components[3] = alpha; this._refreshInt(); this._value = null; return this; } /** * Returns the color as a 32-bit premultiplied alpha integer. * * Format: 0xAARRGGBB * @param {number} alpha - The alpha value to multiply by (0-1) * @param {boolean} [applyToRGB=true] - Whether to premultiply RGB channels * @returns {number} The premultiplied color as a 32-bit integer * @example * ```ts * // Convert to premultiplied format * const color = new Color('red'); * * // Full opacity (0xFFRRGGBB) * color.toPremultiplied(1.0); // 0xFFFF0000 * * // 50% transparency with premultiplied RGB * color.toPremultiplied(0.5); // 0x7F7F0000 * * // 50% transparency without RGB premultiplication * color.toPremultiplied(0.5, false); // 0x7FFF0000 * ``` * @remarks * - Returns full opacity (0xFF000000) when alpha is 1.0 * - Returns 0 when alpha is 0.0 and applyToRGB is true * - RGB values are rounded during premultiplication */ toPremultiplied(alpha, applyToRGB = true) { if (alpha === 1) { return (255 << 24) + this._int; } if (alpha === 0) { return applyToRGB ? 0 : this._int; } let r = this._int >> 16 & 255; let g = this._int >> 8 & 255; let b = this._int & 255; if (applyToRGB) { r = r * alpha + 0.5 | 0; g = g * alpha + 0.5 | 0; b = b * alpha + 0.5 | 0; } return (alpha * 255 << 24) + (r << 16) + (g << 8) + b; } /** * Convert to a hexadecimal string (6 characters). * @returns A CSS-compatible hex color string (e.g., "#ff0000") * @example * ```ts * import { Color } from 'pixi.js'; * * // Basic colors * new Color('red').toHex(); // returns "#ff0000" * new Color('white').toHex(); // returns "#ffffff" * new Color('black').toHex(); // returns "#000000" * * // From different formats * new Color(0xff0000).toHex(); // returns "#ff0000" * new Color([1, 0, 0]).toHex(); // returns "#ff0000" * new Color({ r: 1, g: 0, b: 0 }).toHex(); // returns "#ff0000" * ``` * @remarks * - Always returns a 6-character hex string * - Includes leading "#" character * - Alpha channel is ignored * - Values are rounded to nearest hex value */ toHex() { const hexString = this._int.toString(16); return `#${"000000".substring(0, 6 - hexString.length) + hexString}`; } /**