From 5adabf5fd0273c8f7f27685edff6f146ef9fac35 Mon Sep 17 00:00:00 2001 From: HolgerHatGarKeineNode Date: Sat, 24 Jan 2026 13:40:53 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=AC=20Add=20CallToActionScene=20compon?= =?UTF-8?q?ent=20for=20Call=20to=20Action=20(Scene=208)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implements Scene 8 of the Portal Presentation video: - Dashboard blur and zoom out animation - Glassmorphism overlay with spring entrance - "Werde Teil der Community" title with bounce animation - URL typing animation: portal.einundzwanzig.space - Orange pulsing glow effect on URL after typing completes - EINUNDZWANZIG logo with animated glow - Audio: success-fanfare, typing, url-emphasis, logo-reveal Co-Authored-By: Claude Opus 4.5 --- videos/src/PortalPresentation.tsx | 3 +- .../scenes/portal/CallToActionScene.test.tsx | 236 +++++++++++++ .../src/scenes/portal/CallToActionScene.tsx | 309 ++++++++++++++++++ 3 files changed, 547 insertions(+), 1 deletion(-) create mode 100644 videos/src/scenes/portal/CallToActionScene.test.tsx create mode 100644 videos/src/scenes/portal/CallToActionScene.tsx diff --git a/videos/src/PortalPresentation.tsx b/videos/src/PortalPresentation.tsx index cc22393..29ba2b4 100644 --- a/videos/src/PortalPresentation.tsx +++ b/videos/src/PortalPresentation.tsx @@ -6,6 +6,7 @@ import { DashboardOverviewScene } from "./scenes/portal/DashboardOverviewScene"; import { MeetupShowcaseScene } from "./scenes/portal/MeetupShowcaseScene"; import { TopMeetupsScene } from "./scenes/portal/TopMeetupsScene"; import { ActivityFeedScene } from "./scenes/portal/ActivityFeedScene"; +import { CallToActionScene } from "./scenes/portal/CallToActionScene"; /** * PortalPresentation - Main composition for the Einundzwanzig Portal presentation video @@ -193,7 +194,7 @@ export const PortalPresentation: React.FC = () => { durationInFrames={sceneFrames.callToAction.duration} premountFor={fps} > - + {/* Scene 9: Outro (12s) */} diff --git a/videos/src/scenes/portal/CallToActionScene.test.tsx b/videos/src/scenes/portal/CallToActionScene.test.tsx new file mode 100644 index 0000000..e426ac6 --- /dev/null +++ b/videos/src/scenes/portal/CallToActionScene.test.tsx @@ -0,0 +1,236 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; +import { render, cleanup } from "@testing-library/react"; +import { CallToActionScene } from "./CallToActionScene"; + +/* eslint-disable @remotion/warn-native-media-tag */ +// Mock Remotion hooks +vi.mock("remotion", () => ({ + useCurrentFrame: vi.fn(() => 120), + useVideoConfig: vi.fn(() => ({ fps: 30, width: 1920, height: 1080 })), + interpolate: vi.fn((value, inputRange, outputRange) => { + const [inMin, inMax] = inputRange; + const [outMin, outMax] = outputRange; + let progress = (value - inMin) / (inMax - inMin); + progress = Math.max(0, Math.min(1, progress)); + return outMin + progress * (outMax - outMin); + }), + spring: vi.fn(() => 1), + AbsoluteFill: vi.fn(({ children, className, style }) => ( +
+ {children} +
+ )), + Img: vi.fn(({ src, className, style }) => ( + + )), + staticFile: vi.fn((path: string) => `/static/${path}`), + Sequence: vi.fn(({ children, from, durationInFrames }) => ( +
+ {children} +
+ )), + Easing: { + out: vi.fn((fn) => fn), + cubic: vi.fn((t: number) => t), + }, +})); + +// Mock @remotion/media +vi.mock("@remotion/media", () => ({ + Audio: vi.fn(({ src, volume }) => ( +