@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.
Files changed (84) hide show
  1. package/README.md +40 -1
  2. package/dist/core/pointer.d.ts +96 -0
  3. package/dist/core/pointer.d.ts.map +1 -0
  4. package/dist/core/pointer.js +71 -0
  5. package/dist/core/pointer.js.map +1 -0
  6. package/dist/motion-gpu.css +295 -0
  7. package/dist/react/advanced.js +2 -1
  8. package/dist/react/index.d.ts +2 -0
  9. package/dist/react/index.d.ts.map +1 -1
  10. package/dist/react/index.js +2 -1
  11. package/dist/react/use-pointer.d.ts +94 -0
  12. package/dist/react/use-pointer.d.ts.map +1 -0
  13. package/dist/react/use-pointer.js +285 -0
  14. package/dist/react/use-pointer.js.map +1 -0
  15. package/dist/svelte/advanced.js +2 -1
  16. package/dist/svelte/index.d.ts +2 -0
  17. package/dist/svelte/index.d.ts.map +1 -1
  18. package/dist/svelte/index.js +2 -1
  19. package/dist/svelte/use-pointer.d.ts +94 -0
  20. package/dist/svelte/use-pointer.d.ts.map +1 -0
  21. package/dist/svelte/use-pointer.js +292 -0
  22. package/dist/svelte/use-pointer.js.map +1 -0
  23. package/dist/vue/FragCanvas.js +8 -0
  24. package/dist/vue/FragCanvas.js.map +1 -0
  25. package/dist/vue/FragCanvas.vue.d.ts +49 -0
  26. package/dist/vue/FragCanvas.vue.d.ts.map +1 -0
  27. package/dist/vue/FragCanvas.vue_vue_type_script_setup_true_lang.js +228 -0
  28. package/dist/vue/FragCanvas.vue_vue_type_script_setup_true_lang.js.map +1 -0
  29. package/dist/vue/MotionGPUErrorOverlay.js +8 -0
  30. package/dist/vue/MotionGPUErrorOverlay.js.map +1 -0
  31. package/dist/vue/MotionGPUErrorOverlay.vue.d.ts +8 -0
  32. package/dist/vue/MotionGPUErrorOverlay.vue.d.ts.map +1 -0
  33. package/dist/vue/MotionGPUErrorOverlay.vue_vue_type_script_setup_true_lang.js +166 -0
  34. package/dist/vue/MotionGPUErrorOverlay.vue_vue_type_script_setup_true_lang.js.map +1 -0
  35. package/dist/vue/Portal.js +7 -0
  36. package/dist/vue/Portal.js.map +1 -0
  37. package/dist/vue/Portal.vue.d.ts +18 -0
  38. package/dist/vue/Portal.vue.d.ts.map +1 -0
  39. package/dist/vue/Portal.vue_vue_type_script_setup_true_lang.js +29 -0
  40. package/dist/vue/Portal.vue_vue_type_script_setup_true_lang.js.map +1 -0
  41. package/dist/vue/advanced.d.ts +12 -0
  42. package/dist/vue/advanced.d.ts.map +1 -0
  43. package/dist/vue/advanced.js +15 -0
  44. package/dist/vue/frame-context.d.ts +22 -0
  45. package/dist/vue/frame-context.d.ts.map +1 -0
  46. package/dist/vue/frame-context.js +38 -0
  47. package/dist/vue/frame-context.js.map +1 -0
  48. package/dist/vue/index.d.ts +21 -0
  49. package/dist/vue/index.d.ts.map +1 -0
  50. package/dist/vue/index.js +14 -0
  51. package/dist/vue/motiongpu-context.d.ts +81 -0
  52. package/dist/vue/motiongpu-context.d.ts.map +1 -0
  53. package/dist/vue/motiongpu-context.js +29 -0
  54. package/dist/vue/motiongpu-context.js.map +1 -0
  55. package/dist/vue/shims-vue.d.js +0 -0
  56. package/dist/vue/use-motiongpu-user-context.d.ts +44 -0
  57. package/dist/vue/use-motiongpu-user-context.d.ts.map +1 -0
  58. package/dist/vue/use-motiongpu-user-context.js +76 -0
  59. package/dist/vue/use-motiongpu-user-context.js.map +1 -0
  60. package/dist/vue/use-pointer.d.ts +94 -0
  61. package/dist/vue/use-pointer.d.ts.map +1 -0
  62. package/dist/vue/use-pointer.js +298 -0
  63. package/dist/vue/use-pointer.js.map +1 -0
  64. package/dist/vue/use-texture.d.ts +45 -0
  65. package/dist/vue/use-texture.d.ts.map +1 -0
  66. package/dist/vue/use-texture.js +135 -0
  67. package/dist/vue/use-texture.js.map +1 -0
  68. package/package.json +25 -7
  69. package/src/lib/core/pointer.ts +177 -0
  70. package/src/lib/react/index.ts +10 -0
  71. package/src/lib/react/use-pointer.ts +515 -0
  72. package/src/lib/svelte/index.ts +10 -0
  73. package/src/lib/svelte/use-pointer.ts +507 -0
  74. package/src/lib/vue/FragCanvas.vue +294 -0
  75. package/src/lib/vue/MotionGPUErrorOverlay.vue +518 -0
  76. package/src/lib/vue/Portal.vue +46 -0
  77. package/src/lib/vue/advanced.ts +32 -0
  78. package/src/lib/vue/frame-context.ts +96 -0
  79. package/src/lib/vue/index.ts +78 -0
  80. package/src/lib/vue/motiongpu-context.ts +97 -0
  81. package/src/lib/vue/shims-vue.d.ts +6 -0
  82. package/src/lib/vue/use-motiongpu-user-context.ts +145 -0
  83. package/src/lib/vue/use-pointer.ts +514 -0
  84. package/src/lib/vue/use-texture.ts +232 -0
@@ -0,0 +1,294 @@
1
+ <script lang="ts">
2
+ import type { MotionGPUErrorReport } from '../core/error-report.js';
3
+ import type { FragMaterial } from '../core/material.js';
4
+ import type {
5
+ AnyPass,
6
+ OutputColorSpace,
7
+ RenderMode,
8
+ RenderTargetDefinitionMap
9
+ } from '../core/types.js';
10
+
11
+ export interface FragCanvasProps {
12
+ material: FragMaterial;
13
+ renderTargets?: RenderTargetDefinitionMap;
14
+ passes?: AnyPass[];
15
+ clearColor?: [number, number, number, number];
16
+ outputColorSpace?: OutputColorSpace;
17
+ renderMode?: RenderMode;
18
+ autoRender?: boolean;
19
+ maxDelta?: number;
20
+ adapterOptions?: GPURequestAdapterOptions;
21
+ deviceDescriptor?: GPUDeviceDescriptor;
22
+ dpr?: number;
23
+ showErrorOverlay?: boolean;
24
+ onError?: (report: MotionGPUErrorReport) => void;
25
+ errorHistoryLimit?: number;
26
+ onErrorHistory?: (history: MotionGPUErrorReport[]) => void;
27
+ canvasClass?: string;
28
+ canvasStyle?: string | Record<string, string | number>;
29
+ }
30
+
31
+ const initialDpr = typeof window === 'undefined' ? 1 : (window.devicePixelRatio ?? 1);
32
+ </script>
33
+
34
+ <script setup lang="ts">
35
+ import { computed, onBeforeUnmount, onMounted, shallowRef, useTemplateRef, watch } from 'vue';
36
+ import { createCurrentWritable as currentWritable } from '../core/current-value.js';
37
+ import { toMotionGPUErrorReport } from '../core/error-report.js';
38
+ import { createFrameRegistry } from '../core/frame-registry.js';
39
+ import { createMotionGPURuntimeLoop } from '../core/runtime-loop.js';
40
+ import { provideFrameRegistry } from './frame-context.js';
41
+ import { provideMotionGPUContext } from './motiongpu-context.js';
42
+ import MotionGPUErrorOverlay from './MotionGPUErrorOverlay.vue';
43
+
44
+ const props = withDefaults(defineProps<FragCanvasProps>(), {
45
+ renderTargets: () => ({}),
46
+ passes: () => [],
47
+ clearColor: () => [0, 0, 0, 1] as [number, number, number, number],
48
+ outputColorSpace: 'srgb',
49
+ renderMode: 'always',
50
+ autoRender: true,
51
+ maxDelta: 0.1,
52
+ dpr: () => initialDpr,
53
+ showErrorOverlay: true,
54
+ errorHistoryLimit: 0,
55
+ canvasClass: ''
56
+ });
57
+
58
+ const wrapperStyle = Object.freeze({
59
+ position: 'relative',
60
+ width: '100%',
61
+ height: '100%',
62
+ minWidth: '0',
63
+ minHeight: '0',
64
+ overflow: 'hidden'
65
+ });
66
+
67
+ const baseCanvasStyle = Object.freeze({
68
+ position: 'absolute',
69
+ inset: '0',
70
+ display: 'block',
71
+ width: '100%',
72
+ height: '100%'
73
+ });
74
+
75
+ const resolvedCanvasStyle = computed(() => [baseCanvasStyle, props.canvasStyle]);
76
+
77
+ defineSlots<{
78
+ default(): unknown;
79
+ errorRenderer(props: { report: MotionGPUErrorReport }): unknown;
80
+ }>();
81
+
82
+ const canvasRef = useTemplateRef<HTMLCanvasElement>('canvasEl');
83
+ const errorReport = shallowRef<MotionGPUErrorReport | null>(null);
84
+ const errorHistory = shallowRef<MotionGPUErrorReport[]>([]);
85
+
86
+ const registry = createFrameRegistry({ maxDelta: 0.1 });
87
+ provideFrameRegistry(registry);
88
+
89
+ let requestFrameSignal: (() => void) | null = null;
90
+ let runtimeLoopHandle: ReturnType<typeof createMotionGPURuntimeLoop> | null = null;
91
+ const requestFrame = (): void => {
92
+ requestFrameSignal?.();
93
+ };
94
+ const invalidateFrame = (): void => {
95
+ registry.invalidate();
96
+ requestFrame();
97
+ };
98
+ const advanceFrame = (): void => {
99
+ registry.advance();
100
+ requestFrame();
101
+ };
102
+
103
+ const size = currentWritable({ width: 0, height: 0 });
104
+ const dprState = currentWritable<number>(initialDpr, requestFrame);
105
+ const maxDeltaState = currentWritable<number>(0.1, (value) => {
106
+ registry.setMaxDelta(value);
107
+ requestFrame();
108
+ });
109
+ const renderModeState = currentWritable<RenderMode>('always', (value) => {
110
+ registry.setRenderMode(value);
111
+ requestFrame();
112
+ });
113
+ const autoRenderState = currentWritable<boolean>(true, (value) => {
114
+ registry.setAutoRender(value);
115
+ requestFrame();
116
+ });
117
+ const userState = currentWritable<Record<string | symbol, unknown>>({});
118
+
119
+ provideMotionGPUContext({
120
+ get canvas() {
121
+ return canvasRef.value ?? undefined;
122
+ },
123
+ size,
124
+ dpr: dprState,
125
+ maxDelta: maxDeltaState,
126
+ renderMode: renderModeState,
127
+ autoRender: autoRenderState,
128
+ user: userState,
129
+ invalidate: invalidateFrame,
130
+ advance: advanceFrame,
131
+ scheduler: {
132
+ createStage: registry.createStage,
133
+ getStage: registry.getStage,
134
+ setDiagnosticsEnabled: registry.setDiagnosticsEnabled,
135
+ getDiagnosticsEnabled: registry.getDiagnosticsEnabled,
136
+ getLastRunTimings: registry.getLastRunTimings,
137
+ getSchedule: registry.getSchedule,
138
+ setProfilingEnabled: registry.setProfilingEnabled,
139
+ setProfilingWindow: registry.setProfilingWindow,
140
+ resetProfiling: registry.resetProfiling,
141
+ getProfilingEnabled: registry.getProfilingEnabled,
142
+ getProfilingWindow: registry.getProfilingWindow,
143
+ getProfilingSnapshot: registry.getProfilingSnapshot
144
+ }
145
+ });
146
+
147
+ /**
148
+ * Normalizes the user-supplied error history limit to a non-negative integer.
149
+ */
150
+ function getNormalizedErrorHistoryLimit(value: number): number {
151
+ if (!Number.isFinite(value) || value <= 0) {
152
+ return 0;
153
+ }
154
+
155
+ return Math.floor(value);
156
+ }
157
+
158
+ watch(
159
+ () => props.renderMode,
160
+ (value) => {
161
+ renderModeState.set(value);
162
+ }
163
+ );
164
+
165
+ watch(
166
+ () => props.autoRender,
167
+ (value) => {
168
+ autoRenderState.set(value);
169
+ }
170
+ );
171
+
172
+ watch(
173
+ () => props.maxDelta,
174
+ (value) => {
175
+ maxDeltaState.set(value);
176
+ }
177
+ );
178
+
179
+ watch(
180
+ () => props.dpr,
181
+ (value) => {
182
+ dprState.set(value);
183
+ }
184
+ );
185
+
186
+ watch([() => errorHistory.value, () => props.errorHistoryLimit], ([history, rawLimit]) => {
187
+ const limit = getNormalizedErrorHistoryLimit(rawLimit);
188
+ if (limit <= 0) {
189
+ if (history.length === 0) {
190
+ return;
191
+ }
192
+ errorHistory.value = [];
193
+ props.onErrorHistory?.([]);
194
+ return;
195
+ }
196
+
197
+ if (history.length <= limit) {
198
+ return;
199
+ }
200
+
201
+ const trimmed = history.slice(history.length - limit);
202
+ errorHistory.value = trimmed;
203
+ props.onErrorHistory?.(trimmed);
204
+ });
205
+
206
+ onMounted(() => {
207
+ renderModeState.set(props.renderMode);
208
+ autoRenderState.set(props.autoRender);
209
+ maxDeltaState.set(props.maxDelta);
210
+ dprState.set(props.dpr);
211
+ requestFrame();
212
+
213
+ const canvas = canvasRef.value;
214
+ if (!canvas) {
215
+ const report = toMotionGPUErrorReport(
216
+ new Error('Canvas element is not available'),
217
+ 'initialization'
218
+ );
219
+ errorReport.value = report;
220
+ const historyLimit = getNormalizedErrorHistoryLimit(props.errorHistoryLimit);
221
+ if (historyLimit > 0) {
222
+ const nextHistory = [report].slice(-historyLimit);
223
+ errorHistory.value = nextHistory;
224
+ props.onErrorHistory?.(nextHistory);
225
+ }
226
+ props.onError?.(report);
227
+ return;
228
+ }
229
+
230
+ const runtimeLoop = createMotionGPURuntimeLoop({
231
+ canvas,
232
+ registry,
233
+ size,
234
+ dpr: dprState,
235
+ maxDelta: maxDeltaState,
236
+ getMaterial: () => props.material,
237
+ getRenderTargets: () => props.renderTargets,
238
+ getPasses: () => props.passes,
239
+ getClearColor: () => props.clearColor,
240
+ getOutputColorSpace: () => props.outputColorSpace,
241
+ getAdapterOptions: () => props.adapterOptions,
242
+ getDeviceDescriptor: () => props.deviceDescriptor,
243
+ getOnError: () => props.onError,
244
+ getErrorHistoryLimit: () => props.errorHistoryLimit,
245
+ getOnErrorHistory: () => props.onErrorHistory,
246
+ reportErrorHistory: (history) => {
247
+ errorHistory.value = history;
248
+ },
249
+ reportError: (report) => {
250
+ errorReport.value = report;
251
+ }
252
+ });
253
+ runtimeLoopHandle = runtimeLoop;
254
+ requestFrameSignal = runtimeLoop.requestFrame;
255
+ });
256
+
257
+ onBeforeUnmount(() => {
258
+ requestFrameSignal = null;
259
+ runtimeLoopHandle?.destroy();
260
+ runtimeLoopHandle = null;
261
+ registry.clear();
262
+ });
263
+ </script>
264
+
265
+ <template>
266
+ <div class="motiongpu-canvas-wrap" :style="wrapperStyle">
267
+ <canvas ref="canvasEl" :class="canvasClass" :style="resolvedCanvasStyle"></canvas>
268
+ <template v-if="showErrorOverlay && errorReport">
269
+ <slot name="errorRenderer" :report="errorReport">
270
+ <MotionGPUErrorOverlay :report="errorReport" />
271
+ </slot>
272
+ </template>
273
+ <slot />
274
+ </div>
275
+ </template>
276
+
277
+ <style>
278
+ .motiongpu-canvas-wrap {
279
+ position: relative;
280
+ width: 100%;
281
+ height: 100%;
282
+ min-width: 0;
283
+ min-height: 0;
284
+ overflow: hidden;
285
+ }
286
+
287
+ .motiongpu-canvas-wrap > canvas {
288
+ position: absolute;
289
+ inset: 0;
290
+ display: block;
291
+ width: 100%;
292
+ height: 100%;
293
+ }
294
+ </style>