@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.
- package/README.md +55 -8
- package/dist/{components/consts.d.ts → consts.d.ts} +1 -1
- package/dist/{components/consts.js → consts.js} +1 -1
- package/dist/index.d.ts +12 -6
- package/dist/index.js +12 -6
- package/dist/{components/Project → project}/Project.svelte +8 -5
- package/dist/{components/Project → project}/Project.svelte.d.ts +4 -3
- package/dist/sequence/Sequence.svelte +92 -0
- package/dist/sequence/Sequence.svelte.d.ts +63 -0
- package/dist/sequence/SequenceController.d.ts +48 -0
- package/dist/sequence/SequenceController.js +159 -0
- package/dist/sequence/types.d.ts +16 -0
- package/dist/sequence/useSequence.d.ts +9 -0
- package/dist/sequence/useSequence.js +20 -0
- package/dist/sheet/Sheet.svelte +21 -0
- package/dist/sheet/Sheet.svelte.d.ts +29 -0
- package/dist/sheet/createSheetObjectAction.d.ts +13 -0
- package/dist/sheet/createSheetObjectAction.js +22 -0
- package/dist/sheet/types.d.ts +8 -0
- package/dist/sheet/types.js +1 -0
- package/dist/sheetObject/SheetObject.svelte +141 -0
- package/dist/sheetObject/SheetObject.svelte.d.ts +29 -0
- package/dist/sheetObject/declare/Declare.svelte +22 -0
- package/dist/sheetObject/declare/Declare.svelte.d.ts +14 -0
- package/dist/sheetObject/sync/Sync.svelte +82 -0
- package/dist/sheetObject/sync/Sync.svelte.d.ts +63 -0
- package/dist/sheetObject/sync/utils/getInitialValue.js +14 -0
- package/dist/sheetObject/sync/utils/isComplexProp.d.ts +2 -0
- package/dist/sheetObject/sync/utils/isComplexProp.js +3 -0
- package/dist/sheetObject/sync/utils/isPrimitive.d.ts +2 -0
- package/dist/sheetObject/sync/utils/isPrimitive.js +6 -0
- package/dist/sheetObject/sync/utils/isStringProp.d.ts +2 -0
- package/dist/sheetObject/sync/utils/isStringProp.js +3 -0
- package/dist/sheetObject/sync/utils/makeAlphanumeric.d.ts +1 -0
- package/dist/sheetObject/sync/utils/makeAlphanumeric.js +7 -0
- package/dist/sheetObject/sync/utils/parsePropLabel.d.ts +2 -0
- package/dist/sheetObject/sync/utils/parsePropLabel.js +10 -0
- package/dist/sheetObject/transfomers/createTransformer.d.ts +2 -0
- package/dist/sheetObject/transfomers/createTransformer.js +3 -0
- package/dist/sheetObject/transfomers/defaults/color.d.ts +1 -0
- package/dist/sheetObject/transfomers/defaults/color.js +12 -0
- package/dist/sheetObject/transfomers/defaults/degrees.d.ts +1 -0
- package/dist/sheetObject/transfomers/defaults/degrees.js +11 -0
- package/dist/sheetObject/transfomers/defaults/euler.d.ts +1 -0
- package/dist/sheetObject/transfomers/defaults/euler.js +17 -0
- package/dist/sheetObject/transfomers/defaults/generic.d.ts +1 -0
- package/dist/sheetObject/transfomers/defaults/generic.js +29 -0
- package/dist/sheetObject/transfomers/defaults/normalized.d.ts +1 -0
- package/dist/sheetObject/transfomers/defaults/normalized.js +12 -0
- package/dist/sheetObject/transfomers/defaults/side.d.ts +1 -0
- package/dist/sheetObject/transfomers/defaults/side.js +12 -0
- package/dist/sheetObject/transfomers/getDefaultTransformer.d.ts +1 -0
- package/dist/sheetObject/transfomers/getDefaultTransformer.js +41 -0
- package/dist/sheetObject/transfomers/types.d.ts +17 -0
- package/dist/sheetObject/transfomers/types.js +1 -0
- package/dist/sheetObject/transform/Transform.svelte +159 -0
- package/dist/sheetObject/transform/Transform.svelte.d.ts +20 -0
- package/dist/{components/Studio → studio}/InnerStudio.svelte +4 -10
- package/dist/{components/Studio → studio}/InnerStudio.svelte.d.ts +3 -5
- package/dist/studio/Studio.svelte +13 -0
- package/dist/{components/Studio → studio}/Studio.svelte.d.ts +3 -5
- package/dist/studio/useStudio.d.ts +21 -0
- package/dist/studio/useStudio.js +24 -0
- package/dist/theatre/Theatre.svelte +15 -0
- package/dist/{components/Theatre → theatre}/Theatre.svelte.d.ts +7 -4
- package/dist/types.d.ts +10 -0
- package/package.json +33 -28
- package/dist/CHANGELOG.md +0 -189
- package/dist/LICENSE.md +0 -21
- package/dist/README.md +0 -19
- package/dist/components/Editable/Editable.svelte +0 -318
- package/dist/components/Editable/Editable.svelte.d.ts +0 -7
- package/dist/components/Editable/typeGuards.d.ts +0 -5
- package/dist/components/Editable/typeGuards.js +0 -12
- package/dist/components/Editable/types.d.ts +0 -31
- package/dist/components/Editable/utils.d.ts +0 -25
- package/dist/components/Editable/utils.js +0 -86
- package/dist/components/Sheet/Sheet.svelte +0 -64
- package/dist/components/Sheet/Sheet.svelte.d.ts +0 -69
- package/dist/components/Studio/Studio.svelte +0 -18
- package/dist/components/Studio/useStudio.d.ts +0 -5
- package/dist/components/Studio/useStudio.js +0 -8
- package/dist/components/Theatre/Theatre.svelte +0 -16
- /package/dist/{components/Editable → sequence}/types.js +0 -0
- /package/dist/{components/theatre.d.ts → theatre.d.ts} +0 -0
- /package/dist/{components/theatre.js → theatre.js} +0 -0
package/README.md
CHANGED
|
@@ -1,19 +1,66 @@
|
|
|
1
|
-
|
|
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
|
-
<
|
|
16
|
+
<a href="https://next.threlte.xyz">
|
|
17
|
+
<img src="./threlte-banner.jpg"/>
|
|
18
|
+
</a>
|
|
4
19
|
|
|
5
|
-
|
|
20
|
+
## Rapidly Build Interactive 3D Apps for the Web
|
|
6
21
|
|
|
7
|
-
|
|
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
|
-
|
|
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
|
-
|
|
26
|
+
Check out our **[documentation](https://next.threlte.xyz)** and our **[Discord community](https://discord.gg/EqUBCfCaGm)**.
|
|
12
27
|
|
|
13
|
-
|
|
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
|
+
[](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
|
|
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
|
|
5
|
+
export const studio = currentWritable(undefined);
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
export { default as Studio } from './
|
|
2
|
-
export { default as Project } from './
|
|
3
|
-
export { default as
|
|
4
|
-
export { default as
|
|
5
|
-
export { default as Theatre } from './
|
|
6
|
-
export {
|
|
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 './
|
|
3
|
-
export { default as Project } from './
|
|
4
|
-
export { default as
|
|
5
|
-
export { default as
|
|
6
|
-
export { default as Theatre } from './
|
|
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 './
|
|
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
|
|
10
|
+
export let isReady = false;
|
|
11
|
+
const syncReady = async () => {
|
|
10
12
|
await project.ready;
|
|
11
13
|
isReady = true;
|
|
12
14
|
};
|
|
13
|
-
|
|
15
|
+
syncReady();
|
|
16
|
+
// CHILD CONTEXT
|
|
14
17
|
setContext(`theatre-project`, project);
|
|
15
18
|
</script>
|
|
16
19
|
|
|
17
|
-
{#
|
|
20
|
+
{#await project.ready then}
|
|
18
21
|
<slot {project} />
|
|
19
|
-
{/
|
|
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
|
|
19
|
-
export
|
|
20
|
-
export
|
|
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 {};
|