@wave3d/core 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/model.d.ts +30 -2
- package/dist/config/model.js +4 -1
- package/dist/config/model.js.map +1 -1
- package/dist/presets.js +35 -0
- package/dist/presets.js.map +1 -1
- package/dist/renderer/WaveRenderer.d.ts +4 -2
- package/dist/renderer/WaveRenderer.js +11 -5
- package/dist/renderer/WaveRenderer.js.map +1 -1
- package/dist/renderer/particleField.d.ts +35 -4
- package/dist/renderer/particleField.js +150 -13
- package/dist/renderer/particleField.js.map +1 -1
- package/dist/renderer/shaders.js +178 -86
- package/dist/renderer/shaders.js.map +1 -1
- package/dist/standalone/wave3d.standalone.js +2321 -2248
- package/package.json +1 -1
- package/skills/wave3d/SKILL.md +1 -1
package/dist/presets.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presets.js","names":[],"sources":["../src/presets.ts"],"sourcesContent":["/**\n * Built-in presets: each a complete studio config (scene + one or more waves) in the wave model.\n * IP-clean — no copyrighted assets. The studio layers its own extra presets (and its historical\n * \"Stripe *\" display names) on top; see apps/studio/src/presets.ts.\n */\nimport { createDefaultConfig, makeStops, makeWaveSpread } from \"./config/model\";\nimport type { ParticlesConfig, StudioConfig, NoiseBand } from \"./config/model\";\n\nconst RAD = 180 / Math.PI;\n\n/**\n * Reusable particle STYLES applied to a wave's `particles` block. Surfaced in the studio's per-wave\n * Particles folder (the \"style\" picker) and used by the \"Particle Zoo\" showcase preset. Each is a dust\n * look independent of the wave it rides — clone before mutating (`structuredClone`).\n */\nexport const PARTICLE_PRESETS: Record<string, ParticlesConfig> = {\n Glitter: {\n count: 16000,\n size: 2.6,\n seed: 7,\n color: \"#ffdca8\",\n shape: \"glitter\",\n edgeBias: 1,\n drift: 300,\n bias: -0.6,\n twinkle: 0.8,\n },\n Embers: {\n count: 16000,\n size: 3.6,\n seed: 7,\n color: \"#ff8a2c\",\n color2: \"#ffe19a\",\n shape: \"soft\",\n edgeBias: 0.15,\n drift: 40,\n rise: 320,\n wander: 120,\n twinkle: 0.85,\n life: 6,\n },\n Snow: {\n count: 12000,\n size: 3,\n seed: 4,\n color: \"#eef4ff\",\n color2: \"#bcd0ee\",\n shape: \"soft\",\n edgeBias: 0.1,\n drift: 20,\n rise: -260,\n wander: 80,\n twinkle: 0.5,\n life: 8,\n },\n Sparks: {\n count: 9000,\n size: 5,\n seed: 9,\n color: \"#ffd27a\",\n color2: \"#fff4d0\",\n shape: \"streak\",\n edgeBias: 1,\n drift: 620,\n rise: 90,\n wander: 20,\n bias: -0.4,\n twinkle: 0.9,\n life: 2.5,\n },\n Fireflies: {\n count: 2200,\n size: 5,\n seed: 11,\n color: \"#dfff9a\",\n color2: \"#8fd94a\",\n shape: \"star\",\n edgeBias: 0.1,\n drift: 25,\n swirl: 0.3,\n wander: 170,\n twinkle: 1,\n life: 5,\n },\n Bubbles: {\n count: 3000,\n size: 7,\n sizeJitter: 0.9,\n seed: 6,\n color: \"#cdeefb\",\n color2: \"#8fd0e6\",\n shape: \"ring\",\n edgeBias: 0.2,\n drift: 30,\n rise: 240,\n wander: 60,\n twinkle: 0.3,\n life: 7,\n },\n};\n\n/** Degrees → radians (for the Particle Zoo's per-wave rotation, authored in degrees). */\nconst rad = (deg: number): number => (deg * Math.PI) / 180;\n\n/** Clamp a signed magnitude to ±m (used to cap the Zoo's long-range particle motion terms). */\nconst capMag = (v: number | undefined, m: number): number | undefined =>\n v == null ? v : Math.sign(v) * Math.min(Math.abs(v), m);\n\n/** Build a preset from a set of wave parameters. rotation/hue are given in RADIANS and\n * converted to degrees. All presets are solid-theme, so they reuse the hero palette +\n * surfaceColor fibers (600/0.2) and sheen 0, like the hero. camTarget/zoom frame the\n * wave (we pan the look-at to centre each one). */\nfunction buildPreset(p: {\n speed: number;\n contrast: number;\n sat: number;\n hueRad: number;\n dispX: number;\n dispZ: number;\n dispAmt: number;\n pos: [number, number, number];\n rotRad: [number, number, number];\n scale: [number, number, number];\n twF: [number, number, number];\n twP: [number, number, number];\n glow: [number, number, number];\n grain: number;\n blur: number;\n zoom: number;\n camTarget: [number, number];\n noiseBands?: NoiseBand[];\n twistMotion?: boolean;\n}): StudioConfig {\n const c = createDefaultConfig();\n const w = c.waves[0];\n w.speed = p.speed;\n w.colorContrast = p.contrast;\n w.colorSaturation = p.sat;\n w.hueShift = p.hueRad * RAD;\n w.displaceFrequency = { x: p.dispX, y: p.dispZ };\n w.displaceAmount = p.dispAmt;\n w.position = { x: p.pos[0], y: p.pos[1], z: p.pos[2] };\n w.rotation = { x: p.rotRad[0] * RAD, y: p.rotRad[1] * RAD, z: p.rotRad[2] * RAD };\n w.scale = { x: p.scale[0], y: p.scale[1], z: p.scale[2] };\n w.twistFrequency = { x: p.twF[0], y: p.twF[1], z: p.twF[2] };\n w.twistPower = { x: p.twP[0], y: p.twP[1], z: p.twP[2] };\n w.creaseLight = p.glow[0];\n w.creaseSharpness = p.glow[1];\n w.creaseSoftness = p.glow[2];\n if (p.noiseBands) w.noiseBands = p.noiseBands;\n if (p.twistMotion) w.twistMotion = true;\n c.grain = p.grain;\n c.blur = p.blur;\n c.cameraPosition = { x: 100, y: 0, z: 5000 };\n c.cameraTarget = { x: p.camTarget[0], y: p.camTarget[1], z: 0 };\n c.cameraZoom = p.zoom;\n return c;\n}\n\n/** Presets: each a complete studio config (scene + one or more waves) in the wave model. */\nexport const PRESETS: Record<string, () => StudioConfig> = {\n // The app's default wave: a centred, full-frame ribbon (window-independent framing).\n // Shown first and named \"Hero\"; several presets below derive from it.\n Hero: () =>\n buildPreset({\n speed: 0.04,\n contrast: 1,\n sat: 1,\n hueRad: -0.00159265,\n dispX: 0.005831,\n dispZ: 0.016001,\n dispAmt: -7.821,\n pos: [380, -301.7, -11.1],\n rotRad: [-0.44959, -0.11759, 1.874407],\n scale: [9, 8, 5],\n twF: [-0.65, 0.41, -0.58],\n twP: [3.63, 0.7, 3.95],\n glow: [1.98, 0.806, 0.834],\n grain: 1.1,\n blur: 0.02,\n zoom: 0.55,\n camTarget: [-420, -200], // user-tuned default framing\n }),\n // Stripe's real hero, recreated faithfully: an orthographic ×10 scene that overflows the\n // frame, so only the twisted crop shows. This is the model's plain default config.\n \"Wave 2\": () => createDefaultConfig(),\n // camTarget on the waves below is a first-pass centring; tune per-wave. NOTE: Wave 4 also\n // uses a variant vertex shader (animated twist-X wobble) we don't fully replicate — its\n // STATIC frame is close, the motion differs.\n \"Wave 3\": () =>\n buildPreset({\n speed: 0.08,\n contrast: 1,\n sat: 1,\n hueRad: -0.00159265,\n dispX: 0.005831,\n dispZ: 0.016001,\n dispAmt: -7.821,\n pos: [-200.7, -65.4, -11.1],\n rotRad: [-2.875593, 3.095927, -2.925927],\n scale: [3, 3, 3],\n twF: [0.059, 0.32, -0.397],\n twP: [3.63, 0.44, 5.99],\n glow: [3.86, 0.923, 1],\n grain: 1.2,\n blur: 0.02,\n zoom: 1.3,\n camTarget: [-104, 13], // centred; zoomed in (wide/flat wave)\n }),\n \"Wave 4\": () =>\n buildPreset({\n speed: 0.0525,\n contrast: 0.969,\n sat: 1.383,\n hueRad: 0.0376991,\n dispX: 0.005,\n dispZ: 0.0212,\n dispAmt: 6.68,\n pos: [206.1, -438, -11.1],\n rotRad: [-0.666018, -0.031416, 0.779115],\n scale: [6.0501, 8.3983, 6.9854],\n twF: [-0.424, 0.024, -1.312],\n twP: [1.81, 0.94, 4.76],\n glow: [1.55, 1.174, 0.972],\n grain: 0.576,\n blur: 0,\n zoom: 0.9316,\n camTarget: [194, -402], // centred on the wave\n twistMotion: true, // variant vertex shader — animated twist-X wobble\n noiseBands: [\n {\n startX: 0.856,\n endX: 1,\n startY: 0,\n endY: 0.913,\n feather: 0.5,\n strength: 0.346,\n frequency: 1018,\n colorAttenuation: 1,\n parabolaPower: 0,\n },\n {\n startX: 0.038,\n endX: 0.538,\n startY: 0.105,\n endY: 1,\n feather: 0.3315,\n strength: 1,\n frequency: 190,\n colorAttenuation: 0,\n parabolaPower: 2.11,\n },\n ],\n }),\n // The dark-background hero: identical geometry/camera to the default hero, but theme\n // \"wireframe\" → the line shader on a dark page background, with grain 1.2. Same palette.\n Wireframe: () => {\n const c = createDefaultConfig();\n c.waves[0].theme = \"wireframe\";\n c.grain = 1.2;\n c.background = \"#0a2540\"; // dark navy page background\n c.transparentBackground = false;\n return c;\n },\n \"Neon Dark Multistrand\": () => {\n const c = createDefaultConfig();\n const w = c.waves[0];\n w.theme = \"wireframe\"; // line shader on the near-black background — neon wireframe look\n w.blendMode = \"additive\";\n w.palette = makeStops([\"#00f5d4\", \"#00bbf9\", \"#9b5de5\", \"#f15bb5\", \"#fee440\"]);\n w.creaseLight = 1.0;\n c.background = \"#05060c\";\n c.transparentBackground = false; // fill the dark bg so the neon lines read on black (not the page)\n c.waves = makeWaveSpread(w, 3); // three overlapping neon waves\n c.waveCount = 3;\n return c;\n },\n \"Mesh Gradient\": () => {\n const c = PRESETS[\"Hero\"](); // the centred default \"Hero\" wave\n const w = c.waves[0];\n w.gradientType = \"mesh\";\n w.meshGradientPoints = [\n { color: \"#0a84ff\", x: 0.06, y: 0.9, influence: 0.68 },\n { color: \"#64d2ff\", x: 0.88, y: 0.92, influence: 0.72 },\n { color: \"#bf5af2\", x: 0.5, y: 0.64, influence: 0.58 },\n { color: \"#ff375f\", x: 0.1, y: 0.14, influence: 0.7 },\n { color: \"#ff9f0a\", x: 0.84, y: 0.12, influence: 0.74 },\n { color: \"#30d158\", x: 0.94, y: 0.5, influence: 0.54 },\n ];\n w.meshGradientSoftness = 0.68;\n w.blendMode = \"normal\";\n w.hueShift = 0;\n w.colorContrast = 1.06;\n w.colorSaturation = 1.12;\n w.fiberStrength = 0.14;\n c.grain = 0.3;\n c.blur = 0.008;\n c.background = \"#070914\";\n c.backgroundMode = \"color\";\n c.transparentBackground = false;\n return c;\n },\n \"Solar Bloom\": () => {\n // Radial gradient: a warm core blooming out to a deep-indigo edge. usePaletteTexture off so\n // our own stops map along the radial gradCoord instead of sampling the baked hero LUT.\n const c = PRESETS[\"Hero\"]();\n const w = c.waves[0];\n w.usePaletteTexture = false;\n w.gradientType = \"radial\";\n w.gradientShift = 0.14;\n w.palette = [\n { color: \"#fff3c4\", pos: 0 }, // warm-white core\n { color: \"#ffd166\", pos: 0.22 }, // gold\n { color: \"#ff8c42\", pos: 0.42 }, // orange\n { color: \"#ff5d8f\", pos: 0.62 }, // coral-pink\n { color: \"#a64dff\", pos: 0.82 }, // violet\n { color: \"#241246\", pos: 1 }, // deep indigo edge\n ];\n w.blendMode = \"normal\";\n w.hueShift = 0;\n w.colorContrast = 1.05;\n w.colorSaturation = 1.18;\n w.fiberStrength = 0.12;\n c.grain = 0.3;\n c.blur = 0.01;\n // Deep warm radial vignette behind the bloom.\n c.background = \"#0a0714\";\n c.backgroundMode = \"gradient\";\n c.backgroundGradientType = \"radial\";\n c.backgroundGradientSource = \"stops\";\n c.backgroundPalette = makeStops([\"#2a1330\", \"#08040f\"]);\n c.transparentBackground = false;\n return c;\n },\n \"Latte Ring\": () => {\n // A warm cream-and-gold ring of combed silk curling around a dark void — the crema swirl on a\n // latte. The camera ORBITS a wide radial fan (arc 286°) so its combed length sweeps across the\n // frame as a flowing arc instead of a head-on fan; a mesh gradient warms it gold→cream with an\n // orange edge, and a noise band frays the fibers finer toward the tips. Exercises the radial wave\n // mode + the particle layer (ambient field + shed-from-edge dust into the void).\n const c = PRESETS[\"Hero\"]();\n const w = c.waves[0];\n // A wide radial fan (fans the ribbon's length); the orbiting camera below crops it to a ring.\n w.radialAmount = 0.72;\n w.radialArc = 286;\n w.radialCenter = -160;\n w.radialRadius = 300;\n w.radialSpread = 1.47;\n w.rotation = { x: 0, y: 0, z: 0 };\n w.position = { x: -280, y: -320, z: 0 };\n w.scale = { x: 1.12, y: 1.12, z: 1.12 };\n w.opacity = 0.5;\n // A big broad swell (amount 101.73) with a fine second octave riding on it, so the ring's silk\n // ripples and folds as it turns; `speed` sets the swell's drift rate.\n w.displaceFrequency = { x: 0.0026, y: 0.0048 };\n w.displaceAmount = 101.73;\n w.detailAmount = 6;\n w.detailFrequency = 0.1;\n w.speed = 0.21;\n // Fine combed fibers; the noise band overrides them finer + wispier over the OUTER half (uv.y>0.5)\n // for organic variation instead of a uniform comb. (Bands override fiber params per uv region.)\n w.fiberCount = 110;\n w.fiberStrength = 0.95;\n w.creaseLight = 0.55;\n w.edgeFeather = 0.34;\n w.noiseBands = [\n {\n startX: 0,\n endX: 1,\n startY: 0.5,\n endY: 1,\n feather: 0.4,\n strength: 1,\n frequency: 300,\n colorAttenuation: 0.85,\n parabolaPower: 2.5,\n },\n ];\n // Mesh gradient: gold + cream dominant with an orange accent — the latte's crema tones. A 2D\n // colour field (not a length-wise ramp) so the warmth pools within the fibers.\n w.usePaletteTexture = false;\n w.gradientType = \"mesh\";\n w.meshGradientSoftness = 0.7;\n w.meshGradientPoints = [\n { color: \"#f3c06a\", x: 0.5, y: 0.1, influence: 0.7 }, // warm gold\n { color: \"#f9edd4\", x: 0.34, y: 0.36, influence: 0.62 }, // hot cream\n { color: \"#e6923a\", x: 0.15, y: 0.55, influence: 0.5 }, // orange accent\n { color: \"#f1d49a\", x: 0.82, y: 0.42, influence: 0.55 }, // gold\n { color: \"#ece7d8\", x: 0.58, y: 0.88, influence: 0.72 }, // cool cream\n ];\n w.blendMode = \"normal\";\n w.hueShift = 0;\n w.colorContrast = 1.05;\n w.colorSaturation = 1.15;\n // Orbit the camera around the fan so its length reads as a sweeping arc wrapping the void.\n c.cameraDistance = 600;\n c.cameraPosition = { x: -854.327, y: 135.331, z: 478.048 };\n c.cameraTarget = { x: -720.043, y: 10.575, z: -93.27 };\n c.cameraZoom = 1.222;\n // Scene: a near-black void with gentle bloom on the silk + dust.\n c.background = \"#050404\";\n c.backgroundMode = \"color\";\n c.transparentBackground = false;\n c.grain = 0.25;\n c.blur = 0;\n c.bloomStrength = 0.18;\n c.bloomRadius = 0.55;\n c.bloomThreshold = 0.72;\n // Golden dust shed off the ring's own edge into the void (biased to one flank). Per-wave: it rides\n // this wave's deform and drifts outward from it. edgeBias 1 = spawn on the rim (the shed look).\n w.particles = {\n count: 20000,\n size: 2.9,\n color: \"#ffdca8\",\n seed: 7,\n twinkle: 0.8,\n edgeBias: 1,\n drift: 490,\n bias: -0.6,\n };\n return c;\n },\n \"Particle Zoo\": () => {\n // One scene demoing every particle STYLE — each wave sheds a different kind of dust off its own\n // surface (embers / snow / sparks / fireflies / bubbles). Every wave is a DIFFERENT shape family\n // too (dome / flat sheet / radial fan / helix coil / twist curl), spread apart so none overlap and\n // the frame stays full. The showcase for the per-wave particle system; styles come from\n // PARTICLE_PRESETS (the studio \"preset style\" picker).\n const c = createDefaultConfig();\n c.background = \"#05070d\";\n c.backgroundMode = \"color\";\n c.transparentBackground = false;\n c.grain = 0.26;\n c.blur = 0;\n c.bloomStrength = 0.3;\n c.bloomThreshold = 0.66; // high, so the central sparks fan glows without blowing the middle out\n c.cameraPosition = { x: 100, y: 0, z: 5000 };\n c.cameraTarget = { x: 0, y: 0, z: 0 };\n c.cameraZoom = 0.6;\n // Five well-separated waves, each a DIFFERENT shape family so the silhouettes read as distinct,\n // not five copies of one ribbon. Frame at cameraZoom 0.6 spans ~2222×1250 world units centred on\n // the origin (x ∈ [-1111, 1111], y ∈ [-625, 625], orthographic → screen-xy = world-xy), so the\n // positions/scales below keep the meshes from overlapping. `shape` carries the per-family knobs\n // (displace / twist / helix / radial); `rot` is in degrees. style, palette, opacity as before.\n const zoo = [\n {\n // Embers rising off a broad DOME — low-frequency, high-amplitude displacement mound.\n style: \"Embers\",\n palette: [\"#ff7a1e\", \"#ffd27a\", \"#c23a12\"],\n pos: [-720, 285],\n scale: [1.0, 1.0, 1.0],\n rot: [-20, 0, -14],\n opacity: 0.72,\n shape: {\n displaceFrequency: { x: 0.0024, y: 0.0065 },\n displaceAmount: 118,\n twistPower: { x: 2.4, y: 2.4, z: 3.2 },\n },\n },\n {\n // Snow settling on a near-flat drifting SHEET — tilted toward the camera, barely rippled.\n style: \"Snow\",\n palette: [\"#8fb8e8\", \"#e8f1fb\", \"#aeb9d6\"],\n pos: [700, 320],\n scale: [1.1, 1.0, 0.9],\n rot: [-62, 0, 12],\n opacity: 0.72,\n shape: {\n displaceFrequency: { x: 0.006, y: 0.013 },\n displaceAmount: 22,\n twistPower: { x: 0.8, y: 0.8, z: 1.0 },\n },\n },\n {\n // Sparks bursting off a RADIAL FAN — the one spiky, fanned silhouette; dimmed so it glows\n // without blowing the centre out.\n style: \"Sparks\",\n palette: [\"#ffd27a\", \"#fff4d0\", \"#c8853a\"],\n pos: [0, -30],\n scale: [0.85, 0.85, 0.85],\n rot: [0, 0, 0],\n opacity: 0.32,\n shape: {\n radialAmount: 0.82,\n radialArc: 118,\n radialCenter: 90, // fan points up\n radialRadius: 40,\n radialSpread: 1.0,\n displaceAmount: 30,\n },\n },\n {\n // Fireflies wandering around a HELIX coil — a screw-thread column of light.\n style: \"Fireflies\",\n palette: [\"#3d5a24\", \"#7bd23a\", \"#40521f\"],\n pos: [-560, -300],\n scale: [1.25, 1.25, 1.25],\n rot: [0, 0, 8],\n opacity: 0.72,\n shape: {\n helixTurns: 3,\n helixRadius: 44,\n helixRoll: 1,\n displaceAmount: 8,\n twistPower: { x: 1.0, y: 1.0, z: 1.2 },\n },\n },\n {\n // Bubbles rising off a strongly TWISTED curl — an S-ribbon coiling on its length.\n style: \"Bubbles\",\n palette: [\"#2e8fb0\", \"#7fd4e8\", \"#1a5a6e\"],\n pos: [660, -270],\n scale: [1.0, 1.15, 1.0],\n rot: [-16, 0, -20],\n opacity: 0.72,\n shape: {\n displaceFrequency: { x: 0.005, y: 0.011 },\n displaceAmount: 46,\n twistFrequency: { x: -0.06, y: 0.09, z: -0.5 },\n twistPower: { x: 4.0, y: 6.0, z: 9.0 },\n },\n },\n ];\n const base = c.waves[0];\n c.waves = zoo.map((z, i) => {\n const w = structuredClone(base);\n w.usePaletteTexture = false;\n w.gradientType = \"linear\";\n w.gradientAngle = 0;\n w.palette = makeStops(z.palette);\n w.blendMode = \"normal\";\n w.hueShift = 0;\n w.colorContrast = 1;\n w.colorSaturation = 1.1;\n w.opacity = z.opacity;\n w.scale = { x: z.scale[0], y: z.scale[1], z: z.scale[2] };\n w.rotation = { x: rad(z.rot[0]), y: rad(z.rot[1]), z: rad(z.rot[2]) };\n w.position = { x: z.pos[0], y: z.pos[1], z: 0 };\n w.seed = i * 7;\n w.speed = 0.05;\n Object.assign(w, z.shape); // the wave's distinct shape family (displace / twist / helix / radial)\n // Each PARTICLE_PRESET is tuned as a standalone hero cloud whose dust flings far; here every\n // specimen should sit ON the wave that emits it, reading as dust clinging to the surface rather\n // than a cloud floating nearby. Pull the motion terms right down (a small fraction of the hero\n // reach + tight clamps) so the dust overlaps its own wave; the styles still read apart by sprite\n // shape / colour / wave shape.\n const p = structuredClone(PARTICLE_PRESETS[z.style]);\n const PULL = 0.13; // fraction of each preset's hero-scale reach kept here\n if (p.drift != null) p.drift = capMag(p.drift * PULL, 24);\n if (p.rise != null) p.rise = capMag(p.rise * PULL, 28);\n if (p.wander != null) p.wander = capMag(p.wander * PULL, 15);\n if (p.swirl != null) p.swirl = capMag(p.swirl * PULL, 0.05);\n w.particles = p;\n return w;\n });\n c.waveCount = c.waves.length;\n return c;\n },\n Holographic: () => {\n // Conic gradient: an iridescent oil-slick sweep. The palette wraps (first ≈ last stop) so\n // the conic seam is invisible.\n const c = PRESETS[\"Hero\"]();\n const w = c.waves[0];\n w.usePaletteTexture = false;\n w.gradientType = \"conic\";\n w.gradientShift = 0.08;\n w.palette = [\n { color: \"#8ef6e4\", pos: 0 }, // mint (seam)\n { color: \"#6ec3ff\", pos: 0.18 }, // sky\n { color: \"#9b8cff\", pos: 0.36 }, // periwinkle\n { color: \"#ff8ad8\", pos: 0.54 }, // pink\n { color: \"#ffd98e\", pos: 0.72 }, // peach\n { color: \"#a0f0c8\", pos: 0.88 }, // seafoam\n { color: \"#8ef6e4\", pos: 1 }, // mint again (seamless wrap)\n ];\n w.blendMode = \"normal\";\n w.hueShift = 0;\n w.colorContrast = 1.04;\n w.colorSaturation = 1.12;\n w.fiberStrength = 0.12;\n c.grain = 0.28;\n c.blur = 0.01;\n // Subtle deep teal → violet wash behind the iridescence.\n c.background = \"#05060c\";\n c.backgroundMode = \"gradient\";\n c.backgroundGradientType = \"linear\";\n c.backgroundGradientAngle = 135;\n c.backgroundGradientSource = \"stops\";\n c.backgroundPalette = makeStops([\"#04121a\", \"#0a0518\"]);\n c.transparentBackground = false;\n return c;\n },\n Aurora: () => {\n // Mesh gradient: a moody aurora — teals/greens drifting into violet over a night-sky base\n // (distinct from the brighter iOS-style \"Mesh Gradient\").\n const c = PRESETS[\"Hero\"]();\n const w = c.waves[0];\n w.gradientType = \"mesh\";\n w.meshGradientPoints = [\n { color: \"#0a1f3c\", x: 0.08, y: 0.12, influence: 0.62 },\n { color: \"#1fddb0\", x: 0.3, y: 0.7, influence: 0.78 },\n { color: \"#57f5a3\", x: 0.58, y: 0.86, influence: 0.7 },\n { color: \"#3a86ff\", x: 0.82, y: 0.55, influence: 0.62 },\n { color: \"#a15cff\", x: 0.5, y: 0.32, influence: 0.7 },\n { color: \"#071433\", x: 0.92, y: 0.08, influence: 0.6 },\n ];\n w.meshGradientSoftness = 0.72;\n w.blendMode = \"normal\";\n w.hueShift = 0;\n w.colorContrast = 1.05;\n w.colorSaturation = 1.18;\n w.fiberStrength = 0.12;\n c.grain = 0.3;\n c.blur = 0.008;\n // Dark night-sky MESH backdrop (also shows off the mesh background type).\n c.background = \"#03060f\";\n c.backgroundMode = \"gradient\";\n c.backgroundGradientType = \"mesh\";\n c.backgroundMeshPoints = [\n { color: \"#02040c\", x: 0.15, y: 0.85, influence: 0.7 },\n { color: \"#08243a\", x: 0.5, y: 0.5, influence: 0.75 },\n { color: \"#0a0f2e\", x: 0.85, y: 0.7, influence: 0.7 },\n { color: \"#04121a\", x: 0.7, y: 0.2, influence: 0.6 },\n { color: \"#000208\", x: 0.12, y: 0.12, influence: 0.6 },\n ];\n c.backgroundMeshSoftness = 0.75;\n c.transparentBackground = false;\n return c;\n },\n Palestine: () => {\n const c = PRESETS[\"Hero\"](); // the centred default \"Hero\" wave\n const w = c.waves[0];\n w.paletteSource = \"palestine\";\n w.blendMode = \"normal\";\n w.hueShift = 0;\n w.colorContrast = 1;\n w.colorSaturation = 1;\n c.grain = 0.35;\n c.background = \"#f2efe8\";\n c.transparentBackground = true;\n return c;\n },\n Spain: () => {\n const c = PRESETS[\"Hero\"](); // the centred default \"Hero\" wave\n const w = c.waves[0];\n w.paletteSource = \"spain\";\n w.blendMode = \"normal\";\n w.hueShift = 0;\n w.colorContrast = 1.18;\n w.colorSaturation = 1.25;\n w.creaseLight = 1.6; // moderate crease-light: rich crimson without washing to salmon (Hero's is 1.98)\n c.grain = 0.3;\n c.background = \"#1a0608\"; // deep oxblood stage\n c.backgroundMode = \"color\";\n c.transparentBackground = false; // opaque, so the dark stage makes the flag pop\n return c;\n },\n \"Vaporwave Sunset\": () => {\n // The Hero wave re-posed/re-framed, plus the vaporwave palette.\n const c = PRESETS[\"Hero\"](); // the centred default \"Hero\" wave\n const w = c.waves[0];\n w.position.x = 525;\n w.rotation.x = -0.64 * RAD;\n w.rotation.z = 1.68 * RAD;\n w.paletteSource = \"vaporwave\";\n w.blendMode = \"normal\";\n w.hueShift = 0;\n w.colorContrast = 1.08;\n w.colorSaturation = 1.15;\n w.creaseLight = 1.25;\n c.cameraZoom = 1.1;\n c.cameraTarget = { x: 150, y: 360, z: 0 };\n c.background = \"#09051f\";\n c.transparentBackground = false;\n return c;\n },\n Corkscrew: () => {\n // The helix mode, shown off on its own: `helixRoll` at 1 rolls the ribbon's cross-section in\n // step with the sweep, so the flat strip becomes an auger blade winding around its own length\n // axis, and `helixRadius` lifts that blade off the axis so the turns read as a screw thread\n // rather than a flat twist. No twist at all — this shape is unreachable with twistFrequency,\n // whose expStep angle is monotone and can only ramp once (see the helix docs in config/model).\n const c = PRESETS[\"Hero\"]();\n const w = c.waves[0];\n w.helixTurns = 5;\n w.helixRadius = 45;\n w.helixRoll = 1;\n w.helixPhase = 0;\n w.twistFrequency = { x: 0, y: 0, z: 0 };\n w.twistPower = { x: 4, y: 4, z: 2 };\n // A slow swell along the blade so it breathes; the corkscrew itself is static geometry.\n w.displaceAmount = 16;\n w.displaceFrequency = { x: 0.006, y: 0.0008 };\n w.speed = 0.1;\n w.position = { x: 0, y: 0, z: 0 };\n w.rotation = { x: 0, y: 0, z: 12 }; // tilt so it climbs across the frame\n w.scale = { x: 3, y: 3, z: 1.5 };\n // Mesh gradient: the colour field runs along the blade, so each turn picks up a different part\n // of the spectrum instead of the one hue a linear stop ramp would give.\n w.gradientType = \"mesh\";\n w.meshGradientPoints = [\n { color: \"#0a84ff\", x: 0.06, y: 0.9, influence: 0.68 },\n { color: \"#64d2ff\", x: 0.88, y: 0.92, influence: 0.72 },\n { color: \"#bf5af2\", x: 0.5, y: 0.64, influence: 0.58 },\n { color: \"#ff375f\", x: 0.1, y: 0.14, influence: 0.7 },\n { color: \"#ff9f0a\", x: 0.84, y: 0.12, influence: 0.74 },\n { color: \"#30d158\", x: 0.94, y: 0.5, influence: 0.54 },\n ];\n w.meshGradientSoftness = 0.68;\n w.blendMode = \"normal\";\n w.hueShift = 0;\n w.colorContrast = 1.06;\n w.colorSaturation = 1.12;\n w.fiberStrength = 0.14;\n // Framed down the axis rather than side-on: the coil reads as a screw receding into the frame,\n // and each turn shows its blade face instead of an edge. cameraDistance is the orbit radius\n // (= |position − target|); the camera is orthographic, so it's the rig's dolly, not the scale —\n // cameraZoom sets that.\n c.cameraPosition = { x: -526.009, y: -285.284, z: -425.489 };\n c.cameraTarget = { x: -95.046, y: -17.053, z: -105.608 };\n c.cameraDistance = 600;\n c.cameraZoom = 1.176;\n c.grain = 0.3;\n c.blur = 0.008;\n c.bloomStrength = 0.35;\n c.bloomRadius = 0.6;\n c.bloomThreshold = 0.55;\n c.background = \"#070914\";\n c.backgroundMode = \"color\";\n c.transparentBackground = false;\n return c;\n },\n Kaleidoscope: () => {\n const c = PRESETS[\"Wave 3\"]();\n const w = c.waves[0];\n w.paletteSource = \"kaleidoscope\";\n w.blendMode = \"normal\";\n w.hueShift = 0;\n w.colorContrast = 1.05;\n w.colorSaturation = 1.12;\n c.grain = 0.5;\n return c;\n },\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"presets.js","names":[],"sources":["../src/presets.ts"],"sourcesContent":["/**\n * Built-in presets: each a complete studio config (scene + one or more waves) in the wave model.\n * IP-clean — no copyrighted assets. The studio layers its own extra presets (and its historical\n * \"Stripe *\" display names) on top; see apps/studio/src/presets.ts.\n */\nimport { createDefaultConfig, makeStops, makeWaveSpread } from \"./config/model\";\nimport type {\n NoiseBand,\n ParticlesConfig,\n StudioConfig,\n WaveInteractionConfig,\n} from \"./config/model\";\n\nconst RAD = 180 / Math.PI;\n\n/**\n * Reusable particle STYLES applied to a wave's `particles` block. Surfaced in the studio's per-wave\n * Particles folder (the \"style\" picker) and used by the \"Particle Zoo\" showcase preset. Each is a dust\n * look independent of the wave it rides — clone before mutating (`structuredClone`).\n */\nexport const PARTICLE_PRESETS: Record<string, ParticlesConfig> = {\n Glitter: {\n count: 16000,\n size: 2.6,\n seed: 7,\n color: \"#ffdca8\",\n shape: \"glitter\",\n edgeBias: 1,\n drift: 300,\n bias: -0.6,\n twinkle: 0.8,\n },\n Embers: {\n count: 16000,\n size: 3.6,\n seed: 7,\n color: \"#ff8a2c\",\n color2: \"#ffe19a\",\n shape: \"soft\",\n edgeBias: 0.15,\n drift: 40,\n rise: 320,\n wander: 120,\n twinkle: 0.85,\n life: 6,\n },\n Snow: {\n count: 12000,\n size: 3,\n seed: 4,\n color: \"#eef4ff\",\n color2: \"#bcd0ee\",\n shape: \"soft\",\n edgeBias: 0.1,\n drift: 20,\n rise: -260,\n wander: 80,\n twinkle: 0.5,\n life: 8,\n },\n Sparks: {\n count: 9000,\n size: 5,\n seed: 9,\n color: \"#ffd27a\",\n color2: \"#fff4d0\",\n shape: \"streak\",\n edgeBias: 1,\n drift: 620,\n rise: 90,\n wander: 20,\n bias: -0.4,\n twinkle: 0.9,\n life: 2.5,\n },\n Fireflies: {\n count: 2200,\n size: 5,\n seed: 11,\n color: \"#dfff9a\",\n color2: \"#8fd94a\",\n shape: \"star\",\n edgeBias: 0.1,\n drift: 25,\n swirl: 0.3,\n wander: 170,\n twinkle: 1,\n life: 5,\n },\n Bubbles: {\n count: 3000,\n size: 7,\n sizeJitter: 0.9,\n seed: 6,\n color: \"#cdeefb\",\n color2: \"#8fd0e6\",\n shape: \"ring\",\n edgeBias: 0.2,\n drift: 30,\n rise: 240,\n wander: 60,\n twinkle: 0.3,\n life: 7,\n },\n};\n\n/** Degrees → radians (for the Particle Zoo's per-wave rotation, authored in degrees). */\nconst rad = (deg: number): number => (deg * Math.PI) / 180;\n\n/** Identity, but it pins a Zoo entry's inline interaction literal to {@link WaveInteractionConfig}:\n * without it the entries are merely INFERRED, so `source` / `target` widen to `string` (needing an\n * `as const` per field) and a misspelt knob would slip through unchecked. */\nconst interaction = (it: WaveInteractionConfig): WaveInteractionConfig => it;\n\n/** Clamp a signed magnitude to ±m (used to cap the Zoo's long-range particle motion terms). */\nconst capMag = (v: number | undefined, m: number): number | undefined =>\n v == null ? v : Math.sign(v) * Math.min(Math.abs(v), m);\n\n/** Build a preset from a set of wave parameters. rotation/hue are given in RADIANS and\n * converted to degrees. All presets are solid-theme, so they reuse the hero palette +\n * surfaceColor fibers (600/0.2) and sheen 0, like the hero. camTarget/zoom frame the\n * wave (we pan the look-at to centre each one). */\nfunction buildPreset(p: {\n speed: number;\n contrast: number;\n sat: number;\n hueRad: number;\n dispX: number;\n dispZ: number;\n dispAmt: number;\n pos: [number, number, number];\n rotRad: [number, number, number];\n scale: [number, number, number];\n twF: [number, number, number];\n twP: [number, number, number];\n glow: [number, number, number];\n grain: number;\n blur: number;\n zoom: number;\n camTarget: [number, number];\n noiseBands?: NoiseBand[];\n twistMotion?: boolean;\n}): StudioConfig {\n const c = createDefaultConfig();\n const w = c.waves[0];\n w.speed = p.speed;\n w.colorContrast = p.contrast;\n w.colorSaturation = p.sat;\n w.hueShift = p.hueRad * RAD;\n w.displaceFrequency = { x: p.dispX, y: p.dispZ };\n w.displaceAmount = p.dispAmt;\n w.position = { x: p.pos[0], y: p.pos[1], z: p.pos[2] };\n w.rotation = { x: p.rotRad[0] * RAD, y: p.rotRad[1] * RAD, z: p.rotRad[2] * RAD };\n w.scale = { x: p.scale[0], y: p.scale[1], z: p.scale[2] };\n w.twistFrequency = { x: p.twF[0], y: p.twF[1], z: p.twF[2] };\n w.twistPower = { x: p.twP[0], y: p.twP[1], z: p.twP[2] };\n w.creaseLight = p.glow[0];\n w.creaseSharpness = p.glow[1];\n w.creaseSoftness = p.glow[2];\n if (p.noiseBands) w.noiseBands = p.noiseBands;\n if (p.twistMotion) w.twistMotion = true;\n c.grain = p.grain;\n c.blur = p.blur;\n c.cameraPosition = { x: 100, y: 0, z: 5000 };\n c.cameraTarget = { x: p.camTarget[0], y: p.camTarget[1], z: 0 };\n c.cameraZoom = p.zoom;\n return c;\n}\n\n/** Presets: each a complete studio config (scene + one or more waves) in the wave model. */\nexport const PRESETS: Record<string, () => StudioConfig> = {\n // The app's default wave: a centred, full-frame ribbon (window-independent framing).\n // Shown first and named \"Hero\"; several presets below derive from it.\n Hero: () =>\n buildPreset({\n speed: 0.04,\n contrast: 1,\n sat: 1,\n hueRad: -0.00159265,\n dispX: 0.005831,\n dispZ: 0.016001,\n dispAmt: -7.821,\n pos: [380, -301.7, -11.1],\n rotRad: [-0.44959, -0.11759, 1.874407],\n scale: [9, 8, 5],\n twF: [-0.65, 0.41, -0.58],\n twP: [3.63, 0.7, 3.95],\n glow: [1.98, 0.806, 0.834],\n grain: 1.1,\n blur: 0.02,\n zoom: 0.55,\n camTarget: [-420, -200], // user-tuned default framing\n }),\n // Stripe's real hero, recreated faithfully: an orthographic ×10 scene that overflows the\n // frame, so only the twisted crop shows. This is the model's plain default config.\n \"Wave 2\": () => createDefaultConfig(),\n // camTarget on the waves below is a first-pass centring; tune per-wave. NOTE: Wave 4 also\n // uses a variant vertex shader (animated twist-X wobble) we don't fully replicate — its\n // STATIC frame is close, the motion differs.\n \"Wave 3\": () =>\n buildPreset({\n speed: 0.08,\n contrast: 1,\n sat: 1,\n hueRad: -0.00159265,\n dispX: 0.005831,\n dispZ: 0.016001,\n dispAmt: -7.821,\n pos: [-200.7, -65.4, -11.1],\n rotRad: [-2.875593, 3.095927, -2.925927],\n scale: [3, 3, 3],\n twF: [0.059, 0.32, -0.397],\n twP: [3.63, 0.44, 5.99],\n glow: [3.86, 0.923, 1],\n grain: 1.2,\n blur: 0.02,\n zoom: 1.3,\n camTarget: [-104, 13], // centred; zoomed in (wide/flat wave)\n }),\n \"Wave 4\": () =>\n buildPreset({\n speed: 0.0525,\n contrast: 0.969,\n sat: 1.383,\n hueRad: 0.0376991,\n dispX: 0.005,\n dispZ: 0.0212,\n dispAmt: 6.68,\n pos: [206.1, -438, -11.1],\n rotRad: [-0.666018, -0.031416, 0.779115],\n scale: [6.0501, 8.3983, 6.9854],\n twF: [-0.424, 0.024, -1.312],\n twP: [1.81, 0.94, 4.76],\n glow: [1.55, 1.174, 0.972],\n grain: 0.576,\n blur: 0,\n zoom: 0.9316,\n camTarget: [194, -402], // centred on the wave\n twistMotion: true, // variant vertex shader — animated twist-X wobble\n noiseBands: [\n {\n startX: 0.856,\n endX: 1,\n startY: 0,\n endY: 0.913,\n feather: 0.5,\n strength: 0.346,\n frequency: 1018,\n colorAttenuation: 1,\n parabolaPower: 0,\n },\n {\n startX: 0.038,\n endX: 0.538,\n startY: 0.105,\n endY: 1,\n feather: 0.3315,\n strength: 1,\n frequency: 190,\n colorAttenuation: 0,\n parabolaPower: 2.11,\n },\n ],\n }),\n // The dark-background hero: identical geometry/camera to the default hero, but theme\n // \"wireframe\" → the line shader on a dark page background, with grain 1.2. Same palette.\n Wireframe: () => {\n const c = createDefaultConfig();\n c.waves[0].theme = \"wireframe\";\n c.grain = 1.2;\n c.background = \"#0a2540\"; // dark navy page background\n c.transparentBackground = false;\n return c;\n },\n \"Neon Dark Multistrand\": () => {\n const c = createDefaultConfig();\n const w = c.waves[0];\n w.theme = \"wireframe\"; // line shader on the near-black background — neon wireframe look\n w.blendMode = \"additive\";\n w.palette = makeStops([\"#00f5d4\", \"#00bbf9\", \"#9b5de5\", \"#f15bb5\", \"#fee440\"]);\n w.creaseLight = 1.0;\n c.background = \"#05060c\";\n c.transparentBackground = false; // fill the dark bg so the neon lines read on black (not the page)\n c.waves = makeWaveSpread(w, 3); // three overlapping neon waves\n c.waveCount = 3;\n return c;\n },\n \"Mesh Gradient\": () => {\n const c = PRESETS[\"Hero\"](); // the centred default \"Hero\" wave\n const w = c.waves[0];\n w.gradientType = \"mesh\";\n w.meshGradientPoints = [\n { color: \"#0a84ff\", x: 0.06, y: 0.9, influence: 0.68 },\n { color: \"#64d2ff\", x: 0.88, y: 0.92, influence: 0.72 },\n { color: \"#bf5af2\", x: 0.5, y: 0.64, influence: 0.58 },\n { color: \"#ff375f\", x: 0.1, y: 0.14, influence: 0.7 },\n { color: \"#ff9f0a\", x: 0.84, y: 0.12, influence: 0.74 },\n { color: \"#30d158\", x: 0.94, y: 0.5, influence: 0.54 },\n ];\n w.meshGradientSoftness = 0.68;\n w.blendMode = \"normal\";\n w.hueShift = 0;\n w.colorContrast = 1.06;\n w.colorSaturation = 1.12;\n w.fiberStrength = 0.14;\n c.grain = 0.3;\n c.blur = 0.008;\n c.background = \"#070914\";\n c.backgroundMode = \"color\";\n c.transparentBackground = false;\n return c;\n },\n \"Solar Bloom\": () => {\n // Radial gradient: a warm core blooming out to a deep-indigo edge. usePaletteTexture off so\n // our own stops map along the radial gradCoord instead of sampling the baked hero LUT.\n const c = PRESETS[\"Hero\"]();\n const w = c.waves[0];\n w.usePaletteTexture = false;\n w.gradientType = \"radial\";\n w.gradientShift = 0.14;\n w.palette = [\n { color: \"#fff3c4\", pos: 0 }, // warm-white core\n { color: \"#ffd166\", pos: 0.22 }, // gold\n { color: \"#ff8c42\", pos: 0.42 }, // orange\n { color: \"#ff5d8f\", pos: 0.62 }, // coral-pink\n { color: \"#a64dff\", pos: 0.82 }, // violet\n { color: \"#241246\", pos: 1 }, // deep indigo edge\n ];\n w.blendMode = \"normal\";\n w.hueShift = 0;\n w.colorContrast = 1.05;\n w.colorSaturation = 1.18;\n w.fiberStrength = 0.12;\n c.grain = 0.3;\n c.blur = 0.01;\n // Deep warm radial vignette behind the bloom.\n c.background = \"#0a0714\";\n c.backgroundMode = \"gradient\";\n c.backgroundGradientType = \"radial\";\n c.backgroundGradientSource = \"stops\";\n c.backgroundPalette = makeStops([\"#2a1330\", \"#08040f\"]);\n c.transparentBackground = false;\n return c;\n },\n \"Latte Ring\": () => {\n // A warm cream-and-gold ring of combed silk curling around a dark void — the crema swirl on a\n // latte. The camera ORBITS a wide radial fan (arc 286°) so its combed length sweeps across the\n // frame as a flowing arc instead of a head-on fan; a mesh gradient warms it gold→cream with an\n // orange edge, and a noise band frays the fibers finer toward the tips. Exercises the radial wave\n // mode + the particle layer (ambient field + shed-from-edge dust into the void).\n const c = PRESETS[\"Hero\"]();\n const w = c.waves[0];\n // A wide radial fan (fans the ribbon's length); the orbiting camera below crops it to a ring.\n w.radialAmount = 0.72;\n w.radialArc = 286;\n w.radialCenter = -160;\n w.radialRadius = 300;\n w.radialSpread = 1.47;\n w.rotation = { x: 0, y: 0, z: 0 };\n w.position = { x: -280, y: -320, z: 0 };\n w.scale = { x: 1.12, y: 1.12, z: 1.12 };\n w.opacity = 0.5;\n // A big broad swell (amount 101.73) with a fine second octave riding on it, so the ring's silk\n // ripples and folds as it turns; `speed` sets the swell's drift rate.\n w.displaceFrequency = { x: 0.0026, y: 0.0048 };\n w.displaceAmount = 101.73;\n w.detailAmount = 6;\n w.detailFrequency = 0.1;\n w.speed = 0.21;\n // Fine combed fibers; the noise band overrides them finer + wispier over the OUTER half (uv.y>0.5)\n // for organic variation instead of a uniform comb. (Bands override fiber params per uv region.)\n w.fiberCount = 110;\n w.fiberStrength = 0.95;\n w.creaseLight = 0.55;\n w.edgeFeather = 0.34;\n w.noiseBands = [\n {\n startX: 0,\n endX: 1,\n startY: 0.5,\n endY: 1,\n feather: 0.4,\n strength: 1,\n frequency: 300,\n colorAttenuation: 0.85,\n parabolaPower: 2.5,\n },\n ];\n // Mesh gradient: gold + cream dominant with an orange accent — the latte's crema tones. A 2D\n // colour field (not a length-wise ramp) so the warmth pools within the fibers.\n w.usePaletteTexture = false;\n w.gradientType = \"mesh\";\n w.meshGradientSoftness = 0.7;\n w.meshGradientPoints = [\n { color: \"#f3c06a\", x: 0.5, y: 0.1, influence: 0.7 }, // warm gold\n { color: \"#f9edd4\", x: 0.34, y: 0.36, influence: 0.62 }, // hot cream\n { color: \"#e6923a\", x: 0.15, y: 0.55, influence: 0.5 }, // orange accent\n { color: \"#f1d49a\", x: 0.82, y: 0.42, influence: 0.55 }, // gold\n { color: \"#ece7d8\", x: 0.58, y: 0.88, influence: 0.72 }, // cool cream\n ];\n w.blendMode = \"normal\";\n w.hueShift = 0;\n w.colorContrast = 1.05;\n w.colorSaturation = 1.15;\n // Orbit the camera around the fan so its length reads as a sweeping arc wrapping the void.\n c.cameraDistance = 600;\n c.cameraPosition = { x: -854.327, y: 135.331, z: 478.048 };\n c.cameraTarget = { x: -720.043, y: 10.575, z: -93.27 };\n c.cameraZoom = 1.222;\n // Scene: a near-black void with gentle bloom on the silk + dust.\n c.background = \"#050404\";\n c.backgroundMode = \"color\";\n c.transparentBackground = false;\n c.grain = 0.25;\n c.blur = 0;\n c.bloomStrength = 0.18;\n c.bloomRadius = 0.55;\n c.bloomThreshold = 0.72;\n // Golden dust shed off the ring's own edge into the void (biased to one flank). Per-wave: it rides\n // this wave's deform and drifts outward from it. edgeBias 1 = spawn on the rim (the shed look).\n w.particles = {\n count: 20000,\n size: 2.9,\n color: \"#ffdca8\",\n seed: 7,\n twinkle: 0.8,\n edgeBias: 1,\n drift: 490,\n bias: -0.6,\n };\n return c;\n },\n \"Particle Zoo\": () => {\n // One scene demoing every particle STYLE — each wave sheds a different kind of dust off its own\n // surface (embers / snow / sparks / fireflies / bubbles). Every wave is a DIFFERENT shape family\n // too (dome / flat sheet / radial fan / helix coil / twist curl), spread apart so none overlap and\n // the frame stays full. The showcase for the per-wave particle system; styles come from\n // PARTICLE_PRESETS (the studio \"preset style\" picker).\n //\n // Each specimen also answers the cursor a DIFFERENT way — agitate / push / click-ripple /\n // param-binding / drag-wake — so the scene doubles as the interactivity showcase, and each one\n // shows its dust reacting alongside its ribbon.\n const c = createDefaultConfig();\n c.background = \"#05070d\";\n c.backgroundMode = \"color\";\n c.transparentBackground = false;\n c.grain = 0.26;\n c.blur = 0;\n c.bloomStrength = 0.3;\n c.bloomThreshold = 0.66; // high, so the central sparks fan glows without blowing the middle out\n c.cameraPosition = { x: 100, y: 0, z: 5000 };\n c.cameraTarget = { x: 0, y: 0, z: 0 };\n c.cameraZoom = 0.6;\n // Shared cursor. A TIGHT radius so hovering one specimen doesn't stir its neighbours: the waves\n // sit ~700-1400 world units apart in a 1250-tall frame, and radius is a fraction of viewport\n // height doubled into NDC-y, so 0.22 → 0.44 NDC-y ≈ one specimen. Touch is opt-in and this is a\n // showcase, so turn it on (listeners are passive — it does not block page scrolling).\n c.interaction = { enabled: true, radius: 0.22, ribbonFlow: 0.5, touch: true };\n // Five well-separated waves, each a DIFFERENT shape family so the silhouettes read as distinct,\n // not five copies of one ribbon. Frame at cameraZoom 0.6 spans ~2222×1250 world units centred on\n // the origin (x ∈ [-1111, 1111], y ∈ [-625, 625], orthographic → screen-xy = world-xy), so the\n // positions/scales below keep the meshes from overlapping. `shape` carries the per-family knobs\n // (displace / twist / helix / radial); `rot` is in degrees. style, palette, opacity as before.\n const zoo = [\n {\n // Embers rising off a broad DOME — low-frequency, high-amplitude displacement mound.\n style: \"Embers\",\n // STIR THE FIRE — cursor agitation. The churn octave stirs the mound and the embers riding\n // it scatter; shove high so the ones already airborne get swept along too.\n interact: interaction({ hover: { agitate: 34, lighten: 0.25 } }),\n shove: 2.5,\n palette: [\"#ff7a1e\", \"#ffd27a\", \"#c23a12\"],\n pos: [-720, 285],\n scale: [1.0, 1.0, 1.0],\n rot: [-20, 0, -14],\n opacity: 0.72,\n shape: {\n displaceFrequency: { x: 0.0024, y: 0.0065 },\n displaceAmount: 118,\n twistPower: { x: 2.4, y: 2.4, z: 3.2 },\n },\n },\n {\n // Snow settling on a near-flat drifting SHEET — tilted toward the camera, barely rippled.\n style: \"Snow\",\n // PRESS INTO THE DRIFT — a NEGATIVE push, so the cursor dents the sheet away from you like a\n // palm in deep snow, and the settled flakes sink into the hollow with it. Slow smoothing so\n // the hollow follows heavily; low shove because falling snow shouldn't whip around.\n interact: interaction({ hover: { push: -22, smoothing: 0.45 } }),\n shove: 0.6,\n palette: [\"#8fb8e8\", \"#e8f1fb\", \"#aeb9d6\"],\n pos: [700, 320],\n scale: [1.1, 1.0, 0.9],\n rot: [-62, 0, 12],\n opacity: 0.72,\n shape: {\n displaceFrequency: { x: 0.006, y: 0.013 },\n displaceAmount: 22,\n twistPower: { x: 0.8, y: 0.8, z: 1.0 },\n },\n },\n {\n // Sparks bursting off a RADIAL FAN — the one spiky, fanned silhouette; dimmed so it glows\n // without blowing the centre out.\n style: \"Sparks\",\n // STRIKE IT — click/tap only, no hover field. A ring radiates from the hit and, at full\n // shove, visibly blows OUT through the spark burst instead of stopping at the ribbon: the\n // clearest demo of dust reacting to the pointer.\n interact: interaction({ press: { ripple: 46 } }),\n shove: 4,\n palette: [\"#ffd27a\", \"#fff4d0\", \"#c8853a\"],\n pos: [0, -30],\n scale: [0.85, 0.85, 0.85],\n rot: [0, 0, 0],\n opacity: 0.32,\n shape: {\n radialAmount: 0.82,\n radialArc: 118,\n radialCenter: 90, // fan points up\n radialRadius: 40,\n radialSpread: 1.0,\n displaceAmount: 30,\n },\n },\n {\n // Fireflies wandering around a HELIX coil — a screw-thread column of light.\n style: \"Fireflies\",\n // WIND THE COIL — a BINDING, not a pointer field. Hovering turns the helix a full rotation\n // and the fireflies ride round with it, because each field mirrors its wave's live shape\n // uniforms every frame. Deliberately the one specimen with no `hover` block: its particle\n // program never compiles the pointer path, yet its dust still follows the wave.\n interact: interaction({\n bindings: [{ source: \"hover\", target: \"helixPhase\", to: 360, smoothing: 0.5 }],\n }),\n palette: [\"#3d5a24\", \"#7bd23a\", \"#40521f\"],\n pos: [-560, -300],\n scale: [1.25, 1.25, 1.25],\n rot: [0, 0, 8],\n opacity: 0.72,\n shape: {\n helixTurns: 3,\n helixRadius: 44,\n helixRoll: 1,\n displaceAmount: 8,\n twistPower: { x: 1.0, y: 1.0, z: 1.2 },\n },\n },\n {\n // Bubbles rising off a strongly TWISTED curl — an S-ribbon coiling on its length.\n style: \"Bubbles\",\n // DRAG THROUGH THE WATER — the drag-wake. Sweep the cursor and the ribbon behind it is\n // pulled into a trailing trough that heals when you stop, with the bubbles streaming into\n // the wake; `thin` adds a watery translucency right under the cursor.\n interact: interaction({ hover: { wake: 30, thin: 0.45 } }),\n shove: 1.6,\n palette: [\"#2e8fb0\", \"#7fd4e8\", \"#1a5a6e\"],\n pos: [660, -270],\n scale: [1.0, 1.15, 1.0],\n rot: [-16, 0, -20],\n opacity: 0.72,\n shape: {\n displaceFrequency: { x: 0.005, y: 0.011 },\n displaceAmount: 46,\n twistFrequency: { x: -0.06, y: 0.09, z: -0.5 },\n twistPower: { x: 4.0, y: 6.0, z: 9.0 },\n },\n },\n ];\n const base = c.waves[0];\n c.waves = zoo.map((z, i) => {\n const w = structuredClone(base);\n w.usePaletteTexture = false;\n w.gradientType = \"linear\";\n w.gradientAngle = 0;\n w.palette = makeStops(z.palette);\n w.blendMode = \"normal\";\n w.hueShift = 0;\n w.colorContrast = 1;\n w.colorSaturation = 1.1;\n w.opacity = z.opacity;\n w.scale = { x: z.scale[0], y: z.scale[1], z: z.scale[2] };\n w.rotation = { x: rad(z.rot[0]), y: rad(z.rot[1]), z: rad(z.rot[2]) };\n w.position = { x: z.pos[0], y: z.pos[1], z: 0 };\n w.seed = i * 7;\n w.speed = 0.05;\n Object.assign(w, z.shape); // the wave's distinct shape family (displace / twist / helix / radial)\n // Each PARTICLE_PRESET is tuned as a standalone hero cloud whose dust flings far; here every\n // specimen should sit ON the wave that emits it, reading as dust clinging to the surface rather\n // than a cloud floating nearby. Pull the motion terms right down (a small fraction of the hero\n // reach + tight clamps) so the dust overlaps its own wave; the styles still read apart by sprite\n // shape / colour / wave shape.\n const p = structuredClone(PARTICLE_PRESETS[z.style]);\n const PULL = 0.13; // fraction of each preset's hero-scale reach kept here\n if (p.drift != null) p.drift = capMag(p.drift * PULL, 24);\n if (p.rise != null) p.rise = capMag(p.rise * PULL, 28);\n if (p.wander != null) p.wander = capMag(p.wander * PULL, 15);\n if (p.swirl != null) p.swirl = capMag(p.swirl * PULL, 0.05);\n if (z.shove != null) p.pointerShove = z.shove;\n w.particles = p;\n // One distinct interaction per specimen (agitate / push / ripple / binding / wake) — see each\n // entry above. Absent would mean inert, so only assign what the entry authored.\n if (z.interact) w.interaction = structuredClone(z.interact);\n return w;\n });\n c.waveCount = c.waves.length;\n return c;\n },\n Holographic: () => {\n // Conic gradient: an iridescent oil-slick sweep. The palette wraps (first ≈ last stop) so\n // the conic seam is invisible.\n const c = PRESETS[\"Hero\"]();\n const w = c.waves[0];\n w.usePaletteTexture = false;\n w.gradientType = \"conic\";\n w.gradientShift = 0.08;\n w.palette = [\n { color: \"#8ef6e4\", pos: 0 }, // mint (seam)\n { color: \"#6ec3ff\", pos: 0.18 }, // sky\n { color: \"#9b8cff\", pos: 0.36 }, // periwinkle\n { color: \"#ff8ad8\", pos: 0.54 }, // pink\n { color: \"#ffd98e\", pos: 0.72 }, // peach\n { color: \"#a0f0c8\", pos: 0.88 }, // seafoam\n { color: \"#8ef6e4\", pos: 1 }, // mint again (seamless wrap)\n ];\n w.blendMode = \"normal\";\n w.hueShift = 0;\n w.colorContrast = 1.04;\n w.colorSaturation = 1.12;\n w.fiberStrength = 0.12;\n c.grain = 0.28;\n c.blur = 0.01;\n // Subtle deep teal → violet wash behind the iridescence.\n c.background = \"#05060c\";\n c.backgroundMode = \"gradient\";\n c.backgroundGradientType = \"linear\";\n c.backgroundGradientAngle = 135;\n c.backgroundGradientSource = \"stops\";\n c.backgroundPalette = makeStops([\"#04121a\", \"#0a0518\"]);\n c.transparentBackground = false;\n return c;\n },\n Aurora: () => {\n // Mesh gradient: a moody aurora — teals/greens drifting into violet over a night-sky base\n // (distinct from the brighter iOS-style \"Mesh Gradient\").\n const c = PRESETS[\"Hero\"]();\n const w = c.waves[0];\n w.gradientType = \"mesh\";\n w.meshGradientPoints = [\n { color: \"#0a1f3c\", x: 0.08, y: 0.12, influence: 0.62 },\n { color: \"#1fddb0\", x: 0.3, y: 0.7, influence: 0.78 },\n { color: \"#57f5a3\", x: 0.58, y: 0.86, influence: 0.7 },\n { color: \"#3a86ff\", x: 0.82, y: 0.55, influence: 0.62 },\n { color: \"#a15cff\", x: 0.5, y: 0.32, influence: 0.7 },\n { color: \"#071433\", x: 0.92, y: 0.08, influence: 0.6 },\n ];\n w.meshGradientSoftness = 0.72;\n w.blendMode = \"normal\";\n w.hueShift = 0;\n w.colorContrast = 1.05;\n w.colorSaturation = 1.18;\n w.fiberStrength = 0.12;\n c.grain = 0.3;\n c.blur = 0.008;\n // Dark night-sky MESH backdrop (also shows off the mesh background type).\n c.background = \"#03060f\";\n c.backgroundMode = \"gradient\";\n c.backgroundGradientType = \"mesh\";\n c.backgroundMeshPoints = [\n { color: \"#02040c\", x: 0.15, y: 0.85, influence: 0.7 },\n { color: \"#08243a\", x: 0.5, y: 0.5, influence: 0.75 },\n { color: \"#0a0f2e\", x: 0.85, y: 0.7, influence: 0.7 },\n { color: \"#04121a\", x: 0.7, y: 0.2, influence: 0.6 },\n { color: \"#000208\", x: 0.12, y: 0.12, influence: 0.6 },\n ];\n c.backgroundMeshSoftness = 0.75;\n c.transparentBackground = false;\n return c;\n },\n Palestine: () => {\n const c = PRESETS[\"Hero\"](); // the centred default \"Hero\" wave\n const w = c.waves[0];\n w.paletteSource = \"palestine\";\n w.blendMode = \"normal\";\n w.hueShift = 0;\n w.colorContrast = 1;\n w.colorSaturation = 1;\n c.grain = 0.35;\n c.background = \"#f2efe8\";\n c.transparentBackground = true;\n return c;\n },\n Spain: () => {\n const c = PRESETS[\"Hero\"](); // the centred default \"Hero\" wave\n const w = c.waves[0];\n w.paletteSource = \"spain\";\n w.blendMode = \"normal\";\n w.hueShift = 0;\n w.colorContrast = 1.18;\n w.colorSaturation = 1.25;\n w.creaseLight = 1.6; // moderate crease-light: rich crimson without washing to salmon (Hero's is 1.98)\n c.grain = 0.3;\n c.background = \"#1a0608\"; // deep oxblood stage\n c.backgroundMode = \"color\";\n c.transparentBackground = false; // opaque, so the dark stage makes the flag pop\n return c;\n },\n \"Vaporwave Sunset\": () => {\n // The Hero wave re-posed/re-framed, plus the vaporwave palette.\n const c = PRESETS[\"Hero\"](); // the centred default \"Hero\" wave\n const w = c.waves[0];\n w.position.x = 525;\n w.rotation.x = -0.64 * RAD;\n w.rotation.z = 1.68 * RAD;\n w.paletteSource = \"vaporwave\";\n w.blendMode = \"normal\";\n w.hueShift = 0;\n w.colorContrast = 1.08;\n w.colorSaturation = 1.15;\n w.creaseLight = 1.25;\n c.cameraZoom = 1.1;\n c.cameraTarget = { x: 150, y: 360, z: 0 };\n c.background = \"#09051f\";\n c.transparentBackground = false;\n return c;\n },\n Corkscrew: () => {\n // The helix mode, shown off on its own: `helixRoll` at 1 rolls the ribbon's cross-section in\n // step with the sweep, so the flat strip becomes an auger blade winding around its own length\n // axis, and `helixRadius` lifts that blade off the axis so the turns read as a screw thread\n // rather than a flat twist. No twist at all — this shape is unreachable with twistFrequency,\n // whose expStep angle is monotone and can only ramp once (see the helix docs in config/model).\n const c = PRESETS[\"Hero\"]();\n const w = c.waves[0];\n w.helixTurns = 5;\n w.helixRadius = 45;\n w.helixRoll = 1;\n w.helixPhase = 0;\n w.twistFrequency = { x: 0, y: 0, z: 0 };\n w.twistPower = { x: 4, y: 4, z: 2 };\n // A slow swell along the blade so it breathes; the corkscrew itself is static geometry.\n w.displaceAmount = 16;\n w.displaceFrequency = { x: 0.006, y: 0.0008 };\n w.speed = 0.1;\n w.position = { x: 0, y: 0, z: 0 };\n w.rotation = { x: 0, y: 0, z: 12 }; // tilt so it climbs across the frame\n w.scale = { x: 3, y: 3, z: 1.5 };\n // Mesh gradient: the colour field runs along the blade, so each turn picks up a different part\n // of the spectrum instead of the one hue a linear stop ramp would give.\n w.gradientType = \"mesh\";\n w.meshGradientPoints = [\n { color: \"#0a84ff\", x: 0.06, y: 0.9, influence: 0.68 },\n { color: \"#64d2ff\", x: 0.88, y: 0.92, influence: 0.72 },\n { color: \"#bf5af2\", x: 0.5, y: 0.64, influence: 0.58 },\n { color: \"#ff375f\", x: 0.1, y: 0.14, influence: 0.7 },\n { color: \"#ff9f0a\", x: 0.84, y: 0.12, influence: 0.74 },\n { color: \"#30d158\", x: 0.94, y: 0.5, influence: 0.54 },\n ];\n w.meshGradientSoftness = 0.68;\n w.blendMode = \"normal\";\n w.hueShift = 0;\n w.colorContrast = 1.06;\n w.colorSaturation = 1.12;\n w.fiberStrength = 0.14;\n // Framed down the axis rather than side-on: the coil reads as a screw receding into the frame,\n // and each turn shows its blade face instead of an edge. cameraDistance is the orbit radius\n // (= |position − target|); the camera is orthographic, so it's the rig's dolly, not the scale —\n // cameraZoom sets that.\n c.cameraPosition = { x: -526.009, y: -285.284, z: -425.489 };\n c.cameraTarget = { x: -95.046, y: -17.053, z: -105.608 };\n c.cameraDistance = 600;\n c.cameraZoom = 1.176;\n c.grain = 0.3;\n c.blur = 0.008;\n c.bloomStrength = 0.35;\n c.bloomRadius = 0.6;\n c.bloomThreshold = 0.55;\n c.background = \"#070914\";\n c.backgroundMode = \"color\";\n c.transparentBackground = false;\n return c;\n },\n Kaleidoscope: () => {\n const c = PRESETS[\"Wave 3\"]();\n const w = c.waves[0];\n w.paletteSource = \"kaleidoscope\";\n w.blendMode = \"normal\";\n w.hueShift = 0;\n w.colorContrast = 1.05;\n w.colorSaturation = 1.12;\n c.grain = 0.5;\n return c;\n },\n};\n"],"mappings":"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"}
|
|
@@ -277,8 +277,10 @@ declare class WaveRenderer {
|
|
|
277
277
|
* uniforms + matrixWorld) so the dust rides the SAME deform as the ribbon. Runs after refresh()'s
|
|
278
278
|
* per-wave loop so the wave transforms/uniforms are current. No allocation; a no-op when off. */
|
|
279
279
|
private updateSceneFx;
|
|
280
|
-
/** The
|
|
281
|
-
*
|
|
280
|
+
/** The subset of waveDefines() the particle program shares: the shape gates (what waveShape reads,
|
|
281
|
+
* so the dust matches its wave's deform) plus the pointer gates (what pointerField reads, so the
|
|
282
|
+
* dust reacts to the same cursor). Every one of these is derived from CONFIG alone — live input
|
|
283
|
+
* must never reach here, or each frame would flip the define set and recompile the point program. */
|
|
282
284
|
private shapeDefines;
|
|
283
285
|
/** Create/dispose the interaction controller as config toggles interaction on/off. Called from
|
|
284
286
|
* refresh(); the compiled define set (POINTER_FX etc.) is handled separately by waveDefines(). */
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ensureStudioConfig } from "../config/model.js";
|
|
2
2
|
import { WaveGeometry } from "./WaveGeometry.js";
|
|
3
3
|
import { ditherFragmentShader, fragmentShader, halftoneCmykFragmentShader, halftoneFragmentShader, heatmapFragmentShader, innerLightFragmentShader, lineFragmentShader, paperTextureFragmentShader, postFragmentShader, postVertexShader, vertexShader } from "./shaders.js";
|
|
4
|
-
import { ParticleField } from "./particleField.js";
|
|
5
4
|
import { InteractionController, SCENE_APPLIERS, WAVE_APPLIERS, anyPointerFxActive, interactionActive, wavePointerFxActive, waveRipplesActive } from "./interaction.js";
|
|
5
|
+
import { ParticleField } from "./particleField.js";
|
|
6
6
|
import { PALETTE_MAPS, buildBackgroundGradientCanvas, buildBackgroundImageCanvas, buildBackgroundMeshCanvas, buildPaletteTexture, canvasToTexture, configurePaletteTexture, drawBackgroundMediaFrame, loadPaletteImage, paletteMapCanvas, paletteSignature } from "./palette.js";
|
|
7
7
|
import { buildHeroPaletteCanvas, buildHeroPaletteTexture } from "./heroPalette.js";
|
|
8
8
|
import * as THREE from "three";
|
|
@@ -1354,7 +1354,9 @@ var WaveRenderer = class {
|
|
|
1354
1354
|
const cfg = (this.config.waves[i] ?? this.config.waves[this.config.waves.length - 1])?.particles;
|
|
1355
1355
|
if (cfg && cfg.count > 0) {
|
|
1356
1356
|
if (!wave.particleField) {
|
|
1357
|
-
wave.particleField = new ParticleField()
|
|
1357
|
+
wave.particleField = new ParticleField(() => {
|
|
1358
|
+
if (!this.running) this.renderOnce();
|
|
1359
|
+
});
|
|
1358
1360
|
this.scene.add(wave.particleField.points);
|
|
1359
1361
|
}
|
|
1360
1362
|
wave.particleField.sync(cfg, loop);
|
|
@@ -1401,8 +1403,10 @@ var WaveRenderer = class {
|
|
|
1401
1403
|
});
|
|
1402
1404
|
});
|
|
1403
1405
|
}
|
|
1404
|
-
/** The
|
|
1405
|
-
*
|
|
1406
|
+
/** The subset of waveDefines() the particle program shares: the shape gates (what waveShape reads,
|
|
1407
|
+
* so the dust matches its wave's deform) plus the pointer gates (what pointerField reads, so the
|
|
1408
|
+
* dust reacts to the same cursor). Every one of these is derived from CONFIG alone — live input
|
|
1409
|
+
* must never reach here, or each frame would flip the define set and recompile the point program. */
|
|
1406
1410
|
shapeDefines(sc) {
|
|
1407
1411
|
const all = this.waveDefines(sc);
|
|
1408
1412
|
const out = {};
|
|
@@ -1411,7 +1415,9 @@ var WaveRenderer = class {
|
|
|
1411
1415
|
"DETAIL_OCTAVE",
|
|
1412
1416
|
"HELIX",
|
|
1413
1417
|
"TWIST_MOTION",
|
|
1414
|
-
"RADIAL"
|
|
1418
|
+
"RADIAL",
|
|
1419
|
+
"POINTER_FX",
|
|
1420
|
+
"POINTER_RIPPLES"
|
|
1415
1421
|
]) if (k in all) out[k] = "";
|
|
1416
1422
|
return out;
|
|
1417
1423
|
}
|