@@ -1,147 +0,0 @@
|
||||
import React from "react"
|
||||
import { Drawer, Slider, ColorPicker, Select } from "antd"
|
||||
import type { Color } from "antd/es/color-picker"
|
||||
import type { SubtitleStyleConfig } from "@/pages/editing-planner/types/subtitle"
|
||||
import {
|
||||
FONT_OPTIONS,
|
||||
ANIMATION_OPTIONS,
|
||||
ASR_LANGUAGE_OPTIONS,
|
||||
} from "@/pages/editing-planner/constants/subtitleStyle"
|
||||
import SubtitlePreview from "./subtitle-style/SubtitlePreview"
|
||||
import { SubtitleModeSwitch } from "./subtitle-style/SubtitleModeSwitch"
|
||||
import { SubtitlePositionSelector } from "./subtitle-style/SubtitlePositionSelector"
|
||||
import { SubtitleEffectButtons } from "./subtitle-style/SubtitleEffectButtons"
|
||||
|
||||
interface SubtitleStylePanelProps {
|
||||
open: boolean
|
||||
onClose: () => void
|
||||
config: SubtitleStyleConfig
|
||||
onChange: (config: SubtitleStyleConfig) => void
|
||||
}
|
||||
|
||||
const SubtitleStylePanel: React.FC<SubtitleStylePanelProps> = ({
|
||||
open,
|
||||
onClose,
|
||||
config,
|
||||
onChange,
|
||||
}) => {
|
||||
const update = (partial: Partial<SubtitleStyleConfig>) => {
|
||||
onChange({ ...config, ...partial })
|
||||
}
|
||||
|
||||
return (
|
||||
<Drawer
|
||||
title="💬 字幕样式配置"
|
||||
placement="right"
|
||||
width={380}
|
||||
styles={{ wrapper: { maxWidth: "100vw" } }}
|
||||
open={open}
|
||||
onClose={onClose}
|
||||
className="subtitle-style-drawer"
|
||||
>
|
||||
<div className="sub-field">
|
||||
<div className="sub-toggle-row">
|
||||
<span className="sub-label">启用字幕</span>
|
||||
<div
|
||||
className={`ep-toggle${config.enabled ? " active" : ""}`}
|
||||
onClick={() => update({ enabled: !config.enabled })}
|
||||
>
|
||||
<div className="ep-toggle-knob" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{config.enabled && (
|
||||
<>
|
||||
<div className="sub-field">
|
||||
<label className="sub-label">字幕来源</label>
|
||||
<SubtitleModeSwitch mode={config.mode} onModeChange={(mode) => update({ mode })} />
|
||||
</div>
|
||||
|
||||
{config.mode === "asr" && (
|
||||
<div className="sub-field">
|
||||
<label className="sub-label">识别语言</label>
|
||||
<Select
|
||||
className="sub-select"
|
||||
value={config.asrLanguage}
|
||||
onChange={(v) => update({ asrLanguage: v })}
|
||||
options={ASR_LANGUAGE_OPTIONS}
|
||||
popupMatchSelectWidth={false}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="sub-field">
|
||||
<label className="sub-label">
|
||||
字体大小 <span className="sub-value">{config.fontSize}px</span>
|
||||
</label>
|
||||
<Slider
|
||||
min={12}
|
||||
max={48}
|
||||
value={config.fontSize}
|
||||
onChange={(v) => update({ fontSize: v })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="sub-field">
|
||||
<label className="sub-label">字体颜色</label>
|
||||
<div className="sub-color-row">
|
||||
<ColorPicker
|
||||
value={config.fontColor}
|
||||
onChange={(_color: Color, hex: string) => update({ fontColor: hex })}
|
||||
showText
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="sub-field">
|
||||
<label className="sub-label">字体</label>
|
||||
<Select
|
||||
className="sub-select"
|
||||
value={config.font}
|
||||
onChange={(v) => update({ font: v })}
|
||||
options={FONT_OPTIONS.map((f) => ({ value: f, label: f }))}
|
||||
popupMatchSelectWidth={false}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="sub-field">
|
||||
<label className="sub-label">位置</label>
|
||||
<SubtitlePositionSelector
|
||||
position={config.position}
|
||||
onPositionChange={(position) => update({ position })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="sub-field">
|
||||
<label className="sub-label">效果</label>
|
||||
<SubtitleEffectButtons
|
||||
stroke={config.stroke}
|
||||
shadow={config.shadow}
|
||||
onStrokeChange={(stroke) => update({ stroke })}
|
||||
onShadowChange={(shadow) => update({ shadow })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="sub-field">
|
||||
<label className="sub-label">动画效果</label>
|
||||
<Select
|
||||
className="sub-select"
|
||||
value={config.animation}
|
||||
onChange={(v) => update({ animation: v })}
|
||||
options={ANIMATION_OPTIONS.map((o) => ({
|
||||
value: o.value,
|
||||
label: o.label,
|
||||
}))}
|
||||
popupMatchSelectWidth={false}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<SubtitlePreview config={config} />
|
||||
</>
|
||||
)}
|
||||
</Drawer>
|
||||
)
|
||||
}
|
||||
|
||||
export default SubtitleStylePanel
|
||||
Reference in New Issue
Block a user