auto-save 2026-05-13 19:45 (~3)
This commit is contained in:
@@ -2228,6 +2228,13 @@
|
|||||||
"type": "session-heartbeat",
|
"type": "session-heartbeat",
|
||||||
"message": "Codex 会话活跃 · 最近命令:codex · 3 项未提交变更 · 最近提交:auto-save 2026-05-13 19:34 (~4)",
|
"message": "Codex 会话活跃 · 最近命令:codex · 3 项未提交变更 · 最近提交:auto-save 2026-05-13 19:34 (~4)",
|
||||||
"files_changed": 3
|
"files_changed": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-13T19:39:46+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-13 19:39 (~3)",
|
||||||
|
"hash": "fddc83b",
|
||||||
|
"files_changed": 3
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -832,13 +832,13 @@ api/main.py
|
|||||||
<div class="changelog">
|
<div class="changelog">
|
||||||
<article class="change">
|
<article class="change">
|
||||||
<header>
|
<header>
|
||||||
<h3>2026-05-13 · 钉住关键帧详情不再触发尺寸跳变</h3>
|
<h3>2026-05-13 · 钉住关键帧详情改为左侧停靠</h3>
|
||||||
<span class="tag orange">KeyframePanelNode</span>
|
<span class="tag orange">KeyframePanelNode</span>
|
||||||
</header>
|
</header>
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<p><strong>问题:</strong>钉住时面板从 ReactFlow 画布节点切到浏览器上层浮层,原本被画布 zoom 缩放过的视觉尺寸会丢失,表现为突然放大或缩小。</p>
|
<p><strong>问题:</strong>钉住后仍像自由浮层一样停在画布附近,用户继续缩放画布或调整面板尺寸时容易把它和画布节点混在一起。</p>
|
||||||
<p><strong>改动:</strong>钉住瞬间只冻结当前屏幕缩放比例,不改面板自身 <code>framePanelScale</code>;右下角拖拽缩放也按冻结比例换算。</p>
|
<p><strong>改动:</strong>钉住后统一吸附到浏览器左侧边缘,脱离 ReactFlow 画布缩放;钉住瞬间把当前可见大小转换成面板真实尺寸,之后只由右下角拖拽或标题栏按钮调整。</p>
|
||||||
<p><strong>影响:</strong><code>web/components/nodes/index.tsx</code>;钉住只改变“是否跟随画布”,不再顺手改变面板大小。</p>
|
<p><strong>影响:</strong><code>web/components/nodes/index.tsx</code>;钉住语义从“原地浮在上层”改为“左侧停靠工作面板”。</p>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
<article class="change">
|
<article class="change">
|
||||||
|
|||||||
@@ -517,7 +517,6 @@ export function KeyframePanelNode({ data }: any) {
|
|||||||
const { getZoom } = useReactFlow()
|
const { getZoom } = useReactFlow()
|
||||||
const panelRef = useRef<HTMLDivElement>(null)
|
const panelRef = useRef<HTMLDivElement>(null)
|
||||||
const [pinRect, setPinRect] = useState<{ left: number; top: number }>({ left: 24, top: 72 })
|
const [pinRect, setPinRect] = useState<{ left: number; top: number }>({ left: 24, top: 72 })
|
||||||
const [pinScreenScale, setPinScreenScale] = useState(1)
|
|
||||||
if (!d.job || d.expandedFrame === null) return null
|
if (!d.job || d.expandedFrame === null) return null
|
||||||
const active = d.job.frames.find((f) => f.index === d.expandedFrame)
|
const active = d.job.frames.find((f) => f.index === d.expandedFrame)
|
||||||
const scale = d.framePanelScale ?? 1
|
const scale = d.framePanelScale ?? 1
|
||||||
@@ -532,14 +531,9 @@ export function KeyframePanelNode({ data }: any) {
|
|||||||
|
|
||||||
const togglePinned = () => {
|
const togglePinned = () => {
|
||||||
if (!pinned) {
|
if (!pinned) {
|
||||||
const rect = panelRef.current?.getBoundingClientRect()
|
const zoom = getZoom()
|
||||||
if (rect) {
|
setScale(scale * zoom)
|
||||||
setPinScreenScale(rect.width > 0 ? rect.width / panelWidth : 1)
|
setPinRect({ left: 16, top: 64 })
|
||||||
setPinRect({
|
|
||||||
left: Math.max(12, Math.min(window.innerWidth - Math.min(rect.width, window.innerWidth - 24), rect.left)),
|
|
||||||
top: Math.max(12, Math.min(window.innerHeight - 80, rect.top)),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
d.onFramePanelPinnedChange?.(!pinned)
|
d.onFramePanelPinnedChange?.(!pinned)
|
||||||
}
|
}
|
||||||
@@ -550,7 +544,7 @@ export function KeyframePanelNode({ data }: any) {
|
|||||||
const startX = e.clientX
|
const startX = e.clientX
|
||||||
const startY = e.clientY
|
const startY = e.clientY
|
||||||
const startScale = scale
|
const startScale = scale
|
||||||
const zoom = pinned ? pinScreenScale : getZoom()
|
const zoom = pinned ? 1 : getZoom()
|
||||||
const onMove = (ev: PointerEvent) => {
|
const onMove = (ev: PointerEvent) => {
|
||||||
const dx = (ev.clientX - startX) / zoom
|
const dx = (ev.clientX - startX) / zoom
|
||||||
const dy = (ev.clientY - startY) / zoom
|
const dy = (ev.clientY - startY) / zoom
|
||||||
@@ -581,7 +575,7 @@ export function KeyframePanelNode({ data }: any) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-1.5">
|
<div className="flex items-center gap-1.5">
|
||||||
<span className="mr-1 text-[10px] text-white/60">
|
<span className="mr-1 text-[10px] text-white/60">
|
||||||
{pinned ? "已钉住 · 切图不移动" : "拖动标题栏移动 · 可钉住"}
|
{pinned ? "已钉住左侧 · 不跟画布" : "拖动标题栏移动 · 可钉住"}
|
||||||
</span>
|
</span>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -591,7 +585,7 @@ export function KeyframePanelNode({ data }: any) {
|
|||||||
? "bg-white text-orange-600 shadow"
|
? "bg-white text-orange-600 shadow"
|
||||||
: "bg-white/10 text-white/85 hover:bg-white/20 hover:text-white"
|
: "bg-white/10 text-white/85 hover:bg-white/20 hover:text-white"
|
||||||
}`}
|
}`}
|
||||||
title={pinned ? "取消钉住,允许拖动" : "钉住面板,防止被拖动"}
|
title={pinned ? "取消钉住,回到画布节点" : "钉住到左侧,脱离画布缩放"}
|
||||||
>
|
>
|
||||||
<Pin className="h-3 w-3" />
|
<Pin className="h-3 w-3" />
|
||||||
</button>
|
</button>
|
||||||
@@ -658,12 +652,7 @@ export function KeyframePanelNode({ data }: any) {
|
|||||||
return createPortal(
|
return createPortal(
|
||||||
<div
|
<div
|
||||||
className="fixed z-[240]"
|
className="fixed z-[240]"
|
||||||
style={{
|
style={{ left: pinRect.left, top: pinRect.top }}
|
||||||
left: pinRect.left,
|
|
||||||
top: pinRect.top,
|
|
||||||
transform: `scale(${pinScreenScale})`,
|
|
||||||
transformOrigin: "top left",
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{panel}
|
{panel}
|
||||||
</div>,
|
</div>,
|
||||||
|
|||||||
Reference in New Issue
Block a user