@open-motion/core 0.0.1-alpha.0 → 0.0.2
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 +38 -0
- package/dist/Player.js +27 -5
- package/dist/index.d.ts +28 -1
- package/dist/index.js +165 -19
- package/package.json +4 -3
package/README.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# @open-motion/core
|
|
2
|
+
|
|
3
|
+
Core React primitives, hooks, and player for **OpenMotion** — the open-source programmatic video engine.
|
|
4
|
+
|
|
5
|
+
## ✨ Features
|
|
6
|
+
|
|
7
|
+
- ⚛️ **React Components**: Use `Composition`, `Sequence`, `Video`, and more to build your video.
|
|
8
|
+
- 🎣 **Powerful Hooks**: Access `useCurrentFrame`, `useVideoConfig`, and `getInputProps` anywhere.
|
|
9
|
+
- ⏱️ **Animation Utilities**: High-performance `spring` animations and multi-segment `interpolate` functions.
|
|
10
|
+
- 🎞️ **Interactive Player**: Real-time preview and scrubbing during development.
|
|
11
|
+
|
|
12
|
+
## 🚀 Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pnpm add @open-motion/core
|
|
16
|
+
# or
|
|
17
|
+
npm install @open-motion/core
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## 📖 Usage
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
import { Composition, Sequence, spring, useCurrentFrame, useVideoConfig } from "@open-motion/core";
|
|
24
|
+
|
|
25
|
+
const MyVideo = () => {
|
|
26
|
+
const frame = useCurrentFrame();
|
|
27
|
+
const { fps } = useVideoConfig();
|
|
28
|
+
const scale = spring({ frame, fps });
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<div style={{ flex: 1, backgroundColor: "white", display: "flex", justifyContent: "center", alignItems: "center" }}>
|
|
32
|
+
<h1 style={{ transform: `scale(${scale})` }}>Hello OpenMotion</h1>
|
|
33
|
+
</div>
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Learn more at the [main OpenMotion repository](https://github.com/jsongo/open-motion).
|
package/dist/Player.js
CHANGED
|
@@ -7,8 +7,23 @@ const index_1 = require("./index");
|
|
|
7
7
|
const Player = ({ component: Component, config, inputProps = {}, controls = true, autoPlay = false, loop = false, }) => {
|
|
8
8
|
const [frame, setFrame] = (0, react_1.useState)(0);
|
|
9
9
|
const [isPlaying, setIsPlaying] = (0, react_1.useState)(autoPlay);
|
|
10
|
+
const [scale, setScale] = (0, react_1.useState)(1);
|
|
11
|
+
const containerRef = (0, react_1.useRef)(null);
|
|
10
12
|
const requestRef = (0, react_1.useRef)();
|
|
11
13
|
const lastTimeRef = (0, react_1.useRef)();
|
|
14
|
+
(0, react_1.useEffect)(() => {
|
|
15
|
+
const handleResize = () => {
|
|
16
|
+
if (containerRef.current) {
|
|
17
|
+
const parentWidth = containerRef.current.parentElement?.clientWidth || window.innerWidth;
|
|
18
|
+
const s = Math.min(1, (parentWidth - 40) / config.width);
|
|
19
|
+
if (s > 0)
|
|
20
|
+
setScale(s);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
handleResize();
|
|
24
|
+
window.addEventListener('resize', handleResize);
|
|
25
|
+
return () => window.removeEventListener('resize', handleResize);
|
|
26
|
+
}, [config.width]);
|
|
12
27
|
const animate = (0, react_1.useCallback)((time) => {
|
|
13
28
|
if (lastTimeRef.current !== undefined) {
|
|
14
29
|
const deltaTime = time - lastTimeRef.current;
|
|
@@ -51,12 +66,19 @@ const Player = ({ component: Component, config, inputProps = {}, controls = true
|
|
|
51
66
|
setFrame(Number(e.target.value));
|
|
52
67
|
setIsPlaying(false);
|
|
53
68
|
};
|
|
54
|
-
return ((0, jsx_runtime_1.jsxs)("div", {
|
|
69
|
+
return ((0, jsx_runtime_1.jsxs)("div", { ref: containerRef, style: {
|
|
70
|
+
display: 'inline-block',
|
|
71
|
+
border: '1px solid #ccc',
|
|
72
|
+
borderRadius: '4px',
|
|
73
|
+
overflow: 'hidden',
|
|
74
|
+
background: '#f0f0f0',
|
|
75
|
+
width: config.width * scale,
|
|
76
|
+
}, children: [(0, jsx_runtime_1.jsx)("div", { style: {
|
|
55
77
|
width: config.width,
|
|
56
78
|
height: config.height,
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}, children: (0, jsx_runtime_1.jsx)(index_1.CompositionProvider, { config: config, frame:
|
|
79
|
+
transform: `scale(${scale})`,
|
|
80
|
+
transformOrigin: 'top left',
|
|
81
|
+
background: '#fff'
|
|
82
|
+
}, children: (0, jsx_runtime_1.jsx)(index_1.CompositionProvider, { config: config, frame: frame, inputProps: inputProps, children: (0, jsx_runtime_1.jsx)(Component, {}) }) }), controls && ((0, jsx_runtime_1.jsxs)("div", { style: { padding: '10px', background: '#f0f0f0', display: 'flex', alignItems: 'center', gap: '10px', position: 'relative', zIndex: 10 }, children: [(0, jsx_runtime_1.jsx)("button", { onClick: togglePlay, children: isPlaying ? 'Pause' : 'Play' }), (0, jsx_runtime_1.jsx)("input", { type: "range", min: "0", max: config.durationInFrames - 1, step: "1", value: Math.floor(frame), onChange: handleSeek, style: { flex: 1 } }), (0, jsx_runtime_1.jsxs)("div", { style: { minWidth: '80px', fontSize: '12px', textAlign: 'right', color: '#000' }, children: [Math.floor(frame), " / ", config.durationInFrames] })] }))] }));
|
|
61
83
|
};
|
|
62
84
|
exports.Player = Player;
|
package/dist/index.d.ts
CHANGED
|
@@ -34,13 +34,27 @@ export declare const delayRender: (label?: string) => number;
|
|
|
34
34
|
* continueRender: Signal that an async resource has finished loading.
|
|
35
35
|
*/
|
|
36
36
|
export declare const continueRender: (handle: number) => void;
|
|
37
|
+
/**
|
|
38
|
+
* Easing functions
|
|
39
|
+
*/
|
|
40
|
+
export type EasingFunction = (t: number) => number;
|
|
41
|
+
export declare const Easing: {
|
|
42
|
+
linear: (t: number) => number;
|
|
43
|
+
ease: (t: number) => number;
|
|
44
|
+
in: (t: number) => number;
|
|
45
|
+
out: (t: number) => number;
|
|
46
|
+
inOut: (t: number) => number;
|
|
47
|
+
bezier: (_x1: number, y1: number, _x2: number, y2: number) => (t: number) => number;
|
|
48
|
+
step: (t: number) => 0 | 1;
|
|
49
|
+
};
|
|
37
50
|
/**
|
|
38
51
|
* interpolate function: maps a value from one range to another.
|
|
39
52
|
* Compatible with Remotion's interpolate.
|
|
40
53
|
*/
|
|
41
|
-
export declare const interpolate: (input: number, inputRange: [
|
|
54
|
+
export declare const interpolate: (input: number, inputRange: number[], outputRange: number[], options?: {
|
|
42
55
|
extrapolateLeft?: "extrapolate" | "clamp";
|
|
43
56
|
extrapolateRight?: "extrapolate" | "clamp";
|
|
57
|
+
easing?: EasingFunction;
|
|
44
58
|
}) => number;
|
|
45
59
|
/**
|
|
46
60
|
* Time Hijacking Bridge Script
|
|
@@ -74,4 +88,17 @@ export declare const Audio: React.FC<{
|
|
|
74
88
|
startFrom?: number;
|
|
75
89
|
volume?: number;
|
|
76
90
|
}>;
|
|
91
|
+
/**
|
|
92
|
+
* Video Component
|
|
93
|
+
* Supports frame-accurate seeking and synchronization with the engine.
|
|
94
|
+
*/
|
|
95
|
+
export declare const Video: React.FC<{
|
|
96
|
+
src: string;
|
|
97
|
+
startFrom?: number;
|
|
98
|
+
endAt?: number;
|
|
99
|
+
playbackRate?: number;
|
|
100
|
+
muted?: boolean;
|
|
101
|
+
volume?: number;
|
|
102
|
+
style?: React.CSSProperties;
|
|
103
|
+
}>;
|
|
77
104
|
export * from './Player';
|
package/dist/index.js
CHANGED
|
@@ -10,25 +10,76 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
|
|
|
10
10
|
if (k2 === undefined) k2 = k;
|
|
11
11
|
o[k2] = m[k];
|
|
12
12
|
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
13
35
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
36
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
37
|
};
|
|
16
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.Audio = exports.spring = exports.Sequence = exports.getTimeHijackScript = exports.interpolate = exports.continueRender = exports.delayRender = exports.Composition = exports.getCompositionById = exports.getCompositions = exports.registerComposition = exports.getInputProps = exports.useAbsoluteFrame = exports.useCurrentFrame = exports.useVideoConfig = exports.CompositionProvider = void 0;
|
|
39
|
+
exports.Video = exports.Audio = exports.spring = exports.Sequence = exports.getTimeHijackScript = exports.interpolate = exports.Easing = exports.continueRender = exports.delayRender = exports.Composition = exports.getCompositionById = exports.getCompositions = exports.registerComposition = exports.getInputProps = exports.useAbsoluteFrame = exports.useCurrentFrame = exports.useVideoConfig = exports.CompositionProvider = void 0;
|
|
18
40
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
19
|
-
const react_1 = require("react");
|
|
41
|
+
const react_1 = __importStar(require("react"));
|
|
20
42
|
const VideoConfigContext = (0, react_1.createContext)(null);
|
|
21
43
|
const FrameContext = (0, react_1.createContext)(0);
|
|
22
44
|
const AbsoluteFrameContext = (0, react_1.createContext)(0);
|
|
23
45
|
const InputPropsContext = (0, react_1.createContext)({});
|
|
24
46
|
const CompositionProvider = ({ config, frame, inputProps = {}, children }) => {
|
|
25
|
-
|
|
47
|
+
const [currentFrame, setCurrentFrame] = react_1.default.useState(frame);
|
|
48
|
+
react_1.default.useEffect(() => {
|
|
49
|
+
if (typeof window !== 'undefined') {
|
|
50
|
+
window.__OPEN_MOTION_READY__ = true;
|
|
51
|
+
}
|
|
52
|
+
}, [currentFrame]);
|
|
53
|
+
react_1.default.useEffect(() => {
|
|
54
|
+
setCurrentFrame(frame);
|
|
55
|
+
}, [frame]);
|
|
56
|
+
react_1.default.useEffect(() => {
|
|
57
|
+
if (typeof window !== 'undefined') {
|
|
58
|
+
const handler = (e) => {
|
|
59
|
+
if (typeof e.detail?.frame === 'number') {
|
|
60
|
+
setCurrentFrame(e.detail.frame);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
window.addEventListener('open-motion-frame-update', handler);
|
|
64
|
+
return () => window.removeEventListener('open-motion-frame-update', handler);
|
|
65
|
+
}
|
|
66
|
+
}, []);
|
|
67
|
+
return ((0, jsx_runtime_1.jsx)(VideoConfigContext.Provider, { value: config, children: (0, jsx_runtime_1.jsx)(InputPropsContext.Provider, { value: inputProps, children: (0, jsx_runtime_1.jsx)(AbsoluteFrameContext.Provider, { value: currentFrame, children: (0, jsx_runtime_1.jsx)(FrameContext.Provider, { value: currentFrame, children: (0, jsx_runtime_1.jsx)("div", { style: {
|
|
68
|
+
width: config.width,
|
|
69
|
+
height: config.height,
|
|
70
|
+
backgroundColor: 'white',
|
|
71
|
+
display: 'flex',
|
|
72
|
+
flexDirection: 'column',
|
|
73
|
+
position: 'relative',
|
|
74
|
+
overflow: 'hidden',
|
|
75
|
+
}, children: children }) }) }) }) }));
|
|
26
76
|
};
|
|
27
77
|
exports.CompositionProvider = CompositionProvider;
|
|
28
78
|
const useVideoConfig = () => {
|
|
29
79
|
const context = (0, react_1.useContext)(VideoConfigContext);
|
|
30
|
-
if (!context)
|
|
31
|
-
|
|
80
|
+
if (!context) {
|
|
81
|
+
return { width: 1920, height: 1080, fps: 30, durationInFrames: 100 };
|
|
82
|
+
}
|
|
32
83
|
return context;
|
|
33
84
|
};
|
|
34
85
|
exports.useVideoConfig = useVideoConfig;
|
|
@@ -71,9 +122,9 @@ let delayRenderCounter = 0;
|
|
|
71
122
|
*/
|
|
72
123
|
const delayRender = (label) => {
|
|
73
124
|
const handle = delayRenderCounter++;
|
|
74
|
-
console.debug(`OpenMotion: delayRender[${handle}] ${label || ''}`);
|
|
75
125
|
if (typeof window !== 'undefined') {
|
|
76
126
|
window.__OPEN_MOTION_DELAY_RENDER_COUNT__ = (window.__OPEN_MOTION_DELAY_RENDER_COUNT__ || 0) + 1;
|
|
127
|
+
console.debug(`[OpenMotion] delayRender: ${label || handle}, count: ${window.__OPEN_MOTION_DELAY_RENDER_COUNT__}`);
|
|
77
128
|
}
|
|
78
129
|
return handle;
|
|
79
130
|
};
|
|
@@ -82,25 +133,81 @@ exports.delayRender = delayRender;
|
|
|
82
133
|
* continueRender: Signal that an async resource has finished loading.
|
|
83
134
|
*/
|
|
84
135
|
const continueRender = (handle) => {
|
|
85
|
-
console.debug(`OpenMotion: continueRender[${handle}]`);
|
|
86
136
|
if (typeof window !== 'undefined') {
|
|
87
137
|
window.__OPEN_MOTION_DELAY_RENDER_COUNT__ = Math.max(0, (window.__OPEN_MOTION_DELAY_RENDER_COUNT__ || 0) - 1);
|
|
138
|
+
console.debug(`[OpenMotion] continueRender: ${handle}, count: ${window.__OPEN_MOTION_DELAY_RENDER_COUNT__}`);
|
|
88
139
|
}
|
|
89
140
|
};
|
|
90
141
|
exports.continueRender = continueRender;
|
|
142
|
+
exports.Easing = {
|
|
143
|
+
linear: (t) => t,
|
|
144
|
+
ease: (t) => t * t * (3 - 2 * t),
|
|
145
|
+
in: (t) => t * t,
|
|
146
|
+
out: (t) => t * (2 - t),
|
|
147
|
+
inOut: (t) => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t),
|
|
148
|
+
bezier: (_x1, y1, _x2, y2) => {
|
|
149
|
+
// Simple cubic bezier approximation (y-only for now)
|
|
150
|
+
return (t) => {
|
|
151
|
+
const u = 1 - t;
|
|
152
|
+
const tt = t * t;
|
|
153
|
+
const uu = u * u;
|
|
154
|
+
const ttt = tt * t;
|
|
155
|
+
// P0=0, P3=1
|
|
156
|
+
return 3 * uu * t * y1 + 3 * u * tt * y2 + ttt;
|
|
157
|
+
};
|
|
158
|
+
},
|
|
159
|
+
step: (t) => (t < 0.5 ? 0 : 1),
|
|
160
|
+
};
|
|
91
161
|
/**
|
|
92
162
|
* interpolate function: maps a value from one range to another.
|
|
93
163
|
* Compatible with Remotion's interpolate.
|
|
94
164
|
*/
|
|
95
165
|
const interpolate = (input, inputRange, outputRange, options) => {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
166
|
+
if (inputRange.length < 2)
|
|
167
|
+
return outputRange[0];
|
|
168
|
+
// Simple linear interpolation between multiple segments
|
|
169
|
+
for (let i = 0; i < inputRange.length - 1; i++) {
|
|
170
|
+
const minInput = inputRange[i];
|
|
171
|
+
const maxInput = inputRange[i + 1];
|
|
172
|
+
const minOutput = outputRange[i];
|
|
173
|
+
const maxOutput = outputRange[i + 1];
|
|
174
|
+
if (input >= minInput && input <= maxInput) {
|
|
175
|
+
let progress = (input - minInput) / (maxInput - minInput);
|
|
176
|
+
if (options?.easing) {
|
|
177
|
+
progress = options.easing(progress);
|
|
178
|
+
}
|
|
179
|
+
return minOutput + progress * (maxOutput - minOutput);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
const firstInput = inputRange[0];
|
|
183
|
+
const lastInput = inputRange[inputRange.length - 1];
|
|
184
|
+
const firstOutput = outputRange[0];
|
|
185
|
+
const lastOutput = outputRange[outputRange.length - 1];
|
|
186
|
+
if (input < firstInput) {
|
|
187
|
+
if (options?.extrapolateLeft === 'clamp')
|
|
188
|
+
return firstOutput;
|
|
189
|
+
// Extrapolate using first segment
|
|
190
|
+
const nextInput = inputRange[1];
|
|
191
|
+
const nextOutput = outputRange[1];
|
|
192
|
+
let progress = (input - firstInput) / (nextInput - firstInput);
|
|
193
|
+
if (options?.easing) {
|
|
194
|
+
progress = options.easing(progress);
|
|
195
|
+
}
|
|
196
|
+
return firstOutput + progress * (nextOutput - firstOutput);
|
|
197
|
+
}
|
|
198
|
+
if (input > lastInput) {
|
|
199
|
+
if (options?.extrapolateRight === 'clamp')
|
|
200
|
+
return lastOutput;
|
|
201
|
+
// Extrapolate using last segment
|
|
202
|
+
const prevInput = inputRange[inputRange.length - 2];
|
|
203
|
+
const prevOutput = outputRange[outputRange.length - 2];
|
|
204
|
+
let progress = (input - lastInput) / (lastInput - prevInput);
|
|
205
|
+
if (options?.easing) {
|
|
206
|
+
progress = options.easing(progress);
|
|
207
|
+
}
|
|
208
|
+
return lastOutput + progress * (lastOutput - prevOutput);
|
|
209
|
+
}
|
|
210
|
+
return firstOutput;
|
|
104
211
|
};
|
|
105
212
|
exports.interpolate = interpolate;
|
|
106
213
|
/**
|
|
@@ -131,8 +238,6 @@ const getTimeHijackScript = (frame, fps) => {
|
|
|
131
238
|
return setTimeout(() => callback(timeMs), 0);
|
|
132
239
|
};
|
|
133
240
|
window.cancelAnimationFrame = (id) => clearTimeout(id);
|
|
134
|
-
|
|
135
|
-
console.debug('OpenMotion: Time hijacked for frame ' + frame + ' at ' + timeMs + 'ms');
|
|
136
241
|
})();
|
|
137
242
|
`;
|
|
138
243
|
};
|
|
@@ -171,13 +276,54 @@ exports.spring = spring;
|
|
|
171
276
|
* Audio Component
|
|
172
277
|
*/
|
|
173
278
|
const Audio = (props) => {
|
|
279
|
+
const startFrame = (0, exports.useAbsoluteFrame)();
|
|
174
280
|
if (typeof window !== 'undefined') {
|
|
175
281
|
window.__OPEN_MOTION_AUDIO_ASSETS__ = window.__OPEN_MOTION_AUDIO_ASSETS__ || [];
|
|
176
|
-
|
|
177
|
-
|
|
282
|
+
const exists = window.__OPEN_MOTION_AUDIO_ASSETS__.find((a) => a.src === props.src &&
|
|
283
|
+
(a.startFrom || 0) === (props.startFrom || 0) &&
|
|
284
|
+
(a.volume || 1) === (props.volume || 1) &&
|
|
285
|
+
a.startFrame === startFrame);
|
|
286
|
+
if (!exists) {
|
|
287
|
+
window.__OPEN_MOTION_AUDIO_ASSETS__.push({
|
|
288
|
+
...props,
|
|
289
|
+
startFrame,
|
|
290
|
+
});
|
|
178
291
|
}
|
|
179
292
|
}
|
|
180
293
|
return null;
|
|
181
294
|
};
|
|
182
295
|
exports.Audio = Audio;
|
|
296
|
+
/**
|
|
297
|
+
* Video Component
|
|
298
|
+
* Supports frame-accurate seeking and synchronization with the engine.
|
|
299
|
+
*/
|
|
300
|
+
const Video = ({ src, startFrom = 0, endAt, playbackRate = 1, muted = true, volume = 1, style }) => {
|
|
301
|
+
const frame = (0, exports.useCurrentFrame)();
|
|
302
|
+
const { fps } = (0, exports.useVideoConfig)();
|
|
303
|
+
const videoRef = react_1.default.useRef(null);
|
|
304
|
+
const isVisible = endAt === undefined || frame < endAt;
|
|
305
|
+
react_1.default.useEffect(() => {
|
|
306
|
+
const video = videoRef.current;
|
|
307
|
+
if (!video || !isVisible)
|
|
308
|
+
return;
|
|
309
|
+
const targetTime = (frame * playbackRate + startFrom) / fps;
|
|
310
|
+
// Only seek if the difference is significant to avoid jitter
|
|
311
|
+
if (Math.abs(video.currentTime - targetTime) > 0.001) {
|
|
312
|
+
video.currentTime = targetTime;
|
|
313
|
+
}
|
|
314
|
+
}, [frame, fps, startFrom, playbackRate, isVisible]);
|
|
315
|
+
if (!isVisible)
|
|
316
|
+
return null;
|
|
317
|
+
return ((0, jsx_runtime_1.jsx)("video", { ref: videoRef, src: src, muted: muted, playsInline: true, style: {
|
|
318
|
+
display: 'block',
|
|
319
|
+
objectFit: 'cover',
|
|
320
|
+
...style,
|
|
321
|
+
}, onLoadedMetadata: (e) => {
|
|
322
|
+
const video = e.currentTarget;
|
|
323
|
+
video.volume = volume;
|
|
324
|
+
// Ensure it's paused so we can control it via currentTime
|
|
325
|
+
video.pause();
|
|
326
|
+
} }));
|
|
327
|
+
};
|
|
328
|
+
exports.Video = Video;
|
|
183
329
|
__exportStar(require("./Player"), exports);
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-motion/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "https://github.com/
|
|
9
|
+
"url": "https://github.com/jsongo/open-motion.git",
|
|
10
10
|
"directory": "packages/core"
|
|
11
11
|
},
|
|
12
12
|
"publishConfig": {
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {},
|
|
19
19
|
"peerDependencies": {
|
|
20
|
-
"react": "^18.0.0"
|
|
20
|
+
"react": "^18.0.0",
|
|
21
|
+
"react-dom": "^18.0.0"
|
|
21
22
|
},
|
|
22
23
|
"scripts": {
|
|
23
24
|
"build": "tsc"
|