pixi-effects 0.35.0 → 0.37.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 (77) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +5 -5
  3. package/ai/chat-template.html +3 -3
  4. package/ai/tools/check.mjs +38 -9
  5. package/ai/tools/lookup.mjs +15 -2
  6. package/dist/{Base-pNq6sVGl.d.cts → Base-BlA6SeqJ.d.cts} +1 -1
  7. package/dist/{Base-CXsMdmJB.d.ts → Base-YqM0Ljvp.d.ts} +1 -1
  8. package/dist/Composition-5KZETM4J.js +7 -0
  9. package/dist/{Composition-NDXKQHB4.js.map → Composition-5KZETM4J.js.map} +1 -1
  10. package/dist/Composition-MHDI7UNZ.cjs +16 -0
  11. package/dist/{Composition-OLH7RC5Z.cjs.map → Composition-MHDI7UNZ.cjs.map} +1 -1
  12. package/dist/Controller.d.cts +2 -2
  13. package/dist/Controller.d.ts +2 -2
  14. package/dist/{Movie-VYtUN4TS.d.ts → Movie-CJN_gvLB.d.cts} +26 -2
  15. package/dist/{Movie-Db4QnMIH.d.cts → Movie-CfHaGmUP.d.ts} +26 -2
  16. package/dist/{Spans-QHHWC2PB.js → Spans-FSSO2HGX.js} +6 -6
  17. package/dist/{Spans-QHHWC2PB.js.map → Spans-FSSO2HGX.js.map} +1 -1
  18. package/dist/{Spans-QRMN2EZO.cjs → Spans-WVJH77BW.cjs} +11 -11
  19. package/dist/{Spans-QRMN2EZO.cjs.map → Spans-WVJH77BW.cjs.map} +1 -1
  20. package/dist/{blendModes-WIUCYIMC.cjs → blendModes-FD3THLNC.cjs} +5 -5
  21. package/dist/{blendModes-WIUCYIMC.cjs.map → blendModes-FD3THLNC.cjs.map} +1 -1
  22. package/dist/{blendModes-PP5NPBXY.js → blendModes-FMYO6SQN.js} +4 -4
  23. package/dist/{blendModes-PP5NPBXY.js.map → blendModes-FMYO6SQN.js.map} +1 -1
  24. package/dist/{chunk-ITDYFBB6.js → chunk-32MMNDDN.js} +7 -6
  25. package/dist/chunk-32MMNDDN.js.map +1 -0
  26. package/dist/{chunk-GL2AQFLQ.cjs → chunk-3SAS3ZE5.cjs} +7 -6
  27. package/dist/chunk-3SAS3ZE5.cjs.map +1 -0
  28. package/dist/{chunk-7TTCPHAV.cjs → chunk-E26M4NTL.cjs} +235 -49
  29. package/dist/chunk-E26M4NTL.cjs.map +1 -0
  30. package/dist/{chunk-XV4L72FW.js → chunk-IPQNT65V.js} +6 -6
  31. package/dist/chunk-IPQNT65V.js.map +1 -0
  32. package/dist/{chunk-IMQJVRMT.cjs → chunk-JN7JHNZR.cjs} +5 -5
  33. package/dist/{chunk-IMQJVRMT.cjs.map → chunk-JN7JHNZR.cjs.map} +1 -1
  34. package/dist/{chunk-2GNK6DPV.js → chunk-KNDEKWQO.js} +203 -18
  35. package/dist/chunk-KNDEKWQO.js.map +1 -0
  36. package/dist/{chunk-5IJENZOG.cjs → chunk-MJMOPWMK.cjs} +92 -92
  37. package/dist/chunk-MJMOPWMK.cjs.map +1 -0
  38. package/dist/{chunk-LEECUCTG.cjs → chunk-QHIOOK5S.cjs} +436 -29
  39. package/dist/chunk-QHIOOK5S.cjs.map +1 -0
  40. package/dist/{chunk-Y253JQOH.js → chunk-SBR75G73.js} +416 -11
  41. package/dist/chunk-SBR75G73.js.map +1 -0
  42. package/dist/{chunk-RTJD3ZSW.js → chunk-VNP7QCJE.js} +4 -4
  43. package/dist/{chunk-RTJD3ZSW.js.map → chunk-VNP7QCJE.js.map} +1 -1
  44. package/dist/index.cjs +41 -33
  45. package/dist/index.d.cts +47 -7
  46. package/dist/index.d.ts +47 -7
  47. package/dist/index.js +5 -5
  48. package/dist/loader.css +1 -1
  49. package/dist/present.cjs +5 -5
  50. package/dist/present.d.cts +2 -2
  51. package/dist/present.d.ts +2 -2
  52. package/dist/present.js +5 -5
  53. package/dist/three.cjs +6 -6
  54. package/dist/three.d.cts +2 -2
  55. package/dist/three.d.ts +2 -2
  56. package/dist/three.js +2 -2
  57. package/dist/{types-CavnUvd5.d.cts → types-DvnXXm33.d.cts} +67 -3
  58. package/dist/{types-CavnUvd5.d.ts → types-DvnXXm33.d.ts} +67 -3
  59. package/docs/api.md +5 -4
  60. package/docs/dsl.md +42 -5
  61. package/llms-full.txt +305 -22
  62. package/package.json +1 -1
  63. package/skills/pixi-effects/SKILL.md +5 -4
  64. package/skills/pixi-effects/reference/cheatsheet.md +9 -6
  65. package/skills/pixi-effects/reference/pitfalls.md +7 -0
  66. package/skills/pixi-effects/reference/recipes.md +237 -3
  67. package/skills/pixi-effects/template.html +6 -6
  68. package/dist/Composition-NDXKQHB4.js +0 -7
  69. package/dist/Composition-OLH7RC5Z.cjs +0 -16
  70. package/dist/chunk-2GNK6DPV.js.map +0 -1
  71. package/dist/chunk-5IJENZOG.cjs.map +0 -1
  72. package/dist/chunk-7TTCPHAV.cjs.map +0 -1
  73. package/dist/chunk-GL2AQFLQ.cjs.map +0 -1
  74. package/dist/chunk-ITDYFBB6.js.map +0 -1
  75. package/dist/chunk-LEECUCTG.cjs.map +0 -1
  76. package/dist/chunk-XV4L72FW.js.map +0 -1
  77. package/dist/chunk-Y253JQOH.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { describeLayer } from './chunk-ITDYFBB6.js';
1
+ import { describeLayer } from './chunk-32MMNDDN.js';
2
2
  import { suggestName } from './chunk-BXOCEZ4U.js';
3
3
 
4
4
  // src/core/blend.ts
@@ -83,7 +83,7 @@ function blendFilterFor(mode) {
83
83
  }
84
84
  async function enableAdvancedBlend(renderer) {
85
85
  try {
86
- const { registerBlendModes } = await import('./blendModes-PP5NPBXY.js');
86
+ const { registerBlendModes } = await import('./blendModes-FMYO6SQN.js');
87
87
  registerBlendModes();
88
88
  } catch (e) {
89
89
  const why = e instanceof Error ? e.message : String(e);
@@ -128,5 +128,5 @@ function maxConcurrentAdvanced(layers, span) {
128
128
  }
129
129
 
130
130
  export { MANY_ADVANCED, applyBlendMode, blendFilterFor, enableAdvancedBlend, isAdvancedBlend, maxConcurrentAdvanced, setBlendFilterFactory, usesAdvancedBlend };
131
- //# sourceMappingURL=chunk-RTJD3ZSW.js.map
132
- //# sourceMappingURL=chunk-RTJD3ZSW.js.map
131
+ //# sourceMappingURL=chunk-VNP7QCJE.js.map
132
+ //# sourceMappingURL=chunk-VNP7QCJE.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/blend.ts"],"names":[],"mappings":"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","file":"chunk-RTJD3ZSW.js","sourcesContent":["import { describeLayer } from './lint';\nimport { suggestName } from './options';\n\n/** The modes Pixi draws itself (`add`, `screen`, `multiply`) and `normal`. */\nexport const BASIC_BLEND_MODES = ['normal', 'add', 'screen', 'multiply'] as const;\n/** The modes that need the backdrop: our own `BlendModeFilter`s (`src/filters/blendModes.ts`), loaded only when a movie uses one. */\nexport const ADVANCED_BLEND_MODES = [\n 'overlay', 'soft-light', 'hard-light', 'color-dodge', 'color-burn', 'darken', 'lighten', 'difference', 'exclusion',\n 'hue', 'saturation', 'color', 'luminosity', 'linear-burn',\n] as const;\n/** Every `blendMode` there is (the one table the warnings, the types and the docs check against). */\nexport const BLEND_MODES: readonly string[] = [...BASIC_BLEND_MODES, ...ADVANCED_BLEND_MODES];\n\nexport function isAdvancedBlend(mode: unknown): boolean {\n return typeof mode === 'string' && (ADVANCED_BLEND_MODES as readonly string[]).includes(mode);\n}\n\n/** Why `mode` is not a blend mode, with the likely name and the choices; null when it is one. */\nexport function blendProblem(mode: unknown): string | null {\n if (typeof mode === 'string' && BLEND_MODES.includes(mode)) return null;\n const guess = typeof mode === 'string' ? suggestName(mode, BLEND_MODES) : null;\n const shown = typeof mode === 'string' ? `\"${mode}\"` : String(mode);\n return `blendMode ${shown} is not supported${guess ? `; did you mean \"${guess}\"?` : ''} (use ${BLEND_MODES.join(', ')})`;\n}\n\n/** Does any layer of this composition (or one nested in it, or a mask layer) use an advanced blend? */\nexport function usesAdvancedBlend(spec: unknown): boolean {\n const visit = (n: unknown): boolean => {\n if (!n || typeof n !== 'object') return false;\n if (Array.isArray(n)) return n.some(visit);\n const o = n as Record<string, unknown>;\n return isAdvancedBlend(o.blendMode) || visit(o.sequences) || visit(o.mask) || visit(o.layer); // (`layer`: a mask written as { layer: <spec>, invert })\n };\n return visit(spec);\n}\n\n/** What to say about a layer's blend mode: `Composition` collects these per build, so the same mistake in 300 particle layers is said once. */\nexport type BlendReport = (message: string, spec: { name?: string; type: string }) => void;\nconst sayNow: BlendReport = (message, spec) => console.warn(`pixi-effects: ${describeLayer(spec)}: ${message}`);\n\n/** The blend filters of an advanced mode were not registered (a movie registers them in `Movie.init`, or loading them failed): the layer is drawn normal. */\nexport function blendUnavailableMessage(mode: string): string {\n return `blendMode \"${mode}\" could not be set up (the blend filters are not registered); the layer is drawn normal`;\n}\n\n/**\n * Apply a layer's `blendMode` to its display object; an unknown mode, or an advanced mode while the blend filters are not registered, says so\n * and the layer is drawn normal. Returns the blend filter it added to the layer's filter chain (the caller destroys it with the layer), if any.\n */\nexport function applyBlendMode(\n spec: { blendMode?: string; name?: string; type: string },\n display: { blendMode?: unknown; filters?: unknown },\n report: BlendReport = sayNow,\n): BlendFilterLike | null {\n const mode = spec.blendMode;\n if (mode === undefined) return null;\n const problem = blendProblem(mode);\n if (problem) { report(problem, spec); return null; }\n if (isAdvancedBlend(mode) && !blendRegistered()) { report(blendUnavailableMessage(mode), spec); return null; }\n // A container's blend mode applies INSIDE a filter's offscreen pass (against transparent black: multiply gave\n // solid black) and not to the filtered result. With filters, the pass that draws onto the backdrop is the last\n // filter's, so the mode goes there; the container stays normal.\n const filters = display.filters;\n if (Array.isArray(filters) && filters.length > 0) {\n if (isAdvancedBlend(mode)) {\n // an advanced mode is a filter of its own (it reads the backdrop): it joins the chain as the last pass\n const blend = blendFilterFor(mode);\n if (!blend) { report(blendUnavailableMessage(mode), spec); return null; }\n display.filters = [...filters, blend];\n return blend;\n }\n (filters[filters.length - 1] as { blendMode?: unknown }).blendMode = mode;\n return null;\n }\n display.blendMode = mode;\n return null;\n}\n\n/** What blend.ts needs of a blend filter (the real ones are Pixi filters; tests use plain objects). */\nexport type BlendFilterLike = { blendMode?: unknown; destroy(): void };\nlet factory: ((mode: string) => BlendFilterLike | null) | null = null;\n\n/** `filters/blendModes.ts` hands its filter maker here when it registers, so this file never imports Pixi. */\nexport function setBlendFilterFactory(f: ((mode: string) => BlendFilterLike | null) | null): void {\n factory = f;\n}\n\n/** Are the blend filters registered (a movie that uses an advanced mode registers them in `Movie.init`)? */\nexport function blendRegistered(): boolean {\n return factory !== null;\n}\n\n/** A fresh blend filter for an advanced mode, or null when the blends are not registered (or the mode is not an advanced one). */\nexport function blendFilterFor(mode: string): BlendFilterLike | null {\n return isAdvancedBlend(mode) && factory ? factory(mode) : null;\n}\n\n/**\n * Called by `Movie.init` when a layer uses an advanced mode, and only then: loads our blend filters (a separate chunk), registers them on\n * the pixi the movie runs on, and on WebGL turns the back buffer on (an advanced blend reads what is already drawn; WebGPU copies the\n * backdrop by itself, and has no such switch). A movie that uses none never reaches this, so nothing about it changes.\n */\nexport async function enableAdvancedBlend(renderer: unknown): Promise<void> {\n try {\n const { registerBlendModes } = await import('../filters/blendModes');\n registerBlendModes();\n } catch (e) {\n // a page that serves dist/index.js without its chunk, a CDN hiccup: the movie still plays, its advanced blends drawn normal\n const why = e instanceof Error ? e.message : String(e);\n console.warn(`pixi-effects: the blend filters could not be loaded (${why}); layers with an advanced blendMode are drawn normal. Serve the whole dist/ folder (the filters are the blendModes-*.js file next to index.js)`);\n return;\n }\n const bb = (renderer as { backBuffer?: { useBackBuffer: boolean } }).backBuffer;\n if (bb) bb.useBackBuffer = true;\n}\n\n/** This many layers with an advanced blend on screen at once is slow: each is a full-frame pass (measured on WebGL: about 1.5–2 ms each at 1080p). */\nexport const MANY_ADVANCED = 10;\n\ntype Counted = { at?: number; duration?: number; blendMode?: unknown; type?: string; sequences?: unknown };\n\n/** The layers a composition draws (its children each blend one by one when it has a mode): null, camera and audio layers draw nothing; nested compositions are walked. */\nfunction drawnLeaves(sequences: unknown): number {\n if (!Array.isArray(sequences)) return 0;\n let n = 0;\n for (const s of sequences as Counted[]) {\n if (!s || s.type === 'null' || s.type === 'camera' || s.type === 'audio') continue;\n n += s.type === 'composition' ? drawnLeaves(s.sequences) : 1;\n }\n return n;\n}\n\n/**\n * The full-frame passes one layer costs while it is on screen: 1 for a layer with an advanced mode; for a composition with one, one for each\n * drawn layer inside it (its children inherit the mode and blend one by one); for a composition without, the most that its own layers add\n * at one instant (a card with three blends in it, on screen with four other cards, is twelve).\n */\nfunction passesOf(l: Counted, span: number): number {\n const isComposition = l.type === 'composition';\n if (isAdvancedBlend(l.blendMode)) return isComposition ? Math.max(1, drawnLeaves(l.sequences)) : 1;\n return isComposition && Array.isArray(l.sequences) ? maxConcurrentAdvanced(l.sequences as Counted[], l.duration ?? span) : 0;\n}\n\n/** The most full-frame advanced-blend passes on screen at one instant, from the layers' `at` and `duration` (a layer with no duration lasts to the end). */\nexport function maxConcurrentAdvanced(layers: ReadonlyArray<Counted>, span: number): number {\n const events: Array<[number, number]> = [];\n for (const l of layers) {\n const w = passesOf(l, span);\n if (w === 0) continue;\n const at = l.at ?? 0;\n const end = l.duration === undefined ? span : at + l.duration;\n const start = Math.max(0, at); // a negative `at` starts before the composition: only what is after 0 is on screen\n if (end > start) events.push([start, w], [end, -w]);\n }\n events.sort((a, b) => a[0] - b[0] || a[1] - b[1]); // at one instant, the layers that end go before the ones that start\n let now = 0, most = 0;\n for (const [, d] of events) { now += d; most = Math.max(most, now); }\n return most;\n}\n"]}
1
+ {"version":3,"sources":["../src/core/blend.ts"],"names":[],"mappings":"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","file":"chunk-VNP7QCJE.js","sourcesContent":["import { describeLayer } from './lint';\nimport { suggestName } from './options';\n\n/** The modes Pixi draws itself (`add`, `screen`, `multiply`) and `normal`. */\nexport const BASIC_BLEND_MODES = ['normal', 'add', 'screen', 'multiply'] as const;\n/** The modes that need the backdrop: our own `BlendModeFilter`s (`src/filters/blendModes.ts`), loaded only when a movie uses one. */\nexport const ADVANCED_BLEND_MODES = [\n 'overlay', 'soft-light', 'hard-light', 'color-dodge', 'color-burn', 'darken', 'lighten', 'difference', 'exclusion',\n 'hue', 'saturation', 'color', 'luminosity', 'linear-burn',\n] as const;\n/** Every `blendMode` there is (the one table the warnings, the types and the docs check against). */\nexport const BLEND_MODES: readonly string[] = [...BASIC_BLEND_MODES, ...ADVANCED_BLEND_MODES];\n\nexport function isAdvancedBlend(mode: unknown): boolean {\n return typeof mode === 'string' && (ADVANCED_BLEND_MODES as readonly string[]).includes(mode);\n}\n\n/** Why `mode` is not a blend mode, with the likely name and the choices; null when it is one. */\nexport function blendProblem(mode: unknown): string | null {\n if (typeof mode === 'string' && BLEND_MODES.includes(mode)) return null;\n const guess = typeof mode === 'string' ? suggestName(mode, BLEND_MODES) : null;\n const shown = typeof mode === 'string' ? `\"${mode}\"` : String(mode);\n return `blendMode ${shown} is not supported${guess ? `; did you mean \"${guess}\"?` : ''} (use ${BLEND_MODES.join(', ')})`;\n}\n\n/** Does any layer of this composition (or one nested in it, or a mask layer) use an advanced blend? */\nexport function usesAdvancedBlend(spec: unknown): boolean {\n const visit = (n: unknown): boolean => {\n if (!n || typeof n !== 'object') return false;\n if (Array.isArray(n)) return n.some(visit);\n const o = n as Record<string, unknown>;\n return isAdvancedBlend(o.blendMode) || visit(o.sequences) || visit(o.mask) || visit(o.layer); // (`layer`: a mask written as { layer: <spec>, invert })\n };\n return visit(spec);\n}\n\n/** What to say about a layer's blend mode: `Composition` collects these per build, so the same mistake in 300 particle layers is said once. */\nexport type BlendReport = (message: string, spec: { name?: string; type: string }) => void;\nconst sayNow: BlendReport = (message, spec) => console.warn(`pixi-effects: ${describeLayer(spec)}: ${message}`);\n\n/** The blend filters of an advanced mode were not registered (a movie registers them in `Movie.init`, or loading them failed): the layer is drawn normal. */\nexport function blendUnavailableMessage(mode: string): string {\n return `blendMode \"${mode}\" could not be set up (the blend filters are not registered); the layer is drawn normal`;\n}\n\n/**\n * Apply a layer's `blendMode` to its display object; an unknown mode, or an advanced mode while the blend filters are not registered, says so\n * and the layer is drawn normal. Returns the blend filter it added to the layer's filter chain (the caller destroys it with the layer), if any.\n */\nexport function applyBlendMode(\n spec: { blendMode?: string; name?: string; type: string },\n display: { blendMode?: unknown; filters?: unknown },\n report: BlendReport = sayNow,\n): BlendFilterLike | null {\n const mode = spec.blendMode;\n if (mode === undefined) return null;\n const problem = blendProblem(mode);\n if (problem) { report(problem, spec); return null; }\n if (isAdvancedBlend(mode) && !blendRegistered()) { report(blendUnavailableMessage(mode), spec); return null; }\n // A container's blend mode applies INSIDE a filter's offscreen pass (against transparent black: multiply gave\n // solid black) and not to the filtered result. With filters, the pass that draws onto the backdrop is the last\n // filter's, so the mode goes there; the container stays normal.\n const filters = display.filters;\n if (Array.isArray(filters) && filters.length > 0) {\n if (isAdvancedBlend(mode)) {\n // an advanced mode is a filter of its own (it reads the backdrop): it joins the chain as the last pass\n const blend = blendFilterFor(mode);\n if (!blend) { report(blendUnavailableMessage(mode), spec); return null; }\n display.filters = [...filters, blend];\n return blend;\n }\n (filters[filters.length - 1] as { blendMode?: unknown }).blendMode = mode;\n return null;\n }\n display.blendMode = mode;\n return null;\n}\n\n/** What blend.ts needs of a blend filter (the real ones are Pixi filters; tests use plain objects). */\nexport type BlendFilterLike = { blendMode?: unknown; destroy(): void };\nlet factory: ((mode: string) => BlendFilterLike | null) | null = null;\n\n/** `filters/blendModes.ts` hands its filter maker here when it registers, so this file never imports Pixi. */\nexport function setBlendFilterFactory(f: ((mode: string) => BlendFilterLike | null) | null): void {\n factory = f;\n}\n\n/** Are the blend filters registered (a movie that uses an advanced mode registers them in `Movie.init`)? */\nexport function blendRegistered(): boolean {\n return factory !== null;\n}\n\n/** A fresh blend filter for an advanced mode, or null when the blends are not registered (or the mode is not an advanced one). */\nexport function blendFilterFor(mode: string): BlendFilterLike | null {\n return isAdvancedBlend(mode) && factory ? factory(mode) : null;\n}\n\n/**\n * Called by `Movie.init` when a layer uses an advanced mode, and only then: loads our blend filters (a separate chunk), registers them on\n * the pixi the movie runs on, and on WebGL turns the back buffer on (an advanced blend reads what is already drawn; WebGPU copies the\n * backdrop by itself, and has no such switch). A movie that uses none never reaches this, so nothing about it changes.\n */\nexport async function enableAdvancedBlend(renderer: unknown): Promise<void> {\n try {\n const { registerBlendModes } = await import('../filters/blendModes');\n registerBlendModes();\n } catch (e) {\n // a page that serves dist/index.js without its chunk, a CDN hiccup: the movie still plays, its advanced blends drawn normal\n const why = e instanceof Error ? e.message : String(e);\n console.warn(`pixi-effects: the blend filters could not be loaded (${why}); layers with an advanced blendMode are drawn normal. Serve the whole dist/ folder (the filters are the blendModes-*.js file next to index.js)`);\n return;\n }\n const bb = (renderer as { backBuffer?: { useBackBuffer: boolean } }).backBuffer;\n if (bb) bb.useBackBuffer = true;\n}\n\n/** This many layers with an advanced blend on screen at once is slow: each is a full-frame pass (measured on WebGL: about 1.5–2 ms each at 1080p). */\nexport const MANY_ADVANCED = 10;\n\ntype Counted = { at?: number; duration?: number; blendMode?: unknown; type?: string; sequences?: unknown };\n\n/** The layers a composition draws (its children each blend one by one when it has a mode): null, camera and audio layers draw nothing; nested compositions are walked. */\nfunction drawnLeaves(sequences: unknown): number {\n if (!Array.isArray(sequences)) return 0;\n let n = 0;\n for (const s of sequences as Counted[]) {\n if (!s || s.type === 'null' || s.type === 'camera' || s.type === 'audio') continue;\n n += s.type === 'composition' ? drawnLeaves(s.sequences) : 1;\n }\n return n;\n}\n\n/**\n * The full-frame passes one layer costs while it is on screen: 1 for a layer with an advanced mode; for a composition with one, one for each\n * drawn layer inside it (its children inherit the mode and blend one by one); for a composition without, the most that its own layers add\n * at one instant (a card with three blends in it, on screen with four other cards, is twelve).\n */\nfunction passesOf(l: Counted, span: number): number {\n const isComposition = l.type === 'composition';\n if (isAdvancedBlend(l.blendMode)) return isComposition ? Math.max(1, drawnLeaves(l.sequences)) : 1;\n return isComposition && Array.isArray(l.sequences) ? maxConcurrentAdvanced(l.sequences as Counted[], l.duration ?? span) : 0;\n}\n\n/** The most full-frame advanced-blend passes on screen at one instant, from the layers' `at` and `duration` (a layer with no duration lasts to the end). */\nexport function maxConcurrentAdvanced(layers: ReadonlyArray<Counted>, span: number): number {\n const events: Array<[number, number]> = [];\n for (const l of layers) {\n const w = passesOf(l, span);\n if (w === 0) continue;\n const at = l.at ?? 0;\n const end = l.duration === undefined ? span : at + l.duration;\n const start = Math.max(0, at); // a negative `at` starts before the composition: only what is after 0 is on screen\n if (end > start) events.push([start, w], [end, -w]);\n }\n events.sort((a, b) => a[0] - b[0] || a[1] - b[1]); // at one instant, the layers that end go before the ones that start\n let now = 0, most = 0;\n for (const [, d] of events) { now += d; most = Math.max(most, now); }\n return most;\n}\n"]}
package/dist/index.cjs CHANGED
@@ -1,125 +1,133 @@
1
1
  'use strict';
2
2
 
3
- var chunk7TTCPHAV_cjs = require('./chunk-7TTCPHAV.cjs');
4
- require('./chunk-5IJENZOG.cjs');
5
- var chunkLEECUCTG_cjs = require('./chunk-LEECUCTG.cjs');
6
- require('./chunk-IMQJVRMT.cjs');
7
- require('./chunk-GL2AQFLQ.cjs');
3
+ var chunkE26M4NTL_cjs = require('./chunk-E26M4NTL.cjs');
4
+ require('./chunk-MJMOPWMK.cjs');
5
+ var chunkQHIOOK5S_cjs = require('./chunk-QHIOOK5S.cjs');
6
+ require('./chunk-JN7JHNZR.cjs');
7
+ require('./chunk-3SAS3ZE5.cjs');
8
8
  var chunkTWZNOUM7_cjs = require('./chunk-TWZNOUM7.cjs');
9
9
 
10
10
 
11
11
 
12
12
  Object.defineProperty(exports, "Movie", {
13
13
  enumerable: true,
14
- get: function () { return chunk7TTCPHAV_cjs.Movie; }
14
+ get: function () { return chunkE26M4NTL_cjs.Movie; }
15
15
  });
16
16
  Object.defineProperty(exports, "animateText", {
17
17
  enumerable: true,
18
- get: function () { return chunk7TTCPHAV_cjs.animateText; }
18
+ get: function () { return chunkE26M4NTL_cjs.animateText; }
19
19
  });
20
20
  Object.defineProperty(exports, "audioEnvelope", {
21
21
  enumerable: true,
22
- get: function () { return chunk7TTCPHAV_cjs.audioEnvelope; }
22
+ get: function () { return chunkE26M4NTL_cjs.audioEnvelope; }
23
23
  });
24
24
  Object.defineProperty(exports, "bpmEnvelope", {
25
25
  enumerable: true,
26
- get: function () { return chunk7TTCPHAV_cjs.bpmEnvelope; }
26
+ get: function () { return chunkE26M4NTL_cjs.bpmEnvelope; }
27
27
  });
28
28
  Object.defineProperty(exports, "cameraPath", {
29
29
  enumerable: true,
30
- get: function () { return chunk7TTCPHAV_cjs.cameraPath; }
30
+ get: function () { return chunkE26M4NTL_cjs.cameraPath; }
31
31
  });
32
32
  Object.defineProperty(exports, "computeEnvelope", {
33
33
  enumerable: true,
34
- get: function () { return chunk7TTCPHAV_cjs.computeEnvelope; }
34
+ get: function () { return chunkE26M4NTL_cjs.computeEnvelope; }
35
35
  });
36
36
  Object.defineProperty(exports, "dismissLoader", {
37
37
  enumerable: true,
38
- get: function () { return chunk7TTCPHAV_cjs.dismissLoader; }
38
+ get: function () { return chunkE26M4NTL_cjs.dismissLoader; }
39
39
  });
40
40
  Object.defineProperty(exports, "ease", {
41
41
  enumerable: true,
42
- get: function () { return chunk7TTCPHAV_cjs.parseEase; }
42
+ get: function () { return chunkE26M4NTL_cjs.parseEase; }
43
43
  });
44
44
  Object.defineProperty(exports, "failLoader", {
45
45
  enumerable: true,
46
- get: function () { return chunk7TTCPHAV_cjs.failLoader; }
46
+ get: function () { return chunkE26M4NTL_cjs.failLoader; }
47
47
  });
48
48
  Object.defineProperty(exports, "followPath", {
49
49
  enumerable: true,
50
- get: function () { return chunk7TTCPHAV_cjs.followPath; }
50
+ get: function () { return chunkE26M4NTL_cjs.followPath; }
51
51
  });
52
52
  Object.defineProperty(exports, "kenBurns", {
53
53
  enumerable: true,
54
- get: function () { return chunk7TTCPHAV_cjs.kenBurns; }
54
+ get: function () { return chunkE26M4NTL_cjs.kenBurns; }
55
55
  });
56
56
  Object.defineProperty(exports, "measureText", {
57
57
  enumerable: true,
58
- get: function () { return chunk7TTCPHAV_cjs.measureText; }
58
+ get: function () { return chunkE26M4NTL_cjs.measureText; }
59
59
  });
60
60
  Object.defineProperty(exports, "musicBuffer", {
61
61
  enumerable: true,
62
- get: function () { return chunk7TTCPHAV_cjs.musicBuffer; }
62
+ get: function () { return chunkE26M4NTL_cjs.musicBuffer; }
63
63
  });
64
64
  Object.defineProperty(exports, "musicEnvelope", {
65
65
  enumerable: true,
66
- get: function () { return chunk7TTCPHAV_cjs.musicEnvelope; }
66
+ get: function () { return chunkE26M4NTL_cjs.musicEnvelope; }
67
67
  });
68
68
  Object.defineProperty(exports, "musicEvents", {
69
69
  enumerable: true,
70
- get: function () { return chunk7TTCPHAV_cjs.musicEvents; }
70
+ get: function () { return chunkE26M4NTL_cjs.musicEvents; }
71
71
  });
72
72
  Object.defineProperty(exports, "orbit", {
73
73
  enumerable: true,
74
- get: function () { return chunk7TTCPHAV_cjs.orbit; }
74
+ get: function () { return chunkE26M4NTL_cjs.orbit; }
75
75
  });
76
76
  Object.defineProperty(exports, "particles", {
77
77
  enumerable: true,
78
- get: function () { return chunk7TTCPHAV_cjs.particles; }
78
+ get: function () { return chunkE26M4NTL_cjs.particles; }
79
79
  });
80
80
  Object.defineProperty(exports, "react", {
81
81
  enumerable: true,
82
- get: function () { return chunk7TTCPHAV_cjs.react; }
82
+ get: function () { return chunkE26M4NTL_cjs.react; }
83
83
  });
84
84
  Object.defineProperty(exports, "resolveLoader", {
85
85
  enumerable: true,
86
- get: function () { return chunk7TTCPHAV_cjs.resolveLoader; }
86
+ get: function () { return chunkE26M4NTL_cjs.resolveLoader; }
87
+ });
88
+ Object.defineProperty(exports, "samplePath", {
89
+ enumerable: true,
90
+ get: function () { return chunkE26M4NTL_cjs.samplePath; }
87
91
  });
88
92
  Object.defineProperty(exports, "splitText", {
89
93
  enumerable: true,
90
- get: function () { return chunk7TTCPHAV_cjs.splitText; }
94
+ get: function () { return chunkE26M4NTL_cjs.splitText; }
91
95
  });
92
96
  Object.defineProperty(exports, "stagger", {
93
97
  enumerable: true,
94
- get: function () { return chunk7TTCPHAV_cjs.stagger; }
98
+ get: function () { return chunkE26M4NTL_cjs.stagger; }
95
99
  });
96
100
  Object.defineProperty(exports, "wiggle", {
97
101
  enumerable: true,
98
- get: function () { return chunk7TTCPHAV_cjs.wiggle; }
102
+ get: function () { return chunkE26M4NTL_cjs.wiggle; }
99
103
  });
100
104
  Object.defineProperty(exports, "withFade", {
101
105
  enumerable: true,
102
- get: function () { return chunk7TTCPHAV_cjs.withFade; }
106
+ get: function () { return chunkE26M4NTL_cjs.withFade; }
103
107
  });
104
108
  Object.defineProperty(exports, "Sequence", {
105
109
  enumerable: true,
106
- get: function () { return chunkLEECUCTG_cjs.Sequence; }
110
+ get: function () { return chunkQHIOOK5S_cjs.Sequence; }
107
111
  });
108
112
  Object.defineProperty(exports, "noise", {
109
113
  enumerable: true,
110
- get: function () { return chunkLEECUCTG_cjs.noise; }
114
+ get: function () { return chunkQHIOOK5S_cjs.noise; }
115
+ });
116
+ Object.defineProperty(exports, "noise2", {
117
+ enumerable: true,
118
+ get: function () { return chunkQHIOOK5S_cjs.noise2; }
111
119
  });
112
120
  Object.defineProperty(exports, "rand", {
113
121
  enumerable: true,
114
- get: function () { return chunkLEECUCTG_cjs.rand; }
122
+ get: function () { return chunkQHIOOK5S_cjs.rand; }
115
123
  });
116
124
  Object.defineProperty(exports, "random", {
117
125
  enumerable: true,
118
- get: function () { return chunkLEECUCTG_cjs.random; }
126
+ get: function () { return chunkQHIOOK5S_cjs.random; }
119
127
  });
120
128
  Object.defineProperty(exports, "registerSequenceType", {
121
129
  enumerable: true,
122
- get: function () { return chunkLEECUCTG_cjs.registerSequenceType; }
130
+ get: function () { return chunkQHIOOK5S_cjs.registerSequenceType; }
123
131
  });
124
132
  Object.defineProperty(exports, "warnUnknownOptions", {
125
133
  enumerable: true,
package/dist/index.d.cts CHANGED
@@ -1,8 +1,8 @@
1
- import { M as MusicEvents } from './Movie-Db4QnMIH.cjs';
2
- export { A as AudioInspectOptions, a as AudioReport, b as AudioSourceReport, C as ContactSheetOptions, F as FontReport, c as FrameEvent, I as InspectOptions, d as InspectReport, e as IssueGroup, L as LayerInfo, f as LoadProgressState, g as LoadStage, h as LoaderOption, i as LoopEvent, j as MotionBlurOptions, k as MotionBlurSpec, l as Movie, m as MovieErrorEvent, n as MovieOptions, o as MusicDrumEvents, p as MusicDrumHit, q as MusicNote, r as MusicSummary, s as MusicTrackEvents, O as OnionSkinOptions, P as ProgressEvent, R as RebuildOptions, t as RebuildReason, u as RebuildReport, v as RenderOptions, w as ReviewOptions, x as ReviewReport, S as SnapshotOptions, y as SoundMeasure, T as ThumbnailOptions, z as TimelineData, B as TimelineHtmlOptions, D as TimelineRow, E as TimelineSvgOptions, G as TimelineTransition, V as VolumeEvent, H as dismissLoader, J as failLoader, K as resolveLoader } from './Movie-Db4QnMIH.cjs';
3
- import { S as SequenceSpec, C as CompositionShape, I as ImageSequenceSpec, a as CameraSequenceSpec, K as Keyframe, T as TextSequenceSpec, M as MusicOptions, b as SequenceCommon } from './types-CavnUvd5.cjs';
4
- export { A as ArcShapeSpec, c as AssetSpec, d as AudioAssetSpec, e as AudioMusicSpec, f as AudioSequenceSpec, g as AudioSfxSpec, B as BlendModeName, h as ChromaKeyFilterSpec, i as CircleShapeSpec, j as CompositionSequenceSpec, k as CompositionSpec, l as CrossfadeTransition, m as CustomFilterSpec, D as DipTransition, n as DissolveTransition, E as EllipseShapeSpec, o as Expr, F as FilterSpec, G as GradientSpec, p as IrisTransition, L as LightSequenceSpec, q as LineShapeSpec, r as LumaTransition, s as MaskRefSpec, t as MatteRefSpec, u as MusicDrum, v as MusicDrums, w as MusicInstrument, x as MusicLevel, y as MusicTrack, N as NullSequenceSpec, P as PathShapeSpec, z as PolygonShapeSpec, H as PropValue, J as Props, R as RectShapeSpec, O as SfxKnobs, Q as SfxOptions, U as SfxPreset, V as SfxVoice, W as ShaderSequenceSpec, X as ShapeSequenceSpec, Y as SlideTransition, Z as Stop, _ as StopSpec, $ as TextSpan, a0 as TransitionCommon, a1 as TransitionSpec, a2 as VideoSequenceSpec, a3 as WipeTransition, a4 as ZoomTransition } from './types-CavnUvd5.cjs';
5
- import { S as Sequence } from './Base-pNq6sVGl.cjs';
1
+ import { M as MusicEvents } from './Movie-CJN_gvLB.cjs';
2
+ export { A as AudioInspectOptions, a as AudioReport, b as AudioSourceReport, C as ContactSheetOptions, F as FontReport, c as FrameEvent, I as InspectOptions, d as InspectReport, e as IssueGroup, L as LayerInfo, f as LoadProgressState, g as LoadStage, h as LoaderOption, i as LoopEvent, j as MotionBlurOptions, k as MotionBlurSpec, l as Movie, m as MovieErrorEvent, n as MovieOptions, o as MusicDrumEvents, p as MusicDrumHit, q as MusicNote, r as MusicSummary, s as MusicTrackEvents, O as OnionSkinOptions, P as ProgressEvent, R as RebuildOptions, t as RebuildReason, u as RebuildReport, v as RenderOptions, w as ReviewOptions, x as ReviewReport, S as SnapshotOptions, y as SoundMeasure, T as ThumbnailOptions, z as TimelineData, B as TimelineHtmlOptions, D as TimelineRow, E as TimelineSvgOptions, G as TimelineTransition, V as VolumeEvent, H as dismissLoader, J as failLoader, K as resolveLoader } from './Movie-CJN_gvLB.cjs';
3
+ import { S as SequenceSpec, C as CompositionShape, I as ImageSequenceSpec, a as CameraSequenceSpec, K as Keyframe, T as TextSequenceSpec, M as MusicOptions, b as SequenceCommon } from './types-DvnXXm33.cjs';
4
+ export { A as ArcShapeSpec, c as AssetSpec, d as AudioAssetSpec, e as AudioMusicSpec, f as AudioSequenceSpec, g as AudioSfxSpec, B as BlendModeName, h as CanvasInfo, i as CanvasSequenceSpec, j as ChromaKeyFilterSpec, k as CircleShapeSpec, l as CompositionSequenceSpec, m as CompositionSpec, n as CrossfadeTransition, o as CustomFilterSpec, D as DipTransition, p as DissolveTransition, E as EllipseShapeSpec, q as Expr, F as FilterSpec, G as GradientSpec, r as IrisTransition, L as LightSequenceSpec, s as LineShapeSpec, t as LumaTransition, u as MaskRefSpec, v as MatteRefSpec, w as MusicDrum, x as MusicDrums, y as MusicInstrument, z as MusicLevel, H as MusicTrack, N as NullSequenceSpec, P as PathShapeSpec, J as PolygonShapeSpec, O as PropValue, Q as Props, R as RectShapeSpec, U as SfxKnobs, V as SfxOptions, W as SfxPreset, X as SfxVoice, Y as ShaderSequenceSpec, Z as ShapeSequenceSpec, _ as SlideTransition, $ as Stop, a0 as StopSpec, a1 as TextSpan, a2 as TransitionCommon, a3 as TransitionSpec, a4 as VideoSequenceSpec, a5 as WipeTransition, a6 as ZoomTransition } from './types-DvnXXm33.cjs';
5
+ import { S as Sequence } from './Base-BlA6SeqJ.cjs';
6
6
  import 'pixi.js';
7
7
 
8
8
  /** A text style as written in a `text` layer's `style` (numbers, not expressions, for the fields that size the text). */
@@ -22,6 +22,13 @@ interface SplitOptions {
22
22
  y?: number;
23
23
  /** How each line sits on `x`. Default `'left'`. */
24
24
  align?: 'left' | 'center' | 'right';
25
+ /**
26
+ * Vertical writing (tategaki): characters go down a column, a new line is a new column to the left. `x` is then the RIGHT edge of the first column and `y` the top
27
+ * of a column (`align`: `'left'` keeps y at the top, `'center'` at the middle, `'right'` at the bottom). Only `by: 'chars'` has a vertical form. Each piece also gets
28
+ * `cx` / `cy` (the centre of its cell, punctuation already moved to the upper right) and `rotation` (degrees: the long vowel mark, dashes, waves and brackets are turned
29
+ * a quarter clockwise); place a text layer with `anchorX: 0.5, anchorY: 0.5` at `cx` / `cy` and `rotation: p.rotation`. `animateText(..., { vertical: true })` does all of it.
30
+ */
31
+ vertical?: boolean;
25
32
  }
26
33
  interface TextPiece {
27
34
  text: string;
@@ -34,6 +41,11 @@ interface TextPiece {
34
41
  index: number;
35
42
  /** Which line (0-based) the piece is on. */
36
43
  line: number;
44
+ /** Vertical text only: where the centre of the piece goes (a text layer with `anchorX: 0.5, anchorY: 0.5`). */
45
+ cx?: number;
46
+ cy?: number;
47
+ /** Vertical text only: the turn in degrees the piece needs (0 or 90). */
48
+ rotation?: number;
37
49
  }
38
50
  /**
39
51
  * How big `text` is drawn with `style`: the same numbers a text layer with that style has, measured with the font the
@@ -277,6 +289,30 @@ interface FollowPathOptions {
277
289
  */
278
290
  declare function followPath(opts: FollowPathOptions): Keyframe[];
279
291
 
292
+ /** A path walked by length: where a fraction of the way along is, which way it heads, and the part between two fractions. */
293
+ interface PathSampler {
294
+ /** The arc length of all the sub-paths together, in the path's own units. */
295
+ length: number;
296
+ /** The point a fraction `u` (0–1, clamped) of the length along, and the heading there in radians (`Math.atan2` of the direction, 0 = right, π/2 = down). */
297
+ at(u: number): {
298
+ x: number;
299
+ y: number;
300
+ angle: number;
301
+ };
302
+ /** The part between the fractions `start` and `end` (default the whole path) as flat `[x, y, x, y, …]` pieces, one per sub-path it touches: draw each with `moveTo` / `lineTo` (a line that draws on). */
303
+ trim(start?: number, end?: number): number[][];
304
+ }
305
+ /**
306
+ * Walks SVG path data by arc length, the way `followPath` does, for a `canvas` layer's `draw` (or anything that needs the points of a curve): text set along a curve, a leader
307
+ * line that draws on, a petal that falls along a route. Curves are flattened the way the shape layer draws them. Build it once (module scope or `setup`), ask it every frame.
308
+ *
309
+ * ```js
310
+ * const route = samplePath('M 40 300 C 200 20 400 20 560 300');
311
+ * // in draw: const { x, y, angle } = route.at(t / 4); for (const piece of route.trim(0, t / 4)) { ctx.moveTo(piece[0], piece[1]); … }
312
+ * ```
313
+ */
314
+ declare function samplePath(d: string): PathSampler;
315
+
280
316
  interface CameraPathOptions {
281
317
  /** The route: `[x, y, z]` points the camera passes, in order (at least two). */
282
318
  points: Array<[number, number, number]>;
@@ -403,7 +439,7 @@ type TextPreset = keyof typeof PRESETS;
403
439
  interface AnimateTextTween {
404
440
  /** Start from this preset and change what you give below. */
405
441
  preset?: TextPreset;
406
- /** The hidden state: `x` / `y` are offsets from the resting place, everything else (`alpha`, `scale`, `rotation`, …) is absolute. */
442
+ /** The hidden state: `x` / `y` are offsets from the resting place, everything else (`alpha`, `scale`, …) is absolute; `rotation` too, from the resting rotation (0, except the turned glyphs of vertical text, which rest at 90°). */
407
443
  from?: Record<string, number>;
408
444
  /** The resting state, for properties that have none of their own (`alpha` 1, `scale` 1, `rotation` 0 and the place are known). */
409
445
  to?: Record<string, number>;
@@ -422,6 +458,8 @@ interface AnimateTextOptions {
422
458
  /** Top of the first line. */
423
459
  y?: number;
424
460
  align?: 'left' | 'center' | 'right';
461
+ /** Vertical writing: characters go down a column, a new line is a new column to the left, and `x` is the RIGHT edge of the first column (see `splitText`). Punctuation and the long vowel mark are placed and turned the way tategaki wants. */
462
+ vertical?: boolean;
425
463
  /** Layers are named `<name>-0`, `<name>-1`, … (default `'text'`). */
426
464
  name?: string;
427
465
  /** When the first piece starts, in composition seconds. Default 0. */
@@ -652,6 +690,8 @@ declare function rand(seed: number): number;
652
690
  declare function random(seed: number): () => number;
653
691
  /** Smooth 1-D noise in [-1, 1]: continuous in `x`, a different curve for every `seed`. */
654
692
  declare function noise(x: number, seed?: number): number;
693
+ /** Smooth 2-D noise in [-1, 1]: continuous in `x` and in `y`, a different field for every `seed` (add octaves yourself for clouds: `noise2(x, y) + 0.5 * noise2(2 * x, 2 * y)`). */
694
+ declare function noise2(x: number, y: number, seed?: number): number;
655
695
 
656
696
  interface WithFadeOptions {
657
697
  /** Fade-in duration (seconds), at the start of the sequence. */
@@ -687,4 +727,4 @@ interface WithFadeOptions {
687
727
  */
688
728
  declare function withFade<T extends SequenceCommon>(spec: T, opts: WithFadeOptions): T;
689
729
 
690
- export { type AnimateTextOptions, type AnimateTextTween, type AudioEnvelope, type AudioEnvelopeSource, type CameraPathOptions, CameraSequenceSpec, CompositionShape, type EnvelopeOptions, type FollowPathOptions, ImageSequenceSpec, type KenBurnsOptions, Keyframe, type MeasureStyle, MusicEvents, MusicOptions, type OrbitOptions, type ParticlesOptions, type ReactOptions, type ReactProp, Sequence, SequenceCommon, type SequenceCtor, SequenceSpec, type SplitOptions, type StaggerOptions, type TextPiece, type TextPreset, TextSequenceSpec, type TextSize, type WiggleOptions, type WiggleProp, type WithFadeOptions, animateText, audioEnvelope, bpmEnvelope, cameraPath, computeEnvelope, parseEase as ease, followPath, kenBurns, measureText, musicBuffer, musicEnvelope, musicEvents, noise, orbit, particles, rand, random, react, registerSequenceType, splitText, stagger, warnUnknownOptions, wiggle, withFade };
730
+ export { type AnimateTextOptions, type AnimateTextTween, type AudioEnvelope, type AudioEnvelopeSource, type CameraPathOptions, CameraSequenceSpec, CompositionShape, type EnvelopeOptions, type FollowPathOptions, ImageSequenceSpec, type KenBurnsOptions, Keyframe, type MeasureStyle, MusicEvents, MusicOptions, type OrbitOptions, type ParticlesOptions, type PathSampler, type ReactOptions, type ReactProp, Sequence, SequenceCommon, type SequenceCtor, SequenceSpec, type SplitOptions, type StaggerOptions, type TextPiece, type TextPreset, TextSequenceSpec, type TextSize, type WiggleOptions, type WiggleProp, type WithFadeOptions, animateText, audioEnvelope, bpmEnvelope, cameraPath, computeEnvelope, parseEase as ease, followPath, kenBurns, measureText, musicBuffer, musicEnvelope, musicEvents, noise, noise2, orbit, particles, rand, random, react, registerSequenceType, samplePath, splitText, stagger, warnUnknownOptions, wiggle, withFade };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { M as MusicEvents } from './Movie-VYtUN4TS.js';
2
- export { A as AudioInspectOptions, a as AudioReport, b as AudioSourceReport, C as ContactSheetOptions, F as FontReport, c as FrameEvent, I as InspectOptions, d as InspectReport, e as IssueGroup, L as LayerInfo, f as LoadProgressState, g as LoadStage, h as LoaderOption, i as LoopEvent, j as MotionBlurOptions, k as MotionBlurSpec, l as Movie, m as MovieErrorEvent, n as MovieOptions, o as MusicDrumEvents, p as MusicDrumHit, q as MusicNote, r as MusicSummary, s as MusicTrackEvents, O as OnionSkinOptions, P as ProgressEvent, R as RebuildOptions, t as RebuildReason, u as RebuildReport, v as RenderOptions, w as ReviewOptions, x as ReviewReport, S as SnapshotOptions, y as SoundMeasure, T as ThumbnailOptions, z as TimelineData, B as TimelineHtmlOptions, D as TimelineRow, E as TimelineSvgOptions, G as TimelineTransition, V as VolumeEvent, H as dismissLoader, J as failLoader, K as resolveLoader } from './Movie-VYtUN4TS.js';
3
- import { S as SequenceSpec, C as CompositionShape, I as ImageSequenceSpec, a as CameraSequenceSpec, K as Keyframe, T as TextSequenceSpec, M as MusicOptions, b as SequenceCommon } from './types-CavnUvd5.js';
4
- export { A as ArcShapeSpec, c as AssetSpec, d as AudioAssetSpec, e as AudioMusicSpec, f as AudioSequenceSpec, g as AudioSfxSpec, B as BlendModeName, h as ChromaKeyFilterSpec, i as CircleShapeSpec, j as CompositionSequenceSpec, k as CompositionSpec, l as CrossfadeTransition, m as CustomFilterSpec, D as DipTransition, n as DissolveTransition, E as EllipseShapeSpec, o as Expr, F as FilterSpec, G as GradientSpec, p as IrisTransition, L as LightSequenceSpec, q as LineShapeSpec, r as LumaTransition, s as MaskRefSpec, t as MatteRefSpec, u as MusicDrum, v as MusicDrums, w as MusicInstrument, x as MusicLevel, y as MusicTrack, N as NullSequenceSpec, P as PathShapeSpec, z as PolygonShapeSpec, H as PropValue, J as Props, R as RectShapeSpec, O as SfxKnobs, Q as SfxOptions, U as SfxPreset, V as SfxVoice, W as ShaderSequenceSpec, X as ShapeSequenceSpec, Y as SlideTransition, Z as Stop, _ as StopSpec, $ as TextSpan, a0 as TransitionCommon, a1 as TransitionSpec, a2 as VideoSequenceSpec, a3 as WipeTransition, a4 as ZoomTransition } from './types-CavnUvd5.js';
5
- import { S as Sequence } from './Base-CXsMdmJB.js';
1
+ import { M as MusicEvents } from './Movie-CfHaGmUP.js';
2
+ export { A as AudioInspectOptions, a as AudioReport, b as AudioSourceReport, C as ContactSheetOptions, F as FontReport, c as FrameEvent, I as InspectOptions, d as InspectReport, e as IssueGroup, L as LayerInfo, f as LoadProgressState, g as LoadStage, h as LoaderOption, i as LoopEvent, j as MotionBlurOptions, k as MotionBlurSpec, l as Movie, m as MovieErrorEvent, n as MovieOptions, o as MusicDrumEvents, p as MusicDrumHit, q as MusicNote, r as MusicSummary, s as MusicTrackEvents, O as OnionSkinOptions, P as ProgressEvent, R as RebuildOptions, t as RebuildReason, u as RebuildReport, v as RenderOptions, w as ReviewOptions, x as ReviewReport, S as SnapshotOptions, y as SoundMeasure, T as ThumbnailOptions, z as TimelineData, B as TimelineHtmlOptions, D as TimelineRow, E as TimelineSvgOptions, G as TimelineTransition, V as VolumeEvent, H as dismissLoader, J as failLoader, K as resolveLoader } from './Movie-CfHaGmUP.js';
3
+ import { S as SequenceSpec, C as CompositionShape, I as ImageSequenceSpec, a as CameraSequenceSpec, K as Keyframe, T as TextSequenceSpec, M as MusicOptions, b as SequenceCommon } from './types-DvnXXm33.js';
4
+ export { A as ArcShapeSpec, c as AssetSpec, d as AudioAssetSpec, e as AudioMusicSpec, f as AudioSequenceSpec, g as AudioSfxSpec, B as BlendModeName, h as CanvasInfo, i as CanvasSequenceSpec, j as ChromaKeyFilterSpec, k as CircleShapeSpec, l as CompositionSequenceSpec, m as CompositionSpec, n as CrossfadeTransition, o as CustomFilterSpec, D as DipTransition, p as DissolveTransition, E as EllipseShapeSpec, q as Expr, F as FilterSpec, G as GradientSpec, r as IrisTransition, L as LightSequenceSpec, s as LineShapeSpec, t as LumaTransition, u as MaskRefSpec, v as MatteRefSpec, w as MusicDrum, x as MusicDrums, y as MusicInstrument, z as MusicLevel, H as MusicTrack, N as NullSequenceSpec, P as PathShapeSpec, J as PolygonShapeSpec, O as PropValue, Q as Props, R as RectShapeSpec, U as SfxKnobs, V as SfxOptions, W as SfxPreset, X as SfxVoice, Y as ShaderSequenceSpec, Z as ShapeSequenceSpec, _ as SlideTransition, $ as Stop, a0 as StopSpec, a1 as TextSpan, a2 as TransitionCommon, a3 as TransitionSpec, a4 as VideoSequenceSpec, a5 as WipeTransition, a6 as ZoomTransition } from './types-DvnXXm33.js';
5
+ import { S as Sequence } from './Base-YqM0Ljvp.js';
6
6
  import 'pixi.js';
7
7
 
8
8
  /** A text style as written in a `text` layer's `style` (numbers, not expressions, for the fields that size the text). */
@@ -22,6 +22,13 @@ interface SplitOptions {
22
22
  y?: number;
23
23
  /** How each line sits on `x`. Default `'left'`. */
24
24
  align?: 'left' | 'center' | 'right';
25
+ /**
26
+ * Vertical writing (tategaki): characters go down a column, a new line is a new column to the left. `x` is then the RIGHT edge of the first column and `y` the top
27
+ * of a column (`align`: `'left'` keeps y at the top, `'center'` at the middle, `'right'` at the bottom). Only `by: 'chars'` has a vertical form. Each piece also gets
28
+ * `cx` / `cy` (the centre of its cell, punctuation already moved to the upper right) and `rotation` (degrees: the long vowel mark, dashes, waves and brackets are turned
29
+ * a quarter clockwise); place a text layer with `anchorX: 0.5, anchorY: 0.5` at `cx` / `cy` and `rotation: p.rotation`. `animateText(..., { vertical: true })` does all of it.
30
+ */
31
+ vertical?: boolean;
25
32
  }
26
33
  interface TextPiece {
27
34
  text: string;
@@ -34,6 +41,11 @@ interface TextPiece {
34
41
  index: number;
35
42
  /** Which line (0-based) the piece is on. */
36
43
  line: number;
44
+ /** Vertical text only: where the centre of the piece goes (a text layer with `anchorX: 0.5, anchorY: 0.5`). */
45
+ cx?: number;
46
+ cy?: number;
47
+ /** Vertical text only: the turn in degrees the piece needs (0 or 90). */
48
+ rotation?: number;
37
49
  }
38
50
  /**
39
51
  * How big `text` is drawn with `style`: the same numbers a text layer with that style has, measured with the font the
@@ -277,6 +289,30 @@ interface FollowPathOptions {
277
289
  */
278
290
  declare function followPath(opts: FollowPathOptions): Keyframe[];
279
291
 
292
+ /** A path walked by length: where a fraction of the way along is, which way it heads, and the part between two fractions. */
293
+ interface PathSampler {
294
+ /** The arc length of all the sub-paths together, in the path's own units. */
295
+ length: number;
296
+ /** The point a fraction `u` (0–1, clamped) of the length along, and the heading there in radians (`Math.atan2` of the direction, 0 = right, π/2 = down). */
297
+ at(u: number): {
298
+ x: number;
299
+ y: number;
300
+ angle: number;
301
+ };
302
+ /** The part between the fractions `start` and `end` (default the whole path) as flat `[x, y, x, y, …]` pieces, one per sub-path it touches: draw each with `moveTo` / `lineTo` (a line that draws on). */
303
+ trim(start?: number, end?: number): number[][];
304
+ }
305
+ /**
306
+ * Walks SVG path data by arc length, the way `followPath` does, for a `canvas` layer's `draw` (or anything that needs the points of a curve): text set along a curve, a leader
307
+ * line that draws on, a petal that falls along a route. Curves are flattened the way the shape layer draws them. Build it once (module scope or `setup`), ask it every frame.
308
+ *
309
+ * ```js
310
+ * const route = samplePath('M 40 300 C 200 20 400 20 560 300');
311
+ * // in draw: const { x, y, angle } = route.at(t / 4); for (const piece of route.trim(0, t / 4)) { ctx.moveTo(piece[0], piece[1]); … }
312
+ * ```
313
+ */
314
+ declare function samplePath(d: string): PathSampler;
315
+
280
316
  interface CameraPathOptions {
281
317
  /** The route: `[x, y, z]` points the camera passes, in order (at least two). */
282
318
  points: Array<[number, number, number]>;
@@ -403,7 +439,7 @@ type TextPreset = keyof typeof PRESETS;
403
439
  interface AnimateTextTween {
404
440
  /** Start from this preset and change what you give below. */
405
441
  preset?: TextPreset;
406
- /** The hidden state: `x` / `y` are offsets from the resting place, everything else (`alpha`, `scale`, `rotation`, …) is absolute. */
442
+ /** The hidden state: `x` / `y` are offsets from the resting place, everything else (`alpha`, `scale`, …) is absolute; `rotation` too, from the resting rotation (0, except the turned glyphs of vertical text, which rest at 90°). */
407
443
  from?: Record<string, number>;
408
444
  /** The resting state, for properties that have none of their own (`alpha` 1, `scale` 1, `rotation` 0 and the place are known). */
409
445
  to?: Record<string, number>;
@@ -422,6 +458,8 @@ interface AnimateTextOptions {
422
458
  /** Top of the first line. */
423
459
  y?: number;
424
460
  align?: 'left' | 'center' | 'right';
461
+ /** Vertical writing: characters go down a column, a new line is a new column to the left, and `x` is the RIGHT edge of the first column (see `splitText`). Punctuation and the long vowel mark are placed and turned the way tategaki wants. */
462
+ vertical?: boolean;
425
463
  /** Layers are named `<name>-0`, `<name>-1`, … (default `'text'`). */
426
464
  name?: string;
427
465
  /** When the first piece starts, in composition seconds. Default 0. */
@@ -652,6 +690,8 @@ declare function rand(seed: number): number;
652
690
  declare function random(seed: number): () => number;
653
691
  /** Smooth 1-D noise in [-1, 1]: continuous in `x`, a different curve for every `seed`. */
654
692
  declare function noise(x: number, seed?: number): number;
693
+ /** Smooth 2-D noise in [-1, 1]: continuous in `x` and in `y`, a different field for every `seed` (add octaves yourself for clouds: `noise2(x, y) + 0.5 * noise2(2 * x, 2 * y)`). */
694
+ declare function noise2(x: number, y: number, seed?: number): number;
655
695
 
656
696
  interface WithFadeOptions {
657
697
  /** Fade-in duration (seconds), at the start of the sequence. */
@@ -687,4 +727,4 @@ interface WithFadeOptions {
687
727
  */
688
728
  declare function withFade<T extends SequenceCommon>(spec: T, opts: WithFadeOptions): T;
689
729
 
690
- export { type AnimateTextOptions, type AnimateTextTween, type AudioEnvelope, type AudioEnvelopeSource, type CameraPathOptions, CameraSequenceSpec, CompositionShape, type EnvelopeOptions, type FollowPathOptions, ImageSequenceSpec, type KenBurnsOptions, Keyframe, type MeasureStyle, MusicEvents, MusicOptions, type OrbitOptions, type ParticlesOptions, type ReactOptions, type ReactProp, Sequence, SequenceCommon, type SequenceCtor, SequenceSpec, type SplitOptions, type StaggerOptions, type TextPiece, type TextPreset, TextSequenceSpec, type TextSize, type WiggleOptions, type WiggleProp, type WithFadeOptions, animateText, audioEnvelope, bpmEnvelope, cameraPath, computeEnvelope, parseEase as ease, followPath, kenBurns, measureText, musicBuffer, musicEnvelope, musicEvents, noise, orbit, particles, rand, random, react, registerSequenceType, splitText, stagger, warnUnknownOptions, wiggle, withFade };
730
+ export { type AnimateTextOptions, type AnimateTextTween, type AudioEnvelope, type AudioEnvelopeSource, type CameraPathOptions, CameraSequenceSpec, CompositionShape, type EnvelopeOptions, type FollowPathOptions, ImageSequenceSpec, type KenBurnsOptions, Keyframe, type MeasureStyle, MusicEvents, MusicOptions, type OrbitOptions, type ParticlesOptions, type PathSampler, type ReactOptions, type ReactProp, Sequence, SequenceCommon, type SequenceCtor, SequenceSpec, type SplitOptions, type StaggerOptions, type TextPiece, type TextPreset, TextSequenceSpec, type TextSize, type WiggleOptions, type WiggleProp, type WithFadeOptions, animateText, audioEnvelope, bpmEnvelope, cameraPath, computeEnvelope, parseEase as ease, followPath, kenBurns, measureText, musicBuffer, musicEnvelope, musicEvents, noise, noise2, orbit, particles, rand, random, react, registerSequenceType, samplePath, splitText, stagger, warnUnknownOptions, wiggle, withFade };
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
- export { Movie, animateText, audioEnvelope, bpmEnvelope, cameraPath, computeEnvelope, dismissLoader, parseEase as ease, failLoader, followPath, kenBurns, measureText, musicBuffer, musicEnvelope, musicEvents, orbit, particles, react, resolveLoader, splitText, stagger, wiggle, withFade } from './chunk-2GNK6DPV.js';
2
- import './chunk-XV4L72FW.js';
3
- export { Sequence, noise, rand, random, registerSequenceType } from './chunk-Y253JQOH.js';
4
- import './chunk-RTJD3ZSW.js';
5
- import './chunk-ITDYFBB6.js';
1
+ export { Movie, animateText, audioEnvelope, bpmEnvelope, cameraPath, computeEnvelope, dismissLoader, parseEase as ease, failLoader, followPath, kenBurns, measureText, musicBuffer, musicEnvelope, musicEvents, orbit, particles, react, resolveLoader, samplePath, splitText, stagger, wiggle, withFade } from './chunk-KNDEKWQO.js';
2
+ import './chunk-IPQNT65V.js';
3
+ export { Sequence, noise, noise2, rand, random, registerSequenceType } from './chunk-SBR75G73.js';
4
+ import './chunk-VNP7QCJE.js';
5
+ import './chunk-32MMNDDN.js';
6
6
  export { warnUnknownOptions } from './chunk-BXOCEZ4U.js';
7
7
  //# sourceMappingURL=index.js.map
8
8
  //# sourceMappingURL=index.js.map
package/dist/loader.css CHANGED
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * pixi-effects loader: one line of HTML on the page, a few lines of CSS, no JavaScript of your own.
3
3
  *
4
- * <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/pixi-effects@0.35.0/dist/loader.css">
4
+ * <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/pixi-effects@0.37.0/dist/loader.css">
5
5
  * <div class="stage" style="position: relative"> <!-- any box the canvas sits in, with position: relative -->
6
6
  * <canvas id="stage" width="1280" height="720"></canvas>
7
7
  * <div class="pe-loader" data-label="LOADING"></div> <!-- or class="pe-loader pe-loader--bar" -->
package/dist/present.cjs CHANGED
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
- require('./chunk-7TTCPHAV.cjs');
4
- require('./chunk-5IJENZOG.cjs');
5
- require('./chunk-LEECUCTG.cjs');
6
- require('./chunk-IMQJVRMT.cjs');
7
- require('./chunk-GL2AQFLQ.cjs');
3
+ require('./chunk-E26M4NTL.cjs');
4
+ require('./chunk-MJMOPWMK.cjs');
5
+ require('./chunk-QHIOOK5S.cjs');
6
+ require('./chunk-JN7JHNZR.cjs');
7
+ require('./chunk-3SAS3ZE5.cjs');
8
8
  var chunkTWZNOUM7_cjs = require('./chunk-TWZNOUM7.cjs');
9
9
 
10
10
  // src/present/stops.ts
@@ -1,5 +1,5 @@
1
- import { l as Movie, k as MotionBlurSpec } from './Movie-Db4QnMIH.cjs';
2
- import { S as SequenceSpec, J as Props, K as Keyframe, a1 as TransitionSpec, k as CompositionSpec, Z as Stop } from './types-CavnUvd5.cjs';
1
+ import { l as Movie, k as MotionBlurSpec } from './Movie-CJN_gvLB.cjs';
2
+ import { S as SequenceSpec, Q as Props, K as Keyframe, a3 as TransitionSpec, m as CompositionSpec, $ as Stop } from './types-DvnXXm33.cjs';
3
3
  import 'pixi.js';
4
4
 
5
5
  interface PresenterOptions {
package/dist/present.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { l as Movie, k as MotionBlurSpec } from './Movie-VYtUN4TS.js';
2
- import { S as SequenceSpec, J as Props, K as Keyframe, a1 as TransitionSpec, k as CompositionSpec, Z as Stop } from './types-CavnUvd5.js';
1
+ import { l as Movie, k as MotionBlurSpec } from './Movie-CfHaGmUP.js';
2
+ import { S as SequenceSpec, Q as Props, K as Keyframe, a3 as TransitionSpec, m as CompositionSpec, $ as Stop } from './types-DvnXXm33.js';
3
3
  import 'pixi.js';
4
4
 
5
5
  interface PresenterOptions {
package/dist/present.js CHANGED
@@ -1,8 +1,8 @@
1
- import './chunk-2GNK6DPV.js';
2
- import './chunk-XV4L72FW.js';
3
- import './chunk-Y253JQOH.js';
4
- import './chunk-RTJD3ZSW.js';
5
- import './chunk-ITDYFBB6.js';
1
+ import './chunk-KNDEKWQO.js';
2
+ import './chunk-IPQNT65V.js';
3
+ import './chunk-SBR75G73.js';
4
+ import './chunk-VNP7QCJE.js';
5
+ import './chunk-32MMNDDN.js';
6
6
  import { warnUnknownOptions } from './chunk-BXOCEZ4U.js';
7
7
 
8
8
  // src/present/stops.ts
package/dist/three.cjs CHANGED
@@ -1,12 +1,12 @@
1
1
  'use strict';
2
2
 
3
- var chunkLEECUCTG_cjs = require('./chunk-LEECUCTG.cjs');
4
- require('./chunk-GL2AQFLQ.cjs');
3
+ var chunkQHIOOK5S_cjs = require('./chunk-QHIOOK5S.cjs');
4
+ require('./chunk-3SAS3ZE5.cjs');
5
5
  require('./chunk-TWZNOUM7.cjs');
6
6
  var pixi_js = require('pixi.js');
7
7
  var three$1 = require('three');
8
8
 
9
- var ThreeSequence = class extends chunkLEECUCTG_cjs.Sequence {
9
+ var ThreeSequence = class extends chunkQHIOOK5S_cjs.Sequence {
10
10
  _renderer = null;
11
11
  _scene = null;
12
12
  _camera = null;
@@ -25,7 +25,7 @@ var ThreeSequence = class extends chunkLEECUCTG_cjs.Sequence {
25
25
  if (this.duration === void 0) {
26
26
  this.duration = this.parent?.duration ?? this.root.duration;
27
27
  }
28
- const scope = chunkLEECUCTG_cjs.buildScope(this, this.parent, this.root);
28
+ const scope = chunkQHIOOK5S_cjs.buildScope(this, this.parent, this.root);
29
29
  const width = resolveDim(spec.width, scope) ?? this.parent?.width ?? this.root.width;
30
30
  const height = resolveDim(spec.height, scope) ?? this.parent?.height ?? this.root.height;
31
31
  const resolution = spec.resolution ?? 1;
@@ -145,12 +145,12 @@ var ThreeSequence = class extends chunkLEECUCTG_cjs.Sequence {
145
145
  function resolveDim(v, scope) {
146
146
  if (v === void 0) return void 0;
147
147
  if (typeof v === "number") return v;
148
- return chunkLEECUCTG_cjs.evaluateExpr(v, scope);
148
+ return chunkQHIOOK5S_cjs.evaluateExpr(v, scope);
149
149
  }
150
150
 
151
151
  // src/three/index.ts
152
152
  function registerThree() {
153
- chunkLEECUCTG_cjs.registerSequenceType("three", ThreeSequence);
153
+ chunkQHIOOK5S_cjs.registerSequenceType("three", ThreeSequence);
154
154
  }
155
155
  function three(spec) {
156
156
  return spec;
package/dist/three.d.cts CHANGED
@@ -1,6 +1,6 @@
1
- import { b as SequenceCommon, H as PropValue, S as SequenceSpec } from './types-CavnUvd5.cjs';
1
+ import { b as SequenceCommon, O as PropValue, S as SequenceSpec } from './types-DvnXXm33.cjs';
2
2
  import { Scene, Camera, WebGLRenderer } from 'three';
3
- import { S as Sequence, P as PathRouters } from './Base-pNq6sVGl.cjs';
3
+ import { S as Sequence, P as PathRouters } from './Base-BlA6SeqJ.cjs';
4
4
  import 'pixi.js';
5
5
 
6
6
  /** Handed to setup / update / dispose. One per three sequence. */
package/dist/three.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { b as SequenceCommon, H as PropValue, S as SequenceSpec } from './types-CavnUvd5.js';
1
+ import { b as SequenceCommon, O as PropValue, S as SequenceSpec } from './types-DvnXXm33.js';
2
2
  import { Scene, Camera, WebGLRenderer } from 'three';
3
- import { S as Sequence, P as PathRouters } from './Base-CXsMdmJB.js';
3
+ import { S as Sequence, P as PathRouters } from './Base-YqM0Ljvp.js';
4
4
  import 'pixi.js';
5
5
 
6
6
  /** Handed to setup / update / dispose. One per three sequence. */