@motion-core/motion-gpu 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -1
- package/dist/core/pointer.d.ts +96 -0
- package/dist/core/pointer.d.ts.map +1 -0
- package/dist/core/pointer.js +71 -0
- package/dist/core/pointer.js.map +1 -0
- package/dist/motion-gpu.css +295 -0
- package/dist/react/advanced.js +2 -1
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +2 -1
- package/dist/react/use-pointer.d.ts +94 -0
- package/dist/react/use-pointer.d.ts.map +1 -0
- package/dist/react/use-pointer.js +285 -0
- package/dist/react/use-pointer.js.map +1 -0
- package/dist/svelte/advanced.js +2 -1
- package/dist/svelte/index.d.ts +2 -0
- package/dist/svelte/index.d.ts.map +1 -1
- package/dist/svelte/index.js +2 -1
- package/dist/svelte/use-pointer.d.ts +94 -0
- package/dist/svelte/use-pointer.d.ts.map +1 -0
- package/dist/svelte/use-pointer.js +292 -0
- package/dist/svelte/use-pointer.js.map +1 -0
- package/dist/vue/FragCanvas.js +8 -0
- package/dist/vue/FragCanvas.js.map +1 -0
- package/dist/vue/FragCanvas.vue.d.ts +49 -0
- package/dist/vue/FragCanvas.vue.d.ts.map +1 -0
- package/dist/vue/FragCanvas.vue_vue_type_script_setup_true_lang.js +228 -0
- package/dist/vue/FragCanvas.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/vue/MotionGPUErrorOverlay.js +8 -0
- package/dist/vue/MotionGPUErrorOverlay.js.map +1 -0
- package/dist/vue/MotionGPUErrorOverlay.vue.d.ts +8 -0
- package/dist/vue/MotionGPUErrorOverlay.vue.d.ts.map +1 -0
- package/dist/vue/MotionGPUErrorOverlay.vue_vue_type_script_setup_true_lang.js +166 -0
- package/dist/vue/MotionGPUErrorOverlay.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/vue/Portal.js +7 -0
- package/dist/vue/Portal.js.map +1 -0
- package/dist/vue/Portal.vue.d.ts +18 -0
- package/dist/vue/Portal.vue.d.ts.map +1 -0
- package/dist/vue/Portal.vue_vue_type_script_setup_true_lang.js +29 -0
- package/dist/vue/Portal.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/vue/advanced.d.ts +12 -0
- package/dist/vue/advanced.d.ts.map +1 -0
- package/dist/vue/advanced.js +15 -0
- package/dist/vue/frame-context.d.ts +22 -0
- package/dist/vue/frame-context.d.ts.map +1 -0
- package/dist/vue/frame-context.js +38 -0
- package/dist/vue/frame-context.js.map +1 -0
- package/dist/vue/index.d.ts +21 -0
- package/dist/vue/index.d.ts.map +1 -0
- package/dist/vue/index.js +14 -0
- package/dist/vue/motiongpu-context.d.ts +81 -0
- package/dist/vue/motiongpu-context.d.ts.map +1 -0
- package/dist/vue/motiongpu-context.js +29 -0
- package/dist/vue/motiongpu-context.js.map +1 -0
- package/dist/vue/shims-vue.d.js +0 -0
- package/dist/vue/use-motiongpu-user-context.d.ts +44 -0
- package/dist/vue/use-motiongpu-user-context.d.ts.map +1 -0
- package/dist/vue/use-motiongpu-user-context.js +76 -0
- package/dist/vue/use-motiongpu-user-context.js.map +1 -0
- package/dist/vue/use-pointer.d.ts +94 -0
- package/dist/vue/use-pointer.d.ts.map +1 -0
- package/dist/vue/use-pointer.js +298 -0
- package/dist/vue/use-pointer.js.map +1 -0
- package/dist/vue/use-texture.d.ts +45 -0
- package/dist/vue/use-texture.d.ts.map +1 -0
- package/dist/vue/use-texture.js +135 -0
- package/dist/vue/use-texture.js.map +1 -0
- package/package.json +25 -7
- package/src/lib/core/pointer.ts +177 -0
- package/src/lib/react/index.ts +10 -0
- package/src/lib/react/use-pointer.ts +515 -0
- package/src/lib/svelte/index.ts +10 -0
- package/src/lib/svelte/use-pointer.ts +507 -0
- package/src/lib/vue/FragCanvas.vue +294 -0
- package/src/lib/vue/MotionGPUErrorOverlay.vue +518 -0
- package/src/lib/vue/Portal.vue +46 -0
- package/src/lib/vue/advanced.ts +32 -0
- package/src/lib/vue/frame-context.ts +96 -0
- package/src/lib/vue/index.ts +78 -0
- package/src/lib/vue/motiongpu-context.ts +97 -0
- package/src/lib/vue/shims-vue.d.ts +6 -0
- package/src/lib/vue/use-motiongpu-user-context.ts +145 -0
- package/src/lib/vue/use-pointer.ts +514 -0
- package/src/lib/vue/use-texture.ts +232 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { onBeforeUnmount } from 'vue';
|
|
2
|
+
import {
|
|
3
|
+
createCurrentWritable as currentWritable,
|
|
4
|
+
type CurrentReadable
|
|
5
|
+
} from '../core/current-value.js';
|
|
6
|
+
import {
|
|
7
|
+
isAbortError,
|
|
8
|
+
loadTexturesFromUrls,
|
|
9
|
+
type LoadedTexture,
|
|
10
|
+
type TextureLoadOptions
|
|
11
|
+
} from '../core/texture-loader.js';
|
|
12
|
+
import { toMotionGPUErrorReport, type MotionGPUErrorReport } from '../core/error-report.js';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Reactive state returned by {@link useTexture}.
|
|
16
|
+
*/
|
|
17
|
+
export interface UseTextureResult {
|
|
18
|
+
/**
|
|
19
|
+
* Loaded textures or `null` when unavailable/failed.
|
|
20
|
+
*/
|
|
21
|
+
textures: CurrentReadable<LoadedTexture[] | null>;
|
|
22
|
+
/**
|
|
23
|
+
* `true` while an active load request is running.
|
|
24
|
+
*/
|
|
25
|
+
loading: CurrentReadable<boolean>;
|
|
26
|
+
/**
|
|
27
|
+
* Last loading error.
|
|
28
|
+
*/
|
|
29
|
+
error: CurrentReadable<Error | null>;
|
|
30
|
+
/**
|
|
31
|
+
* Last loading error normalized to MotionGPU diagnostics report shape.
|
|
32
|
+
*/
|
|
33
|
+
errorReport: CurrentReadable<MotionGPUErrorReport | null>;
|
|
34
|
+
/**
|
|
35
|
+
* Reloads all textures using current URL input.
|
|
36
|
+
*/
|
|
37
|
+
reload: () => Promise<void>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Supported URL input variants for `useTexture`.
|
|
42
|
+
*/
|
|
43
|
+
export type TextureUrlInput = string[] | (() => string[]);
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Supported options input variants for `useTexture`.
|
|
47
|
+
*/
|
|
48
|
+
export type TextureOptionsInput = TextureLoadOptions | (() => TextureLoadOptions);
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Normalizes unknown thrown values to an `Error` instance.
|
|
52
|
+
*/
|
|
53
|
+
function toError(error: unknown): Error {
|
|
54
|
+
if (error instanceof Error) {
|
|
55
|
+
return error;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return new Error('Unknown texture loading error');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Releases GPU-side resources for a list of loaded textures.
|
|
63
|
+
*/
|
|
64
|
+
function disposeTextures(list: LoadedTexture[] | null): void {
|
|
65
|
+
for (const texture of list ?? []) {
|
|
66
|
+
texture.dispose();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
interface MergedAbortSignal {
|
|
71
|
+
signal: AbortSignal;
|
|
72
|
+
dispose: () => void;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function mergeAbortSignals(
|
|
76
|
+
primary: AbortSignal,
|
|
77
|
+
secondary: AbortSignal | undefined
|
|
78
|
+
): MergedAbortSignal {
|
|
79
|
+
if (!secondary) {
|
|
80
|
+
return {
|
|
81
|
+
signal: primary,
|
|
82
|
+
dispose: () => {}
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (typeof AbortSignal.any === 'function') {
|
|
87
|
+
return {
|
|
88
|
+
signal: AbortSignal.any([primary, secondary]),
|
|
89
|
+
dispose: () => {}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const fallback = new AbortController();
|
|
94
|
+
let disposed = false;
|
|
95
|
+
const cleanup = (): void => {
|
|
96
|
+
if (disposed) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
disposed = true;
|
|
100
|
+
primary.removeEventListener('abort', abort);
|
|
101
|
+
secondary.removeEventListener('abort', abort);
|
|
102
|
+
};
|
|
103
|
+
const abort = (): void => fallback.abort();
|
|
104
|
+
|
|
105
|
+
primary.addEventListener('abort', abort, { once: true });
|
|
106
|
+
secondary.addEventListener('abort', abort, { once: true });
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
signal: fallback.signal,
|
|
110
|
+
dispose: cleanup
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Loads textures from URLs and exposes reactive loading/error state.
|
|
116
|
+
*
|
|
117
|
+
* @param urlInput - URLs array or lazy URL provider.
|
|
118
|
+
* @param optionsInput - Loader options object or lazy options provider.
|
|
119
|
+
* @returns Reactive texture loading state with reload support.
|
|
120
|
+
*/
|
|
121
|
+
export function useTexture(
|
|
122
|
+
urlInput: TextureUrlInput,
|
|
123
|
+
optionsInput: TextureOptionsInput = {}
|
|
124
|
+
): UseTextureResult {
|
|
125
|
+
const textures = currentWritable<LoadedTexture[] | null>(null);
|
|
126
|
+
const loading = currentWritable(true);
|
|
127
|
+
const error = currentWritable<Error | null>(null);
|
|
128
|
+
const errorReport = currentWritable<MotionGPUErrorReport | null>(null);
|
|
129
|
+
let disposed = false;
|
|
130
|
+
let requestVersion = 0;
|
|
131
|
+
let activeController: AbortController | null = null;
|
|
132
|
+
let runningLoad: Promise<void> | null = null;
|
|
133
|
+
let reloadQueued = false;
|
|
134
|
+
const getUrls = typeof urlInput === 'function' ? urlInput : () => urlInput;
|
|
135
|
+
const getOptions =
|
|
136
|
+
typeof optionsInput === 'function'
|
|
137
|
+
? (optionsInput as () => TextureLoadOptions)
|
|
138
|
+
: () => optionsInput;
|
|
139
|
+
|
|
140
|
+
const executeLoad = async (): Promise<void> => {
|
|
141
|
+
if (disposed) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const version = ++requestVersion;
|
|
146
|
+
const controller = new AbortController();
|
|
147
|
+
activeController = controller;
|
|
148
|
+
loading.set(true);
|
|
149
|
+
error.set(null);
|
|
150
|
+
errorReport.set(null);
|
|
151
|
+
|
|
152
|
+
const previous = textures.current;
|
|
153
|
+
const options = getOptions() ?? {};
|
|
154
|
+
const mergedSignal = mergeAbortSignals(controller.signal, options.signal);
|
|
155
|
+
try {
|
|
156
|
+
const loaded = await loadTexturesFromUrls(getUrls(), {
|
|
157
|
+
...options,
|
|
158
|
+
signal: mergedSignal.signal
|
|
159
|
+
});
|
|
160
|
+
if (disposed || version !== requestVersion) {
|
|
161
|
+
disposeTextures(loaded);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
textures.set(loaded);
|
|
166
|
+
disposeTextures(previous);
|
|
167
|
+
} catch (nextError) {
|
|
168
|
+
if (disposed || version !== requestVersion) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (isAbortError(nextError)) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
disposeTextures(previous);
|
|
177
|
+
textures.set(null);
|
|
178
|
+
const normalizedError = toError(nextError);
|
|
179
|
+
error.set(normalizedError);
|
|
180
|
+
errorReport.set(toMotionGPUErrorReport(normalizedError, 'initialization'));
|
|
181
|
+
} finally {
|
|
182
|
+
if (!disposed && version === requestVersion) {
|
|
183
|
+
loading.set(false);
|
|
184
|
+
}
|
|
185
|
+
if (activeController === controller) {
|
|
186
|
+
activeController = null;
|
|
187
|
+
}
|
|
188
|
+
mergedSignal.dispose();
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
const runLoadLoop = async (): Promise<void> => {
|
|
193
|
+
do {
|
|
194
|
+
reloadQueued = false;
|
|
195
|
+
await executeLoad();
|
|
196
|
+
} while (reloadQueued && !disposed);
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
const load = (): Promise<void> => {
|
|
200
|
+
activeController?.abort();
|
|
201
|
+
if (runningLoad) {
|
|
202
|
+
reloadQueued = true;
|
|
203
|
+
return runningLoad;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const pending = runLoadLoop();
|
|
207
|
+
const trackedPending = pending.finally(() => {
|
|
208
|
+
if (runningLoad === trackedPending) {
|
|
209
|
+
runningLoad = null;
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
runningLoad = trackedPending;
|
|
213
|
+
return trackedPending;
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
void load();
|
|
217
|
+
|
|
218
|
+
onBeforeUnmount(() => {
|
|
219
|
+
disposed = true;
|
|
220
|
+
requestVersion += 1;
|
|
221
|
+
activeController?.abort();
|
|
222
|
+
disposeTextures(textures.current);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
return {
|
|
226
|
+
textures,
|
|
227
|
+
loading,
|
|
228
|
+
error,
|
|
229
|
+
errorReport,
|
|
230
|
+
reload: load
|
|
231
|
+
};
|
|
232
|
+
}
|