@wave3d/core 0.2.1 → 0.3.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.
Files changed (40) hide show
  1. package/README.md +47 -0
  2. package/dist/config/model.d.ts +104 -1
  3. package/dist/config/model.js +111 -1
  4. package/dist/config/model.js.map +1 -1
  5. package/dist/index.d.ts +3 -2
  6. package/dist/index.js +2 -2
  7. package/dist/presets.js +15 -0
  8. package/dist/presets.js.map +1 -1
  9. package/dist/renderer/WaveRenderer.d.ts +34 -0
  10. package/dist/renderer/WaveRenderer.js +232 -7
  11. package/dist/renderer/WaveRenderer.js.map +1 -1
  12. package/dist/renderer/interaction.d.ts +119 -0
  13. package/dist/renderer/interaction.js +474 -0
  14. package/dist/renderer/interaction.js.map +1 -0
  15. package/dist/renderer/palette.js +14 -0
  16. package/dist/renderer/palette.js.map +1 -1
  17. package/dist/renderer/shaders.js +105 -0
  18. package/dist/renderer/shaders.js.map +1 -1
  19. package/dist/shell/createWave.d.ts +9 -1
  20. package/dist/shell/createWave.js +7 -1
  21. package/dist/shell/createWave.js.map +1 -1
  22. package/dist/shell/poster.d.ts +12 -0
  23. package/dist/shell/poster.js +4 -3
  24. package/dist/shell/poster.js.map +1 -1
  25. package/dist/standalone/wave3d.standalone.js +864 -219
  26. package/dist/standalone.d.ts +2 -2
  27. package/dist/standalone.js +2 -2
  28. package/dist/studio/StudioWaveRenderer.d.ts +15 -0
  29. package/dist/studio/StudioWaveRenderer.js +32 -1
  30. package/dist/studio/StudioWaveRenderer.js.map +1 -1
  31. package/dist/studio/index.d.ts +2 -1
  32. package/dist/studio/index.js +2 -1
  33. package/dist/studio/randomize.d.ts +3 -3
  34. package/dist/studio/randomize.js +4 -4
  35. package/dist/studio/randomize.js.map +1 -1
  36. package/dist/studio/thumbnail.d.ts +14 -0
  37. package/dist/studio/thumbnail.js +32 -0
  38. package/dist/studio/thumbnail.js.map +1 -0
  39. package/package.json +1 -1
  40. package/skills/wave3d/SKILL.md +20 -2
@@ -0,0 +1,12 @@
1
+ //#region src/shell/poster.d.ts
2
+ /**
3
+ * How the poster image maps into the container box (its CSS `object-fit`).
4
+ * `"fill"` (default) stretches it edge-to-edge, exactly like the canvas — which renders at the
5
+ * container's own aspect — so a poster captured at that aspect aligns pixel-for-pixel and the
6
+ * poster→canvas handoff has no visible jump. `"cover"` crops to preserve the poster's own aspect
7
+ * (pick it for a non-wave / different-aspect placeholder where distortion would look worse).
8
+ */
9
+ type PosterFit = "cover" | "contain" | "fill";
10
+ //#endregion
11
+ export { PosterFit };
12
+ //# sourceMappingURL=poster.d.ts.map
@@ -6,10 +6,11 @@ function ensurePositioned(container) {
6
6
  }
7
7
  /**
8
8
  * Create the poster image — or adopt an existing SSR `<img data-wave3d-poster>` already inside the
9
- * container (no hydration flash). Positioned to cover the container and sit above the canvas.
9
+ * container (no hydration flash). Positioned to overlay the container and sit above the canvas;
10
+ * `fit` (default `"fill"`) sets how it maps into the box — see {@link PosterFit}.
10
11
  * Returns null when there's neither a `src` nor an adoptable image (poster is optional).
11
12
  */
12
- function setupPoster(container, src) {
13
+ function setupPoster(container, src, fit = "fill") {
13
14
  let img = container.querySelector(`img[${POSTER_ATTR}]`);
14
15
  if (!img && !src) return null;
15
16
  if (!img) {
@@ -26,7 +27,7 @@ function setupPoster(container, src) {
26
27
  inset: "0",
27
28
  width: "100%",
28
29
  height: "100%",
29
- objectFit: "cover",
30
+ objectFit: fit,
30
31
  pointerEvents: "none",
31
32
  zIndex: "1",
32
33
  opacity: "1",
@@ -1 +1 @@
1
- {"version":3,"file":"poster.js","names":[],"sources":["../../src/shell/poster.ts"],"sourcesContent":["// Poster management for the shell: the static image shown first (server-rendered or generated)\n// that covers the container until the live wave has painted, then crossfades out.\n\nconst POSTER_ATTR = \"data-wave3d-poster\";\n\nexport interface Poster {\n readonly el: HTMLImageElement;\n /** Fade the poster to transparent over `fadeMs`, then hide it so it can't block the canvas. */\n fadeOut(fadeMs: number): void;\n /** Re-show the poster instantly (used when a live wave is torn down back to the fallback). */\n show(): void;\n /** Remove the poster element from the DOM. */\n remove(): void;\n}\n\n/** Make the container a positioning context so the absolutely-positioned poster overlays the canvas. */\nexport function ensurePositioned(container: HTMLElement): void {\n if (getComputedStyle(container).position === \"static\") container.style.position = \"relative\";\n}\n\n/**\n * Create the poster image — or adopt an existing SSR `<img data-wave3d-poster>` already inside the\n * container (no hydration flash). Positioned to cover the container and sit above the canvas.\n * Returns null when there's neither a `src` nor an adoptable image (poster is optional).\n */\nexport function setupPoster(container: HTMLElement, src?: string): Poster | null {\n let img = container.querySelector<HTMLImageElement>(`img[${POSTER_ATTR}]`);\n if (!img && !src) return null;\n if (!img) {\n img = document.createElement(\"img\");\n img.setAttribute(POSTER_ATTR, \"\");\n img.decoding = \"async\";\n img.alt = \"\";\n img.setAttribute(\"aria-hidden\", \"true\");\n container.appendChild(img);\n }\n if (src) img.src = src;\n Object.assign(img.style, {\n position: \"absolute\",\n inset: \"0\",\n width: \"100%\",\n height: \"100%\",\n objectFit: \"cover\",\n pointerEvents: \"none\", // clicks/scrolls pass through to the canvas beneath\n zIndex: \"1\", // above the WebGL canvas (which sits at the default z-order)\n opacity: \"1\",\n visibility: \"visible\",\n });\n const el = img;\n return {\n el,\n fadeOut(fadeMs) {\n if (fadeMs <= 0) {\n el.style.opacity = \"0\";\n el.style.visibility = \"hidden\";\n return;\n }\n el.style.transition = `opacity ${fadeMs}ms ease`;\n void el.offsetWidth; // force a style flush so the transition runs from the current opacity (1)\n el.style.opacity = \"0\";\n // Hide after the fade so the (transparent) poster can never intercept anything; the timer is\n // rAF-independent so it still completes in a throttled/backgrounded tab.\n setTimeout(() => {\n el.style.visibility = \"hidden\";\n }, fadeMs + 50);\n },\n show() {\n el.style.transition = \"\";\n el.style.opacity = \"1\";\n el.style.visibility = \"visible\";\n },\n remove() {\n el.remove();\n },\n };\n}\n"],"mappings":";AAGA,MAAM,cAAc;;AAapB,SAAgB,iBAAiB,WAA8B;CAC7D,IAAI,iBAAiB,SAAS,CAAC,CAAC,aAAa,UAAU,UAAU,MAAM,WAAW;AACpF;;;;;;AAOA,SAAgB,YAAY,WAAwB,KAA6B;CAC/E,IAAI,MAAM,UAAU,cAAgC,OAAO,YAAY,EAAE;CACzE,IAAI,CAAC,OAAO,CAAC,KAAK,OAAO;CACzB,IAAI,CAAC,KAAK;EACR,MAAM,SAAS,cAAc,KAAK;EAClC,IAAI,aAAa,aAAa,EAAE;EAChC,IAAI,WAAW;EACf,IAAI,MAAM;EACV,IAAI,aAAa,eAAe,MAAM;EACtC,UAAU,YAAY,GAAG;CAC3B;CACA,IAAI,KAAK,IAAI,MAAM;CACnB,OAAO,OAAO,IAAI,OAAO;EACvB,UAAU;EACV,OAAO;EACP,OAAO;EACP,QAAQ;EACR,WAAW;EACX,eAAe;EACf,QAAQ;EACR,SAAS;EACT,YAAY;CACd,CAAC;CACD,MAAM,KAAK;CACX,OAAO;EACL;EACA,QAAQ,QAAQ;GACd,IAAI,UAAU,GAAG;IACf,GAAG,MAAM,UAAU;IACnB,GAAG,MAAM,aAAa;IACtB;GACF;GACA,GAAG,MAAM,aAAa,WAAW,OAAO;GACxC,GAAQ;GACR,GAAG,MAAM,UAAU;GAGnB,iBAAiB;IACf,GAAG,MAAM,aAAa;GACxB,GAAG,SAAS,EAAE;EAChB;EACA,OAAO;GACL,GAAG,MAAM,aAAa;GACtB,GAAG,MAAM,UAAU;GACnB,GAAG,MAAM,aAAa;EACxB;EACA,SAAS;GACP,GAAG,OAAO;EACZ;CACF;AACF"}
1
+ {"version":3,"file":"poster.js","names":[],"sources":["../../src/shell/poster.ts"],"sourcesContent":["// Poster management for the shell: the static image shown first (server-rendered or generated)\n// that covers the container until the live wave has painted, then crossfades out.\n\nconst POSTER_ATTR = \"data-wave3d-poster\";\n\n/**\n * How the poster image maps into the container box (its CSS `object-fit`).\n * `\"fill\"` (default) stretches it edge-to-edge, exactly like the canvas — which renders at the\n * container's own aspect — so a poster captured at that aspect aligns pixel-for-pixel and the\n * poster→canvas handoff has no visible jump. `\"cover\"` crops to preserve the poster's own aspect\n * (pick it for a non-wave / different-aspect placeholder where distortion would look worse).\n */\nexport type PosterFit = \"cover\" | \"contain\" | \"fill\";\n\nexport interface Poster {\n readonly el: HTMLImageElement;\n /** Fade the poster to transparent over `fadeMs`, then hide it so it can't block the canvas. */\n fadeOut(fadeMs: number): void;\n /** Re-show the poster instantly (used when a live wave is torn down back to the fallback). */\n show(): void;\n /** Remove the poster element from the DOM. */\n remove(): void;\n}\n\n/** Make the container a positioning context so the absolutely-positioned poster overlays the canvas. */\nexport function ensurePositioned(container: HTMLElement): void {\n if (getComputedStyle(container).position === \"static\") container.style.position = \"relative\";\n}\n\n/**\n * Create the poster image — or adopt an existing SSR `<img data-wave3d-poster>` already inside the\n * container (no hydration flash). Positioned to overlay the container and sit above the canvas;\n * `fit` (default `\"fill\"`) sets how it maps into the box — see {@link PosterFit}.\n * Returns null when there's neither a `src` nor an adoptable image (poster is optional).\n */\nexport function setupPoster(\n container: HTMLElement,\n src?: string,\n fit: PosterFit = \"fill\",\n): Poster | null {\n let img = container.querySelector<HTMLImageElement>(`img[${POSTER_ATTR}]`);\n if (!img && !src) return null;\n if (!img) {\n img = document.createElement(\"img\");\n img.setAttribute(POSTER_ATTR, \"\");\n img.decoding = \"async\";\n img.alt = \"\";\n img.setAttribute(\"aria-hidden\", \"true\");\n container.appendChild(img);\n }\n if (src) img.src = src;\n Object.assign(img.style, {\n position: \"absolute\",\n inset: \"0\",\n width: \"100%\",\n height: \"100%\",\n objectFit: fit, // \"fill\" by default so the poster maps into the box like the canvas does\n pointerEvents: \"none\", // clicks/scrolls pass through to the canvas beneath\n zIndex: \"1\", // above the WebGL canvas (which sits at the default z-order)\n opacity: \"1\",\n visibility: \"visible\",\n });\n const el = img;\n return {\n el,\n fadeOut(fadeMs) {\n if (fadeMs <= 0) {\n el.style.opacity = \"0\";\n el.style.visibility = \"hidden\";\n return;\n }\n el.style.transition = `opacity ${fadeMs}ms ease`;\n void el.offsetWidth; // force a style flush so the transition runs from the current opacity (1)\n el.style.opacity = \"0\";\n // Hide after the fade so the (transparent) poster can never intercept anything; the timer is\n // rAF-independent so it still completes in a throttled/backgrounded tab.\n setTimeout(() => {\n el.style.visibility = \"hidden\";\n }, fadeMs + 50);\n },\n show() {\n el.style.transition = \"\";\n el.style.opacity = \"1\";\n el.style.visibility = \"visible\";\n },\n remove() {\n el.remove();\n },\n };\n}\n"],"mappings":";AAGA,MAAM,cAAc;;AAsBpB,SAAgB,iBAAiB,WAA8B;CAC7D,IAAI,iBAAiB,SAAS,CAAC,CAAC,aAAa,UAAU,UAAU,MAAM,WAAW;AACpF;;;;;;;AAQA,SAAgB,YACd,WACA,KACA,MAAiB,QACF;CACf,IAAI,MAAM,UAAU,cAAgC,OAAO,YAAY,EAAE;CACzE,IAAI,CAAC,OAAO,CAAC,KAAK,OAAO;CACzB,IAAI,CAAC,KAAK;EACR,MAAM,SAAS,cAAc,KAAK;EAClC,IAAI,aAAa,aAAa,EAAE;EAChC,IAAI,WAAW;EACf,IAAI,MAAM;EACV,IAAI,aAAa,eAAe,MAAM;EACtC,UAAU,YAAY,GAAG;CAC3B;CACA,IAAI,KAAK,IAAI,MAAM;CACnB,OAAO,OAAO,IAAI,OAAO;EACvB,UAAU;EACV,OAAO;EACP,OAAO;EACP,QAAQ;EACR,WAAW;EACX,eAAe;EACf,QAAQ;EACR,SAAS;EACT,YAAY;CACd,CAAC;CACD,MAAM,KAAK;CACX,OAAO;EACL;EACA,QAAQ,QAAQ;GACd,IAAI,UAAU,GAAG;IACf,GAAG,MAAM,UAAU;IACnB,GAAG,MAAM,aAAa;IACtB;GACF;GACA,GAAG,MAAM,aAAa,WAAW,OAAO;GACxC,GAAQ;GACR,GAAG,MAAM,UAAU;GAGnB,iBAAiB;IACf,GAAG,MAAM,aAAa;GACxB,GAAG,SAAS,EAAE;EAChB;EACA,OAAO;GACL,GAAG,MAAM,aAAa;GACtB,GAAG,MAAM,UAAU;GACnB,GAAG,MAAM,aAAa;EACxB;EACA,SAAS;GACP,GAAG,OAAO;EACZ;CACF;AACF"}