第三个页签(与海选审核/演出配置平级),只读查看每个点位集里各点的真实
位置/朝向,配 move.to/camera.focus 时对照用,不必回 Unity 翻 json。
- pointview.js: 独立白模点位查看器(按 kind 上色/朝向箭头/悬停坐标/侧栏清单);
有底图则把正交俯视真实场景图当画布底图、点位按 shot.bounds 线性投上去
(像素级对齐家具),带显隐开关;无底图回退黑底白模。
- app.py: /api/pointsets 给有底图的点位集附 shot{url,bounds};新增
/sceneshot/{name}.png 路由(防目录穿越)。
- Dockerfile/compose: 加 STORY_SCENESHOTS_DIR(/sceneshots) env + 挂载点与注释。
底图由 SGame 仓新增 Editor 工具「剧情场景俯视抓拍」产出
({name}.png + {name}.shot.json,map-local 覆盖范围)。
156 lines
5.8 KiB
HTML
156 lines
5.8 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>Story 协作编辑器 · M5</title>
|
||
<link rel="stylesheet" href="vendor/drawflow.min.css">
|
||
<link rel="stylesheet" href="style.css">
|
||
</head>
|
||
<body>
|
||
|
||
<!-- 登录遮罩 -->
|
||
<div id="login" class="overlay">
|
||
<div class="login-box">
|
||
<h2>剧情事件协作编辑器</h2>
|
||
<p class="hint">输入你的专属口令进入(口令即身份,改动记录自动署名)</p>
|
||
<input id="login-pass" type="password" placeholder="专属口令" autocomplete="off">
|
||
<button id="login-btn">进入</button>
|
||
<div id="login-err" class="err"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<header>
|
||
<h1>剧情事件协作编辑器 <span class="ver">M5</span></h1>
|
||
<div class="mode-switch">
|
||
<button id="mode-review" class="mode-btn active">海选审核</button>
|
||
<button id="mode-perform" class="mode-btn">演出配置</button>
|
||
<button id="mode-points" class="mode-btn">场景/点位</button>
|
||
</div>
|
||
<div class="toolbar" id="review-toolbar">
|
||
<button id="btn-save" class="primary" disabled>保存</button>
|
||
<button id="btn-validate" disabled>校验</button>
|
||
<button id="btn-playtest" disabled>试走</button>
|
||
<span class="sep"></span>
|
||
<button id="btn-confirm" disabled>确认</button>
|
||
<button id="btn-discard" disabled>丢弃</button>
|
||
<span class="sep"></span>
|
||
<button id="btn-import">导入 IR</button>
|
||
<button id="btn-export">导出 confirmed</button>
|
||
</div>
|
||
<span class="who" id="who"></span>
|
||
</header>
|
||
|
||
<div id="wrap">
|
||
<!-- 左:事件列表 -->
|
||
<aside id="list-pane">
|
||
<div class="filters">
|
||
<select id="filter-status">
|
||
<option value="all">全部</option>
|
||
<option value="pending">待审</option>
|
||
<option value="confirmed">已确认</option>
|
||
<option value="discarded">已丢弃</option>
|
||
</select>
|
||
<input id="search" type="text" placeholder="搜索标题/group">
|
||
</div>
|
||
<div id="event-list"></div>
|
||
</aside>
|
||
|
||
<!-- 中:分支图(Drawflow 可拖拽连线) -->
|
||
<main id="graph-pane">
|
||
<div id="graph-tools">
|
||
<button id="btn-undo" class="mini" disabled title="撤销 (Ctrl+Z)">↶ 撤销</button>
|
||
<button id="btn-redo" class="mini" disabled title="重做 (Ctrl+Y)">↷ 重做</button>
|
||
<span class="gsep"></span>
|
||
<button id="btn-autolayout" class="mini" disabled title="自动整理布局 (R)">自动整理</button>
|
||
<button id="btn-addsucc" class="mini" disabled title="给选中节点加后继 (Enter)">加后继</button>
|
||
<span class="tip">拖出口圆点→目标=连跳转 · 拖动摆位 · Del 删除 · R 整理 · Enter 加后继 · Ctrl+Z/Y 撤销重做</span>
|
||
</div>
|
||
<div id="drawflow"></div>
|
||
<div id="graph-empty" class="empty-center">从左侧选择一个事件</div>
|
||
</main>
|
||
|
||
<!-- 右:表单编辑 -->
|
||
<section id="edit-pane">
|
||
<div id="meta-edit"></div>
|
||
<div class="sec-title">节点编辑 <button id="btn-addnode" class="mini" disabled>+节点</button></div>
|
||
<div id="node-edit"><div class="empty">点击中间任意节点进行编辑</div></div>
|
||
</section>
|
||
</div>
|
||
|
||
<!-- 演出配置页(仅已确认事件;当前=预览,P2 起在此配置演出细节)-->
|
||
<div id="perform-wrap" class="hidden">
|
||
<aside id="perform-list-pane">
|
||
<div class="perform-listhead">已确认事件 · 演出配置</div>
|
||
<div id="perform-list"></div>
|
||
</aside>
|
||
<main id="perform-main">
|
||
<div id="perform-empty" class="empty-center">从左侧选择一个已确认事件,预览其演出(后续在此配置细节)</div>
|
||
</main>
|
||
</div>
|
||
|
||
<!-- 场景/点位页(只读:看每个点位集里各点的真实位置/朝向,配 move.to 时对照用)-->
|
||
<div id="points-wrap" class="hidden">
|
||
<aside id="points-list-pane">
|
||
<div class="perform-listhead">场景点位集</div>
|
||
<div id="points-set-list"></div>
|
||
</aside>
|
||
<main id="points-main">
|
||
<div id="points-empty" class="empty-center">从左侧选择一个点位集,查看其中各点的位置与朝向</div>
|
||
<div id="points-view"></div>
|
||
</main>
|
||
</div>
|
||
|
||
<!-- 校验结果遮罩 -->
|
||
<div id="validate-modal" class="overlay hidden">
|
||
<div class="modal">
|
||
<h3>校验结果</h3>
|
||
<div id="validate-body"></div>
|
||
<button class="modal-close">关闭</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 导入遮罩 -->
|
||
<div id="import-modal" class="overlay hidden">
|
||
<div class="modal">
|
||
<h3>导入 IR(选择一个或多个 JSON 文件)</h3>
|
||
<div id="import-drop" class="drop">
|
||
<p>点击选择文件,或把 .json 文件拖到这里</p>
|
||
<p class="hint">每个文件可为单个事件对象,或事件数组;支持多选</p>
|
||
<input id="import-file" type="file" accept=".json,application/json" multiple hidden>
|
||
</div>
|
||
<div id="import-files" class="filelist"></div>
|
||
<details class="import-paste">
|
||
<summary>或粘贴 JSON 文本</summary>
|
||
<textarea id="import-text" placeholder='{"id":"QY_XXX", ...} 或 [ {...}, {...} ]'></textarea>
|
||
</details>
|
||
<div class="modal-actions">
|
||
<button id="import-do" class="primary">导入</button>
|
||
<button class="modal-close">取消</button>
|
||
</div>
|
||
<div id="import-result" class="err"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 试走遮罩 -->
|
||
<div id="playtest-modal" class="overlay hidden">
|
||
<div class="modal wide">
|
||
<h3>剧本试走 <button class="modal-close" style="float:right">关闭</button></h3>
|
||
<div id="pt-layout">
|
||
<div id="pt-flow"></div>
|
||
<div id="pt-ledger"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script src="vendor/drawflow.min.js"></script>
|
||
<script src="graph.js"></script>
|
||
<script src="form.js"></script>
|
||
<script src="playtest.js"></script>
|
||
<script src="timeline.js"></script>
|
||
<script src="scene_edit.js"></script>
|
||
<script src="pointview.js"></script>
|
||
<script src="app.js"></script>
|
||
</body>
|
||
</html>
|