Upload 10 files
Browse files- remotion/Scene.tsx +40 -20
remotion/Scene.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
import { AbsoluteFill, Img,
|
| 2 |
import { SceneApi, ProjectSettings } from './types';
|
| 3 |
import { AudioWave } from './AudioWave';
|
| 4 |
|
|
@@ -47,34 +47,54 @@ export const Scene: React.FC<Props> = ({ scene, settings }) => {
|
|
| 47 |
}
|
| 48 |
};
|
| 49 |
|
| 50 |
-
//
|
| 51 |
-
const
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
|
| 66 |
return (
|
| 67 |
<AbsoluteFill style={{ overflow: 'hidden', ...getTransitionStyle() }}>
|
| 68 |
{/* Background Image with Ken Burns */}
|
| 69 |
{scene.image_url ? (
|
| 70 |
-
<AbsoluteFill style={{ transform: `scale(${scale})
|
| 71 |
{(scene.media_type === 'video' || scene.image_url.includes('.mp4')) ? (
|
| 72 |
-
<
|
| 73 |
src={scene.image_url}
|
| 74 |
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
| 75 |
muted={true}
|
| 76 |
-
// Loop video if shorter than scene duration
|
| 77 |
-
loop
|
| 78 |
/>
|
| 79 |
) : (
|
| 80 |
<Img
|
|
|
|
| 1 |
+
import { AbsoluteFill, Img, OffthreadVideo, useCurrentFrame, useVideoConfig, interpolate, Easing, Audio } from 'remotion';
|
| 2 |
import { SceneApi, ProjectSettings } from './types';
|
| 3 |
import { AudioWave } from './AudioWave';
|
| 4 |
|
|
|
|
| 47 |
}
|
| 48 |
};
|
| 49 |
|
| 50 |
+
// Camera Movement Logic
|
| 51 |
+
const movements = settings.cameraMovements || ['zoom_in'];
|
| 52 |
+
// Pick movement based on scene index to ensure stable pseudo-randomness or sequentiality
|
| 53 |
+
const movementType = movements[scene.order_index % movements.length];
|
| 54 |
+
|
| 55 |
+
let scale = 1;
|
| 56 |
+
let translateX = 0;
|
| 57 |
+
let translateY = 0;
|
| 58 |
+
|
| 59 |
+
switch (movementType) {
|
| 60 |
+
case 'zoom_in':
|
| 61 |
+
scale = interpolate(frame, [0, durationFrames], [1, 1.15], { easing: Easing.bezier(0.25, 1, 0.5, 1) });
|
| 62 |
+
break;
|
| 63 |
+
case 'zoom_out':
|
| 64 |
+
scale = interpolate(frame, [0, durationFrames], [1.15, 1], { easing: Easing.bezier(0.25, 1, 0.5, 1) });
|
| 65 |
+
break;
|
| 66 |
+
case 'pan_left':
|
| 67 |
+
scale = 1.15; // Zoom in slightly to allow panning without black bars
|
| 68 |
+
translateX = interpolate(frame, [0, durationFrames], [0, -40]); // Pan right-to-left
|
| 69 |
+
break;
|
| 70 |
+
case 'pan_right':
|
| 71 |
+
scale = 1.15;
|
| 72 |
+
translateX = interpolate(frame, [0, durationFrames], [-40, 0]); // Pan left-to-right (corrected logic)
|
| 73 |
+
break;
|
| 74 |
+
case 'pan_up':
|
| 75 |
+
scale = 1.15;
|
| 76 |
+
translateY = interpolate(frame, [0, durationFrames], [0, -40]);
|
| 77 |
+
break;
|
| 78 |
+
case 'pan_down':
|
| 79 |
+
scale = 1.15;
|
| 80 |
+
translateY = interpolate(frame, [0, durationFrames], [-40, 0]);
|
| 81 |
+
break;
|
| 82 |
+
case 'static':
|
| 83 |
+
default:
|
| 84 |
+
scale = 1;
|
| 85 |
+
break;
|
| 86 |
+
}
|
| 87 |
|
| 88 |
return (
|
| 89 |
<AbsoluteFill style={{ overflow: 'hidden', ...getTransitionStyle() }}>
|
| 90 |
{/* Background Image with Ken Burns */}
|
| 91 |
{scene.image_url ? (
|
| 92 |
+
<AbsoluteFill style={{ transform: `scale(${scale}) translate(${translateX}px, ${translateY}px)` }}>
|
| 93 |
{(scene.media_type === 'video' || scene.image_url.includes('.mp4')) ? (
|
| 94 |
+
<OffthreadVideo
|
| 95 |
src={scene.image_url}
|
| 96 |
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
| 97 |
muted={true}
|
|
|
|
|
|
|
| 98 |
/>
|
| 99 |
) : (
|
| 100 |
<Img
|