diff --git a/remotion/rewind/AlbumScene.tsx b/remotion/rewind/AlbumScene.tsx index 623d512..eebf699 100644 --- a/remotion/rewind/AlbumScene.tsx +++ b/remotion/rewind/AlbumScene.tsx @@ -1,51 +1,61 @@ -/* eslint-disable @next/next/no-img-element */ -import React, { useMemo, useRef } from 'react' -import { spring, useCurrentFrame, useVideoConfig } from 'remotion'; +import React, { useMemo } from 'react'; +import { Img, spring, useCurrentFrame, useVideoConfig } from 'remotion'; -interface AlbumsSceneProps { +interface AlbumSceneProps { message: string; emoji: string; data: { + photos: number; albums: { name: string; cover: string; }[]; }; } -export default function AlbumsScene({ message, emoji, data }: AlbumsSceneProps) { - const albums = useMemo(() => data.albums.map((album, index) => ({ - name: album.name, - cover: album.cover, - })), [data.albums]); - + +export default function AlbumScene({ message, emoji, data }: AlbumSceneProps) { const frame = useCurrentFrame(); const { fps } = useVideoConfig(); - const initialDelay = useRef(frame); + + const albums = useMemo(() => data.albums, [data.albums]); + return (
-

- {message} -

+ {emoji} +

+ {message} +

+
+
{albums.map((album, index) => { - const delay = (initialDelay.current) + (index * 0.1 * fps); + const delay = index * 5; const scale = spring({ frame: frame - delay, fps, @@ -57,56 +67,37 @@ export default function AlbumsScene({ message, emoji, data }: AlbumsSceneProps) }); return ( -
- memory -

- {album.name} -

+ opacity: scale, + }} + > + {album.name} +

+ {album.name} +

- ) + ); })}
- ) + ); } - -// Add this CSS to your global styles or a CSS-in-JS solution -const styles = ` -@keyframes zoomIn { - from { - transform: scale(0.5); - opacity: 0; - } - to { - transform: scale(1); - opacity: 1; - } -} -`; - -// Inject styles into the document -const styleSheet = document.createElement("style"); -styleSheet.type = "text/css"; -styleSheet.innerText = styles; -document.head.appendChild(styleSheet); diff --git a/remotion/rewind/CountryScene.tsx b/remotion/rewind/CountryScene.tsx index fa02ac8..aaa063f 100644 --- a/remotion/rewind/CountryScene.tsx +++ b/remotion/rewind/CountryScene.tsx @@ -1,55 +1,59 @@ -import React from 'react' -import { spring, useCurrentFrame, useVideoConfig, interpolate } from 'remotion'; +import React, { useMemo } from 'react'; +import { spring, useCurrentFrame, useVideoConfig } from 'remotion'; interface CountrySceneProps { message: string; emoji: string; - data: any; + data: { + countries: string[]; + }; } export default function CountryScene({ message, emoji, data }: CountrySceneProps) { const frame = useCurrentFrame(); const { fps } = useVideoConfig(); - const countries = data.countries as string[]; - - // Message animation (takes 1 second to appear) - const messageOpacity = interpolate( - frame, - [240, 260], - [0, 1], - { extrapolateRight: 'clamp' } - ); + + const countries = useMemo(() => data.countries, [data.countries]); return (
-

- {message} -

- {countries.map((country: string, index: number) => { - // Start countries after message (1 second) with 0.3 second delay between each - const delay = (240) + (index * 0.1 * fps); + + {emoji} + +

+ {message} +

+
+ +
+ {countries.map((country, index) => { + const delay = index * 5; const scale = spring({ frame: frame - delay, fps, @@ -61,29 +65,21 @@ export default function CountryScene({ message, emoji, data }: CountrySceneProps }); return ( -
-
-

{country}

-
+
+ {country}
); })}
- ) + ); } diff --git a/remotion/rewind/FriendsScene.tsx b/remotion/rewind/FriendsScene.tsx index dffdf6d..46e2afd 100644 --- a/remotion/rewind/FriendsScene.tsx +++ b/remotion/rewind/FriendsScene.tsx @@ -1,6 +1,5 @@ -/* eslint-disable @next/next/no-img-element */ -import React, { useMemo, useRef } from 'react' -import { spring, useCurrentFrame, useVideoConfig } from 'remotion'; +import React from 'react'; +import { Img, spring, useCurrentFrame, useVideoConfig } from 'remotion'; interface FriendsSceneProps { message: string; @@ -12,100 +11,129 @@ interface FriendsSceneProps { }[]; }; } + export default function FriendsScene({ message, emoji, data }: FriendsSceneProps) { - const friends = useMemo(() => data.friends.map((friend, index) => ({ - name: friend.name, - cover: friend.cover, - })), [data.friends]); - const frame = useCurrentFrame(); const { fps } = useVideoConfig(); - const initialDelay = useRef(frame); + return (
-

- {message} -

- {friends.map((friend, index) => { - const delay = (initialDelay.current) + (index * 0.1 * fps); + {emoji} +

+ {message} +

+
+ +
+ {data.friends.map((friend, index) => { + const delay = index * 5; const scale = spring({ frame: frame - delay, fps, from: 0, to: 1, config: { - damping: 12, + mass: 0.8, + damping: 15, + stiffness: 100 + }, + }); + + const rotation = spring({ + frame: frame - delay, + fps, + from: 0, + to: index % 2 === 0 ? 8 : -8, + config: { + mass: 0.5, + damping: 20, + stiffness: 80 }, }); return ( -
- memory -

+

+ {friend.name} +

{friend.name} -

+

- ) + ); })}
- ) + ); } - -// Add this CSS to your global styles or a CSS-in-JS solution -const styles = ` -@keyframes zoomIn { - from { - transform: scale(0.5); - opacity: 0; - } - to { - transform: scale(1); - opacity: 1; - } -} -`; - -// Inject styles into the document -const styleSheet = document.createElement("style"); -styleSheet.type = "text/css"; -styleSheet.innerText = styles; -document.head.appendChild(styleSheet); diff --git a/remotion/rewind/MemoriesScene.tsx b/remotion/rewind/MemoriesScene.tsx index 470e2d0..6ba096a 100644 --- a/remotion/rewind/MemoriesScene.tsx +++ b/remotion/rewind/MemoriesScene.tsx @@ -1,5 +1,5 @@ import React, { useMemo, useRef } from 'react' -import { spring, useCurrentFrame, useVideoConfig } from 'remotion'; +import { Img, spring, useCurrentFrame, useVideoConfig } from 'remotion'; interface MemoriesSceneProps { message: string; @@ -11,60 +11,113 @@ interface MemoriesSceneProps { export default function MemoriesScene({ message, emoji, data }: MemoriesSceneProps) { const images = useMemo(() => data.images.map((image, index) => ({ src: image, - rotate: `${(index % 2 === 0 ? 1 : -1) * Math.random() * 10}deg`, + rotate: (index % 2 === 0 ? 1 : -1) * 8, })), [data.images]); const frame = useCurrentFrame(); const { fps } = useVideoConfig(); - const initialDelay = useRef(frame); + + const messageOpacity = spring({ + frame, + fps, + from: 0, + to: 1, + config: { + mass: 0.5, + damping: 20, + stiffness: 100 + } + }); + + const messageY = spring({ + frame, + fps, + from: -20, + to: 0, + config: { + mass: 0.5, + damping: 20, + stiffness: 100 + } + }); + return (
-

- {message} -

- {images.map((image, index) => { - const delay = (initialDelay.current) + (index * 0.1 * fps); + {emoji} +

+ {message} +

+
+
+ {images.slice(0, 4).map((image, index) => { + const delay = index * 5; const scale = spring({ frame: frame - delay, fps, from: 0, to: 1, config: { - damping: 12, + mass: 0.8, + damping: 15, + stiffness: 100 + }, + }); + + const rotation = spring({ + frame: frame - delay, + fps, + from: 0, + to: image.rotate, // Use the stable rotation value directly + config: { + mass: 0.5, + damping: 20, + stiffness: 80 }, }); return ( - memory ) @@ -73,23 +126,3 @@ export default function MemoriesScene({ message, emoji, data }: MemoriesScenePro
) } - -// Add this CSS to your global styles or a CSS-in-JS solution -const styles = ` -@keyframes zoomIn { - from { - transform: scale(0.5); - opacity: 0; - } - to { - transform: scale(1); - opacity: 1; - } -} -`; - -// Inject styles into the document -const styleSheet = document.createElement("style"); -styleSheet.type = "text/css"; -styleSheet.innerText = styles; -document.head.appendChild(styleSheet); diff --git a/remotion/rewind/WelcomeScene.tsx b/remotion/rewind/WelcomeScene.tsx index 5cdbb88..24c3ead 100644 --- a/remotion/rewind/WelcomeScene.tsx +++ b/remotion/rewind/WelcomeScene.tsx @@ -1,58 +1,81 @@ import React from 'react' +import { spring, useCurrentFrame, useVideoConfig, interpolate } from 'remotion' interface WelcomeSceneProps { message: string; emoji: string; } + export default function WelcomeScene({ message, emoji }: WelcomeSceneProps) { + const frame = useCurrentFrame(); + const { fps } = useVideoConfig(); + + const scale = spring({ + frame, + fps, + from: 0.5, + to: 1, + config: { damping: 12 } + }); + + const opacity = spring({ + frame, + fps, + from: 0, + to: 1, + config: { damping: 12 } + }); + + const rotation = spring({ + frame, + fps, + from: -5, + to: 0, + config: { damping: 12 } + }); + + const hue = interpolate( + frame, + [0, 60], + [180, 240], + { extrapolateRight: 'clamp' } + ); + return (

{emoji}

{message}

) } - -// Add this CSS to your global styles or a CSS-in-JS solution -const styles = ` -@keyframes zoomIn { - from { - transform: scale(0.5); - opacity: 0; - } - to { - transform: scale(1); - opacity: 1; - } -} -`; - -// Inject styles into the document -const styleSheet = document.createElement("style"); -styleSheet.type = "text/css"; -styleSheet.innerText = styles; -document.head.appendChild(styleSheet);