o2o-ado2-short-form/remotion/src/components/SellingBadge.tsx

70 lines
2.0 KiB
TypeScript

import React from "react";
import {
useCurrentFrame,
useVideoConfig,
interpolate,
spring,
AbsoluteFill,
} from "remotion";
import { serifFont } from "../fonts";
// 셀링포인트: 3개 독립 pill 박스를 세로로 쌓고 순차 등장.
// 컬러 지양 → 반투명 다크 pill + 흰색 텍스트. 앞 구간 단독 노출(시선 집중).
export const SellingBadge: React.FC<{
items: string[];
fromFrame: number;
toFrame: number;
}> = ({ items, fromFrame, toFrame }) => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
const STAGGER = 9; // 박스 간 등장 간격(frame)
return (
<AbsoluteFill
style={{
justifyContent: "flex-start",
alignItems: "center",
flexDirection: "column",
paddingTop: 200, // 상단 배치 (~16%) — 이미지 가림 최소화
gap: 18,
}}
>
{items.map((item, i) => {
const start = fromFrame + i * STAGGER;
const enter = spring({
frame: frame - start,
fps,
config: { damping: 200, mass: 0.5 },
});
const rise = interpolate(enter, [0, 1], [22, 0]);
const appear = interpolate(
frame,
[start, start + 8, toFrame - 10, toFrame],
[0, 1, 1, 0],
{ extrapolateLeft: "clamp", extrapolateRight: "clamp" },
);
return (
<div
key={i}
style={{
opacity: appear,
transform: `translateY(${rise}px)`,
fontFamily: serifFont,
fontWeight: 700,
fontSize: 38,
color: "#FFFFFF",
letterSpacing: 0.5,
whiteSpace: "nowrap",
// 배경 제거 → 블러리 소프트 쉐도우로 가독성 확보
textShadow:
"0 2px 22px rgba(0,0,0,0.95), 0 0 14px rgba(0,0,0,0.85), 0 0 40px rgba(0,0,0,0.6)",
}}
>
{item}
</div>
);
})}
</AbsoluteFill>
);
};