feat(timeline): P2 并行编排——scene 多轨编辑器 + 白模重叠预览
剧情 Timeline P2 前端 + 共享内核(与 SGame 源真同步): - ir_core/IR_SCHEMA/样张:scene v0.3 + scene 校验 + 导出 gate(D3),与 SGame 仓逐字一致 - timeline.js:appendScene 按 authored start 铺多轨 clip(自然重叠预览),move from 同 actor 跨轨续连(D4); drawStage 改逐 actor 查对话→多人气泡同时计时;导出 _clipDur 纯函数;show() 加 startId 参;常量加 CAMERA_DUR - scene_edit.js(新):演出段编辑模态——拖 clip 改 start(吸附 0.1s)、拖右缘改 dur、增删 clip/轨道、 选中属性条精确编辑、客户端轻量 lint(镜像 validate.py)、▶ 预览此段(复用播放核) - graph.js:scene 节点(KIND_CN/summary/nodeInner 列轨道)+双击进编辑模态 - form.js:右栏 renderScene 精确数值编辑(轨道/clip 的 start/dur/kind/目标)+打开编辑器按钮 - app.py export:捕获 CompileError 并入 report(scene 被拦时不再 500) - test_scene.js:离线 10 断言全过(重叠确凿/晚 1.5s 起步/from 续连);gitignore 忽略本地 _localdemo.db 待浏览器目测拖拽编辑落 IR + 白模重叠演出。
This commit is contained in:
@ -325,3 +325,62 @@ body.perform-mode .mode-switch { border-color:#2f7a60; }
|
||||
.tl-clip.k-stop { background:#d87878; color:#fff; }
|
||||
.tl-playhead { position:absolute; top:0; bottom:0; width:2px; background:#ff5a4a;
|
||||
pointer-events:none; z-index:4; box-shadow:0 0 4px rgba(255,90,74,.7); }
|
||||
|
||||
/* ===== 演出段 scene 节点(分支图)===== */
|
||||
#drawflow .kind-scene { background:#16241f; border-color:#3a7a64; }
|
||||
#drawflow .kind-scene .nlabel { color:#7ee3c8; }
|
||||
.drawflow-node .scenebody { padding-top:2px; }
|
||||
.drawflow-node .scenebody .screl { font-size:11px; color:#bfe6d8; line-height:1.5; }
|
||||
.drawflow-node .scenebody .screl.more { color:#7a8a82; }
|
||||
.drawflow-node .scenebody .schint { font-size:10px; color:#5a8a7a; margin-top:3px; font-style:italic; }
|
||||
|
||||
/* ===== 演出段编辑模态 ===== */
|
||||
.scene-edit { width:92vw; max-width:1280px; max-height:92vh; }
|
||||
.se-psinfo { font-size:12px; color:#9a907e; font-weight:normal; }
|
||||
.se-toolbar { display:flex; align-items:center; gap:10px; margin:4px 0 8px; flex-wrap:wrap; }
|
||||
.se-toolbar .se-tip { font-size:11px; color:#8a8275; }
|
||||
.se-toolbar .se-total { margin-left:auto; font-size:12px; color:#e6c878; }
|
||||
.se-trackswrap { overflow-x:auto; background:#15130d; border:1px solid #2a2419; border-radius:6px; padding-bottom:4px; }
|
||||
.se-ruler { position:relative; height:16px; border-bottom:1px solid #2a2419; min-width:100%; }
|
||||
.se-tick { position:absolute; top:0; height:16px; border-left:1px solid #2a2419; }
|
||||
.se-tick span { font-size:9px; color:#6a6256; padding-left:3px; }
|
||||
.se-lanes { position:relative; min-width:100%; }
|
||||
.se-lane { position:relative; border-bottom:1px solid #211c15; }
|
||||
.se-lane-label { position:sticky; left:0; z-index:5; display:inline-flex; align-items:center; gap:3px;
|
||||
width:54px; height:100%; background:#1d1810; color:#d8cda0; font-size:11px; padding:0 3px;
|
||||
border-right:1px solid #2a2419; box-sizing:border-box; }
|
||||
.se-lane-label button { background:none; border:none; color:#9a8f78; cursor:pointer; font-size:11px; padding:0 1px; }
|
||||
.se-lane-label .se-addclip:hover { color:#7ee3c8; }
|
||||
.se-lane-label .se-deltrack:hover { color:#e38f7e; }
|
||||
.se-clip { position:absolute; top:5px; height:24px; line-height:24px; padding:0 6px; border-radius:4px;
|
||||
font-size:11px; color:#1a1710; white-space:nowrap; overflow:hidden; cursor:grab; user-select:none;
|
||||
box-shadow:0 1px 3px rgba(0,0,0,.5); }
|
||||
.se-clip.sel { box-shadow:0 0 0 2px #ff5a4a, 0 1px 3px rgba(0,0,0,.5); z-index:3; }
|
||||
.se-clip.k-dialogue { background:#7ec8e3; }
|
||||
.se-clip.k-move { background:#e6c878; }
|
||||
.se-clip.k-anim { background:#9ee37e; }
|
||||
.se-clip.k-camera { background:#c89ee3; }
|
||||
.se-clip.k-wait { background:#9a9488; color:#fff; }
|
||||
.se-resize { position:absolute; top:0; right:0; width:7px; height:100%; cursor:ew-resize; background:rgba(0,0,0,.18); border-radius:0 4px 4px 0; }
|
||||
.se-empty, .se-prop-empty { padding:14px; color:#8a8275; font-size:12px; text-align:center; }
|
||||
.se-lint { margin:8px 0 4px; font-size:11.5px; padding:5px 8px; border-radius:5px; }
|
||||
.se-lint.ok { color:#7ee3a0; background:rgba(60,120,80,.12); }
|
||||
.se-lint.bad { color:#f0b070; background:rgba(160,90,40,.14); }
|
||||
.se-prop { background:#19150f; border:1px solid #2a2419; border-radius:6px; padding:8px; min-height:40px; }
|
||||
.se-prop-row { display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
|
||||
.se-prop-kind { font-size:12px; color:#e6c878; font-weight:bold; }
|
||||
.se-f { font-size:11px; color:#a89e88; display:flex; align-items:center; gap:4px; }
|
||||
.se-f input, .se-f select { width:auto; min-width:64px; background:#221d16; color:#e8e0d4; border:1px solid #3a3326; border-radius:4px; padding:2px 4px; font-size:12px; }
|
||||
.se-f input[type=number] { width:64px; }
|
||||
.se-delclip { margin-left:auto; color:#e38f7e !important; }
|
||||
.se-preview { margin-top:10px; }
|
||||
.se-prev-head { font-size:12px; color:#7ee3c8; margin-bottom:4px; }
|
||||
.se-prev-host { height:560px; background:#100e09; border:1px solid #2a2419; border-radius:6px; overflow:hidden; position:relative; }
|
||||
|
||||
/* scene 右栏 clip 行(form.js 精确数值编辑) */
|
||||
.se-cliprow { display:flex; align-items:flex-end; gap:5px; flex-wrap:wrap; padding:5px 0; border-top:1px dashed #2a2419; }
|
||||
.se-cliprow .fld { margin:0; }
|
||||
.se-cliprow .fld label { font-size:10px; }
|
||||
.se-cliprow input[type=number] { width:52px; }
|
||||
.se-cliprow select { min-width:60px; }
|
||||
#edit-pane .optdet-like { border:1px solid #2a2419; border-radius:5px; padding:6px; margin-bottom:6px; }
|
||||
|
||||
Reference in New Issue
Block a user