iter 2
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
"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>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user