UNPKG

react-particle-text

Version:

A React component that creates interactive particle text effects using Three.js

2,481 lines (2,000 loc) 1.3 MB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var jsxRuntime = require('react/jsx-runtime'); var React = require('react'); /** * @license * Copyright 2010-2025 Three.js Authors * SPDX-License-Identifier: MIT */ const REVISION = '178'; /** * Disables face culling. * * @type {number} * @constant */ const CullFaceNone = 0; /** * Culls back faces. * * @type {number} * @constant */ const CullFaceBack = 1; /** * Culls front faces. * * @type {number} * @constant */ const CullFaceFront = 2; /** * Filters shadow maps using the Percentage-Closer Filtering (PCF) algorithm. * * @type {number} * @constant */ const PCFShadowMap = 1; /** * Filters shadow maps using the Percentage-Closer Filtering (PCF) algorithm with * better soft shadows especially when using low-resolution shadow maps. * * @type {number} * @constant */ const PCFSoftShadowMap = 2; /** * Filters shadow maps using the Variance Shadow Map (VSM) algorithm. * When using VSMShadowMap all shadow receivers will also cast shadows. * * @type {number} * @constant */ const VSMShadowMap = 3; /** * Only front faces are rendered. * * @type {number} * @constant */ const FrontSide = 0; /** * Only back faces are rendered. * * @type {number} * @constant */ const BackSide = 1; /** * Both front and back faces are rendered. * * @type {number} * @constant */ const DoubleSide = 2; /** * No blending is performed which effectively disables * alpha transparency. * * @type {number} * @constant */ const NoBlending = 0; /** * The default blending. * * @type {number} * @constant */ const NormalBlending = 1; /** * Represents additive blending. * * @type {number} * @constant */ const AdditiveBlending = 2; /** * Represents subtractive blending. * * @type {number} * @constant */ const SubtractiveBlending = 3; /** * Represents multiply blending. * * @type {number} * @constant */ const MultiplyBlending = 4; /** * Represents custom blending. * * @type {number} * @constant */ const CustomBlending = 5; /** * A `source + destination` blending equation. * * @type {number} * @constant */ const AddEquation = 100; /** * A `source - destination` blending equation. * * @type {number} * @constant */ const SubtractEquation = 101; /** * A `destination - source` blending equation. * * @type {number} * @constant */ const ReverseSubtractEquation = 102; /** * A blend equation that uses the minimum of source and destination. * * @type {number} * @constant */ const MinEquation = 103; /** * A blend equation that uses the maximum of source and destination. * * @type {number} * @constant */ const MaxEquation = 104; /** * Multiplies all colors by `0`. * * @type {number} * @constant */ const ZeroFactor = 200; /** * Multiplies all colors by `1`. * * @type {number} * @constant */ const OneFactor = 201; /** * Multiplies all colors by the source colors. * * @type {number} * @constant */ const SrcColorFactor = 202; /** * Multiplies all colors by `1` minus each source color. * * @type {number} * @constant */ const OneMinusSrcColorFactor = 203; /** * Multiplies all colors by the source alpha value. * * @type {number} * @constant */ const SrcAlphaFactor = 204; /** * Multiplies all colors by 1 minus the source alpha value. * * @type {number} * @constant */ const OneMinusSrcAlphaFactor = 205; /** * Multiplies all colors by the destination alpha value. * * @type {number} * @constant */ const DstAlphaFactor = 206; /** * Multiplies all colors by `1` minus the destination alpha value. * * @type {number} * @constant */ const OneMinusDstAlphaFactor = 207; /** * Multiplies all colors by the destination color. * * @type {number} * @constant */ const DstColorFactor = 208; /** * Multiplies all colors by `1` minus each destination color. * * @type {number} * @constant */ const OneMinusDstColorFactor = 209; /** * Multiplies the RGB colors by the smaller of either the source alpha * value or the value of `1` minus the destination alpha value. The alpha * value is multiplied by `1`. * * @type {number} * @constant */ const SrcAlphaSaturateFactor = 210; /** * Multiplies all colors by a constant color. * * @type {number} * @constant */ const ConstantColorFactor = 211; /** * Multiplies all colors by `1` minus a constant color. * * @type {number} * @constant */ const OneMinusConstantColorFactor = 212; /** * Multiplies all colors by a constant alpha value. * * @type {number} * @constant */ const ConstantAlphaFactor = 213; /** * Multiplies all colors by 1 minus a constant alpha value. * * @type {number} * @constant */ const OneMinusConstantAlphaFactor = 214; /** * Never pass. * * @type {number} * @constant */ const NeverDepth = 0; /** * Always pass. * * @type {number} * @constant */ const AlwaysDepth = 1; /** * Pass if the incoming value is less than the depth buffer value. * * @type {number} * @constant */ const LessDepth = 2; /** * Pass if the incoming value is less than or equal to the depth buffer value. * * @type {number} * @constant */ const LessEqualDepth = 3; /** * Pass if the incoming value equals the depth buffer value. * * @type {number} * @constant */ const EqualDepth = 4; /** * Pass if the incoming value is greater than or equal to the depth buffer value. * * @type {number} * @constant */ const GreaterEqualDepth = 5; /** * Pass if the incoming value is greater than the depth buffer value. * * @type {number} * @constant */ const GreaterDepth = 6; /** * Pass if the incoming value is not equal to the depth buffer value. * * @type {number} * @constant */ const NotEqualDepth = 7; /** * Multiplies the environment map color with the surface color. * * @type {number} * @constant */ const MultiplyOperation = 0; /** * Uses reflectivity to blend between the two colors. * * @type {number} * @constant */ const MixOperation = 1; /** * Adds the two colors. * * @type {number} * @constant */ const AddOperation = 2; /** * No tone mapping is applied. * * @type {number} * @constant */ const NoToneMapping = 0; /** * Linear tone mapping. * * @type {number} * @constant */ const LinearToneMapping = 1; /** * Reinhard tone mapping. * * @type {number} * @constant */ const ReinhardToneMapping = 2; /** * Cineon tone mapping. * * @type {number} * @constant */ const CineonToneMapping = 3; /** * ACES Filmic tone mapping. * * @type {number} * @constant */ const ACESFilmicToneMapping = 4; /** * Custom tone mapping. * * Expects a custom implementation by modifying shader code of the material's fragment shader. * * @type {number} * @constant */ const CustomToneMapping = 5; /** * AgX tone mapping. * * @type {number} * @constant */ const AgXToneMapping = 6; /** * Neutral tone mapping. * * Implementation based on the Khronos 3D Commerce Group standard tone mapping. * * @type {number} * @constant */ const NeutralToneMapping = 7; /** * Maps textures using the geometry's UV coordinates. * * @type {number} * @constant */ const UVMapping = 300; /** * Reflection mapping for cube textures. * * @type {number} * @constant */ const CubeReflectionMapping = 301; /** * Refraction mapping for cube textures. * * @type {number} * @constant */ const CubeRefractionMapping = 302; /** * Reflection mapping for equirectangular textures. * * @type {number} * @constant */ const EquirectangularReflectionMapping = 303; /** * Refraction mapping for equirectangular textures. * * @type {number} * @constant */ const EquirectangularRefractionMapping = 304; /** * Reflection mapping for PMREM textures. * * @type {number} * @constant */ const CubeUVReflectionMapping = 306; /** * The texture will simply repeat to infinity. * * @type {number} * @constant */ const RepeatWrapping = 1000; /** * The last pixel of the texture stretches to the edge of the mesh. * * @type {number} * @constant */ const ClampToEdgeWrapping = 1001; /** * The texture will repeats to infinity, mirroring on each repeat. * * @type {number} * @constant */ const MirroredRepeatWrapping = 1002; /** * Returns the value of the texture element that is nearest (in Manhattan distance) * to the specified texture coordinates. * * @type {number} * @constant */ const NearestFilter = 1003; /** * Chooses the mipmap that most closely matches the size of the pixel being textured * and uses the `NearestFilter` criterion (the texel nearest to the center of the pixel) * to produce a texture value. * * @type {number} * @constant */ const NearestMipmapNearestFilter = 1004; /** * Chooses the two mipmaps that most closely match the size of the pixel being textured and * uses the `NearestFilter` criterion to produce a texture value from each mipmap. * The final texture value is a weighted average of those two values. * * @type {number} * @constant */ const NearestMipmapLinearFilter = 1005; /** * Returns the weighted average of the four texture elements that are closest to the specified * texture coordinates, and can include items wrapped or repeated from other parts of a texture, * depending on the values of `wrapS` and `wrapT`, and on the exact mapping. * * @type {number} * @constant */ const LinearFilter = 1006; /** * Chooses the mipmap that most closely matches the size of the pixel being textured and uses * the `LinearFilter` criterion (a weighted average of the four texels that are closest to the * center of the pixel) to produce a texture value. * * @type {number} * @constant */ const LinearMipmapNearestFilter = 1007; /** * Chooses the two mipmaps that most closely match the size of the pixel being textured and uses * the `LinearFilter` criterion to produce a texture value from each mipmap. The final texture value * is a weighted average of those two values. * * @type {number} * @constant */ const LinearMipmapLinearFilter = 1008; /** * An unsigned byte data type for textures. * * @type {number} * @constant */ const UnsignedByteType = 1009; /** * A byte data type for textures. * * @type {number} * @constant */ const ByteType = 1010; /** * A short data type for textures. * * @type {number} * @constant */ const ShortType = 1011; /** * An unsigned short data type for textures. * * @type {number} * @constant */ const UnsignedShortType = 1012; /** * An int data type for textures. * * @type {number} * @constant */ const IntType = 1013; /** * An unsigned int data type for textures. * * @type {number} * @constant */ const UnsignedIntType = 1014; /** * A float data type for textures. * * @type {number} * @constant */ const FloatType = 1015; /** * A half float data type for textures. * * @type {number} * @constant */ const HalfFloatType = 1016; /** * An unsigned short 4_4_4_4 (packed) data type for textures. * * @type {number} * @constant */ const UnsignedShort4444Type = 1017; /** * An unsigned short 5_5_5_1 (packed) data type for textures. * * @type {number} * @constant */ const UnsignedShort5551Type = 1018; /** * An unsigned int 24_8 data type for textures. * * @type {number} * @constant */ const UnsignedInt248Type = 1020; /** * An unsigned int 5_9_9_9 (packed) data type for textures. * * @type {number} * @constant */ const UnsignedInt5999Type = 35902; /** * Discards the red, green and blue components and reads just the alpha component. * * @type {number} * @constant */ const AlphaFormat = 1021; /** * Discards the alpha component and reads the red, green and blue component. * * @type {number} * @constant */ const RGBFormat = 1022; /** * Reads the red, green, blue and alpha components. * * @type {number} * @constant */ const RGBAFormat = 1023; /** * Reads each element as a single depth value, converts it to floating point, and clamps to the range `[0,1]`. * * @type {number} * @constant */ const DepthFormat = 1026; /** * Reads each element is a pair of depth and stencil values. The depth component of the pair is interpreted as * in `DepthFormat`. The stencil component is interpreted based on the depth + stencil internal format. * * @type {number} * @constant */ const DepthStencilFormat = 1027; /** * Discards the green, blue and alpha components and reads just the red component. * * @type {number} * @constant */ const RedFormat = 1028; /** * Discards the green, blue and alpha components and reads just the red component. The texels are read as integers instead of floating point. * * @type {number} * @constant */ const RedIntegerFormat = 1029; /** * Discards the alpha, and blue components and reads the red, and green components. * * @type {number} * @constant */ const RGFormat = 1030; /** * Discards the alpha, and blue components and reads the red, and green components. The texels are read as integers instead of floating point. * * @type {number} * @constant */ const RGIntegerFormat = 1031; /** * Reads the red, green, blue and alpha components. The texels are read as integers instead of floating point. * * @type {number} * @constant */ const RGBAIntegerFormat = 1033; /** * A DXT1-compressed image in an RGB image format. * * @type {number} * @constant */ const RGB_S3TC_DXT1_Format = 33776; /** * A DXT1-compressed image in an RGB image format with a simple on/off alpha value. * * @type {number} * @constant */ const RGBA_S3TC_DXT1_Format = 33777; /** * A DXT3-compressed image in an RGBA image format. Compared to a 32-bit RGBA texture, it offers 4:1 compression. * * @type {number} * @constant */ const RGBA_S3TC_DXT3_Format = 33778; /** * A DXT5-compressed image in an RGBA image format. It also provides a 4:1 compression, but differs to the DXT3 * compression in how the alpha compression is done. * * @type {number} * @constant */ const RGBA_S3TC_DXT5_Format = 33779; /** * PVRTC RGB compression in 4-bit mode. One block for each 4×4 pixels. * * @type {number} * @constant */ const RGB_PVRTC_4BPPV1_Format = 35840; /** * PVRTC RGB compression in 2-bit mode. One block for each 8×4 pixels. * * @type {number} * @constant */ const RGB_PVRTC_2BPPV1_Format = 35841; /** * PVRTC RGBA compression in 4-bit mode. One block for each 4×4 pixels. * * @type {number} * @constant */ const RGBA_PVRTC_4BPPV1_Format = 35842; /** * PVRTC RGBA compression in 2-bit mode. One block for each 8×4 pixels. * * @type {number} * @constant */ const RGBA_PVRTC_2BPPV1_Format = 35843; /** * ETC1 RGB format. * * @type {number} * @constant */ const RGB_ETC1_Format = 36196; /** * ETC2 RGB format. * * @type {number} * @constant */ const RGB_ETC2_Format = 37492; /** * ETC2 RGBA format. * * @type {number} * @constant */ const RGBA_ETC2_EAC_Format = 37496; /** * ASTC RGBA 4x4 format. * * @type {number} * @constant */ const RGBA_ASTC_4x4_Format = 37808; /** * ASTC RGBA 5x4 format. * * @type {number} * @constant */ const RGBA_ASTC_5x4_Format = 37809; /** * ASTC RGBA 5x5 format. * * @type {number} * @constant */ const RGBA_ASTC_5x5_Format = 37810; /** * ASTC RGBA 6x5 format. * * @type {number} * @constant */ const RGBA_ASTC_6x5_Format = 37811; /** * ASTC RGBA 6x6 format. * * @type {number} * @constant */ const RGBA_ASTC_6x6_Format = 37812; /** * ASTC RGBA 8x5 format. * * @type {number} * @constant */ const RGBA_ASTC_8x5_Format = 37813; /** * ASTC RGBA 8x6 format. * * @type {number} * @constant */ const RGBA_ASTC_8x6_Format = 37814; /** * ASTC RGBA 8x8 format. * * @type {number} * @constant */ const RGBA_ASTC_8x8_Format = 37815; /** * ASTC RGBA 10x5 format. * * @type {number} * @constant */ const RGBA_ASTC_10x5_Format = 37816; /** * ASTC RGBA 10x6 format. * * @type {number} * @constant */ const RGBA_ASTC_10x6_Format = 37817; /** * ASTC RGBA 10x8 format. * * @type {number} * @constant */ const RGBA_ASTC_10x8_Format = 37818; /** * ASTC RGBA 10x10 format. * * @type {number} * @constant */ const RGBA_ASTC_10x10_Format = 37819; /** * ASTC RGBA 12x10 format. * * @type {number} * @constant */ const RGBA_ASTC_12x10_Format = 37820; /** * ASTC RGBA 12x12 format. * * @type {number} * @constant */ const RGBA_ASTC_12x12_Format = 37821; /** * BPTC RGBA format. * * @type {number} * @constant */ const RGBA_BPTC_Format = 36492; /** * BPTC Signed RGB format. * * @type {number} * @constant */ const RGB_BPTC_SIGNED_Format = 36494; /** * BPTC Unsigned RGB format. * * @type {number} * @constant */ const RGB_BPTC_UNSIGNED_Format = 36495; /** * RGTC1 Red format. * * @type {number} * @constant */ const RED_RGTC1_Format = 36283; /** * RGTC1 Signed Red format. * * @type {number} * @constant */ const SIGNED_RED_RGTC1_Format = 36284; /** * RGTC2 Red Green format. * * @type {number} * @constant */ const RED_GREEN_RGTC2_Format = 36285; /** * RGTC2 Signed Red Green format. * * @type {number} * @constant */ const SIGNED_RED_GREEN_RGTC2_Format = 36286; /** * Basic depth packing. * * @type {number} * @constant */ const BasicDepthPacking = 3200; /** * A depth value is packed into 32 bit RGBA. * * @type {number} * @constant */ const RGBADepthPacking = 3201; /** * Normal information is relative to the underlying surface. * * @type {number} * @constant */ const TangentSpaceNormalMap = 0; /** * Normal information is relative to the object orientation. * * @type {number} * @constant */ const ObjectSpaceNormalMap = 1; // Color space string identifiers, matching CSS Color Module Level 4 and WebGPU names where available. /** * No color space. * * @type {string} * @constant */ const NoColorSpace = ''; /** * sRGB color space. * * @type {string} * @constant */ const SRGBColorSpace = 'srgb'; /** * sRGB-linear color space. * * @type {string} * @constant */ const LinearSRGBColorSpace = 'srgb-linear'; /** * Linear transfer function. * * @type {string} * @constant */ const LinearTransfer = 'linear'; /** * sRGB transfer function. * * @type {string} * @constant */ const SRGBTransfer = 'srgb'; /** * Keeps the current value. * * @type {number} * @constant */ const KeepStencilOp = 7680; /** * Will always return true. * * @type {number} * @constant */ const AlwaysStencilFunc = 519; /** * Never pass. * * @type {number} * @constant */ const NeverCompare = 512; /** * Pass if the incoming value is less than the texture value. * * @type {number} * @constant */ const LessCompare = 513; /** * Pass if the incoming value equals the texture value. * * @type {number} * @constant */ const EqualCompare = 514; /** * Pass if the incoming value is less than or equal to the texture value. * * @type {number} * @constant */ const LessEqualCompare = 515; /** * Pass if the incoming value is greater than the texture value. * * @type {number} * @constant */ const GreaterCompare = 516; /** * Pass if the incoming value is not equal to the texture value. * * @type {number} * @constant */ const NotEqualCompare = 517; /** * Pass if the incoming value is greater than or equal to the texture value. * * @type {number} * @constant */ const GreaterEqualCompare = 518; /** * Always pass. * * @type {number} * @constant */ const AlwaysCompare = 519; /** * The contents are intended to be specified once by the application, and used many * times as the source for drawing and image specification commands. * * @type {number} * @constant */ const StaticDrawUsage = 35044; /** * GLSL 3 shader code. * * @type {string} * @constant */ const GLSL3 = '300 es'; /** * WebGL coordinate system. * * @type {number} * @constant */ const WebGLCoordinateSystem = 2000; /** * WebGPU coordinate system. * * @type {number} * @constant */ const WebGPUCoordinateSystem = 2001; /** * This type represents mouse buttons and interaction types in context of controls. * * @typedef {Object} ConstantsMouse * @property {number} MIDDLE - The left mouse button. * @property {number} LEFT - The middle mouse button. * @property {number} RIGHT - The right mouse button. * @property {number} ROTATE - A rotate interaction. * @property {number} DOLLY - A dolly interaction. * @property {number} PAN - A pan interaction. **/ /** * This type represents touch interaction types in context of controls. * * @typedef {Object} ConstantsTouch * @property {number} ROTATE - A rotate interaction. * @property {number} PAN - A pan interaction. * @property {number} DOLLY_PAN - The dolly-pan interaction. * @property {number} DOLLY_ROTATE - A dolly-rotate interaction. **/ /** * This type represents the different timestamp query types. * * @typedef {Object} ConstantsTimestampQuery * @property {string} COMPUTE - A `compute` timestamp query. * @property {string} RENDER - A `render` timestamp query. **/ /** * Represents the different interpolation sampling types. * * @typedef {Object} ConstantsInterpolationSamplingType * @property {string} PERSPECTIVE - Perspective-correct interpolation. * @property {string} LINEAR - Linear interpolation. * @property {string} FLAT - Flat interpolation. */ /** * Represents the different interpolation sampling modes. * * @typedef {Object} ConstantsInterpolationSamplingMode * @property {string} NORMAL - Normal sampling mode. * @property {string} CENTROID - Centroid sampling mode. * @property {string} SAMPLE - Sample-specific sampling mode. * @property {string} FLAT_FIRST - Flat interpolation using the first vertex. * @property {string} FLAT_EITHER - Flat interpolation using either vertex. */ /** * This modules allows to dispatch event objects on custom JavaScript objects. * * Main repository: [eventdispatcher.js]{@link https://github.com/mrdoob/eventdispatcher.js/} * * Code Example: * ```js * class Car extends EventDispatcher { * start() { * this.dispatchEvent( { type: 'start', message: 'vroom vroom!' } ); * } *}; * * // Using events with the custom object * const car = new Car(); * car.addEventListener( 'start', function ( event ) { * alert( event.message ); * } ); * * car.start(); * ``` */ class EventDispatcher { /** * Adds the given event listener to the given event type. * * @param {string} type - The type of event to listen to. * @param {Function} listener - The function that gets called when the event is fired. */ addEventListener( type, listener ) { if ( this._listeners === undefined ) this._listeners = {}; const listeners = this._listeners; if ( listeners[ type ] === undefined ) { listeners[ type ] = []; } if ( listeners[ type ].indexOf( listener ) === -1 ) { listeners[ type ].push( listener ); } } /** * Returns `true` if the given event listener has been added to the given event type. * * @param {string} type - The type of event. * @param {Function} listener - The listener to check. * @return {boolean} Whether the given event listener has been added to the given event type. */ hasEventListener( type, listener ) { const listeners = this._listeners; if ( listeners === undefined ) return false; return listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== -1; } /** * Removes the given event listener from the given event type. * * @param {string} type - The type of event. * @param {Function} listener - The listener to remove. */ removeEventListener( type, listener ) { const listeners = this._listeners; if ( listeners === undefined ) return; const listenerArray = listeners[ type ]; if ( listenerArray !== undefined ) { const index = listenerArray.indexOf( listener ); if ( index !== -1 ) { listenerArray.splice( index, 1 ); } } } /** * Dispatches an event object. * * @param {Object} event - The event that gets fired. */ dispatchEvent( event ) { const listeners = this._listeners; if ( listeners === undefined ) return; const listenerArray = listeners[ event.type ]; if ( listenerArray !== undefined ) { event.target = this; // Make a copy, in case listeners are removed while iterating. const array = listenerArray.slice( 0 ); for ( let i = 0, l = array.length; i < l; i ++ ) { array[ i ].call( this, event ); } event.target = null; } } } const _lut = [ '00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '0a', '0b', '0c', '0d', '0e', '0f', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '1a', '1b', '1c', '1d', '1e', '1f', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '2a', '2b', '2c', '2d', '2e', '2f', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '3a', '3b', '3c', '3d', '3e', '3f', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '4a', '4b', '4c', '4d', '4e', '4f', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '5a', '5b', '5c', '5d', '5e', '5f', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '6a', '6b', '6c', '6d', '6e', '6f', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '7a', '7b', '7c', '7d', '7e', '7f', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '8a', '8b', '8c', '8d', '8e', '8f', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '9a', '9b', '9c', '9d', '9e', '9f', 'a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a8', 'a9', 'aa', 'ab', 'ac', 'ad', 'ae', 'af', 'b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'b9', 'ba', 'bb', 'bc', 'bd', 'be', 'bf', 'c0', 'c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7', 'c8', 'c9', 'ca', 'cb', 'cc', 'cd', 'ce', 'cf', 'd0', 'd1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8', 'd9', 'da', 'db', 'dc', 'dd', 'de', 'df', 'e0', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6', 'e7', 'e8', 'e9', 'ea', 'eb', 'ec', 'ed', 'ee', 'ef', 'f0', 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'fa', 'fb', 'fc', 'fd', 'fe', 'ff' ]; const DEG2RAD = Math.PI / 180; const RAD2DEG = 180 / Math.PI; /** * Generate a [UUID]{@link https://en.wikipedia.org/wiki/Universally_unique_identifier} * (universally unique identifier). * * @return {string} The UUID. */ function generateUUID() { // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/21963136#21963136 const d0 = Math.random() * 0xffffffff | 0; const d1 = Math.random() * 0xffffffff | 0; const d2 = Math.random() * 0xffffffff | 0; const d3 = Math.random() * 0xffffffff | 0; const uuid = _lut[ d0 & 0xff ] + _lut[ d0 >> 8 & 0xff ] + _lut[ d0 >> 16 & 0xff ] + _lut[ d0 >> 24 & 0xff ] + '-' + _lut[ d1 & 0xff ] + _lut[ d1 >> 8 & 0xff ] + '-' + _lut[ d1 >> 16 & 0x0f | 0x40 ] + _lut[ d1 >> 24 & 0xff ] + '-' + _lut[ d2 & 0x3f | 0x80 ] + _lut[ d2 >> 8 & 0xff ] + '-' + _lut[ d2 >> 16 & 0xff ] + _lut[ d2 >> 24 & 0xff ] + _lut[ d3 & 0xff ] + _lut[ d3 >> 8 & 0xff ] + _lut[ d3 >> 16 & 0xff ] + _lut[ d3 >> 24 & 0xff ]; // .toLowerCase() here flattens concatenated strings to save heap memory space. return uuid.toLowerCase(); } /** * Clamps the given value between min and max. * * @param {number} value - The value to clamp. * @param {number} min - The min value. * @param {number} max - The max value. * @return {number} The clamped value. */ function clamp( value, min, max ) { return Math.max( min, Math.min( max, value ) ); } /** * Computes the Euclidean modulo of the given parameters that * is `( ( n % m ) + m ) % m`. * * @param {number} n - The first parameter. * @param {number} m - The second parameter. * @return {number} The Euclidean modulo. */ function euclideanModulo( n, m ) { // https://en.wikipedia.org/wiki/Modulo_operation return ( ( n % m ) + m ) % m; } /** * Returns a value linearly interpolated from two known points based on the given interval - * `t = 0` will return `x` and `t = 1` will return `y`. * * @param {number} x - The start point * @param {number} y - The end point. * @param {number} t - The interpolation factor in the closed interval `[0, 1]`. * @return {number} The interpolated value. */ function lerp( x, y, t ) { return ( 1 - t ) * x + t * y; } /** * Denormalizes the given value according to the given typed array. * * @param {number} value - The value to denormalize. * @param {TypedArray} array - The typed array that defines the data type of the value. * @return {number} The denormalize (float) value in the range `[0,1]`. */ function denormalize( value, array ) { switch ( array.constructor ) { case Float32Array: return value; case Uint32Array: return value / 4294967295.0; case Uint16Array: return value / 65535.0; case Uint8Array: return value / 255.0; case Int32Array: return Math.max( value / 2147483647.0, -1 ); case Int16Array: return Math.max( value / 32767.0, -1 ); case Int8Array: return Math.max( value / 127.0, -1 ); default: throw new Error( 'Invalid component type.' ); } } /** * Normalizes the given value according to the given typed array. * * @param {number} value - The float value in the range `[0,1]` to normalize. * @param {TypedArray} array - The typed array that defines the data type of the value. * @return {number} The normalize value. */ function normalize( value, array ) { switch ( array.constructor ) { case Float32Array: return value; case Uint32Array: return Math.round( value * 4294967295.0 ); case Uint16Array: return Math.round( value * 65535.0 ); case Uint8Array: return Math.round( value * 255.0 ); case Int32Array: return Math.round( value * 2147483647.0 ); case Int16Array: return Math.round( value * 32767.0 ); case Int8Array: return Math.round( value * 127.0 ); default: throw new Error( 'Invalid component type.' ); } } /** * Class representing a 2D vector. A 2D vector is an ordered pair of numbers * (labeled x and y), which can be used to represent a number of things, such as: * * - A point in 2D space (i.e. a position on a plane). * - A direction and length across a plane. In three.js the length will * always be the Euclidean distance(straight-line distance) from `(0, 0)` to `(x, y)` * and the direction is also measured from `(0, 0)` towards `(x, y)`. * - Any arbitrary ordered pair of numbers. * * There are other things a 2D vector can be used to represent, such as * momentum vectors, complex numbers and so on, however these are the most * common uses in three.js. * * Iterating through a vector instance will yield its components `(x, y)` in * the corresponding order. * ```js * const a = new THREE.Vector2( 0, 1 ); * * //no arguments; will be initialised to (0, 0) * const b = new THREE.Vector2( ); * * const d = a.distanceTo( b ); * ``` */ class Vector2 { /** * Constructs a new 2D vector. * * @param {number} [x=0] - The x value of this vector. * @param {number} [y=0] - The y value of this vector. */ constructor( x = 0, y = 0 ) { /** * This flag can be used for type testing. * * @type {boolean} * @readonly * @default true */ Vector2.prototype.isVector2 = true; /** * The x value of this vector. * * @type {number} */ this.x = x; /** * The y value of this vector. * * @type {number} */ this.y = y; } /** * Alias for {@link Vector2#x}. * * @type {number} */ get width() { return this.x; } set width( value ) { this.x = value; } /** * Alias for {@link Vector2#y}. * * @type {number} */ get height() { return this.y; } set height( value ) { this.y = value; } /** * Sets the vector components. * * @param {number} x - The value of the x component. * @param {number} y - The value of the y component. * @return {Vector2} A reference to this vector. */ set( x, y ) { this.x = x; this.y = y; return this; } /** * Sets the vector components to the same value. * * @param {number} scalar - The value to set for all vector components. * @return {Vector2} A reference to this vector. */ setScalar( scalar ) { this.x = scalar; this.y = scalar; return this; } /** * Sets the vector's x component to the given value * * @param {number} x - The value to set. * @return {Vector2} A reference to this vector. */ setX( x ) { this.x = x; return this; } /** * Sets the vector's y component to the given value * * @param {number} y - The value to set. * @return {Vector2} A reference to this vector. */ setY( y ) { this.y = y; return this; } /** * Allows to set a vector component with an index. * * @param {number} index - The component index. `0` equals to x, `1` equals to y. * @param {number} value - The value to set. * @return {Vector2} A reference to this vector. */ setComponent( index, value ) { switch ( index ) { case 0: this.x = value; break; case 1: this.y = value; break; default: throw new Error( 'index is out of range: ' + index ); } return this; } /** * Returns the value of the vector component which matches the given index. * * @param {number} index - The component index. `0` equals to x, `1` equals to y. * @return {number} A vector component value. */ getComponent( index ) { switch ( index ) { case 0: return this.x; case 1: return this.y; default: throw new Error( 'index is out of range: ' + index ); } } /** * Returns a new vector with copied values from this instance. * * @return {Vector2} A clone of this instance. */ clone() { return new this.constructor( this.x, this.y ); } /** * Copies the values of the given vector to this instance. * * @param {Vector2} v - The vector to copy. * @return {Vector2} A reference to this vector. */ copy( v ) { this.x = v.x; this.y = v.y; return this; } /** * Adds the given vector to this instance. * * @param {Vector2} v - The vector to add. * @return {Vector2} A reference to this vector. */ add( v ) { this.x += v.x; this.y += v.y; return this; } /** * Adds the given scalar value to all components of this instance. * * @param {number} s - The scalar to add. * @return {Vector2} A reference to this vector. */ addScalar( s ) { this.x += s; this.y += s; return this; } /** * Adds the given vectors and stores the result in this instance. * * @param {Vector2} a - The first vector. * @param {Vector2} b - The second vector. * @return {Vector2} A reference to this vector. */ addVectors( a, b ) { this.x = a.x + b.x; this.y = a.y + b.y; return this; } /** * Adds the given vector scaled by the given factor to this instance. * * @param {Vector2} v - The vector. * @param {number} s - The factor that scales `v`. * @return {Vector2} A reference to this vector. */ addScaledVector( v, s ) { this.x += v.x * s; this.y += v.y * s; return this; } /** * Subtracts the given vector from this instance. * * @param {Vector2} v - The vector to subtract. * @return {Vector2} A reference to this vector. */ sub( v ) { this.x -= v.x; this.y -= v.y; return this; } /** * Subtracts the given scalar value from all components of this instance. * * @param {number} s - The scalar to subtract. * @return {Vector2} A reference to this vector. */ subScalar( s ) { this.x -= s; this.y -= s; return this; } /** * Subtracts the given vectors and stores the result in this instance. * * @param {Vector2} a - The first vector. * @param {Vector2} b - The second vector. * @return {Vector2} A reference to this vector. */ subVectors( a, b ) { this.x = a.x - b.x; this.y = a.y - b.y; return this; } /** * Multiplies the given vector with this instance. * * @param {Vector2} v - The vector to multiply. * @return {Vector2} A reference to this vector. */ multiply( v ) { this.x *= v.x; this.y *= v.y; return this; } /** * Multiplies the given scalar value with all components of this instance. * * @param {number} scalar - The scalar to multiply. * @return {Vector2} A reference to this vector. */ multiplyScalar( scalar ) { this.x *= scalar; this.y *= scalar; return this; } /** * Divides this instance by the given vector. * * @param {Vector2} v - The vector to divide. * @return {Vector2} A reference to this vector. */ divide( v ) { this.x /= v.x; this.y /= v.y; return this; } /** * Divides this vector by the given scalar. * * @param {number} scalar - The scalar to divide. * @return {Vector2} A reference to this vector. */ divideScalar( scalar ) { return this.multiplyScalar( 1 / scalar ); } /** * Multiplies this vector (with an implicit 1 as the 3rd component) by * the given 3x3 matrix. * * @param {Matrix3} m - The matrix to apply. * @return {Vector2} A reference to this vector. */ applyMatrix3( m ) { const x = this.x, y = this.y; const e = m.elements; this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ]; this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ]; return this; } /** * If this vector's x or y value is greater than the given vector's x or y * value, replace that value with the corresponding min value. * * @param {Vector2} v - The vector. * @return {Vector2} A reference to this vector. */ min( v ) { this.x = Math.min( this.x, v.x ); this.y = Math.min( this.y, v.y ); return this; } /** * If this vector's x or y value is less than the given vector's x or y * value, replace that value with the corresponding max value. * * @param {Vector2} v - The vector. * @return {Vector2} A reference to this vector. */ max( v ) { this.x = Math.max( this.x, v.x ); this.y = Math.max( this.y, v.y ); return this; } /** * If this vector's x or y value is greater than the max vector's x or y * value, it is replaced by the corresponding value. * If this vector's x or y value is less than the min vector's x or y value, * it is replaced by the corresponding value. * * @param {Vector2} min - The minimum x and y values. * @param {Vector2} max - The maximum x and y values in the desired range. * @return {Vector2} A reference to this vector. */ clamp( min, max ) { // assumes min < max, componentwise this.x = clamp( this.x, min.x, max.x ); this.y = clamp( this.y, min.y, max.y ); return this; } /** * If this vector's x or y values are greater than the max value, they are * replaced by the max value. * If this vector's x or y values are less than the min value, they are * replaced by the min value. * * @param {number} minVal - The minimum value the components will be clamped to. * @param {number} maxVal - The maximum value the components will be clamped to. * @return {Vector2} A reference to this vector. */ clampScalar( minVal, maxVal ) { this.x = clamp( this.x, minVal, maxVal ); this.y = clamp( this.y, minVal, maxVal ); return this; } /** * If this vector's length is greater than the max value, it is replaced by * the max value. * If this vector's length is less than the min value, it is replaced by the * min value. * * @param {number} min - The minimum value the vector length will be clamped to. * @param {number} max - The maximum value the vector length will be clamped to. * @return {Vector2} A reference to this vector. */ clampLength( min, max ) { const length = this.length(); return this.divideScalar( length || 1 ).multiplyScalar( clamp( length, min, max ) ); } /** * The components of this vector are rounded down to the nearest integer value. * * @return {Vector2} A reference to this vector. */ floor() { this.x = Math.floor( this.x ); this.y = Math.floor( this.y ); return this; } /** * The components of this vector are rounded up to the nearest integer value. * * @return {Vector2} A reference to this vector. */ ceil() { this.x = Math.ceil( this.x ); this.y = Math.ceil( this.y ); return this; } /** * The components of this vector are rounded to the nearest integer value * * @return {Vector2} A reference to this vector. */ round() { this.x = Math.round( this.x ); this.y = Math.round( this.y ); return this; } /** * The components of this vector are rounded towards zero (up if negative, * down if positive) to an integer value. * * @return {Vector2} A reference to this vector. */ roundToZero() { this.x = Math.trunc( this.x ); this.y = Math.trunc( this.y ); return this; } /** * Inverts this vector - i.e. sets x = -x and y = -y. * * @return {Vector2} A reference to this vector. */ negate() { this.x = - this.x; this.y = - this.y; return this; } /** * Calculates the dot product of the given vector with this instance. * * @param {Vector2} v - The vector to compute the dot product with. * @return {number} The result of the dot product. */ dot( v ) { return this.x * v.x + this.y * v.y; } /** * Calculates the cross product of the given vector with this instance. * * @param {Vector2} v - The vector to compute the cross product with. * @return {number} The result of the cross product. */ cross( v ) { return this.x * v.y - this.y * v.x; } /** * Computes the square of the Euclidean length (straight-line length) from * (0, 0) to (x, y). If you are comparing the lengths of vectors, you should * compare the length squared instead as it is slightly more efficient to calculate. * * @return {number} The square length of this vector. */ lengthSq() { return this.x * this.x + this.y * this.y; } /** * Computes the Euclidean length (straight-line length) from (0, 0) to (x, y). * * @return {number} The length of this vector. */ length() { return Math.sqrt( this.x * this.x + this.y * this.y ); } /** * Computes the Manhattan length of this vector. * * @return {number} The length of this vector. */ manhattanLength() { return Math.abs( this.x ) + Math.abs( this.y ); } /** * Converts this vector to a unit vector - that is, sets it equal to a vector * with the same direction as this one, but with a vector length of `1`. * * @return {Vector2} A reference to this vector. */ normalize() { return this.divideScalar( this.length() || 1 ); } /** * Computes the angle in radians of this vector with respect to the positive x-axis. * * @return {number} The angle in radians. */ angle() { const angle = Math.atan2( - this.y, - this.x ) + Math.PI; return angle; } /** * Returns the angle between the given vector and this instance in radians. * * @param {Vector2} v - The vector to compute the angle with. * @return {number} The angle in radians. */ angleTo( v ) { const denominator = Math.sqrt( this.lengthSq() * v.lengthSq() ); if ( denominator === 0 ) return Math.PI / 2; const theta = this.dot( v ) / denominator; // clamp, to handle numerical problems return Math.acos( clamp( theta, -1, 1 ) ); } /** * Computes the distance from the given vector to this instance. * * @param {Vector2} v - The vector to compute the distance to. * @return {number} The distance. */ distanceTo( v ) { return Math.sqrt( this.distanceToSquared( v ) ); } /** * Computes the squared distance from the given vector to this instance. * If you are just comparing the distance with another distance, you should compare * the distance squared instead as it is slightly more efficient to calculate. * * @param {Vector2} v - The vector to compute the squared distance to. * @return {number} The squared distance. */ distanceToSquared( v ) { const dx = this.x - v.x, dy = this.y - v.y; return dx * dx + dy * dy; } /** * Computes the Manhattan distance from the given vector to this instance. * * @param {Vector2} v - The vector to compute the Manhattan distance to. * @return {number} The Manhattan distance. */ manhattanDistanceTo( v ) { return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ); } /** * Sets this vector to a vector with the same direction as this one, but * with the specified length. * * @param {number} length - The new length of this vector. * @return {Vector2} A reference to this vector. */ setLength( length ) { return this.normalize().multiplyScalar( length ); } /** * Linearly interpolates between the given vector and this instance, where * alpha is the percent distance along the line - alpha = 0 will be this * vector, and alpha = 1 will be the given one. * * @param {Vector2} v - The vector to interpolate towards. * @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`. * @return {Vector2} A reference to this vector. */ lerp( v, alpha ) { this.x += ( v.x - this.x ) * alpha; this.y += ( v.y - this.y ) * alpha; return this; } /** * Linearly interpolates between the given vectors, where alpha is the percent * distance along the line - alpha = 0 will be first vector, and alpha = 1 will * be the second one. The result is stored in this instance. * * @param {Vector2} v1 - The first vector. * @param {Vector2} v2 - The second vector. * @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`. * @return {Vector2} A reference to this vector. */ lerpVectors( v1, v2, alpha ) { this.x = v1.x + ( v2.x - v1.x ) * alpha; this.y = v1.y + ( v2.y - v1.y ) * alpha; return this; } /** * Returns `true` if this vector is equal with the given one. * * @param {Vector2} v - The vector to test for equality. * @return {boolean} Whether this vector is equal with the given one. */ equals( v ) { return ( ( v.x === this.x ) && ( v.y === this.y ) ); } /** * Sets this vector's x value to be `array[ offset ]` and y * value to be `array[ offset + 1 ]`. * * @param {Array<number>} array - An array holding the vector component values. * @param {number} [offset=0] - The offset into the array. * @return {Vector2} A reference to this vector. */ fromArray( array, offset = 0 ) { this.x = array[ offset ]; this.y = array[ offset + 1 ]; return this; } /** * Writes the components of this vector to the given array. If no array is provided, * the method returns a new instance. * * @param {Array<number>} [array=[]] - The target array holding the vector components. * @param {number} [offset=0] - Index of the first element in the array. * @return {Array<number>} The vector components. */ toArray( array = [], offset = 0 ) { array[ offset ] = this.x; array[ offset + 1 ] = this.y; return array; } /** * Sets the components of this vector from the given buffer attribute. * * @param {BufferAttribute} attribute - The buffer attribute holding vector data. * @param {number} index - The index into the attribute. * @return {Vector2} A reference to this vector. */ fromBufferAttribute( attribute, index ) { this.x = attribute.getX( index ); this.y = attribute.getY( index ); return this; } /** * Rotates this vector around the given center by the given angle. * * @param {Vector2} center - The point around which to rotate. * @param {number} angle - The angle to rotate, in radians. * @return {Vector2} A reference to this vector. */ rotateAround( center, angle ) { const c = Math.cos( angle ), s = Math.sin( angle ); const x = this.x - center.x; const y = this.y - center.y; this.x = x * c - y * s + center.x; this.y = x * s + y * c + center.y; return this; } /** * Sets each component of this vector to a pseudo-random value between `0` and * `1`, excluding `1`. * * @return {Vector2} A reference to this vector. */ random() { this.x = Math.random(); this.y = Math.random(); return this; } *[ Symbol.iterator ]() { yield this.x; yield this.y; } } /** * Class for representing a Quaternion. Quaternions are used in three.js to represent rotations. * * Iterating through a vector instance will yield its components `(x, y, z, w)` in * the corresponding order. * * Note that three.js expects Quaternions to be normalized. * ```js * const quaternion = new THREE.Quaternion(); * quaternion.setFromAxisAngle( new THREE.Vector3( 0, 1, 0 ), Math.PI / 2 ); * * const vector = new THREE.Vector3( 1, 0, 0 ); * vector.applyQuaternion( quaternion ); * ``` */ class Quaternion { /** * Constructs a new quaternion. * * @param {number} [x=0] - The x value of this quaternion. * @param {number} [y=0] - The y value of this quaternion. * @param {number} [z=0] - The z value of this quaternion. * @param {number} [w=1] - The w value of this quaternion. */ constructor( x = 0, y = 0, z = 0, w = 1 ) { /** * This flag can be used for type testing. * * @type {boolean} * @readonly * @default true */ this.isQuaternion = true; this._x = x; this._y = y; this._z = z; this._w = w; } /** * Interpolates between two quaternions via SLERP. This implementation assumes the * quaternion data are managed in flat arrays. * * @param {Array<number>} dst - The destination array. * @param {number} dstOffset - An offset into the destination array. * @param {Array<number>} src0 - The source array of the first quaternion. * @param {number} srcOffset0 - An offset into the first source array. * @param {Array<number>} src1 - The source array of the second quaternion. * @param {number} srcOffset1 - An offset into the second source array. * @param {number} t - The interpolation factor in the range `[0,1]`. * @see {@link Quaternion#slerp} */ static slerpFlat( dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) { // fuzz-free, array-based Quaternion SLERP operation let x0 = src0[ srcOffset0 + 0 ], y0 = src0[ srcOffset0 + 1 ], z0 = src0[