@threlte/theatre 0.1.0-next.2 → 1.0.0-next.3

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 (86) hide show
  1. package/README.md +55 -8
  2. package/dist/{components/consts.d.ts → consts.d.ts} +1 -1
  3. package/dist/{components/consts.js → consts.js} +1 -1
  4. package/dist/index.d.ts +12 -6
  5. package/dist/index.js +12 -6
  6. package/dist/{components/Project → project}/Project.svelte +8 -5
  7. package/dist/{components/Project → project}/Project.svelte.d.ts +4 -3
  8. package/dist/sequence/Sequence.svelte +92 -0
  9. package/dist/sequence/Sequence.svelte.d.ts +63 -0
  10. package/dist/sequence/SequenceController.d.ts +48 -0
  11. package/dist/sequence/SequenceController.js +159 -0
  12. package/dist/sequence/types.d.ts +16 -0
  13. package/dist/sequence/useSequence.d.ts +9 -0
  14. package/dist/sequence/useSequence.js +20 -0
  15. package/dist/sheet/Sheet.svelte +21 -0
  16. package/dist/sheet/Sheet.svelte.d.ts +29 -0
  17. package/dist/sheet/createSheetObjectAction.d.ts +13 -0
  18. package/dist/sheet/createSheetObjectAction.js +22 -0
  19. package/dist/sheet/types.d.ts +8 -0
  20. package/dist/sheet/types.js +1 -0
  21. package/dist/sheetObject/SheetObject.svelte +141 -0
  22. package/dist/sheetObject/SheetObject.svelte.d.ts +29 -0
  23. package/dist/sheetObject/declare/Declare.svelte +22 -0
  24. package/dist/sheetObject/declare/Declare.svelte.d.ts +14 -0
  25. package/dist/sheetObject/sync/Sync.svelte +82 -0
  26. package/dist/sheetObject/sync/Sync.svelte.d.ts +63 -0
  27. package/dist/sheetObject/sync/utils/getInitialValue.js +14 -0
  28. package/dist/sheetObject/sync/utils/isComplexProp.d.ts +2 -0
  29. package/dist/sheetObject/sync/utils/isComplexProp.js +3 -0
  30. package/dist/sheetObject/sync/utils/isPrimitive.d.ts +2 -0
  31. package/dist/sheetObject/sync/utils/isPrimitive.js +6 -0
  32. package/dist/sheetObject/sync/utils/isStringProp.d.ts +2 -0
  33. package/dist/sheetObject/sync/utils/isStringProp.js +3 -0
  34. package/dist/sheetObject/sync/utils/makeAlphanumeric.d.ts +1 -0
  35. package/dist/sheetObject/sync/utils/makeAlphanumeric.js +7 -0
  36. package/dist/sheetObject/sync/utils/parsePropLabel.d.ts +2 -0
  37. package/dist/sheetObject/sync/utils/parsePropLabel.js +10 -0
  38. package/dist/sheetObject/transfomers/createTransformer.d.ts +2 -0
  39. package/dist/sheetObject/transfomers/createTransformer.js +3 -0
  40. package/dist/sheetObject/transfomers/defaults/color.d.ts +1 -0
  41. package/dist/sheetObject/transfomers/defaults/color.js +12 -0
  42. package/dist/sheetObject/transfomers/defaults/degrees.d.ts +1 -0
  43. package/dist/sheetObject/transfomers/defaults/degrees.js +11 -0
  44. package/dist/sheetObject/transfomers/defaults/euler.d.ts +1 -0
  45. package/dist/sheetObject/transfomers/defaults/euler.js +17 -0
  46. package/dist/sheetObject/transfomers/defaults/generic.d.ts +1 -0
  47. package/dist/sheetObject/transfomers/defaults/generic.js +29 -0
  48. package/dist/sheetObject/transfomers/defaults/normalized.d.ts +1 -0
  49. package/dist/sheetObject/transfomers/defaults/normalized.js +12 -0
  50. package/dist/sheetObject/transfomers/defaults/side.d.ts +1 -0
  51. package/dist/sheetObject/transfomers/defaults/side.js +12 -0
  52. package/dist/sheetObject/transfomers/getDefaultTransformer.d.ts +1 -0
  53. package/dist/sheetObject/transfomers/getDefaultTransformer.js +41 -0
  54. package/dist/sheetObject/transfomers/types.d.ts +17 -0
  55. package/dist/sheetObject/transfomers/types.js +1 -0
  56. package/dist/sheetObject/transform/Transform.svelte +159 -0
  57. package/dist/sheetObject/transform/Transform.svelte.d.ts +20 -0
  58. package/dist/{components/Studio → studio}/InnerStudio.svelte +4 -10
  59. package/dist/{components/Studio → studio}/InnerStudio.svelte.d.ts +3 -5
  60. package/dist/studio/Studio.svelte +13 -0
  61. package/dist/{components/Studio → studio}/Studio.svelte.d.ts +3 -5
  62. package/dist/studio/useStudio.d.ts +21 -0
  63. package/dist/studio/useStudio.js +24 -0
  64. package/dist/theatre/Theatre.svelte +15 -0
  65. package/dist/{components/Theatre → theatre}/Theatre.svelte.d.ts +7 -4
  66. package/dist/types.d.ts +10 -0
  67. package/package.json +33 -28
  68. package/dist/CHANGELOG.md +0 -189
  69. package/dist/LICENSE.md +0 -21
  70. package/dist/README.md +0 -19
  71. package/dist/components/Editable/Editable.svelte +0 -318
  72. package/dist/components/Editable/Editable.svelte.d.ts +0 -7
  73. package/dist/components/Editable/typeGuards.d.ts +0 -5
  74. package/dist/components/Editable/typeGuards.js +0 -12
  75. package/dist/components/Editable/types.d.ts +0 -31
  76. package/dist/components/Editable/utils.d.ts +0 -25
  77. package/dist/components/Editable/utils.js +0 -86
  78. package/dist/components/Sheet/Sheet.svelte +0 -64
  79. package/dist/components/Sheet/Sheet.svelte.d.ts +0 -69
  80. package/dist/components/Studio/Studio.svelte +0 -18
  81. package/dist/components/Studio/useStudio.d.ts +0 -5
  82. package/dist/components/Studio/useStudio.js +0 -8
  83. package/dist/components/Theatre/Theatre.svelte +0 -16
  84. /package/dist/{components/Editable → sequence}/types.js +0 -0
  85. /package/dist/{components/theatre.d.ts → theatre.d.ts} +0 -0
  86. /package/dist/{components/theatre.js → theatre.js} +0 -0
package/README.md CHANGED
@@ -1,19 +1,66 @@
1
- ![Threlte Logo](https://user-images.githubusercontent.com/46897060/178455971-434f4c5d-6c26-4d34-acdc-b4b50e2a8a2c.png)
1
+ <div align="right">
2
+ <a href="https://www.npmjs.com/package/@threlte/theatre">
3
+ <img alt="npm" src="https://img.shields.io/npm/v/@threlte/theatre?color=fe4100&labelColor=171d27&logo=npm&logoColor=white"/>
4
+ </a>
5
+ <a href="https://github.com/threlte/threlte/blob/main/LICENSE.md">
6
+ <img alt="license" src="https://img.shields.io/npm/l/@threlte/core?color=fe4100&labelColor=171d27&logo=git&logoColor=white"/>
7
+ </a>
8
+ <a href="https://discord.com/channels/985983540804091964">
9
+ <img alt="discord" src="https://img.shields.io/discord/985983540804091964?label=discord&color=fe4100&labelColor=171d27&logo=discord&logoColor=white"/>
10
+ </a>
11
+ <a href="https://next.threlte.xyz">
12
+ <img alt="docs" src="https://img.shields.io/website?down_color=red&down_message=offline&label=docs&color=fe4100&labelColor=171d27&up_message=online&url=https%3A%2F%2Fthrelte.xyz&logo=svelte&logoColor=white"/>
13
+ </a>
14
+ </div>
2
15
 
3
- <h1 align="center">@threlte/theatre</h1>
16
+ <a href="https://next.threlte.xyz">
17
+ <img src="./threlte-banner.jpg"/>
18
+ </a>
4
19
 
5
- Provides easy to use components and hooks to use [Theatre.js](https://www.theatrejs.com/) in threlte.
20
+ ## Rapidly Build Interactive 3D Apps for the Web
6
21
 
7
- ## Official Documentation
22
+ Threlte is a [Svelte](https://svelte.dev/) library that simplifies creating 3D apps for the web. It provides a **declarative**, **type-safe**, **reactive** and **interactive** API out-of-the-box.
8
23
 
9
- Visit [threlte.xyz](https://threlte.xyz)
24
+ Threlte's **3D rendering** is powered by [Three.js](https://threejs.org/), and it also provides a **physics engine** through [Rapier](https://rapier.rs/) and an **animation studio** via [Theatre.js](https://www.theatrejs.com/); see [packages](#packages) for details.
10
25
 
11
- ## Support
26
+ Check out our **[documentation](https://next.threlte.xyz)** and our **[Discord community](https://discord.gg/EqUBCfCaGm)**.
12
27
 
13
- Join the [Discord server](https://discord.gg/EqUBCfCaGm)
28
+ ## @threlte/theatre
29
+
30
+ [@threlte/theatre](https://next.threlte.xyz/docs/reference/theatre/getting-started) lets you animate in your Threlte app through the [Theatre.js studio](https://www.theatrejs.com/)
31
+
32
+ The package allows you to use an interactive GUI in the browser during development and visually configure your animations. It supports both Three.js and HTML DOM animations.
33
+
34
+ ## Quickstart
35
+
36
+ ### Installation
37
+
38
+ For a quick interactive setup of a fresh Threlte project, run:
39
+
40
+ ```sh
41
+ npm create threlte my-project
42
+ ```
43
+ and select the `@threlte/theatre` option.
44
+
45
+ Alternatively you can check out the full [installation instructions](https://next.threlte.xyz/docs/learn/getting-started/installation).
46
+
47
+ ### Support
48
+
49
+ Have questions? Feel free to ask in our [Discord support forum](https://discord.com/channels/985983540804091964/1031843197963477002).
50
+
51
+ ## Contributing
52
+
53
+ Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.
54
+
55
+ - **Filing Issues** - if you have feature requestions or you think you spotted a bug, [submit an issue](https://github.com/threlte/threlte/issues/new).
56
+ - **Contributing Code** - if you would like to drop us a PR, read the [contribution guide](https://github.com/threlte/threlte/blob/main/CONTRIBUTING.md) first.
57
+
58
+ ## Sponsors
59
+
60
+ [![Powered by Vercel](./assets/vercel/powered-by-vercel.svg)](https://vercel.com/?utm_source=threlte&utm_campaign=oss)
14
61
 
15
62
  ---
16
63
 
17
64
  ### License
18
65
 
19
- The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
66
+ The MIT License (MIT). Please see the [License File](LICENSE.md) for more information.
@@ -3,4 +3,4 @@ import type { IStudio } from '@theatre/studio';
3
3
  export declare const globalProjects: Map<string, IProject>;
4
4
  export declare const globalSheets: Map<string, ISheet>;
5
5
  export declare const globalObjects: Map<string, ISheetObject<import("@theatre/core").UnknownShorthandCompoundProps>>;
6
- export declare const globalStudio: import("@threlte/core").CurrentWritable<IStudio | undefined>;
6
+ export declare const studio: import("@threlte/core").CurrentWritable<IStudio | undefined>;
@@ -2,4 +2,4 @@ import { currentWritable } from '@threlte/core';
2
2
  export const globalProjects = new Map();
3
3
  export const globalSheets = new Map();
4
4
  export const globalObjects = new Map();
5
- export const globalStudio = currentWritable(undefined);
5
+ export const studio = currentWritable(undefined);
package/dist/index.d.ts CHANGED
@@ -1,6 +1,12 @@
1
- export { default as Studio } from './components/Studio/Studio.svelte';
2
- export { default as Project } from './components/Project/Project.svelte';
3
- export { default as Sheet } from './components/Sheet/Sheet.svelte';
4
- export { default as Editable } from './components/Editable/Editable.svelte';
5
- export { default as Theatre } from './components/Theatre/Theatre.svelte';
6
- export { useStudio } from './components/Studio/useStudio';
1
+ export { default as Studio } from './studio/Studio.svelte';
2
+ export { default as Project } from './project/Project.svelte';
3
+ export { default as Sequence } from './sequence/Sequence.svelte';
4
+ export { default as Sheet } from './sheet/Sheet.svelte';
5
+ export { default as Theatre } from './theatre/Theatre.svelte';
6
+ export { default as SheetObject } from './sheetObject/SheetObject.svelte';
7
+ export { createTransformer } from './sheetObject/transfomers/createTransformer';
8
+ export type { Transformer } from './sheetObject/transfomers/types';
9
+ export { useStudio } from './studio/useStudio';
10
+ export { useSequence } from './sequence/useSequence';
11
+ export { createSheetObjectAction } from './sheet/createSheetObjectAction';
12
+ export type { SequenceController } from './sequence/SequenceController';
package/dist/index.js CHANGED
@@ -1,8 +1,14 @@
1
1
  // components
2
- export { default as Studio } from './components/Studio/Studio.svelte';
3
- export { default as Project } from './components/Project/Project.svelte';
4
- export { default as Sheet } from './components/Sheet/Sheet.svelte';
5
- export { default as Editable } from './components/Editable/Editable.svelte';
6
- export { default as Theatre } from './components/Theatre/Theatre.svelte';
2
+ export { default as Studio } from './studio/Studio.svelte';
3
+ export { default as Project } from './project/Project.svelte';
4
+ export { default as Sequence } from './sequence/Sequence.svelte';
5
+ export { default as Sheet } from './sheet/Sheet.svelte';
6
+ export { default as Theatre } from './theatre/Theatre.svelte';
7
+ // SheetObject related things
8
+ export { default as SheetObject } from './sheetObject/SheetObject.svelte';
9
+ export { createTransformer } from './sheetObject/transfomers/createTransformer';
7
10
  // hooks
8
- export { useStudio } from './components/Studio/useStudio';
11
+ export { useStudio } from './studio/useStudio';
12
+ export { useSequence } from './sequence/useSequence';
13
+ // actions
14
+ export { createSheetObjectAction } from './sheet/createSheetObjectAction';
@@ -1,19 +1,22 @@
1
1
  <script>import { globalProjects } from '../consts';
2
2
  import { getProject } from '../theatre';
3
3
  import { setContext } from 'svelte';
4
+ // PROPS
4
5
  export let name = 'default';
5
6
  export let config = undefined;
7
+ // BINDINGS
6
8
  export const project = globalProjects.get(name) ?? getProject(name, config);
7
9
  globalProjects.set(name, project);
8
- let isReady = false;
9
- const init = async () => {
10
+ export let isReady = false;
11
+ const syncReady = async () => {
10
12
  await project.ready;
11
13
  isReady = true;
12
14
  };
13
- init();
15
+ syncReady();
16
+ // CHILD CONTEXT
14
17
  setContext(`theatre-project`, project);
15
18
  </script>
16
19
 
17
- {#if isReady}
20
+ {#await project.ready then}
18
21
  <slot {project} />
19
- {/if}
22
+ {/await}
@@ -5,6 +5,7 @@ declare const __propDef: {
5
5
  name?: string | undefined;
6
6
  config?: IProjectConfig | undefined;
7
7
  project?: import("@theatre/core").IProject | undefined;
8
+ isReady?: boolean | undefined;
8
9
  };
9
10
  events: {
10
11
  [evt: string]: CustomEvent<any>;
@@ -15,9 +16,9 @@ declare const __propDef: {
15
16
  };
16
17
  };
17
18
  };
18
- export declare type ProjectProps = typeof __propDef.props;
19
- export declare type ProjectEvents = typeof __propDef.events;
20
- export declare type ProjectSlots = typeof __propDef.slots;
19
+ export type ProjectProps = typeof __propDef.props;
20
+ export type ProjectEvents = typeof __propDef.events;
21
+ export type ProjectSlots = typeof __propDef.slots;
21
22
  export default class Project extends SvelteComponentTyped<ProjectProps, ProjectEvents, ProjectSlots> {
22
23
  get project(): import("@theatre/core").IProject;
23
24
  }
@@ -0,0 +1,92 @@
1
+ <script>import { getContext, onDestroy, onMount, setContext } from 'svelte';
2
+ // Parent context
3
+ const { sequences } = getContext('theatre-sheet');
4
+ // Props
5
+ let key = 'default'; // not exposed yet, will be a prop in the future
6
+ // Theatre's native playback options
7
+ export let rate = 1;
8
+ export let range = undefined;
9
+ export let iterationCount = undefined;
10
+ export let direction = undefined;
11
+ export let rafDriver = undefined;
12
+ export let audio = undefined;
13
+ // Threlte's custom playback options
14
+ export let autoplay = false;
15
+ export let autoreset = undefined;
16
+ export let autopause = false;
17
+ export let delay = 0;
18
+ // Get the Sequence instance
19
+ export const sequence = sequences[key];
20
+ // autoplay logic
21
+ if (!autoplay && delay > 0) {
22
+ console.warn('Sequence: delay has no effect unless the option autoplay is enabled.', {
23
+ sequence
24
+ });
25
+ }
26
+ let delayTimer;
27
+ if (autoplay) {
28
+ delayTimer = setTimeout(() => sequence.play(), delay);
29
+ }
30
+ onDestroy(() => {
31
+ clearTimeout(delayTimer);
32
+ });
33
+ // autopause logic
34
+ onDestroy(() => {
35
+ if (autopause) {
36
+ sequence.pause();
37
+ }
38
+ });
39
+ // autoreset logic
40
+ if (autoreset === 'onMount' || autoreset === 'always') {
41
+ sequence.reset();
42
+ }
43
+ onDestroy(() => {
44
+ if (autoreset === 'onDestroy' || autoreset === 'always') {
45
+ sequence.reset();
46
+ }
47
+ });
48
+ // config reactivity
49
+ $: sequence.config({
50
+ audio,
51
+ rate,
52
+ range,
53
+ iterationCount,
54
+ direction,
55
+ rafDriver
56
+ });
57
+ // Bindings
58
+ const { position: positionStore, playing: playingStore, length: lengthStore } = sequence;
59
+ export let position = $positionStore;
60
+ export let playing = $playingStore;
61
+ export const length = $lengthStore;
62
+ export const play = (opts) => sequence.play(opts);
63
+ export const pause = () => sequence.pause();
64
+ // position
65
+ let positionChangedBy = 'user';
66
+ positionStore.subscribe((value) => {
67
+ positionChangedBy = 'code';
68
+ position = value;
69
+ });
70
+ $: position,
71
+ positionChangedBy === 'user' && ($positionStore = position),
72
+ (positionChangedBy = 'user');
73
+ // playing
74
+ let playingChangedBy = 'user';
75
+ playingStore.subscribe((value) => {
76
+ playingChangedBy = 'code';
77
+ playing = value;
78
+ });
79
+ $: playing, playingChangedBy === 'user' && ($playingStore = playing), (playingChangedBy = 'user');
80
+ // pass sequence to children via context
81
+ setContext('theatre-sequence', sequence);
82
+ // pass to parent
83
+ sequences[key] = sequence;
84
+ </script>
85
+
86
+ <slot
87
+ {sequence}
88
+ {position}
89
+ {playing}
90
+ {play}
91
+ {pause}
92
+ />
@@ -0,0 +1,63 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ import type { IRafDriver } from '@theatre/core';
3
+ import type { Autoreset, IterationCount, PlaybackDirection, PlaybackRange, SequenceAudioOptions } from './types';
4
+ declare const __propDef: {
5
+ props: {
6
+ rate?: number | undefined;
7
+ range?: PlaybackRange;
8
+ iterationCount?: IterationCount;
9
+ direction?: PlaybackDirection;
10
+ rafDriver?: IRafDriver | undefined;
11
+ audio?: SequenceAudioOptions | undefined;
12
+ autoplay?: boolean | undefined;
13
+ autoreset?: Autoreset;
14
+ autopause?: boolean | undefined;
15
+ delay?: number | undefined;
16
+ sequence?: import("./SequenceController").SequenceController | undefined;
17
+ position?: number | undefined;
18
+ playing?: boolean | undefined;
19
+ length?: number | undefined;
20
+ play?: ((conf?: {
21
+ iterationCount?: number | undefined;
22
+ range?: [from: number, to: number] | undefined;
23
+ rate?: number | undefined;
24
+ direction?: ("reverse" | "alternate" | "normal" | "alternateReverse") | undefined;
25
+ rafDriver?: IRafDriver | undefined;
26
+ } | undefined) => Promise<boolean>) | undefined;
27
+ pause?: (() => void) | undefined;
28
+ };
29
+ events: {
30
+ [evt: string]: CustomEvent<any>;
31
+ };
32
+ slots: {
33
+ default: {
34
+ sequence: import("./SequenceController").SequenceController;
35
+ position: number;
36
+ playing: boolean;
37
+ play: (conf?: {
38
+ iterationCount?: number | undefined;
39
+ range?: [from: number, to: number] | undefined;
40
+ rate?: number | undefined;
41
+ direction?: ("reverse" | "alternate" | "normal" | "alternateReverse") | undefined;
42
+ rafDriver?: IRafDriver | undefined;
43
+ } | undefined) => Promise<boolean>;
44
+ pause: () => void;
45
+ };
46
+ };
47
+ };
48
+ export type SequenceProps = typeof __propDef.props;
49
+ export type SequenceEvents = typeof __propDef.events;
50
+ export type SequenceSlots = typeof __propDef.slots;
51
+ export default class Sequence extends SvelteComponentTyped<SequenceProps, SequenceEvents, SequenceSlots> {
52
+ get sequence(): import("./SequenceController").SequenceController;
53
+ get length(): number;
54
+ get play(): (conf?: {
55
+ iterationCount?: number | undefined;
56
+ range?: [from: number, to: number] | undefined;
57
+ rate?: number | undefined;
58
+ direction?: ("reverse" | "alternate" | "normal" | "alternateReverse") | undefined;
59
+ rafDriver?: IRafDriver | undefined;
60
+ } | undefined) => Promise<boolean>;
61
+ get pause(): () => void;
62
+ }
63
+ export {};
@@ -0,0 +1,48 @@
1
+ import { onChange, type ISequence } from '@theatre/core';
2
+ import type { Readable, Subscriber, Writable } from 'svelte/store';
3
+ import type { SequenceOptions } from './types';
4
+ /**
5
+ * ### `SequenceController`
6
+ *
7
+ * This class is a wrapper around the native `ISequence` object. It provides
8
+ * reactive stores for the sequence's position, playing state, and length.
9
+ */
10
+ export declare class SequenceController {
11
+ key: string;
12
+ position: SequencePosition;
13
+ playing: SequencePlaying;
14
+ length: SequenceLength;
15
+ private options;
16
+ private sequence;
17
+ constructor(sequence: ISequence, options?: SequenceOptions);
18
+ config(options: SequenceOptions): void;
19
+ play(opts?: Parameters<ISequence['play']>[0]): ReturnType<ISequence['play']>;
20
+ pause(): ReturnType<ISequence['pause']>;
21
+ reset(): void;
22
+ }
23
+ export declare class SequencePosition implements Writable<number> {
24
+ sequence: ISequence;
25
+ play: () => void;
26
+ subscribers: Set<Subscriber<number>>;
27
+ unsubscribe: ReturnType<typeof onChange>;
28
+ constructor(sequence: ISequence, play: () => void);
29
+ subscribe(subscription: Subscriber<number>): () => void;
30
+ update(callback: (prev: number) => number): void;
31
+ set(value: number): void;
32
+ }
33
+ export declare class SequencePlaying implements Writable<boolean> {
34
+ sequence: ISequence;
35
+ play: () => void;
36
+ subscribers: Set<Subscriber<boolean>>;
37
+ constructor(sequence: ISequence, play: () => void);
38
+ subscribe(subscription: Subscriber<boolean>): () => void;
39
+ update(callback: (prev: boolean) => boolean): void;
40
+ set(value: boolean): void;
41
+ }
42
+ export declare class SequenceLength implements Readable<number> {
43
+ sequence: ISequence;
44
+ subscribers: Set<Subscriber<number>>;
45
+ unsubscribe: ReturnType<typeof onChange>;
46
+ constructor(sequence: ISequence);
47
+ subscribe(subscription: Subscriber<number>): () => void;
48
+ }
@@ -0,0 +1,159 @@
1
+ import { onChange, val } from '@theatre/core';
2
+ import { get } from 'svelte/store';
3
+ /**
4
+ * ### `SequenceController`
5
+ *
6
+ * This class is a wrapper around the native `ISequence` object. It provides
7
+ * reactive stores for the sequence's position, playing state, and length.
8
+ */
9
+ export class SequenceController {
10
+ key;
11
+ position;
12
+ playing;
13
+ length;
14
+ options;
15
+ sequence;
16
+ constructor(sequence, options = {}) {
17
+ // api
18
+ this.key = options?.key ?? 'default'; // not in use - for future proofing
19
+ this.sequence = sequence; // theatre native object
20
+ this.options = options; // to be set via config method
21
+ // stores
22
+ this.position = new SequencePosition(sequence, () => this.play());
23
+ this.playing = new SequencePlaying(sequence, () => this.play());
24
+ this.length = new SequenceLength(sequence);
25
+ // methods
26
+ this.config = this.config.bind(this);
27
+ this.play = this.play.bind(this);
28
+ this.pause = this.pause.bind(this);
29
+ this.reset = this.reset.bind(this);
30
+ }
31
+ config(options) {
32
+ // update options
33
+ const updatedOptions = { ...this.options, ...options };
34
+ // ensure no unnecessary updates happen
35
+ const noChange = Object.keys(updatedOptions).every((key) => this.options[key] == updatedOptions[key]);
36
+ if (noChange) {
37
+ return;
38
+ }
39
+ else {
40
+ this.options = updatedOptions;
41
+ }
42
+ // update audio options
43
+ if (options.audio)
44
+ this.sequence.attachAudio(options.audio);
45
+ // get replay conditions
46
+ const replay = options.rate ||
47
+ options.range ||
48
+ options.iterationCount ||
49
+ options.direction ||
50
+ options.rafDriver;
51
+ // and also check if playing
52
+ const playing = get(this.playing);
53
+ // trigger replay if needed
54
+ if (playing && replay) {
55
+ this.pause();
56
+ this.play();
57
+ }
58
+ }
59
+ play(opts = {}) {
60
+ return this.sequence.play({ ...this.options, ...opts });
61
+ }
62
+ pause() {
63
+ return this.sequence.pause();
64
+ }
65
+ reset() {
66
+ this.position.set(0);
67
+ }
68
+ }
69
+ // stores
70
+ export class SequencePosition {
71
+ sequence;
72
+ play;
73
+ subscribers;
74
+ unsubscribe;
75
+ constructor(sequence, play) {
76
+ this.sequence = sequence;
77
+ this.play = play;
78
+ this.subscribers = new Set();
79
+ // TODO: this is a potential memory leak, when is unsubscribe called?
80
+ this.unsubscribe = onChange(this.sequence.pointer.position, (position) => {
81
+ this.subscribers.forEach((subscription) => subscription(position));
82
+ });
83
+ }
84
+ subscribe(subscription) {
85
+ this.subscribers.add(subscription);
86
+ subscription(this.sequence.position);
87
+ return () => {
88
+ this.subscribers.delete(subscription);
89
+ // TODO: run this.unsubscribe after the last delete?
90
+ };
91
+ }
92
+ update(callback) {
93
+ this.set(callback(this.sequence.position));
94
+ }
95
+ set(value) {
96
+ const isPlaying = val(this.sequence.pointer.playing);
97
+ this.sequence.position = value;
98
+ if (isPlaying)
99
+ this.play();
100
+ }
101
+ }
102
+ export class SequencePlaying {
103
+ sequence;
104
+ play;
105
+ subscribers;
106
+ constructor(sequence, play) {
107
+ this.sequence = sequence;
108
+ this.play = play;
109
+ // subs
110
+ this.subscribers = new Set();
111
+ // TODO: this is missing an unsubscribe!!
112
+ onChange(this.sequence.pointer.playing, (playing) => {
113
+ this.subscribers.forEach((subscription) => subscription(playing));
114
+ });
115
+ }
116
+ subscribe(subscription) {
117
+ this.subscribers.add(subscription);
118
+ subscription(val(this.sequence.pointer.playing));
119
+ return () => {
120
+ this.subscribers.delete(subscription);
121
+ };
122
+ }
123
+ update(callback) {
124
+ const isPlaying = val(this.sequence.pointer.playing);
125
+ const shouldBePlaying = callback(isPlaying);
126
+ if (isPlaying && !shouldBePlaying)
127
+ this.sequence.pause();
128
+ if (!isPlaying && shouldBePlaying)
129
+ this.play();
130
+ }
131
+ set(value) {
132
+ const isPlaying = val(this.sequence.pointer.playing);
133
+ const shouldBePlaying = value;
134
+ if (isPlaying && !shouldBePlaying)
135
+ this.sequence.pause();
136
+ if (!isPlaying && shouldBePlaying)
137
+ this.play();
138
+ }
139
+ }
140
+ export class SequenceLength {
141
+ sequence;
142
+ subscribers;
143
+ unsubscribe;
144
+ constructor(sequence) {
145
+ this.sequence = sequence;
146
+ this.subscribers = new Set();
147
+ // TODO: this is a potential memory leak, when is unsubscribe called?
148
+ this.unsubscribe = onChange(this.sequence.pointer.length, (length) => {
149
+ this.subscribers.forEach((run) => run(length));
150
+ });
151
+ }
152
+ subscribe(subscription) {
153
+ this.subscribers.add(subscription);
154
+ subscription(val(this.sequence.pointer.length));
155
+ return () => {
156
+ this.subscribers.delete(subscription);
157
+ };
158
+ }
159
+ }
@@ -0,0 +1,16 @@
1
+ import type { ISequence, IRafDriver } from '@theatre/core';
2
+ export type TheatreSequenceOptions = Required<NonNullable<Parameters<ISequence['play']>[0]>>;
3
+ export type PlaybackRange = TheatreSequenceOptions['range'] | undefined;
4
+ export type IterationCount = TheatreSequenceOptions['iterationCount'] | undefined;
5
+ export type PlaybackDirection = TheatreSequenceOptions['direction'] | undefined;
6
+ export type SequenceAudioOptions = Parameters<ISequence['attachAudio']>[0];
7
+ export type Autoreset = undefined | 'always' | 'onMount' | 'onDestroy';
8
+ export interface SequenceOptions {
9
+ key?: string;
10
+ rate?: number;
11
+ range?: PlaybackRange;
12
+ iterationCount?: IterationCount;
13
+ direction?: PlaybackDirection;
14
+ rafDriver?: IRafDriver;
15
+ audio?: SequenceAudioOptions;
16
+ }
@@ -0,0 +1,9 @@
1
+ import type { SequenceController } from './SequenceController';
2
+ /**
3
+ * ### `useSequence`
4
+ *
5
+ * A hook to get the current sequence controller. If a key is provided, it will
6
+ * get the sequence controller with that key. Otherwise, it will get the
7
+ * "nearest" default sequence controller.
8
+ */
9
+ export declare const useSequence: (key?: undefined) => SequenceController;
@@ -0,0 +1,20 @@
1
+ import { getContext } from 'svelte';
2
+ /**
3
+ * ### `useSequence`
4
+ *
5
+ * A hook to get the current sequence controller. If a key is provided, it will
6
+ * get the sequence controller with that key. Otherwise, it will get the
7
+ * "nearest" default sequence controller.
8
+ */
9
+ export const useSequence = (key = undefined) => {
10
+ let sequence;
11
+ if (key) {
12
+ sequence = getContext('theatre-sheet').sequences[key];
13
+ }
14
+ else {
15
+ sequence =
16
+ getContext('theatre-sequence') ??
17
+ getContext('theatre-sheet').sequences['default'];
18
+ }
19
+ return sequence;
20
+ };
@@ -0,0 +1,21 @@
1
+ <script>import { getContext, setContext } from 'svelte';
2
+ import { SequenceController } from '../sequence/SequenceController';
3
+ import { globalSheets } from '../consts';
4
+ // parent context
5
+ export const project = getContext('theatre-project');
6
+ const projectName = project.address.projectId;
7
+ // props
8
+ export let name = 'default';
9
+ export let instance = undefined;
10
+ // bindings
11
+ export const sheet = globalSheets.get(`${projectName}-${name}-${instance}`) ?? project.sheet(name, instance);
12
+ // register instance logic
13
+ globalSheets.set(`${projectName}-${name}-${instance}`, sheet);
14
+ // init sequence store
15
+ export const sequence = new SequenceController(sheet.sequence);
16
+ // child context
17
+ const sequences = { default: sequence };
18
+ setContext('theatre-sheet', { sheet, sequences });
19
+ </script>
20
+
21
+ <slot {sheet} />
@@ -0,0 +1,29 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ import type { IProject } from '@theatre/core';
3
+ import { SequenceController } from '../sequence/SequenceController';
4
+ declare const __propDef: {
5
+ props: {
6
+ project?: IProject | undefined;
7
+ name?: string | undefined;
8
+ instance?: string | undefined;
9
+ sheet?: import("@theatre/core").ISheet | undefined;
10
+ sequence?: SequenceController | undefined;
11
+ };
12
+ events: {
13
+ [evt: string]: CustomEvent<any>;
14
+ };
15
+ slots: {
16
+ default: {
17
+ sheet: import("@theatre/core").ISheet;
18
+ };
19
+ };
20
+ };
21
+ export type SheetProps = typeof __propDef.props;
22
+ export type SheetEvents = typeof __propDef.events;
23
+ export type SheetSlots = typeof __propDef.slots;
24
+ export default class Sheet extends SvelteComponentTyped<SheetProps, SheetEvents, SheetSlots> {
25
+ get project(): IProject;
26
+ get sheet(): import("@theatre/core").ISheet;
27
+ get sequence(): SequenceController;
28
+ }
29
+ export {};
@@ -0,0 +1,13 @@
1
+ import type { ISheetObject, UnknownShorthandCompoundProps } from '@theatre/core';
2
+ type PropsValue<Props extends UnknownShorthandCompoundProps> = Parameters<Parameters<ISheetObject<Props>['onValuesChange']>[0]>[0];
3
+ export declare function createSheetObjectAction<Props extends UnknownShorthandCompoundProps>(): <T extends HTMLElement>(node: T, { key, props, callback, options }: {
4
+ key: string;
5
+ props: Props;
6
+ callback: (node: T, props: PropsValue<Props>) => void;
7
+ options?: {
8
+ reconfigure?: boolean | undefined;
9
+ } | undefined;
10
+ }) => {
11
+ destroy(): void;
12
+ };
13
+ export {};