| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- import React from "react";
- import {
- useCurrentFrame,
- useVideoConfig,
- AbsoluteFill,
- interpolate,
- Easing,
- } from "remotion";
- import type { RemotionScene } from "../Root";
- import { THEMES } from "../base/theme/colors";
- import { Background } from "../base/components/background";
- import { SubtitleBar } from "../base/components/subtitle-bar";
- import { AnimatedText } from "../base/components/animated-text";
- import { Watermark } from "../base/components/watermark";
- import { ProductShowcase } from "./components/product-showcase";
- import { CTAOverlay } from "./components/cta-overlay";
- interface MarketingSceneProps {
- scene: RemotionScene;
- sceneIndex: number;
- totalScenes: number;
- totalFrames: number;
- title: string;
- }
- const MarketingScene: React.FC<MarketingSceneProps> = ({
- scene,
- sceneIndex,
- totalScenes,
- totalFrames,
- title,
- }) => {
- const frame = useCurrentFrame();
- const colors = THEMES.marketing;
- const fadeOpacity = interpolate(
- frame,
- [0, 8, scene.endFrame - scene.startFrame - 8, scene.endFrame - scene.startFrame],
- [0, 1, 1, 0],
- { extrapolateLeft: "clamp", extrapolateRight: "clamp" }
- );
- const isLastScene = sceneIndex === totalScenes - 1;
- const featureKeyframes = scene.keyframes.filter(
- (kf) => kf.type === "text" || kf.type === "highlight"
- );
- return (
- <AbsoluteFill style={{ opacity: fadeOpacity }}>
- <Background
- colors={colors}
- sceneIndex={sceneIndex}
- totalScenes={totalScenes}
- />
- {/* Decorative glow */}
- <div
- style={{
- position: "absolute",
- top: "30%",
- left: "50%",
- width: 600,
- height: 600,
- borderRadius: 300,
- background: `radial-gradient(circle, ${colors.primary}22, transparent 70%)`,
- transform: "translate(-50%, -50%)",
- }}
- />
- {/* Brand label */}
- <div
- style={{
- position: "absolute",
- top: 40,
- left: 40,
- fontSize: 20,
- fontWeight: 700,
- color: "rgba(255,255,255,0.3)",
- fontFamily: "sans-serif",
- letterSpacing: 4,
- textTransform: "uppercase",
- }}
- >
- {title}
- </div>
- {/* Content */}
- <div
- style={{
- position: "absolute",
- top: 100,
- left: 80,
- right: 80,
- bottom: 140,
- display: "flex",
- flexDirection: "column",
- justifyContent: "center",
- alignItems: isLastScene ? "center" : "flex-start",
- gap: 36,
- overflow: "hidden",
- }}
- >
- {isLastScene ? (
- // CTA scene
- <CTAOverlay
- text={scene.narration}
- subtitle={featureKeyframes[0]?.content}
- color={colors.primaryLight}
- />
- ) : (
- <>
- <AnimatedText
- text={scene.narration}
- fontSize={44}
- color="white"
- fontWeight={700}
- delay={5}
- />
- {featureKeyframes.length > 0 && (
- <ProductShowcase
- features={featureKeyframes.map((kf) => kf.content)}
- accentColor={colors.primaryLight}
- />
- )}
- </>
- )}
- </div>
- {scene.wordTimestamps.length > 0 && (
- <SubtitleBar wordTimestamps={scene.wordTimestamps} />
- )}
- <Watermark />
- </AbsoluteFill>
- );
- };
- export default MarketingScene;
|