| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- import React from "react";
- import { useCurrentFrame, interpolate, Easing } from "remotion";
- interface QuoteBlockProps {
- quote: string;
- author?: string;
- color?: string;
- }
- export const QuoteBlock: React.FC<QuoteBlockProps> = ({
- quote,
- author,
- color = "#f97316",
- }) => {
- const frame = useCurrentFrame();
- const opacity = interpolate(frame, [0, 15], [0, 1], {
- extrapolateRight: "clamp",
- });
- const scale = interpolate(frame, [0, 12], [0.95, 1], {
- extrapolateRight: "clamp",
- easing: Easing.out(Easing.cubic),
- });
- // Typewriter effect for quote text
- const charsVisible = Math.floor(
- interpolate(frame, [5, 5 + quote.length * 1.5], [0, quote.length], {
- extrapolateRight: "clamp",
- })
- );
- const displayText = quote.slice(0, charsVisible);
- return (
- <div
- style={{
- opacity,
- transform: `scale(${scale})`,
- position: "relative",
- paddingLeft: 40,
- }}
- >
- {/* Quote mark */}
- <div
- style={{
- position: "absolute",
- top: -20,
- left: 0,
- fontSize: 80,
- lineHeight: 1,
- color,
- fontFamily: "Georgia, serif",
- fontWeight: 700,
- }}
- >
- "
- </div>
- <div
- style={{
- fontSize: 36,
- fontStyle: "italic",
- color: "white",
- fontFamily: "Georgia, serif",
- lineHeight: 1.6,
- maxWidth: "90%",
- }}
- >
- {displayText}
- <span
- style={{
- display: "inline-block",
- width: 2,
- height: 36,
- backgroundColor: color,
- marginLeft: 2,
- animation: "blink 0.8s infinite",
- }}
- />
- </div>
- {author && (
- <div
- style={{
- marginTop: 20,
- fontSize: 22,
- color: "#9ca3af",
- fontFamily: "sans-serif",
- }}
- >
- — {author}
- </div>
- )}
- </div>
- );
- };
|