Files
main_frontend/src/features/project/CaptionSettingsStep/StylePreview.tsx
T
2026-04-04 14:51:40 +03:00

124 lines
3.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client"
import type { components } from "@shared/api/__generated__/openapi.types"
import type { JSX } from "react"
import { FunctionComponent } from "react"
import cs from "classnames"
import styles from "./StylePreview.module.scss"
type CaptionStyleConfig = components["schemas"]["CaptionStyleConfig"]
interface IStylePreviewProps {
config?: CaptionStyleConfig | null
size?: "small" | "large"
className?: string
}
const SMALL_SCALE = 0.65
const buildContainerStyles = (
config: CaptionStyleConfig,
scale: number,
): React.CSSProperties => {
const bg = config.background
return {
backgroundColor: bg?.bg_color ?? "rgba(0,0,0,0.6)",
borderRadius: (bg?.bg_border_radius_px ?? 8) * scale,
padding: (bg?.bg_padding_px ?? 12) * scale,
...(bg?.bg_blur_px
? { backdropFilter: `blur(${bg.bg_blur_px * scale}px)` }
: {}),
...(bg?.bg_glow_color
? { boxShadow: `0 0 ${20 * scale}px ${bg.bg_glow_color}` }
: {}),
}
}
const buildTextStyles = (
config: CaptionStyleConfig,
scale: number,
): React.CSSProperties => {
const text = config.text
return {
fontFamily: text?.font_family ?? "Lobster",
fontSize: (text?.font_size ?? 40) * scale,
fontWeight: text?.font_weight ?? 400,
color: text?.text_color ?? "#FFFFFF",
textAlign:
(config.layout?.horizontal_alignment as "left" | "center" | "right") ??
"center",
...(text?.text_shadow ? { textShadow: text.text_shadow } : {}),
...(text?.text_stroke_width
? {
WebkitTextStroke: `${(text.text_stroke_width ?? 0) * scale}px ${text.text_stroke_color ?? "#000000"}`,
}
: {}),
}
}
const VERTICAL_MAP: Record<string, string> = {
top: "flex-start",
center: "center",
bottom: "flex-end",
}
const HORIZONTAL_MAP: Record<string, string> = {
left: "flex-start",
center: "center",
right: "flex-end",
}
const buildPositionStyles = (
config: CaptionStyleConfig,
scale: number,
): React.CSSProperties => {
const layout = config.layout
const vPos = layout?.vertical_position ?? "bottom"
const hAlign = layout?.horizontal_alignment ?? "center"
const padding = (layout?.padding_px ?? 20) * scale
return {
justifyContent: VERTICAL_MAP[vPos] ?? "flex-end",
alignItems: HORIZONTAL_MAP[hAlign] ?? "center",
padding,
}
}
export const StylePreview: FunctionComponent<IStylePreviewProps> = ({
config,
size = "small",
className,
}): JSX.Element => {
const safeConfig = config ?? {}
const highlightColor = safeConfig.text?.highlight_color ?? "#FFFF00"
const scale = size === "small" ? SMALL_SCALE : 1
return (
<div
className={cs(styles.root, styles[size], className)}
style={buildPositionStyles(safeConfig, scale)}
data-testid="StylePreview"
>
<div
style={{
...buildContainerStyles(safeConfig, scale),
maxWidth: "100%",
boxSizing: "border-box",
}}
>
<span
style={{
...buildTextStyles(safeConfig, scale),
wordBreak: "break-word",
}}
>
Пример <span style={{ color: highlightColor }}>субтитров</span>
</span>
</div>
</div>
)
}