"use client"; import { cn } from "../../lib/utils"; import React, { ReactNode, useEffect, useState } from "react"; import { motion, HTMLMotionProps } from "framer-motion"; export interface VideoTextProps { src: string; className?: string; autoPlay?: boolean; muted?: boolean; loop?: boolean; preload?: "auto" | "metadata" | "none"; children: ReactNode; fontSize?: string | number; fontWeight?: string | number; textAnchor?: string; dominantBaseline?: string; fontFamily?: string; as?: "div" | "span" | "section" | "article" | "p" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6"; } export function VideoText({ src, children, className = "", autoPlay = true, muted = true, loop = true, preload = "auto", fontSize = 20, fontWeight = "bold", textAnchor = "middle", dominantBaseline = "middle", fontFamily = "sans-serif", as = "div", ...motionProps }: VideoTextProps & HTMLMotionProps<"div">) { const [svgMask, setSvgMask] = useState(""); const content = React.Children.toArray(children).join(""); useEffect(() => { const responsiveFontSize = typeof fontSize === "number" ? `${fontSize}vw` : fontSize; const newSvgMask = ` ${content} `; setSvgMask(newSvgMask); }, [content, fontSize, fontWeight, textAnchor, dominantBaseline, fontFamily]); const validTags = ["div", "span", "section", "article", "p", "h1", "h2", "h3", "h4", "h5", "h6"] as const; type ValidTag = (typeof validTags)[number]; const MotionComponent = motion[validTags.includes(as) ? as : "div"] as React.ElementType; if (!svgMask) { return ( {content} ); } const dataUrlMask = `url("data:image/svg+xml,${encodeURIComponent(svgMask)}")`; return ( Your browser does not support the video tag. {content} ); }