From 9f61f760193a742e28e5e903b8505480720f6364 Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Mon, 27 Jul 2026 09:17:16 +0800 Subject: [PATCH 1/2] =?UTF-8?q?refactor(editing-planner):=20=E6=8B=86?= =?UTF-8?q?=E5=88=86=20LayerConfig=20=E7=BB=84=E4=BB=B6=EF=BC=8C=E6=8C=89?= =?UTF-8?q?=E8=81=8C=E8=B4=A3=E6=8B=86=E4=B8=BA=203=20=E4=B8=AA=E5=AD=90?= =?UTF-8?q?=E9=9D=A2=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 主文件 286→55 行(-81%),拆分为: - PipPreview: 图层迷你预览 - LayerPositionSize: 素材类型/URL/位置/尺寸/圆角/透明度 - LayerTimingAnimation: 时间/入场动画/滑入方向 - index: 组合入口 导入路径保持向后兼容 --- .../components/pip-config/LayerConfig.tsx | 286 ------------------ .../layer-config/LayerPositionSize.tsx | 172 +++++++++++ .../layer-config/LayerTimingAnimation.tsx | 87 ++++++ .../pip-config/layer-config/PipPreview.tsx | 33 ++ .../pip-config/layer-config/index.tsx | 57 ++++ 5 files changed, 349 insertions(+), 286 deletions(-) delete mode 100755 apps/web/src/pages/editing-planner/components/pip-config/LayerConfig.tsx create mode 100644 apps/web/src/pages/editing-planner/components/pip-config/layer-config/LayerPositionSize.tsx create mode 100644 apps/web/src/pages/editing-planner/components/pip-config/layer-config/LayerTimingAnimation.tsx create mode 100644 apps/web/src/pages/editing-planner/components/pip-config/layer-config/PipPreview.tsx create mode 100644 apps/web/src/pages/editing-planner/components/pip-config/layer-config/index.tsx diff --git a/apps/web/src/pages/editing-planner/components/pip-config/LayerConfig.tsx b/apps/web/src/pages/editing-planner/components/pip-config/LayerConfig.tsx deleted file mode 100755 index 2fb7842c5..000000000 --- a/apps/web/src/pages/editing-planner/components/pip-config/LayerConfig.tsx +++ /dev/null @@ -1,286 +0,0 @@ -/** - * 混剪单图层配置区 - */ -import React from "react" -import type { - PipLayer, - PipAnimType, - PipSlideDirection, - PipGridPosition, -} from "@/pages/editing-planner/types" -import { - GRID_POSITIONS, - ANIM_OPTIONS, - SLIDE_DIR_OPTIONS, - LAYER_COLORS, -} from "@/pages/editing-planner/constants/pipConfig" - -interface LayerConfigProps { - layer: PipLayer | null - layers: PipLayer[] - totalDuration: number - onUpdate: (id: string, partial: Partial) => void - onGridClick: (pos: PipGridPosition) => void - onWidthChange: (val: number) => void - onHeightChange: (val: number) => void -} - -const LayerConfig: React.FC = ({ - layer, - layers, - totalDuration, - onUpdate, - onGridClick, - onWidthChange, - onHeightChange, -}) => { - if (!layer) { - return ( -
-
选择或添加图层以配置
-
- ) - } - - return ( -
- {/* ── 迷你预览 ── */} -
- {layers.map((l, idx) => ( -
- {l.name} -
- ))} -
- - {/* ── 素材类型 ── */} -
- -
- - -
-
- - {/* ── 素材 URL ── */} -
- - onUpdate(layer.id, { material_url: e.target.value })} - /> -
- - {/* ── 位置:九宫格 + 坐标 ── */} -
- -
-
- {GRID_POSITIONS.map((pos) => ( - - ))} -
-
-
- - onUpdate(layer.id, { x: Number(e.target.value) })} - /> -
-
- - onUpdate(layer.id, { y: Number(e.target.value) })} - /> -
-
-
-
- - {/* ── 尺寸 ── */} -
- -
- - onWidthChange(Number(e.target.value))} - /> - {layer.width}% -
-
- - onHeightChange(Number(e.target.value))} - /> - {layer.height}% -
-
onUpdate(layer.id, { aspect_lock: !layer.aspect_lock })} - > - {layer.aspect_lock ? "🔒" : "🔓"} - {layer.aspect_lock ? "已锁定比例" : "锁定宽高比"} -
-
- - {/* ── 圆角 ── */} -
- -
- onUpdate(layer.id, { border_radius: Number(e.target.value) })} - /> - {layer.border_radius}% -
-
- - {/* ── 透明度 ── */} -
- -
- onUpdate(layer.id, { opacity: Number(e.target.value) })} - /> - {layer.opacity}% -
-
- - {/* ── 时间 ── */} -
- -
-
- - onUpdate(layer.id, { start_time: Number(e.target.value) })} - /> -
-
- - onUpdate(layer.id, { duration: Number(e.target.value) })} - /> -
-
-
- - {/* ── 入场动画 ── */} -
- - -
- - {/* 滑入方向(仅 slide_in 时显示) */} - {layer.animation === "slide_in" && ( -
- - -
- )} -
- ) -} - -export default LayerConfig diff --git a/apps/web/src/pages/editing-planner/components/pip-config/layer-config/LayerPositionSize.tsx b/apps/web/src/pages/editing-planner/components/pip-config/layer-config/LayerPositionSize.tsx new file mode 100644 index 000000000..6c6eb10a6 --- /dev/null +++ b/apps/web/src/pages/editing-planner/components/pip-config/layer-config/LayerPositionSize.tsx @@ -0,0 +1,172 @@ +import React from "react" +import type { PipLayer, PipGridPosition } from "@/pages/editing-planner/types" +import { GRID_POSITIONS } from "@/pages/editing-planner/constants/pipConfig" + +interface LayerPositionSizeProps { + layer: PipLayer + onUpdate: (id: string, partial: Partial) => void + onGridClick: (pos: PipGridPosition) => void + onWidthChange: (val: number) => void + onHeightChange: (val: number) => void +} + +/** + * 图层位置与尺寸配置面板 + */ +export const LayerPositionSize: React.FC = ({ + layer, + onUpdate, + onGridClick, + onWidthChange, + onHeightChange, +}) => ( + <> + {/* 素材类型 */} +
+ +
+ + +
+
+ + {/* 素材 URL */} +
+ + onUpdate(layer.id, { material_url: e.target.value })} + /> +
+ + {/* 位置:九宫格 + 坐标 */} +
+ +
+
+ {GRID_POSITIONS.map((pos) => ( + + ))} +
+
+
+ + onUpdate(layer.id, { x: Number(e.target.value) })} + /> +
+
+ + onUpdate(layer.id, { y: Number(e.target.value) })} + /> +
+
+
+
+ + {/* 尺寸 */} +
+ +
+ + onWidthChange(Number(e.target.value))} + /> + {layer.width}% +
+
+ + onHeightChange(Number(e.target.value))} + /> + {layer.height}% +
+
onUpdate(layer.id, { aspect_lock: !layer.aspect_lock })} + > + {layer.aspect_lock ? "🔒" : "🔓"} + {layer.aspect_lock ? "已锁定比例" : "锁定宽高比"} +
+
+ + {/* 圆角 */} +
+ +
+ onUpdate(layer.id, { border_radius: Number(e.target.value) })} + /> + {layer.border_radius}% +
+
+ + {/* 透明度 */} +
+ +
+ onUpdate(layer.id, { opacity: Number(e.target.value) })} + /> + {layer.opacity}% +
+
+ +) diff --git a/apps/web/src/pages/editing-planner/components/pip-config/layer-config/LayerTimingAnimation.tsx b/apps/web/src/pages/editing-planner/components/pip-config/layer-config/LayerTimingAnimation.tsx new file mode 100644 index 000000000..a9138f5bc --- /dev/null +++ b/apps/web/src/pages/editing-planner/components/pip-config/layer-config/LayerTimingAnimation.tsx @@ -0,0 +1,87 @@ +import React from "react" +import type { PipLayer, PipAnimType, PipSlideDirection } from "@/pages/editing-planner/types" +import { ANIM_OPTIONS, SLIDE_DIR_OPTIONS } from "@/pages/editing-planner/constants/pipConfig" + +interface LayerTimingAnimationProps { + layer: PipLayer + totalDuration: number + onUpdate: (id: string, partial: Partial) => void +} + +/** + * 图层时间与动画配置面板 + */ +export const LayerTimingAnimation: React.FC = ({ + layer, + totalDuration, + onUpdate, +}) => ( + <> + {/* 时间 */} +
+ +
+
+ + onUpdate(layer.id, { start_time: Number(e.target.value) })} + /> +
+
+ + onUpdate(layer.id, { duration: Number(e.target.value) })} + /> +
+
+
+ + {/* 入场动画 */} +
+ + +
+ + {/* 滑入方向(仅 slide_in 时显示) */} + {layer.animation === "slide_in" && ( +
+ + +
+ )} + +) diff --git a/apps/web/src/pages/editing-planner/components/pip-config/layer-config/PipPreview.tsx b/apps/web/src/pages/editing-planner/components/pip-config/layer-config/PipPreview.tsx new file mode 100644 index 000000000..6f4356eec --- /dev/null +++ b/apps/web/src/pages/editing-planner/components/pip-config/layer-config/PipPreview.tsx @@ -0,0 +1,33 @@ +import React from "react" +import type { PipLayer } from "@/pages/editing-planner/types" +import { LAYER_COLORS } from "@/pages/editing-planner/constants/pipConfig" + +interface PipPreviewProps { + layers: PipLayer[] + selectedId: string +} + +/** + * PIP 图层迷你预览组件 + */ +export const PipPreview: React.FC = ({ layers, selectedId }) => ( +
+ {layers.map((l, idx) => ( +
+ {l.name} +
+ ))} +
+) diff --git a/apps/web/src/pages/editing-planner/components/pip-config/layer-config/index.tsx b/apps/web/src/pages/editing-planner/components/pip-config/layer-config/index.tsx new file mode 100644 index 000000000..4f522e8cb --- /dev/null +++ b/apps/web/src/pages/editing-planner/components/pip-config/layer-config/index.tsx @@ -0,0 +1,57 @@ +/** + * 混剪单图层配置区 + */ +import React from "react" +import type { PipLayer, PipGridPosition } from "@/pages/editing-planner/types" +import { PipPreview } from "./PipPreview" +import { LayerPositionSize } from "./LayerPositionSize" +import { LayerTimingAnimation } from "./LayerTimingAnimation" + +interface LayerConfigProps { + layer: PipLayer | null + layers: PipLayer[] + totalDuration: number + onUpdate: (id: string, partial: Partial) => void + onGridClick: (pos: PipGridPosition) => void + onWidthChange: (val: number) => void + onHeightChange: (val: number) => void +} + +const LayerConfig: React.FC = ({ + layer, + layers, + totalDuration, + onUpdate, + onGridClick, + onWidthChange, + onHeightChange, +}) => { + if (!layer) { + return ( +
+
选择或添加图层以配置
+
+ ) + } + + return ( +
+ {/* 迷你预览 */} + + + {/* 位置与尺寸 */} + + + {/* 时间与动画 */} + +
+ ) +} + +export default LayerConfig -- 2.54.0 From 2023ddc8cfa2531fa8b17cd4e5d4ea914d7f7601 Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Mon, 27 Jul 2026 12:41:35 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20=E6=81=A2=E5=A4=8D=20LayerConfig.tsx?= =?UTF-8?q?=20=E4=B8=BB=E5=85=A5=E5=8F=A3=EF=BC=8Cre-export=20=E5=AD=90?= =?UTF-8?q?=E7=9B=AE=E5=BD=95=E4=BF=9D=E6=8C=81=E8=B7=AF=E5=BE=84=E5=85=BC?= =?UTF-8?q?=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../editing-planner/components/pip-config/LayerConfig.tsx | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 apps/web/src/pages/editing-planner/components/pip-config/LayerConfig.tsx diff --git a/apps/web/src/pages/editing-planner/components/pip-config/LayerConfig.tsx b/apps/web/src/pages/editing-planner/components/pip-config/LayerConfig.tsx new file mode 100644 index 000000000..7800c4f8c --- /dev/null +++ b/apps/web/src/pages/editing-planner/components/pip-config/LayerConfig.tsx @@ -0,0 +1,5 @@ +/** + * LayerConfig 入口(向后兼容) + * 实际实现位于 ./layer-config/ 目录 + */ +export { default } from "./layer-config" -- 2.54.0