{"version":3,"sources":["webpack://party/webpack/universalModuleDefinition","webpack://party/./src/components/circle.ts","webpack://party/./src/components/color.ts","webpack://party/./src/components/gradient.ts","webpack://party/./src/components/index.ts","webpack://party/./src/components/numericSpline.ts","webpack://party/./src/components/rect.ts","webpack://party/./src/components/spline.ts","webpack://party/./src/components/vector.ts","webpack://party/./src/containers.ts","webpack://party/./src/debug.ts","webpack://party/./src/index.ts","webpack://party/./src/particles/emitter.ts","webpack://party/./src/particles/options/emissionOptions.ts","webpack://party/./src/particles/options/emitterOptions.ts","webpack://party/./src/particles/options/index.ts","webpack://party/./src/particles/options/renderOptions.ts","webpack://party/./src/particles/particle.ts","webpack://party/./src/particles/renderer.ts","webpack://party/./src/scene.ts","webpack://party/./src/settings.ts","webpack://party/./src/systems/math.ts","webpack://party/./src/systems/modules.ts","webpack://party/./src/systems/random.ts","webpack://party/./src/systems/shapes.ts","webpack://party/./src/systems/sources.ts","webpack://party/./src/systems/variation.ts","webpack://party/./src/templates/confetti.ts","webpack://party/./src/templates/index.ts","webpack://party/./src/templates/sparkles.ts","webpack://party/./src/util/config.ts","webpack://party/./src/util/index.ts","webpack://party/./src/util/lazy.ts","webpack://party/./src/util/rotation.ts","webpack://party/./src/util/rules.ts","webpack://party/webpack/bootstrap","webpack://party/webpack/startup"],"names":["root","factory","exports","module","define","amd","self","x","y","radius","this","zero","Circle","r","g","b","values","Float32Array","rgb","value","Math","floor","mix","color","weight","Color","lerp","toHex","hex","v","toString","padStart","join","fromHex","startsWith","substr","parseInt","fromHsl","h","s","l","hue2rgb","p","q","t","to255","min","white","black","interpolate","a","solid","Gradient","time","simple","step","colors","length","map","index","Spline","slerp","NumericSpline","width","height","fromScreen","Rect","window","scrollX","scrollY","innerWidth","innerHeight","fromElement","element","getBoundingClientRect","keys","Error","Array","isArray","evaluate","ascendingKeys","sort","upperKeyIndex","findIndex","lowerKey","upperKey","containedTime","invlerp","z","xyz","magnitude","sqrt","sqrMagnitude","add","vector","Vector","subtract","scale","scalar","normalized","angle","rad2deg","acos","cross","dot","cos","deg2rad","from2dAngle","sin","one","right","up","forward","isContainerActive","container","isConnected","makeContainer","name","styles","parent","document","createElement","id","Object","assign","style","appendChild","rootContainer","Lazy","position","left","top","pointerEvents","userSelect","zIndex","settings","body","debugContainer","margin","padding","border","background","fontFamily","current","particleContainer","overflow","perspective","scene","refreshRate","refreshTimer","tick","delta","displayStyle","debug","display","innerHTML","getDebugInformation","emitters","particles","reduce","acc","cur","infos","round","emitterInfos","emitter","options","loops","isExpired","toFixed","push","Debug","Scene","Particle","Emitter","currentLoop","durationTimer","emissionTimer","attemptedBurstIndices","overrideDefaults","getDefaultEmitterOptions","emitterOptions","emission","getDefaultEmissionOptions","emissionOptions","renderer","getDefaultRendererOptions","rendererOptions","clearParticles","splice","duration","burstIndex","bursts","burst","includes","count","evaluateVariation","i","emitParticle","delay","rate","particle","tickParticle","despawningRules","some","rule","lifetime","useGravity","velocity","gravity","location","modules","moduleFunction","sourceSampler","initialLifetime","initialSpeed","size","initialSize","rotation","initialRotation","initialColor","maxParticles","shift","rectSource","bounds","defaultApplyColor","nodeName","toLowerCase","fill","defaultApplyOpacity","opacity","defaultApplyLighting","lighting","filter","abs","defaultApplyTransform","transform","shapeFactory","applyColor","applyOpacity","applyLighting","applyTransform","populatedOptions","Symbol","elements","Map","light","enabled","respectReducedMotion","matchMedia","matches","begin","renderedParticles","end","it","result","next","done","get","remove","delete","renderParticle","has","createParticleElement","lightingCoefficient","rotationToNormal","resolveShapeFactory","cloneNode","set","Renderer","scheduledTickId","undefined","lastTickTimestamp","performance","now","bind","scheduleTick","createEmitter","clearEmitters","sum","requestAnimationFrame","cancelTick","cancelAnimationFrame","timestamp","canRemove","error","console","PI","epsilon","max","factor","isRelative","drive","key","driverKey","through","by","driver","driverValue","relative","build","updateDrivenProperty","evaluateModuleDriver","calculateModuleFactor","initial","toUpperCase","ModuleBuilder","randomRange","random","arr","theta","rect","circle","resolvableShapes","square","rectangle","roundedSquare","roundedRectangle","star","shape","resolved","dummy","firstElementChild","elementSource","source","randomInsideRect","mouseSource","clientX","clientY","circleSource","randomInsideCircle","HTMLElement","MouseEvent","splineSample","spline","variation","pick","amount","percentage","gradient","populated","util","range","spread","speed","skew","randomUnitVector","shapes","sources","dynamicSource","defaults","overrides","exists","defaultExists","alpha","beta","documentElement","scrollHeight","__webpack_module_cache__","__webpack_exports__","__webpack_require__","moduleId","cachedModule","__webpack_modules__","call"],"mappings":"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","file":"party.min.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"party\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"party\"] = factory();\n\telse\n\t\troot[\"party\"] = factory();\n})(self, function() {\nreturn ","/**\r\n * Represents a circle.\r\n */\r\nexport class Circle {\r\n /**\r\n * The x-coordinate of the circle.\r\n */\r\n x: number;\r\n /**\r\n * The y-coordinate of the circle.\r\n */\r\n y: number;\r\n /**\r\n * The radius of the circle.\r\n *\r\n * @defaultValue 0\r\n */\r\n radius: number;\r\n\r\n /**\r\n * Creates a new circle at the specified coordinates, with a default radius of 0.\r\n */\r\n constructor(x: number, y: number, radius = 0) {\r\n this.x = x;\r\n this.y = y;\r\n this.radius = radius;\r\n }\r\n\r\n public static readonly zero = new Circle(0, 0);\r\n}\r\n","import { lerp } from \"../systems/math\";\r\n\r\n/**\r\n * Represents a color consisting of RGB values. The components of it are\r\n * represented as integers in the range 0 to 255.\r\n *\r\n * @example\r\n * ```ts\r\n * const a = new Color(12, 59, 219);\r\n * const b = Color.fromHex(\"#ffa68d\");\r\n * const result = a.mix(b);\r\n * ```\r\n */\r\nexport class Color {\r\n /**\r\n * Returns the r-component of the color.\r\n */\r\n get r(): number {\r\n return this.values[0];\r\n }\r\n /**\r\n * Modifies the r-component of the color.\r\n * Note that this also floors the value.\r\n */\r\n set r(value: number) {\r\n this.values[0] = Math.floor(value);\r\n }\r\n\r\n /**\r\n * Returns the g-component of the color.\r\n */\r\n get g(): number {\r\n return this.values[1];\r\n }\r\n /**\r\n * Modifies the g-component of the color.\r\n * Note that this also floors the value.\r\n */\r\n set g(value: number) {\r\n this.values[1] = Math.floor(value);\r\n }\r\n\r\n /**\r\n * Returns the b-component of the color.\r\n * Note that this also floors the value.\r\n */\r\n get b(): number {\r\n return this.values[2];\r\n }\r\n /**\r\n * Modifies the b-component of the color.\r\n */\r\n set b(value: number) {\r\n this.values[2] = Math.floor(value);\r\n }\r\n\r\n /**\r\n * Returns the rgb-components of the color, bundled as a copied array.\r\n */\r\n get rgb(): [number, number, number] {\r\n return [this.r, this.g, this.b];\r\n }\r\n /**\r\n * Simultaneously updates the rgb-components of the color, by passing an array.\r\n */\r\n set rgb(values: [number, number, number]) {\r\n this.r = values[0];\r\n this.g = values[1];\r\n this.b = values[2];\r\n }\r\n\r\n private values = new Float32Array(3);\r\n\r\n /**\r\n * Creates a new color instance from the specified RGB components.\r\n */\r\n constructor(r: number, g: number, b: number) {\r\n this.rgb = [r, g, b];\r\n }\r\n\r\n /**\r\n * Returns (1, 1, 1).\r\n */\r\n public static readonly white = new Color(255, 255, 255);\r\n /**\r\n * Returns (0, 0, 0).\r\n */\r\n public static readonly black = new Color(0, 0, 0);\r\n\r\n /**\r\n * Mixes the two color together with an optional mixing weight.\r\n * This weight is 0.5 by default, perfectly averaging the color.\r\n */\r\n public mix(color: Color, weight = 0.5): Color {\r\n return new Color(\r\n lerp(this.r, color.r, weight),\r\n lerp(this.g, color.g, weight),\r\n lerp(this.b, color.b, weight)\r\n );\r\n }\r\n\r\n /**\r\n * Returns the hexadecimal representation of the color, prefixed by '#'.\r\n */\r\n public toHex(): string {\r\n const hex = (v: number) => v.toString(16).padStart(2, \"0\");\r\n return \"#\" + hex(this.r) + hex(this.g) + hex(this.b);\r\n }\r\n\r\n /**\r\n * Returns a formatted representation of the color.\r\n */\r\n public toString(): string {\r\n return \"rgb(\" + this.values.join(\", \") + \")\";\r\n }\r\n\r\n /**\r\n * Creates a color from the specified hexadecimal string.\r\n * This string can optionally be prefixed by '#'.\r\n */\r\n public static fromHex(hex: string): Color {\r\n if (hex.startsWith(\"#\")) {\r\n hex = hex.substr(1);\r\n }\r\n return new Color(\r\n parseInt(hex.substr(0, 2), 16),\r\n parseInt(hex.substr(2, 2), 16),\r\n parseInt(hex.substr(4, 2), 16)\r\n );\r\n }\r\n\r\n /**\r\n * Creates a color from the specified HSL components.\r\n *\r\n * @see https://stackoverflow.com/a/9493060/5507624\r\n */\r\n public static fromHsl(h: number, s: number, l: number): Color {\r\n h /= 360;\r\n s /= 100;\r\n l /= 100;\r\n if (s === 0) {\r\n return new Color(l, l, l);\r\n } else {\r\n const hue2rgb = (p: number, q: number, t: number): number => {\r\n if (t < 0) t += 1;\r\n if (t > 1) t -= 1;\r\n if (t < 1 / 6) return p + (q - p) * 6 * t;\r\n if (t < 1 / 2) return q;\r\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\r\n return p;\r\n };\r\n const to255 = (v: number): number => Math.min(255, 256 * v);\r\n\r\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\r\n const p = 2 * l - q;\r\n\r\n return new Color(\r\n to255(hue2rgb(p, q, h + 1 / 3)),\r\n to255(hue2rgb(p, q, h)),\r\n to255(hue2rgb(p, q, h - 1 / 3))\r\n );\r\n }\r\n }\r\n}\r\n","import { Color } from \"./\";\r\nimport { Spline } from \"./spline\";\r\n\r\n/**\r\n * Represents a gradient that can be used to interpolate between multiple color.\r\n */\r\nexport class Gradient extends Spline {\r\n /**\r\n * Interpolates between two color on the gradient.\r\n */\r\n protected interpolate(a: Color, b: Color, t: number): Color {\r\n return a.mix(b, t);\r\n }\r\n\r\n /**\r\n * Returns a solid gradient from the given color.\r\n */\r\n public static solid(color: Color): Gradient {\r\n return new Gradient({ value: color, time: 0.5 });\r\n }\r\n\r\n /**\r\n * Returns a gradient with evenly spaced keys from the given colors.\r\n */\r\n public static simple(...colors: Color[]): Gradient {\r\n const step = 1 / (colors.length - 1);\r\n return new Gradient(\r\n ...colors.map((color, index) => ({\r\n value: color,\r\n time: index * step,\r\n }))\r\n );\r\n }\r\n}\r\n","export * from \"./circle\";\r\nexport * from \"./color\";\r\nexport * from \"./gradient\";\r\nexport * from \"./numericSpline\";\r\nexport * from \"./rect\";\r\nexport * from \"./vector\";\r\n","import { slerp } from \"../systems/math\";\r\nimport { Spline } from \"./spline\";\r\n\r\n/**\r\n * Represents a spline that can take numeric values.\r\n */\r\nexport class NumericSpline extends Spline {\r\n /**\r\n * Smoothly interpolates between two keys on the spline.\r\n */\r\n protected interpolate(a: number, b: number, t: number): number {\r\n return slerp(a, b, t);\r\n }\r\n}\r\n","/**\r\n * Represents a rectangle with an origin and size.\r\n */\r\nexport class Rect {\r\n /**\r\n * The x-position of the rectangle.\r\n */\r\n x: number;\r\n /**\r\n * The y-position of the rectangle.\r\n */\r\n y: number;\r\n /**\r\n * The width of the rectangle.\r\n */\r\n width: number;\r\n /**\r\n * The height of the rectangle.\r\n */\r\n height: number;\r\n\r\n constructor(x: number, y: number, width = 0, height = 0) {\r\n this.x = x;\r\n this.y = y;\r\n this.width = width;\r\n this.height = height;\r\n }\r\n\r\n public static readonly zero: Rect = new Rect(0, 0);\r\n\r\n /**\r\n * Returns a new document-space rectangle from the viewport's bounds.\r\n */\r\n public static fromScreen(): Rect {\r\n return new Rect(\r\n window.scrollX,\r\n window.scrollY,\r\n window.innerWidth,\r\n window.innerHeight\r\n );\r\n }\r\n\r\n /**\r\n * Returns a new document-space rectangle from the specified element.\r\n */\r\n public static fromElement(element: HTMLElement): Rect {\r\n const r = element.getBoundingClientRect();\r\n return new Rect(\r\n window.scrollX + r.x,\r\n window.scrollY + r.y,\r\n r.width,\r\n r.height\r\n );\r\n }\r\n}\r\n","import { invlerp } from \"../systems/math\";\r\n\r\n/**\r\n * Represents a key on a spline.\r\n */\r\nexport interface SplineKey {\r\n /**\r\n * The value of the key.\r\n */\r\n value: T;\r\n /**\r\n * The position of the key.\r\n */\r\n time: number;\r\n}\r\n\r\n/**\r\n * Represents a spline that can be used to continueously evaluate a function\r\n * between keys. The base implementation is kept generic, so the functionality\r\n * can easily be implemented for similar constructs, such as gradients.\r\n */\r\nexport abstract class Spline {\r\n /**\r\n * The keys in the gradient. Note that these are not sorted.\r\n */\r\n protected keys: SplineKey[];\r\n\r\n /**\r\n * Creates a new spline instance, using the specified keys.\r\n * Note that you have to pass at least one key.\r\n */\r\n constructor(...keys: SplineKey[]) {\r\n if (keys.length === 0) {\r\n throw new Error(\"Splines require at least one key.\");\r\n }\r\n if (Array.isArray(keys[0])) {\r\n throw new Error(\r\n \"You are trying to pass an array to the spline constructor, which is not supported. \" +\r\n \"Try to spread the array into the constructor instead.\"\r\n );\r\n }\r\n this.keys = keys;\r\n }\r\n\r\n /**\r\n * Evaluates the spline at the given time.\r\n */\r\n public evaluate(time: number): T {\r\n if (this.keys.length === 0) {\r\n throw new Error(\"Attempt to evaluate a spline with no keys.\");\r\n }\r\n\r\n if (this.keys.length === 1) {\r\n // The spline only contains one key, therefore is constant.\r\n return this.keys[0].value;\r\n }\r\n\r\n // Sort the keys and figure out the first key above the passed time.\r\n const ascendingKeys = this.keys.sort((a, b) => a.time - b.time);\r\n const upperKeyIndex = ascendingKeys.findIndex((g) => g.time > time);\r\n\r\n // If the found index is either 0 or -1, the specified time falls out\r\n // of the range of the supplied keys. In that case, the value of the\r\n // nearest applicant key is returned.\r\n if (upperKeyIndex === 0) {\r\n return ascendingKeys[0].value;\r\n }\r\n if (upperKeyIndex === -1) {\r\n return ascendingKeys[ascendingKeys.length - 1].value;\r\n }\r\n\r\n // Otherwise, find the bounding keys, and extrapolate the time between\r\n // the two. This is then used to interpolate between the two keys,\r\n // using the provided implementation.\r\n const lowerKey = ascendingKeys[upperKeyIndex - 1];\r\n const upperKey = ascendingKeys[upperKeyIndex];\r\n const containedTime = invlerp(lowerKey.time, upperKey.time, time);\r\n\r\n return this.interpolate(lowerKey.value, upperKey.value, containedTime);\r\n }\r\n\r\n /**\r\n * Interpolates using the values of two keys.\r\n */\r\n protected abstract interpolate(a: T, b: T, t: number): T;\r\n}\r\n","import { deg2rad, rad2deg } from \"../systems/math\";\r\n\r\n/**\r\n * Represents a structure used to process vectors.\r\n *\r\n * @remarks\r\n * Note that the operations in this class will **not** modify the original vector,\r\n * except for the property assignments. This is to ensure that vectors are not\r\n * unintentionally modified.\r\n *\r\n * @example\r\n * ```ts\r\n * const vectorA = new Vector(1, 3, 5);\r\n * const vectorB = new Vector(2, 3, 1);\r\n * const vectorC = vectorA.add(vectorB); // (3, 6, 6)\r\n * ```\r\n */\r\nexport class Vector {\r\n /**\r\n * Returns the x-component of the vector.\r\n */\r\n get x(): number {\r\n return this.values[0];\r\n }\r\n /**\r\n * Modifies the x-component of the vector.\r\n */\r\n set x(value: number) {\r\n this.values[0] = value;\r\n }\r\n\r\n /**\r\n * Returns the y-component of the vector.\r\n */\r\n get y(): number {\r\n return this.values[1];\r\n }\r\n /**\r\n * Modifies the y-component of the vector.\r\n */\r\n set y(value: number) {\r\n this.values[1] = value;\r\n }\r\n\r\n /**\r\n * Returns the z-component of the vector.\r\n */\r\n get z(): number {\r\n return this.values[2];\r\n }\r\n /**\r\n * Modifies the z-component of the vector.\r\n */\r\n set z(value: number) {\r\n this.values[2] = value;\r\n }\r\n\r\n /**\r\n * Returns the xyz-components of the vector, bundled as a copied array.\r\n */\r\n get xyz(): [number, number, number] {\r\n return [this.x, this.y, this.z];\r\n }\r\n /**\r\n * Simultaneously updates the xyz-components of the vector, by passing an array.\r\n */\r\n set xyz(values: [number, number, number]) {\r\n this.values[0] = values[0];\r\n this.values[1] = values[1];\r\n this.values[2] = values[2];\r\n }\r\n\r\n private values = new Float32Array(3);\r\n\r\n /**\r\n * Creates a new vector with optional x-, y-, and z-components.\r\n * Omitted components are defaulted to 0.\r\n */\r\n constructor(x = 0, y = 0, z = 0) {\r\n this.xyz = [x, y, z];\r\n }\r\n\r\n /**\r\n * Returns (0, 0, 0).\r\n */\r\n public static readonly zero: Vector = new Vector(0, 0, 0);\r\n /**\r\n * Returns (1, 1, 1).\r\n */\r\n public static readonly one: Vector = new Vector(1, 1, 1);\r\n /**\r\n * Returns (1, 0, 0).\r\n */\r\n public static readonly right: Vector = new Vector(1, 0, 0);\r\n /**\r\n * Returns (0, 1, 0).\r\n */\r\n public static readonly up: Vector = new Vector(0, 1, 0);\r\n /**\r\n * Returns (0, 0, 1).\r\n */\r\n public static readonly forward: Vector = new Vector(0, 0, 1);\r\n\r\n /**\r\n * Returns the length of the vector.\r\n */\r\n public magnitude(): number {\r\n return Math.sqrt(this.sqrMagnitude());\r\n }\r\n\r\n /**\r\n * Returns the squared length of the vector.\r\n */\r\n public sqrMagnitude(): number {\r\n return this.x * this.x + this.y * this.y + this.z * this.z;\r\n }\r\n\r\n /**\r\n * Adds the two vectors together, component-wise.\r\n */\r\n public add(vector: Vector): Vector {\r\n return new Vector(\r\n this.x + vector.x,\r\n this.y + vector.y,\r\n this.z + vector.z\r\n );\r\n }\r\n\r\n /**\r\n * Subtracts the right vector from the left one, component-wise.\r\n */\r\n public subtract(vector: Vector): Vector {\r\n return new Vector(\r\n this.x - vector.x,\r\n this.y - vector.y,\r\n this.z - vector.z\r\n );\r\n }\r\n\r\n /**\r\n * Scales the lefthand vector by another vector or by a number.\r\n */\r\n public scale(scalar: number | Vector): Vector {\r\n if (typeof scalar === \"number\") {\r\n return new Vector(\r\n this.x * scalar,\r\n this.y * scalar,\r\n this.z * scalar\r\n );\r\n } else {\r\n return new Vector(\r\n this.x * scalar.x,\r\n this.y * scalar.y,\r\n this.z * scalar.z\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Normalizes the vector to a length of 1. If the length was previously zero,\r\n * then a zero-length vector will be returned.\r\n */\r\n public normalized(): Vector {\r\n const magnitude = this.magnitude();\r\n if (magnitude !== 0) {\r\n return this.scale(1 / magnitude);\r\n }\r\n return new Vector(...this.xyz);\r\n }\r\n\r\n /**\r\n * Returns the angle between two vectors, in degrees.\r\n */\r\n public angle(vector: Vector): number {\r\n return (\r\n rad2deg *\r\n Math.acos(\r\n (this.x * vector.x + this.y * vector.y + this.z * vector.z) /\r\n (this.magnitude() * vector.magnitude())\r\n )\r\n );\r\n }\r\n\r\n /**\r\n * Returns the cross-product of two vectors.\r\n */\r\n public cross(vector: Vector): Vector {\r\n return new Vector(\r\n this.y * vector.z - this.z * vector.y,\r\n this.z * vector.x - this.x * vector.z,\r\n this.x * vector.y - this.y * vector.x\r\n );\r\n }\r\n\r\n /**\r\n * returns the dot-product of two vectors.\r\n */\r\n public dot(vector: Vector): number {\r\n return (\r\n this.magnitude() *\r\n vector.magnitude() *\r\n Math.cos(deg2rad * this.angle(vector))\r\n );\r\n }\r\n\r\n /**\r\n * Returns a formatted representation of the vector.\r\n */\r\n public toString(): string {\r\n return \"Vector(\" + this.values.join(\", \") + \")\";\r\n }\r\n\r\n /**\r\n * Creates a new vector from an angle, in degrees. Note that the z-component will be zero.\r\n */\r\n public static from2dAngle(angle: number): Vector {\r\n return new Vector(Math.cos(angle * deg2rad), Math.sin(angle * deg2rad));\r\n }\r\n}\r\n","import { settings } from \"./settings\";\r\nimport { Lazy } from \"./util\";\r\n\r\n/**\r\n * The prefix to apply to the containers.\r\n */\r\nconst containerPrefix = \"party-js-\";\r\n\r\n/**\r\n * Checks if the specified container is 'active', meaning not undefined and attached to the DOM.\r\n */\r\nfunction isContainerActive(container: HTMLElement): boolean {\r\n return container && container.isConnected;\r\n}\r\n\r\n/**\r\n * A generic factory method for creating a DOM container. Prefixes the specified name with the\r\n * container prefix, applies the styles and adds it under the parent.\r\n */\r\nfunction makeContainer(\r\n name: string,\r\n styles: Partial,\r\n parent: HTMLElement\r\n): HTMLElement {\r\n const container = document.createElement(\"div\");\r\n container.id = containerPrefix + name;\r\n Object.assign(container.style, styles);\r\n return parent.appendChild(container);\r\n}\r\n\r\n/**\r\n * Represents the root container for DOM elements of the library.\r\n */\r\nexport const rootContainer = new Lazy(\r\n () =>\r\n makeContainer(\r\n \"container\",\r\n {\r\n position: \"fixed\",\r\n left: \"0\",\r\n top: \"0\",\r\n height: \"100vh\",\r\n width: \"100vw\",\r\n pointerEvents: \"none\",\r\n userSelect: \"none\",\r\n zIndex: settings.zIndex.toString(),\r\n },\r\n document.body\r\n ),\r\n isContainerActive\r\n);\r\n/**\r\n * Represents the debugging container of the library, only active if debugging is enabled.\r\n */\r\nexport const debugContainer = new Lazy(\r\n () =>\r\n makeContainer(\r\n \"debug\",\r\n {\r\n position: \"absolute\",\r\n top: \"0\",\r\n left: \"0\",\r\n margin: \"0.5em\",\r\n padding: \"0.5em 1em\",\r\n border: \"2px solid rgb(0, 0, 0, 0.2)\",\r\n background: \"rgb(0, 0, 0, 0.1)\",\r\n color: \"#555\",\r\n fontFamily: \"monospace\",\r\n },\r\n rootContainer.current\r\n ),\r\n isContainerActive\r\n);\r\n/**\r\n * Represents the particle container of the library.\r\n * This is where the particle DOM elements get rendered into.\r\n */\r\nexport const particleContainer = new Lazy(\r\n () =>\r\n makeContainer(\r\n \"particles\",\r\n {\r\n width: \"100%\",\r\n height: \"100%\",\r\n overflow: \"hidden\",\r\n perspective: \"1200px\",\r\n },\r\n rootContainer.current\r\n ),\r\n isContainerActive\r\n);\r\n","import { debugContainer } from \"./containers\";\r\nimport { Scene } from \"./scene\";\r\nimport { settings } from \"./settings\";\r\n\r\n/**\r\n * Represents a utility module to view debug information inside the DOM.\r\n * This is disabled by default and needs to manually be enabled by setting\r\n * the '.enabled' field to true.\r\n *\r\n * While disabled, the utility will not fetch stats and update itself.\r\n */\r\nexport class Debug {\r\n /**\r\n * The rate at which the debug interface should refresh itself (per second).\r\n */\r\n private readonly refreshRate = 8;\r\n /**\r\n * The timer counting down to refreshes.\r\n */\r\n private refreshTimer = 1 / this.refreshRate;\r\n\r\n /**\r\n * Registers a new debug utility that is attached to the given scene.\r\n *\r\n * @param scene The scene to attach to.\r\n */\r\n constructor(private scene: Scene) {}\r\n\r\n /**\r\n * Processes a tick event in the interface. This checks if enough has passed to\r\n * trigger a refresh, and if so, fetches the debug information and updates the DOM.\r\n *\r\n * @param delta The time that has elapsed since the last tick.\r\n */\r\n public tick(delta: number): void {\r\n const container = debugContainer.current;\r\n\r\n // If the current display style does not match the style inferred from the\r\n // enabled-state, update it.\r\n const displayStyle = settings.debug ? \"block\" : \"none\";\r\n if (container.style.display !== displayStyle) {\r\n container.style.display = displayStyle;\r\n }\r\n\r\n if (!settings.debug) {\r\n // If the interface is not enabled, don't fetch or update any infos.\r\n return;\r\n }\r\n\r\n this.refreshTimer += delta;\r\n if (this.refreshTimer > 1 / this.refreshRate) {\r\n this.refreshTimer = 0;\r\n // Update the container with the fetched information joined on line breaks.\r\n container.innerHTML = this.getDebugInformation(delta).join(\"
\");\r\n }\r\n }\r\n\r\n /**\r\n * Fetches the debug information from the specified delta and the linked scene.\r\n *\r\n * @returns An array of debugging information, formatted as HTML.\r\n */\r\n private getDebugInformation(delta: number): string[] {\r\n // Count emitters and particles.\r\n const emitters = this.scene.emitters.length;\r\n const particles = this.scene.emitters.reduce(\r\n (acc, cur) => acc + cur.particles.length,\r\n 0\r\n );\r\n\r\n const infos: string[] = [\r\n `party.js Debug`,\r\n `--------------`,\r\n `FPS: ${Math.round(1 / delta)}`,\r\n `Emitters: ${emitters}`,\r\n `Particles: ${particles}`,\r\n ];\r\n\r\n // Emitter informations are formatted using their index, internal timer\r\n // and total particle count.\r\n const emitterInfos: string[] = this.scene.emitters.map(function (\r\n emitter\r\n ) {\r\n return [\r\n // Show the current loop and the total loops.\r\n `⭯: ${emitter[\"currentLoop\"] + 1}/${\r\n emitter.options.loops >= 0 ? emitter.options.loops : \"∞\"\r\n }`,\r\n // Show the amount of particle contained.\r\n `Σp: ${emitter.particles.length}`,\r\n // Show the internal timer.\r\n !emitter.isExpired\r\n ? `Σt: ${emitter[\"durationTimer\"].toFixed(3)}s`\r\n : \"expired\",\r\n ].join(\", \");\r\n });\r\n\r\n infos.push(\"--------------\", ...emitterInfos);\r\n\r\n return infos;\r\n }\r\n}\r\n","import { Scene } from \"./scene\";\r\nimport { Lazy } from \"./util\";\r\n\r\nexport * from \"./components\";\r\nexport * from \"./templates\";\r\nexport * from \"./systems/shapes\";\r\nexport * from \"./systems/modules\";\r\n\r\n// Create the lazy-initializing scene.\r\nexport const scene = new Lazy(() => {\r\n // The library requires the use of the DOM, hence it cannot run in non-browser environments.\r\n if (typeof document === \"undefined\" || typeof window === \"undefined\") {\r\n throw new Error(\r\n \"It seems like you are trying to run party.js in a non-browser-like environment, which is not supported.\"\r\n );\r\n }\r\n return new Scene();\r\n});\r\n\r\nexport { settings } from \"./settings\";\r\nexport { Particle } from \"./particles/particle\";\r\nexport { Emitter } from \"./particles/emitter\";\r\n\r\nexport * as variation from \"./systems/variation\";\r\nexport * as sources from \"./systems/sources\";\r\nexport * as random from \"./systems/random\";\r\nexport * as math from \"./systems/math\";\r\nexport * as util from \"./util\";\r\n\r\n/**\r\n * Forces the initialization of the otherwise lazy scene.\r\n */\r\nexport function forceInit(): void {\r\n scene.current;\r\n}\r\n\r\nexport * as default from \"./\";\r\n","import { Vector } from \"../components/vector\";\r\nimport { settings } from \"../settings\";\r\nimport { evaluateVariation } from \"../systems/variation\";\r\nimport { overrideDefaults } from \"../util/config\";\r\nimport {\r\n EmissionOptions,\r\n EmitterOptions,\r\n RenderOptions,\r\n getDefaultEmissionOptions,\r\n getDefaultEmitterOptions,\r\n getDefaultRendererOptions,\r\n} from \"./options\";\r\nimport { Particle } from \"./particle\";\r\n\r\n/**\r\n * Defines the set of options that can be used when creating a new emitter.\r\n */\r\nexport interface EmitterConstructionOptions {\r\n emitterOptions?: Partial;\r\n emissionOptions?: Partial;\r\n rendererOptions?: Partial;\r\n}\r\n\r\n/**\r\n * Represents an emitter that is responsible for spawning and updating particles.\r\n *\r\n * Particles themselves are just data-holders, with the system acting upon them and\r\n * modifying them. The modifications are done mainly via modules, that use the\r\n * particle's data together with some function to apply temporal transitions.\r\n *\r\n * @see Particle\r\n * @see ParticleModifierModule\r\n */\r\nexport class Emitter {\r\n /**\r\n * The particles currently contained within the system.\r\n */\r\n public readonly particles: Particle[] = [];\r\n\r\n /**\r\n * The main options of the emitter.\r\n */\r\n public readonly options: EmitterOptions;\r\n /**\r\n * The emission options of the emitter.\r\n */\r\n public readonly emission: EmissionOptions;\r\n /**\r\n * The renderer options of the emitter.\r\n */\r\n public readonly renderer: RenderOptions;\r\n\r\n private currentLoop = 0; // The current loop index.\r\n private durationTimer = 0; // Measures the current runtime duration, to allow loops to reset.\r\n private emissionTimer = 0; // Measures the current emission timer, to allow spawning particles in intervals.\r\n\r\n private attemptedBurstIndices: number[] = []; // The indices of the particle bursts that were attempted this loop.\r\n\r\n /**\r\n * Checks if the emitter is already expired and can be removed.\r\n * Expired emitters do not emit new particles.\r\n */\r\n public get isExpired(): boolean {\r\n return (\r\n this.options.loops >= 0 && this.currentLoop >= this.options.loops\r\n );\r\n }\r\n /**\r\n * Checks if the emitter can safely be removed.\r\n * This is true if no more particles are active.\r\n */\r\n public get canRemove(): boolean {\r\n return this.particles.length === 0;\r\n }\r\n\r\n /**\r\n * Creates a new emitter, using default options.\r\n */\r\n constructor(options?: EmitterConstructionOptions) {\r\n this.options = overrideDefaults(\r\n getDefaultEmitterOptions(),\r\n options?.emitterOptions\r\n );\r\n this.emission = overrideDefaults(\r\n getDefaultEmissionOptions(),\r\n options?.emissionOptions\r\n );\r\n this.renderer = overrideDefaults(\r\n getDefaultRendererOptions(),\r\n options?.rendererOptions\r\n );\r\n }\r\n\r\n /**\r\n * Clears all particles inside the emitter.\r\n *\r\n * @returns The number of cleared particles.\r\n */\r\n public clearParticles(): number {\r\n return this.particles.splice(0).length;\r\n }\r\n\r\n /**\r\n * Processes a tick of the emitter, using the elapsed time.\r\n *\r\n * @remarks\r\n * This handles a few things, namely:\r\n * - Incrementing the duration timer and potentially incrementing the loop.\r\n * - Handling particle bursts & emissions.\r\n * - Despawning particles conditionally.\r\n *\r\n * @param delta The time, in seconds, passed since the last tick.\r\n */\r\n public tick(delta: number): void {\r\n if (!this.isExpired) {\r\n this.durationTimer += delta;\r\n if (this.durationTimer >= this.options.duration) {\r\n this.currentLoop++;\r\n\r\n // To start a new loop, the duration timer and attempted bursts are reset.\r\n this.durationTimer = 0;\r\n this.attemptedBurstIndices = [];\r\n }\r\n\r\n // We need to check the expiry again, in case the added loop or duration changed something.\r\n if (!this.isExpired) {\r\n // Iterate over the bursts, attempting to execute them if the time is ready.\r\n let burstIndex = 0;\r\n for (const burst of this.emission.bursts) {\r\n if (burst.time <= this.durationTimer) {\r\n // Has the burst already been attempted? If not ...\r\n if (!this.attemptedBurstIndices.includes(burstIndex)) {\r\n // Perform the burst, emitting a variable amount of particles.\r\n const count = evaluateVariation(burst.count);\r\n for (let i = 0; i < count; i++) {\r\n this.emitParticle();\r\n }\r\n // Mark the burst as attempted.\r\n this.attemptedBurstIndices.push(burstIndex);\r\n }\r\n }\r\n burstIndex++;\r\n }\r\n\r\n // Handle the 'emission over time'. By using a while-loop instead of a simple\r\n // if-condition, we take high deltas into account, and ensure that the correct\r\n // number of particles will consistently be emitted.\r\n this.emissionTimer += delta;\r\n const delay = 1 / this.emission.rate;\r\n while (this.emissionTimer > delay) {\r\n this.emissionTimer -= delay;\r\n this.emitParticle();\r\n }\r\n }\r\n }\r\n\r\n for (let i = this.particles.length - 1; i >= 0; i--) {\r\n const particle = this.particles[i];\r\n this.tickParticle(particle, delta);\r\n\r\n // Particles should be despawned (i.e. removed from the collection) if any of\r\n // the despawning rules apply to them.\r\n if (this.options.despawningRules.some((rule) => rule(particle))) {\r\n this.particles.splice(i, 1);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Performs an internal tick for the particle.\r\n *\r\n * @remarks\r\n * This method controls the particle's lifetime, location and velocity, according\r\n * to the elapsed delta and the configuration. Additionally, each of the emitter's\r\n * modules is applied to the particle.\r\n *\r\n * @param particle The particle to apply the tick for.\r\n * @param delta The time, in seconds, passed since the last tick.\r\n */\r\n private tickParticle(particle: Particle, delta: number): void {\r\n particle.lifetime -= delta;\r\n\r\n if (this.options.useGravity) {\r\n // Apply gravitational acceleration to the particle.\r\n particle.velocity = particle.velocity.add(\r\n Vector.up.scale(settings.gravity * delta)\r\n );\r\n }\r\n\r\n // Apply the particle's velocity to its location.\r\n particle.location = particle.location.add(\r\n particle.velocity.scale(delta)\r\n );\r\n\r\n // Apply the modules to the particle.\r\n for (const moduleFunction of this.options.modules) {\r\n moduleFunction(particle);\r\n }\r\n }\r\n\r\n /**\r\n * Emits a particle using the registered settings.\r\n * Also may despawn a particle if the maximum number of particles is exceeded.\r\n */\r\n private emitParticle(): Particle {\r\n const particle: Particle = new Particle({\r\n location: this.emission.sourceSampler(),\r\n lifetime: evaluateVariation(this.emission.initialLifetime),\r\n velocity: Vector.from2dAngle(\r\n evaluateVariation(this.emission.angle)\r\n ).scale(evaluateVariation(this.emission.initialSpeed)),\r\n size: evaluateVariation(this.emission.initialSize),\r\n rotation: evaluateVariation(this.emission.initialRotation),\r\n color: evaluateVariation(this.emission.initialColor),\r\n });\r\n this.particles.push(particle);\r\n\r\n // Ensure that no more particles than 'maxParticles' can exist.\r\n if (this.particles.length > this.options.maxParticles) {\r\n this.particles.shift();\r\n }\r\n\r\n return particle;\r\n }\r\n}\r\n","import { Color, Rect, Vector } from \"../../components\";\r\nimport { SourceSampler, rectSource } from \"../../systems/sources\";\r\nimport { Variation } from \"../../systems/variation\";\r\n\r\n/**\r\n * Holds a set of options used to configure the way particles are emitted in.\r\n */\r\nexport interface EmissionOptions {\r\n /**\r\n * The number of particles that should be emitted per second.\r\n *\r\n * @defaultValue 10\r\n */\r\n rate: number;\r\n /**\r\n * The bursts that particles should be bulk-emitted at.\r\n *\r\n * @defaultValue An empty array.\r\n */\r\n bursts: Burst[];\r\n\r\n /**\r\n * The sampler used to generate particle spawn positions.\r\n *\r\n * @defaultValue A sampler that emits particles from (0, 0).\r\n */\r\n sourceSampler: SourceSampler;\r\n /**\r\n * The angle that particles will be emitted at, in degrees. This is used to, for example,\r\n * give the particles a particular amount of initial force in a direction.\r\n *\r\n * @defaultValue 0\r\n */\r\n angle: Variation;\r\n\r\n /**\r\n * The variable, initial lifetime of the emitted particle.\r\n *\r\n * @defaultValue 5\r\n */\r\n initialLifetime: Variation;\r\n /**\r\n * The variable, initial speed of the emitted particles.\r\n *\r\n * @defaultValue 5\r\n */\r\n initialSpeed: Variation;\r\n /**\r\n * The variable, initial size of the emitted particles.\r\n *\r\n * @defaultValue 1\r\n */\r\n initialSize: Variation;\r\n /**\r\n * The variable, initial rotation of the emitted particles, as euler angles.\r\n *\r\n * @defaultValue `Vector.zero`\r\n */\r\n initialRotation: Variation;\r\n /**\r\n * The variable, initial color of the emitted particles.\r\n *\r\n * @defaultValue `Color.white`\r\n */\r\n initialColor: Variation;\r\n}\r\n\r\n/**\r\n * Represents a burst of emitted particles.\r\n */\r\nexport interface Burst {\r\n /**\r\n * The time to perform the burst at. This must be less than the duration of the emitter.\r\n */\r\n time: number;\r\n /**\r\n * The variable number of particles that should be emitted.\r\n */\r\n count: Variation;\r\n /**\r\n * The (optional) likelihood that the burst will activate, from 0 (never) to 1 (always).\r\n */\r\n probability?: number;\r\n}\r\n\r\n/**\r\n * Returns the default set of emission options.\r\n */\r\nexport function getDefaultEmissionOptions(): EmissionOptions {\r\n return {\r\n rate: 10,\r\n\r\n angle: 0,\r\n bursts: [],\r\n sourceSampler: rectSource(Rect.zero),\r\n\r\n initialLifetime: 5,\r\n initialSpeed: 5,\r\n initialSize: 1,\r\n initialRotation: Vector.zero,\r\n initialColor: Color.white,\r\n };\r\n}\r\n","import { ModuleFunction } from \"../../systems/modules\";\r\nimport { despawningRules } from \"../../util/rules\";\r\nimport { Particle } from \"../particle\";\r\n\r\n/**\r\n * Represents a rule that decides whether a particle should be despawned or not.\r\n */\r\nexport type ParticleDespawnRule = (particle: Particle) => boolean;\r\n\r\n/**\r\n * Holds a set of options that control the basic functionality of an emitter.\r\n */\r\nexport interface EmitterOptions {\r\n /**\r\n * The duration of one emission cycle.\r\n * @defaultValue 5\r\n */\r\n duration: number;\r\n /**\r\n * The number of loops that should be performed. Negative numbers result in infinite loops.\r\n * @defaultValue 1\r\n */\r\n loops: number;\r\n\r\n /**\r\n * Whether to apply gravity to the emitted particles.\r\n * @defaultValue true\r\n */\r\n useGravity: boolean;\r\n /**\r\n * The maximum number of particles that may be active in the current emitter.\r\n * @defaultValue 300\r\n */\r\n maxParticles: number;\r\n /**\r\n * The rules used to determine when particles should be despawned.\r\n *\r\n * @remarks\r\n * Note that if this array is reset, the particles will never be despawned by the\r\n * emitter, and will only be cleared once the system is destroyed.\r\n *\r\n * @defaultValue Despawns particles when their lifetime is over or when they leave the document bounds.\r\n */\r\n despawningRules: ParticleDespawnRule[];\r\n /**\r\n * The array of module functions used to modify particles while they are active.\r\n *\r\n * @remarks\r\n * New modules can be created via the `ModuleBuilder` class. Alternatively, for full\r\n * control, a function can be passed that takes a particle as a parameter, and modifies it.\r\n */\r\n modules: ModuleFunction[];\r\n}\r\n\r\n/**\r\n * Returns the default set of emitter options.\r\n */\r\nexport function getDefaultEmitterOptions(): EmitterOptions {\r\n return {\r\n duration: 5,\r\n loops: 1,\r\n\r\n useGravity: true,\r\n maxParticles: 300,\r\n despawningRules: [despawningRules.lifetime, despawningRules.bounds],\r\n modules: [],\r\n };\r\n}\r\n","export * from \"./emitterOptions\";\r\nexport * from \"./emissionOptions\";\r\nexport * from \"./renderOptions\";\r\n","import { Color } from \"../../components\";\r\nimport { Variation } from \"../../systems/variation\";\r\nimport { Particle } from \"../particle\";\r\n\r\n/**\r\n * Represents a delegate used by the renderer to apply a certain property to the\r\n * particle's HTMLElement. Note that this property is generic and does not\r\n * have to contain the particle itself.\r\n */\r\nexport type ApplyFunction = (property: T, element: HTMLElement) => void;\r\n\r\n/**\r\n * Holds the options used to configure the renderer for a particle system.\r\n */\r\nexport interface RenderOptions {\r\n /**\r\n * The factory used to determine the element (or \"shape\") that a particle will be rendered as.\r\n * This variation can also return a resolve-able string.\r\n *\r\n * @remarks\r\n * Depending on the type of value that is returned from the factory, additional\r\n * processing has to be done.\r\n *\r\n * - strings: The `party.resolvableShapes` lookup is used to resolve the string to an actual\r\n * HTMLElement, before following the same procedure as if an HTMLElement would have been passed.\r\n * - HTMLElements: The returned element is deep cloned and used to represent the particle in the document.\r\n *\r\n * @defaultValue Creates a square-shaped `
` element with a size of 10px.\r\n */\r\n shapeFactory: Variation;\r\n\r\n /**\r\n * The delegate used to apply a certain color to the particle's HTMLElement.\r\n * @defaultValue Applies the specified color to the element's \"background\" property.\r\n */\r\n applyColor?: ApplyFunction;\r\n /**\r\n * The delegate used to apply a certain degree of opacity to the particle's HTMLElement.\r\n * @defaultValue Applies the specified opacity to the element's \"opacity\" property.\r\n */\r\n applyOpacity?: ApplyFunction;\r\n /**\r\n * The delegate used to apply a certain degree of lighting to the particle's HTMLElement.\r\n * @defaultValue Applies the specified lighting to the element as a brightness filter.\r\n */\r\n applyLighting?: ApplyFunction;\r\n /**\r\n * The delegate used to apply a certain transform to the particle's HTMLElement.\r\n * @defaultValue Applies the specified transform to the element as a 3D CSS transform.\r\n */\r\n applyTransform?: ApplyFunction;\r\n}\r\n\r\n/**\r\n * Returns the default set of renderer options.\r\n */\r\nexport function getDefaultRendererOptions(): RenderOptions {\r\n return {\r\n shapeFactory: \"square\",\r\n\r\n applyColor: defaultApplyColor,\r\n applyOpacity: defaultApplyOpacity,\r\n applyLighting: defaultApplyLighting,\r\n applyTransform: defaultApplyTransform,\r\n };\r\n}\r\n\r\n/**\r\n * Applies the specified color to the element.\r\n *\r\n * @remarks\r\n * This function is aware of the element's node type:\r\n * - `div` elements have their `background` set.\r\n * - `svg` elements have their `fill` and `color` set.\r\n * - Other elements have their `color` set.\r\n */\r\nfunction defaultApplyColor(color: Color, element: HTMLElement): void {\r\n const hex = color.toHex();\r\n // Note that by default, HTML node names are uppercase.\r\n switch (element.nodeName.toLowerCase()) {\r\n case \"div\":\r\n element.style.background = hex;\r\n break;\r\n case \"svg\":\r\n element.style.fill = element.style.color = hex;\r\n break;\r\n default:\r\n element.style.color = hex;\r\n break;\r\n }\r\n}\r\n/**\r\n * Applies the specified opacity to the element.\r\n */\r\nfunction defaultApplyOpacity(opacity: number, element: HTMLElement): void {\r\n element.style.opacity = opacity.toString();\r\n}\r\n/**\r\n * Applies the specified lighting to the element as a brightness filter.\r\n *\r\n * @remarks\r\n * This function assumes an ambient light with intensity 0.5, and that the\r\n * particle should be lit from both sides. The brightness filter can exceed 1,\r\n * to give the particles a \"glossy\" feel.\r\n */\r\nfunction defaultApplyLighting(lighting: number, element: HTMLElement): void {\r\n element.style.filter = `brightness(${0.5 + Math.abs(lighting)})`;\r\n}\r\n/**\r\n * Applies the specified transform to the element as a 3D CSS transform.\r\n * Also takes into account the current window scroll, to make sure that particles are\r\n * rendered inside of the fixed container.\r\n */\r\nfunction defaultApplyTransform(particle: Particle, element: HTMLElement): void {\r\n element.style.transform =\r\n // Make sure to take window scrolling into account.\r\n `translateX(${(particle.location.x - window.scrollX).toFixed(3)}px) ` +\r\n `translateY(${(particle.location.y - window.scrollY).toFixed(3)}px) ` +\r\n `translateZ(${particle.location.z.toFixed(3)}px) ` +\r\n `rotateX(${particle.rotation.x.toFixed(3)}deg) ` +\r\n `rotateY(${particle.rotation.y.toFixed(3)}deg) ` +\r\n `rotateZ(${particle.rotation.z.toFixed(3)}deg) ` +\r\n `scale(${particle.size.toFixed(3)})`;\r\n}\r\n","import { Color, Vector } from \"../components\";\r\nimport { overrideDefaults } from \"../util/config\";\r\n\r\n/**\r\n * Represents a set of options that can be used to create the particle.\r\n */\r\nexport type ParticleCreationOptions = Partial<\r\n Omit\r\n>;\r\n\r\n/**\r\n * Represents an emitted particle.\r\n */\r\nexport class Particle {\r\n /**\r\n * The unique (symbolic) ID of the particle.\r\n */\r\n id: symbol;\r\n\r\n /**\r\n * The remaining lifetime of the particle.\r\n */\r\n lifetime: number;\r\n /**\r\n * The current size of the particle.\r\n */\r\n size: number;\r\n /**\r\n * The current location of the particle, in pixels.\r\n */\r\n location: Vector;\r\n /**\r\n * The current rotation of the particle, in euler angles, in degrees.\r\n */\r\n rotation: Vector;\r\n /**\r\n * The current velocity of the particle.\r\n */\r\n velocity: Vector;\r\n /**\r\n * The current color of the particle.\r\n */\r\n color: Color;\r\n /**\r\n * The opacity of the particle (from 0 to 1).\r\n */\r\n opacity: number;\r\n\r\n /**\r\n * The initial lifetime of the particle.\r\n */\r\n initialLifetime: number;\r\n /**\r\n * The initial size of the particle.\r\n */\r\n initialSize: number;\r\n /**\r\n * The initial rotation of the particle.\r\n */\r\n initialRotation: Vector;\r\n\r\n /**\r\n * Creates a new particle instance through the specified options.\r\n */\r\n constructor(options: ParticleCreationOptions) {\r\n const populatedOptions = overrideDefaults(\r\n {\r\n lifetime: 0,\r\n size: 1,\r\n location: Vector.zero,\r\n rotation: Vector.zero,\r\n velocity: Vector.zero,\r\n color: Color.white,\r\n opacity: 1,\r\n },\r\n options\r\n );\r\n\r\n // Generate a symbolic ID.\r\n this.id = Symbol();\r\n\r\n // Assign various properties, together with some initials for later reference.\r\n this.size = this.initialSize = populatedOptions.size;\r\n this.lifetime = this.initialLifetime = populatedOptions.lifetime;\r\n this.rotation = this.initialRotation = populatedOptions.rotation;\r\n\r\n this.location = populatedOptions.location;\r\n this.velocity = populatedOptions.velocity;\r\n this.color = populatedOptions.color;\r\n this.opacity = populatedOptions.opacity;\r\n }\r\n}\r\n","import { settings } from \"..\";\r\nimport { Vector } from \"../components/vector\";\r\nimport { particleContainer } from \"../containers\";\r\nimport { resolveShapeFactory } from \"../systems/shapes\";\r\nimport { rotationToNormal } from \"../util\";\r\nimport { Emitter } from \"./emitter\";\r\nimport { RenderOptions } from \"./options\";\r\nimport { Particle } from \"./particle\";\r\n\r\n/**\r\n * Represents a renderer used to draw particles to the DOM via HTML\r\n * elements. Additionally, it is responsible for purging the elements\r\n * of destroyed particles from the DOM.\r\n */\r\nexport class Renderer {\r\n /**\r\n * The lookup of elements currently handled by the renderer, with the\r\n * particle ID as key and a HTMLElement as the value.\r\n */\r\n public elements: Map = new Map();\r\n /**\r\n * The normalized direction the light comes from.\r\n */\r\n public light: Vector = new Vector(0, 0, 1);\r\n\r\n /**\r\n * The collection of symbols containing the particles that were rendered this frame.\r\n * This is, for example, used to delete unused particles from the DOM.\r\n */\r\n private renderedParticles: symbol[];\r\n\r\n /**\r\n * Whether or not the renderer should actually draw particles.\r\n */\r\n private enabled = true;\r\n\r\n public constructor() {\r\n // Respect that users might prefer reduced motion.\r\n // See: https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion\r\n this.enabled =\r\n !settings.respectReducedMotion ||\r\n !window.matchMedia(\"(prefers-reduced-motion)\").matches;\r\n }\r\n\r\n /**\r\n * Begins a new render block. During the rendering phase, a list of rendered particles\r\n * is tracked, so that stale particles can be removed later.\r\n */\r\n public begin(): void {\r\n this.renderedParticles = [];\r\n }\r\n /**\r\n * Terminates an existing render block. This checks which particles were rendered\r\n * during the block and purges all unused HTMLElements from the DOM.\r\n *\r\n * @returns The amount of particles that were rendered.\r\n */\r\n public end(): number {\r\n const it = this.elements.keys();\r\n\r\n let result = it.next();\r\n while (!result.done) {\r\n const id = result.value as symbol;\r\n if (!this.renderedParticles.includes(id)) {\r\n this.elements.get(id).remove();\r\n this.elements.delete(id);\r\n }\r\n result = it.next();\r\n }\r\n\r\n return this.renderedParticles.length;\r\n }\r\n\r\n /**\r\n * Renders an individual particle to the DOM. If the particle is rendered for the first\r\n * time, a HTMLElement will be created using the emitter's render settings.\r\n *\r\n * @param particle The particle to be rendered.\r\n * @param emitter The system containing the particle.\r\n */\r\n public renderParticle(particle: Particle, emitter: Emitter): void {\r\n if (!this.enabled) return;\r\n\r\n const options: RenderOptions = emitter.renderer;\r\n\r\n // Ensure that an element for the particle exists.\r\n const element = this.elements.has(particle.id)\r\n ? this.elements.get(particle.id)\r\n : this.createParticleElement(particle, options);\r\n\r\n if (options.applyColor) {\r\n // If the options offer a coloring method, apply it.\r\n options.applyColor(particle.color, element);\r\n }\r\n\r\n if (options.applyOpacity) {\r\n // If the options offer an opacity modifying method, apply it.\r\n options.applyOpacity(particle.opacity, element);\r\n }\r\n\r\n if (options.applyLighting) {\r\n // If the options offer a lighting method, apply it.\r\n // Lighting is calculated as a combination of the particle's normal\r\n // direction and the lighting direction.\r\n const normal = rotationToNormal(particle.rotation);\r\n const lightingCoefficient = normal.dot(this.light);\r\n\r\n options.applyLighting(lightingCoefficient, element);\r\n }\r\n\r\n if (options.applyTransform) {\r\n // If the options offer a transformation method, apply it.\r\n // This ensures the particle is rendered at the correct position with the correct rotation.\r\n options.applyTransform(particle, element);\r\n }\r\n\r\n // Mark the particle as rendered.\r\n this.renderedParticles.push(particle.id);\r\n }\r\n\r\n /**\r\n * Creates the HTMLElement for a particle that does not have one already.\r\n */\r\n private createParticleElement(\r\n particle: Particle,\r\n options: RenderOptions\r\n ): HTMLElement {\r\n // Resolve the element returned from the factory.\r\n const resolved = resolveShapeFactory(options.shapeFactory);\r\n // Clone the node to ensure we do not break existing elements.\r\n const element = resolved.cloneNode(true) as HTMLElement;\r\n\r\n // Ensure that the elements can be \"stacked\" ontop of eachother.\r\n element.style.position = \"absolute\";\r\n\r\n // Register the new element in the map, while appending the new element to the DOM.\r\n this.elements.set(\r\n particle.id,\r\n particleContainer.current.appendChild(element)\r\n );\r\n\r\n return element;\r\n }\r\n}\r\n","import { Debug } from \"./debug\";\r\nimport { Emitter, EmitterConstructionOptions } from \"./particles/emitter\";\r\nimport { Renderer } from \"./particles/renderer\";\r\n\r\n/**\r\n * Represents a scene that contains emitters and their particles.\r\n *\r\n * Scenes are responsible for spawning and updating emitters, and\r\n * removing them once they are done.\r\n *\r\n * Scenes are not explicitely present in the DOM as an element, only\r\n * the contained particles are.\r\n */\r\nexport class Scene {\r\n /**\r\n * The emitters currently present in the scene.\r\n */\r\n public emitters: Emitter[] = [];\r\n\r\n /**\r\n * The debug instance associated with the scene.\r\n */\r\n public readonly debug = new Debug(this);\r\n /**\r\n * The renderer associated with the scene.\r\n */\r\n public readonly renderer = new Renderer();\r\n\r\n /**\r\n * The ID of the currently scheduled tick.\r\n */\r\n private scheduledTickId?: number = undefined;\r\n /**\r\n * The timestamp of the last tick, used to calculate deltas.\r\n *\r\n * @initialValue `performance.now()` (time origin)\r\n * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMHighResTimeStamp\r\n */\r\n private lastTickTimestamp = performance.now();\r\n\r\n /**\r\n * Initializes a new scene and starts the ticking job.\r\n */\r\n constructor() {\r\n // Ensure the scene context is preserved on the tick.\r\n this.tick = this.tick.bind(this);\r\n this.scheduleTick();\r\n }\r\n\r\n /**\r\n * Creates and returns a new, default emitter object.\r\n */\r\n public createEmitter(options?: EmitterConstructionOptions): Emitter {\r\n const emitter = new Emitter(options);\r\n this.emitters.push(emitter);\r\n return emitter;\r\n }\r\n /**\r\n * Clears all emitters from the scene.\r\n *\r\n * @returns The number of cleared emitters.\r\n */\r\n public clearEmitters(): number {\r\n return this.emitters.splice(0).length;\r\n }\r\n /**\r\n * Clears the particles from all emitters in the scene.\r\n * Note that this does not remove the actual emitter objects though.\r\n *\r\n * @returns The number of cleared particles.\r\n */\r\n public clearParticles(): number {\r\n return this.emitters.reduce(\r\n (sum, emitter) => sum + emitter.clearParticles(),\r\n 0\r\n );\r\n }\r\n\r\n /**\r\n * Schedules a tick in the scene.\r\n */\r\n public scheduleTick(): void {\r\n this.scheduledTickId = window.requestAnimationFrame(this.tick);\r\n }\r\n /**\r\n * Cancels a pending tick operation.\r\n */\r\n public cancelTick(): void {\r\n window.cancelAnimationFrame(this.scheduledTickId);\r\n }\r\n\r\n /**\r\n * Processes a tick cycle, updating all emitters contained in the scene.\r\n * This is handled as a JS animation frame event, hence the passed timestamp.\r\n *\r\n * @remarks\r\n * The emitter ticking and particle rendering is run using try-catch blocks,\r\n * to ensure that we can recover from potential errors.\r\n *\r\n * @param timestamp The current timestamp of the animation frame.\r\n */\r\n private tick(timestamp: number): void {\r\n // Calculate the elapsed delta and convert it to seconds.\r\n const delta = (timestamp - this.lastTickTimestamp) / 1000;\r\n\r\n try {\r\n // Perform ticks for all the emitters in the scene.\r\n for (let i = 0; i < this.emitters.length; i++) {\r\n const emitter = this.emitters[i];\r\n\r\n emitter.tick(delta);\r\n if (emitter.isExpired && emitter.canRemove) {\r\n this.emitters.splice(i--, 1);\r\n }\r\n }\r\n } catch (error) {\r\n console.error(\r\n `An error occurred while updating the scene's emitters:\\n\"${error}\"`\r\n );\r\n }\r\n\r\n try {\r\n // Instruct the renderer to draw the particles of all systems.\r\n this.renderer.begin();\r\n for (const emitter of this.emitters) {\r\n for (const particle of emitter.particles) {\r\n this.renderer.renderParticle(particle, emitter);\r\n }\r\n }\r\n this.renderer.end();\r\n } catch (error) {\r\n console.error(\r\n `An error occurred while rendering the scene's particles:\\n\"${error}\"`\r\n );\r\n }\r\n\r\n // Perform a tick on the debug interface\r\n this.debug.tick(delta);\r\n\r\n // Save the timestamp as the last tick timestamp and schedule a new tick.\r\n this.lastTickTimestamp = timestamp;\r\n this.scheduleTick();\r\n }\r\n}\r\n","/**\r\n * Represents global settings used throughout the library.\r\n */\r\nexport interface Settings {\r\n /**\r\n * Whether the debugging mode should be enabled.\r\n *\r\n * @defaultValue false\r\n */\r\n debug: boolean;\r\n /**\r\n * The amount of gravity to apply to particles in the scene, in pixels.\r\n * Note that this value is positive by default, since the y-axis increases\r\n * downwards in a DOM.\r\n *\r\n * @defaultValue 800\r\n */\r\n gravity: number;\r\n /**\r\n * The z-index to place the DOM containers at.\r\n *\r\n * @defaultValue 99999\r\n */\r\n zIndex: number;\r\n /**\r\n * Whether or not to respect the \"prefers-reduced-motion\" media query, in\r\n * case users do not want particle effects flying around their screen. Note\r\n * that this has to be set **before** the library initializes the renderer.\r\n *\r\n * @defaultValue true\r\n */\r\n respectReducedMotion: boolean;\r\n}\r\n\r\nexport const settings: Settings = {\r\n debug: false,\r\n gravity: 800,\r\n zIndex: 99999,\r\n respectReducedMotion: true,\r\n};\r\n","/**\r\n * Constant coefficient to convert degrees to radians.\r\n */\r\nexport const deg2rad: number = Math.PI / 180;\r\n/**\r\n * Constant coefficient to convert radians to degrees.\r\n */\r\nexport const rad2deg: number = 180 / Math.PI;\r\n/**\r\n * A small value to approximately compare values.\r\n */\r\nexport const epsilon = 0.000001;\r\n\r\n/**\r\n * Linearly interpolates between a and b by t.\r\n */\r\nexport function lerp(a: number, b: number, t: number): number {\r\n return (1 - t) * a + t * b;\r\n}\r\n\r\n/**\r\n * Smoothly interpolates between a and b by t (using cosine interpolation).\r\n */\r\nexport function slerp(a: number, b: number, t: number): number {\r\n return lerp(a, b, (1 - Math.cos(t * Math.PI)) / 2);\r\n}\r\n\r\n/**\r\n * Inversely lerps v between a and b to find t.\r\n */\r\nexport function invlerp(a: number, b: number, v: number): number {\r\n return (v - a) / (b - a);\r\n}\r\n\r\n/**\r\n * Clamps the specified value between a minimum and a maximum.\r\n */\r\nexport function clamp(value: number, min: number, max: number): number {\r\n return Math.min(max, Math.max(min, value));\r\n}\r\n\r\n/**\r\n * Checks if a is approximately equal to b.\r\n */\r\nexport function approximately(a: number, b: number): boolean {\r\n return Math.abs(a - b) < epsilon;\r\n}\r\n","import { Vector } from \"../components\";\r\nimport { Spline } from \"../components/spline\";\r\nimport { Particle } from \"../particles/particle\";\r\n\r\ntype ValueOf = T[keyof T];\r\n\r\n/**\r\n * Represents a value that can be used to drive a particle module.\r\n */\r\nexport type ModuleDriverValue =\r\n | T\r\n | Spline\r\n | ((factor: number, particle?: Particle) => T);\r\n/**\r\n * Represents a value that can be used to modify the properties of a particle over it's lifetime.\r\n */\r\nexport type ModuleFunction = (particle: Particle) => void;\r\n\r\n/**\r\n * Represents the properties of a particle that are drivable through modules.\r\n */\r\nexport type DrivableProperties = Pick<\r\n Particle,\r\n \"color\" | \"opacity\" | \"rotation\" | \"size\"\r\n>;\r\n\r\n/**\r\n * Represents the possible, drivable keys of a particle.\r\n */\r\nexport type DrivableKey = keyof DrivableProperties;\r\n/**\r\n * Represents the possible types of drivable keys.\r\n */\r\nexport type DrivableType = ValueOf;\r\n/**\r\n * Represents the possible factors of drivable values.\r\n */\r\nexport type DrivableFactor = \"lifetime\" | \"relativeLifetime\" | \"size\";\r\n\r\n/**\r\n * Represents a builder for particle modules. Returns an evaluatable module\r\n * function, that can be consumed by emitters.\r\n *\r\n * @remarks\r\n * Not all properties can be driven. TypeScript will validate this at compile time,\r\n * but no internal validation is performed due to performance reasons. Also, note\r\n * that the driving factor is \"lifetime\" by default.\r\n *\r\n * @example\r\n * ```ts\r\n * new ModuleBuilder()\r\n * .drive(\"size\")\r\n * .by((t) => t * 2)\r\n * .through(\"lifetime\")\r\n * .build();\r\n * ```\r\n */\r\nexport class ModuleBuilder {\r\n /**\r\n * The specified key of the builder.\r\n */\r\n protected driverKey?: DrivableKey;\r\n /**\r\n * The value to drive the property with.\r\n */\r\n protected driverValue?: ModuleDriverValue;\r\n\r\n /**\r\n * The factor driving the built function.\r\n *\r\n * @defaultValue \"lifetime\"\r\n */\r\n protected factor: DrivableFactor = \"lifetime\";\r\n\r\n protected isRelative = false;\r\n\r\n /**\r\n * Specifies the key in the particle that should be driven.\r\n *\r\n * @remarks\r\n * Note that not all of a particle's properties are drivable through modules. If you\r\n * need full control of a particle inside of a module, you can use a module function directly.\r\n *\r\n * @returns The chained builder instance.\r\n */\r\n public drive(key: TKey): ModuleBuilder {\r\n this.driverKey = key;\r\n return this;\r\n }\r\n\r\n /**\r\n * Specifies the factor to drive the evaluated value by. Supports \"lifetime\" and \"size\".\r\n *\r\n * @returns The chained builder instance.\r\n */\r\n public through(factor: DrivableFactor): ModuleBuilder {\r\n this.factor = factor;\r\n return this;\r\n }\r\n\r\n /**\r\n * Specifies the value to drive the module behaviour by. This can be a constant,\r\n * a spline or an evaluable function. Note that in the last case, the driving\r\n * factor is passed as a parameter.\r\n *\r\n * @returns The chained builder instance.\r\n */\r\n public by(\r\n driver: ModuleDriverValue\r\n ): ModuleBuilder {\r\n this.driverValue = driver;\r\n return this;\r\n }\r\n\r\n /**\r\n * Specifies that the module function is supposed to act relative to the\r\n * properties initial value.\r\n *\r\n * @remarks\r\n * Note that this is only possible if an \"initial*\" property exists on the\r\n * particle object. The operation applied to the initial and new value\r\n * is dependant on their type:\r\n * - `Vector`: Both vectors are added.\r\n * - `number`: Both numbers are multiplied.\r\n *\r\n * For more advanced relative customizations, consider using the particle\r\n * object in the driver value function instead, like:\r\n * ```ts\r\n * .by((t, p) => p.initialSize + t * 2);\r\n * ```\r\n */\r\n public relative(isRelative = true): ModuleBuilder {\r\n this.isRelative = isRelative;\r\n return this;\r\n }\r\n\r\n /**\r\n * Consumes the builder and returns an evaluatable module function.\r\n *\r\n * @remarks\r\n * Note that you need to specify the driving key and value, otherwise an error\r\n * will be thrown.\r\n */\r\n public build(): ModuleFunction {\r\n if (typeof this.driverKey === \"undefined\") {\r\n throw new Error(\r\n \"No driving key was provided in the module builder. Did you forget a '.drive()' call?\"\r\n );\r\n }\r\n if (typeof this.driverValue === \"undefined\") {\r\n throw new Error(\r\n \"No driving value was provided in the module builder. Did you forget a '.through()' call?\"\r\n );\r\n }\r\n\r\n return (particle: Particle) => {\r\n updateDrivenProperty(\r\n particle,\r\n this.driverKey,\r\n evaluateModuleDriver(\r\n this.driverValue,\r\n calculateModuleFactor(this.factor, particle),\r\n particle\r\n ),\r\n this.isRelative\r\n );\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Evaluates the module driver using a specified factor.\r\n */\r\nfunction evaluateModuleDriver(\r\n driver: ModuleDriverValue,\r\n factor: number,\r\n particle: Particle\r\n): T {\r\n if (typeof driver === \"object\" && \"evaluate\" in driver) {\r\n return driver.evaluate(factor);\r\n }\r\n if (typeof driver === \"function\") {\r\n return (driver as (factor: number, particle: Particle) => T)(\r\n factor,\r\n particle\r\n );\r\n }\r\n return driver;\r\n}\r\n\r\n/**\r\n * Calculates a module factor using a specified particle as context.\r\n */\r\nfunction calculateModuleFactor(\r\n factor: DrivableFactor,\r\n particle: Particle\r\n): number {\r\n switch (factor) {\r\n case \"lifetime\":\r\n return particle.initialLifetime - particle.lifetime;\r\n case \"relativeLifetime\":\r\n return (\r\n (particle.initialLifetime - particle.lifetime) /\r\n particle.initialLifetime\r\n );\r\n case \"size\":\r\n return particle.size;\r\n default:\r\n throw new Error(`Invalid driving factor '${factor}'.`);\r\n }\r\n}\r\n\r\n/**\r\n * Updates a driven property of a particle using the specified value.\r\n *\r\n * @remarks\r\n * If the operation is marked as relative, the function infers the new value\r\n * through the value's type. Note that relative properties must have a\r\n * corresponding \"initial*\" value in the particle's properties.\r\n */\r\nfunction updateDrivenProperty(\r\n particle: Particle,\r\n key: DrivableKey,\r\n value: DrivableType,\r\n relative = false\r\n): void {\r\n if (!relative) {\r\n particle[key] = value as never;\r\n } else {\r\n const initial = particle[\r\n \"initial\" + key[0].toUpperCase() + key.substr(1)\r\n ] as DrivableType;\r\n\r\n if (typeof initial === \"undefined\") {\r\n throw new Error(\r\n `Unable to use relative chaining with key '${key}'; no initial value exists.`\r\n );\r\n }\r\n\r\n if (value instanceof Vector) {\r\n updateDrivenProperty(particle, key, (initial as Vector).add(value));\r\n } else if (typeof value === \"number\") {\r\n updateDrivenProperty(particle, key, (initial as number) * value);\r\n } else {\r\n throw new Error(\r\n `Unable to use relative chaining with particle key '${key}'; no relative operation for '${value}' could be inferred.`\r\n );\r\n }\r\n }\r\n}\r\n","import { Circle, Rect, Vector } from \"../components\";\r\nimport { lerp } from \"./math\";\r\n\r\n/**\r\n * Returns a random value from min to max.\r\n */\r\nexport function randomRange(min = 0, max = 1): number {\r\n return lerp(min, max, Math.random());\r\n}\r\n\r\n/**\r\n * Picks a random element from the specified array. Returns undefined if the array is empty.\r\n */\r\nexport function pick(arr: T[]): T {\r\n return arr.length === 0\r\n ? undefined\r\n : arr[Math.floor(Math.random() * arr.length)];\r\n}\r\n\r\n/**\r\n * Returns a random unit vector.\r\n */\r\nexport function randomUnitVector(): Vector {\r\n const theta = randomRange(0, 2 * Math.PI);\r\n const z = randomRange(-1, 1);\r\n return new Vector(\r\n Math.sqrt(1 - z * z) * Math.cos(theta),\r\n Math.sqrt(1 - z * z) * Math.sin(theta),\r\n z\r\n );\r\n}\r\n\r\n/**\r\n * Returns a random point inside the given rect.\r\n */\r\nexport function randomInsideRect(rect: Rect): Vector {\r\n return new Vector(\r\n rect.x + randomRange(0, rect.width),\r\n rect.y + randomRange(0, rect.height)\r\n );\r\n}\r\n\r\nexport function randomInsideCircle(circle: Circle): Vector {\r\n const theta = randomRange(0, 2 * Math.PI);\r\n const radius = randomRange(0, circle.radius);\r\n return new Vector(\r\n circle.x + Math.cos(theta) * radius,\r\n circle.y + Math.sin(theta) * radius\r\n );\r\n}\r\n","import { Variation, evaluateVariation } from \"./variation\";\r\n\r\n/**\r\n * Represents the lookup that maps resolveable element keys to their HTML strings.\r\n *\r\n * @remarks\r\n * The default shapes are made to fit inside a dimension of 10x10 pixels, except\r\n * the 'star' shape, which exceeds it slightly.\r\n */\r\nexport const resolvableShapes: Record = {\r\n square: `
`,\r\n rectangle: `
`,\r\n circle: ``,\r\n roundedSquare: `
`,\r\n roundedRectangle: `
`,\r\n star: ``,\r\n};\r\n\r\n/**\r\n * Resolves the specified element factory using the resolvable elements, if needed.\r\n */\r\nexport function resolveShapeFactory(\r\n factory: Variation\r\n): HTMLElement {\r\n // Retrieve the unresolved element from the factory.\r\n const shape = evaluateVariation(factory);\r\n // If a string is returned, we need to resolve the element. This means\r\n // looking up the string in the resolver lookup. If the key was not\r\n // resolvable, we throw an error.\r\n if (typeof shape === \"string\") {\r\n const resolved = resolvableShapes[shape];\r\n if (!resolved) {\r\n throw new Error(\r\n `Failed to resolve shape key '${shape}'. Did you forget to add it to the 'resolvableShapes' lookup?`\r\n );\r\n }\r\n // We're in luck, we can resolve the element! We create a dummy
element\r\n // to set the innerHTML of, and return the first element child.\r\n const dummy = document.createElement(\"div\");\r\n dummy.innerHTML = resolved;\r\n return dummy.firstElementChild as HTMLElement;\r\n }\r\n return shape;\r\n}\r\n","import { Circle, Rect, Vector } from \"../components\";\r\nimport { randomInsideCircle, randomInsideRect } from \"./random\";\r\n\r\n/**\r\n * Represents a method used for sampling points to emit particles from.\r\n */\r\nexport type SourceSampler = () => Vector;\r\n/**\r\n * Represents all types where a source type can be dynamically inferred.\r\n */\r\nexport type DynamicSourceType = Circle | Rect | HTMLElement | MouseEvent;\r\n\r\n/**\r\n * Dynamically infers a source sampler for the specified source type.\r\n */\r\nexport function dynamicSource(source: unknown): SourceSampler {\r\n if (source instanceof HTMLElement) {\r\n return elementSource(source);\r\n }\r\n if (source instanceof Circle) {\r\n return circleSource(source);\r\n }\r\n if (source instanceof Rect) {\r\n return rectSource(source);\r\n }\r\n if (source instanceof MouseEvent) {\r\n return mouseSource(source);\r\n }\r\n\r\n throw new Error(`Cannot infer the source type of '${source}'.`);\r\n}\r\n\r\n/**\r\n * Creates a sampler to retrieve random points inside a specified HTMLElement.\r\n */\r\nexport function elementSource(source: HTMLElement): SourceSampler {\r\n return () => randomInsideRect(Rect.fromElement(source));\r\n}\r\n\r\n/**\r\n * Creates a sampler to retrieve the position of a mouse event.\r\n */\r\nexport function mouseSource(source: MouseEvent): SourceSampler {\r\n return () =>\r\n new Vector(\r\n window.scrollX + source.clientX,\r\n window.scrollY + source.clientY\r\n );\r\n}\r\n/**\r\n * Creates a sampler to retrieve random points inside a specified rectangle.\r\n */\r\nexport function rectSource(source: Rect): SourceSampler {\r\n return () => randomInsideRect(source);\r\n}\r\n/**\r\n * Creates a sampler to retrieve random points inside a specified circle.\r\n */\r\nexport function circleSource(source: Circle): SourceSampler {\r\n return () => randomInsideCircle(source);\r\n}\r\n","import { Color, Gradient } from \"../components\";\r\nimport { Spline } from \"../components/spline\";\r\nimport { pick, randomRange } from \"./random\";\r\n\r\n/**\r\n * Represents a junction of types that can be used as a variation on a value.\r\n * At any point in time, the variation can be evaluated to retrieve a \"primitive\" value.\r\n * The variation can consist of a constant, an array or an evaluateable function.\r\n */\r\nexport type Variation = T | T[] | (() => T);\r\n\r\n/**\r\n * Returns a value instance of a variation.\r\n */\r\nexport function evaluateVariation(variation: Variation): T {\r\n if (Array.isArray(variation)) return pick(variation);\r\n if (typeof variation === \"function\") return (variation as () => T)();\r\n return variation;\r\n}\r\n\r\n/**\r\n * Creates a variation function that returns a random number from min to max.\r\n */\r\nexport function range(min: number, max: number): Variation {\r\n return () => randomRange(min, max);\r\n}\r\n\r\n/**\r\n * Creates a variation function that skews the specified value by a specified, absolute\r\n * amount. This means that instead of the value itself, a random number that deviates\r\n * at most by the specified amount is returned.\r\n *\r\n * @remarks\r\n * If you want to skew by a percentage instead, use `skewRelative`.\r\n */\r\nexport function skew(value: number, amount: number): Variation {\r\n return () => value + randomRange(-amount, amount);\r\n}\r\n\r\n/**\r\n * Creates a variation function that skews the specified value by a specified percentage.\r\n * This means that instead of the value itself, a random number that deviates by a maximum\r\n * of the specified percentage is returned.\r\n */\r\nexport function skewRelative(\r\n value: number,\r\n percentage: number\r\n): Variation {\r\n return () => value * (1 + randomRange(-percentage, percentage));\r\n}\r\n\r\n/**\r\n * Creates a variation function that returns a random sample from the given spline.\r\n *\r\n * @param spline The spline to sample from.\r\n */\r\nexport function splineSample(spline: Spline): Variation {\r\n return () => spline.evaluate(Math.random());\r\n}\r\n\r\n/**\r\n * Creates a variation function that returns a random sample from the given gradient.\r\n *\r\n * @remarks\r\n * This function is an alias for the spline variation, since a gradient is just\r\n * a spline under the hood.\r\n *\r\n * @param gradient The gradient to sample from.\r\n */\r\nexport function gradientSample(gradient: Gradient): Variation {\r\n return splineSample(gradient);\r\n}\r\n","import { scene } from \"../\";\r\nimport { Color, Vector } from \"../components\";\r\nimport { Emitter } from \"../particles/emitter\";\r\nimport { ModuleBuilder, ModuleFunction } from \"../systems/modules\";\r\nimport * as random from \"../systems/random\";\r\nimport * as sources from \"../systems/sources\";\r\nimport * as variation from \"../systems/variation\";\r\nimport * as util from \"../util\";\r\n\r\n/**\r\n * The configuration to apply to the confetti.\r\n */\r\nexport interface ConfettiConfiguration {\r\n count: variation.Variation;\r\n spread: variation.Variation;\r\n speed: variation.Variation;\r\n size: variation.Variation;\r\n rotation: variation.Variation;\r\n color: variation.Variation;\r\n shapes: variation.Variation;\r\n modules: ModuleFunction[];\r\n}\r\n\r\n/**\r\n * The standard confetti template.\r\n *\r\n * @param source The source to emit the confetti from.\r\n * @param options The (optional) configuration overrides.\r\n */\r\nexport function confetti(\r\n source: sources.DynamicSourceType,\r\n options?: Partial\r\n): Emitter {\r\n const populated = util.overrideDefaults(\r\n {\r\n count: variation.range(20, 40),\r\n spread: variation.range(35, 45),\r\n speed: variation.range(300, 600),\r\n size: variation.skew(1, 0.2),\r\n rotation: () => random.randomUnitVector().scale(180),\r\n color: () => Color.fromHsl(random.randomRange(0, 360), 100, 70),\r\n modules: [\r\n new ModuleBuilder()\r\n .drive(\"size\")\r\n .by((t) => Math.min(1, t * 3))\r\n .relative()\r\n .build(),\r\n new ModuleBuilder()\r\n .drive(\"rotation\")\r\n .by((t) => new Vector(140, 200, 260).scale(t))\r\n .relative()\r\n .build(),\r\n ],\r\n shapes: [\"square\", \"circle\"],\r\n },\r\n options\r\n );\r\n\r\n const emitter = scene.current.createEmitter({\r\n emitterOptions: {\r\n loops: 1,\r\n duration: 8,\r\n modules: populated.modules,\r\n },\r\n emissionOptions: {\r\n rate: 0,\r\n bursts: [{ time: 0, count: populated.count }],\r\n\r\n sourceSampler: sources.dynamicSource(source),\r\n angle: variation.skew(\r\n -90,\r\n variation.evaluateVariation(populated.spread)\r\n ),\r\n\r\n initialLifetime: 8,\r\n initialSpeed: populated.speed,\r\n initialSize: populated.size,\r\n initialRotation: populated.rotation,\r\n initialColor: populated.color,\r\n },\r\n rendererOptions: {\r\n shapeFactory: populated.shapes,\r\n },\r\n });\r\n\r\n return emitter;\r\n}\r\n","export * from \"./confetti\";\r\nexport * from \"./sparkles\";\r\n","import { scene } from \"..\";\r\nimport { Color, NumericSpline, Vector } from \"../components\";\r\nimport { Emitter } from \"../particles/emitter\";\r\nimport { ModuleBuilder, ModuleFunction } from \"../systems/modules\";\r\nimport * as random from \"../systems/random\";\r\nimport * as sources from \"../systems/sources\";\r\nimport * as variation from \"../systems/variation\";\r\nimport * as util from \"../util\";\r\n\r\n/**\r\n * The configuration to apply to the sparkles.\r\n */\r\nexport interface SparkleConfiguration {\r\n lifetime: variation.Variation;\r\n count: variation.Variation;\r\n speed: variation.Variation;\r\n size: variation.Variation;\r\n rotation: variation.Variation;\r\n color: variation.Variation;\r\n modules: ModuleFunction[];\r\n}\r\n\r\n/**\r\n * The standard sparkles template.\r\n *\r\n * @param source The source to emit the sparkles from.\r\n * @param options The (optional) configuration overrides.\r\n */\r\nexport function sparkles(\r\n source: sources.DynamicSourceType,\r\n options?: Partial\r\n): Emitter {\r\n const populated = util.overrideDefaults(\r\n {\r\n lifetime: variation.range(1, 2),\r\n count: variation.range(10, 20),\r\n speed: variation.range(100, 200),\r\n size: variation.range(0.8, 1.8),\r\n rotation: () => new Vector(0, 0, random.randomRange(0, 360)),\r\n color: () => Color.fromHsl(50, 100, random.randomRange(55, 85)),\r\n modules: [\r\n new ModuleBuilder()\r\n .drive(\"rotation\")\r\n .by((t) => new Vector(0, 0, 200).scale(t))\r\n .relative()\r\n .build(),\r\n new ModuleBuilder()\r\n .drive(\"size\")\r\n .by(\r\n new NumericSpline(\r\n { time: 0, value: 0 },\r\n { time: 0.3, value: 1 },\r\n { time: 0.7, value: 1 },\r\n { time: 1, value: 0 }\r\n )\r\n )\r\n .through(\"relativeLifetime\")\r\n .relative()\r\n .build(),\r\n new ModuleBuilder()\r\n .drive(\"opacity\")\r\n .by(\r\n new NumericSpline(\r\n { time: 0, value: 1 },\r\n { time: 0.5, value: 1 },\r\n { time: 1, value: 0 }\r\n )\r\n )\r\n .through(\"relativeLifetime\")\r\n .build(),\r\n ],\r\n },\r\n options\r\n );\r\n\r\n const emitter = scene.current.createEmitter({\r\n emitterOptions: {\r\n loops: 1,\r\n duration: 3,\r\n useGravity: false,\r\n modules: populated.modules,\r\n },\r\n emissionOptions: {\r\n rate: 0,\r\n bursts: [{ time: 0, count: populated.count }],\r\n\r\n sourceSampler: sources.dynamicSource(source),\r\n angle: variation.range(0, 360),\r\n\r\n initialLifetime: populated.lifetime,\r\n initialSpeed: populated.speed,\r\n initialSize: populated.size,\r\n initialRotation: populated.rotation,\r\n initialColor: populated.color,\r\n },\r\n rendererOptions: {\r\n applyLighting: undefined,\r\n shapeFactory: \"star\",\r\n },\r\n });\r\n\r\n return emitter;\r\n}\r\n","/**\r\n * Replaces the supplied defaults with the properties specified in the overrides.\r\n * This returns a new object.\r\n */\r\nexport function overrideDefaults(defaults: T, overrides?: Partial): T {\r\n return Object.assign({}, defaults, overrides);\r\n}\r\n","export * from \"./config\";\r\nexport * from \"./rotation\";\r\nexport * from \"./rules\";\r\nexport * from \"./lazy\";\r\n","/**\r\n * A factory method used to initialize a lazy value.\r\n */\r\ntype LazyFactory = () => T;\r\n/**\r\n * A predicate method used to check if a lazy value was already initialized.\r\n */\r\ntype ExistsPredicate = (value: T) => boolean;\r\n\r\n/**\r\n * A wrapper class to lazily initialize a value.\r\n * Supports custom factory and predicate methods.\r\n */\r\nexport class Lazy {\r\n /**\r\n * The current value of the lazy object. Will be initialized, if the 'exists'\r\n * predicate doesn't match.\r\n */\r\n public get current(): T {\r\n if (!this.exists(this.value)) {\r\n this.value = this.factory();\r\n }\r\n return this.value;\r\n }\r\n\r\n private value?: T;\r\n\r\n constructor(\r\n private factory: LazyFactory,\r\n private exists: ExistsPredicate = Lazy.defaultExists\r\n ) {}\r\n\r\n private static defaultExists(value: T): boolean {\r\n return typeof value !== \"undefined\";\r\n }\r\n}\r\n","import { Vector } from \"../components\";\r\nimport { deg2rad } from \"../systems/math\";\r\n\r\n/**\r\n * Converts the specified euler rotation (in degrees) into the corresponding normal vector.\r\n *\r\n * @remarks\r\n * The normal is calculated by placing a (figurative) plane in a coordinate-system's\r\n * origin, and rotating it by the specified angles. Note that the z-component of the\r\n * rotation is irrelevant for the normal and can be ignored. Then, two vectors\r\n * describing the orientation of the plane are calculated. Their cross product\r\n * denotes the normal vector.\r\n *\r\n * @param rotation The euler rotation angles (in degrees) to calculate the normal for.\r\n */\r\nexport function rotationToNormal(rotation: Vector): Vector {\r\n const alpha = rotation.x * deg2rad;\r\n const beta = rotation.y * deg2rad;\r\n\r\n const a = new Vector(Math.cos(beta), 0, Math.sin(beta));\r\n const b = new Vector(0, Math.cos(alpha), Math.sin(alpha));\r\n\r\n return a.cross(b);\r\n}\r\n","import { Particle } from \"../particles/particle\";\r\n\r\n/**\r\n * Contains a set of pre-defined particle despawning rules.\r\n */\r\nexport const despawningRules = {\r\n /**\r\n * A rule that despawns a particle once its lifetime is over.\r\n */\r\n lifetime: function (particle: Particle): boolean {\r\n return particle.lifetime <= 0;\r\n },\r\n /**\r\n * A rule that despawns a particle once its y-coordinate is outside of the document.\r\n */\r\n bounds: function (particle: Particle): boolean {\r\n // Get document height: https://stackoverflow.com/a/44077777/5507624\r\n const height = document.documentElement.scrollHeight;\r\n return particle.location.y > height;\r\n },\r\n};\r\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(\"./src/index.ts\");\n"],"sourceRoot":""}