auto-save 2026-05-14 00:14 (+10, ~3)
This commit is contained in:
@@ -454,7 +454,6 @@ export default function Home() {
|
||||
data: nodeData,
|
||||
draggable: true,
|
||||
width: savedWidths[n.id] ?? n.w,
|
||||
style: { width: savedWidths[n.id] ?? n.w },
|
||||
})),
|
||||
)
|
||||
|
||||
@@ -463,7 +462,7 @@ export default function Home() {
|
||||
const widths: Record<string, number> = {}
|
||||
for (const n of nodes) {
|
||||
if (n.id === KEYFRAME_PANEL_ID) continue
|
||||
const w = (n.style?.width ?? n.width) as number | string | undefined
|
||||
const w = n.width
|
||||
if (typeof w === "number") widths[n.id] = Math.round(w)
|
||||
}
|
||||
try { window.localStorage.setItem(NODE_WIDTHS_KEY, JSON.stringify(widths)) } catch {}
|
||||
|
||||
@@ -1,32 +1,55 @@
|
||||
"use client"
|
||||
import { NodeResizeControl } from "@xyflow/react"
|
||||
import { type PointerEvent } from "react"
|
||||
import { useReactFlow } from "@xyflow/react"
|
||||
|
||||
/** 节点右边缘 resize 把手:高度跟随节点,宽度可拖(240–1200px)。平时透明,hover 显紫色细条。 */
|
||||
/** 节点右边缘 resize 把手:手写 pointer 事件改 node.width,自适应 viewport zoom,不走 xyflow NodeResizeControl(在 glass-node overflow:hidden 下不工作)。 */
|
||||
export function ResizeRight({ minWidth = 240, maxWidth = 1200 }: { minWidth?: number; maxWidth?: number }) {
|
||||
const { setNodes, getZoom } = useReactFlow()
|
||||
|
||||
const onPointerDown = (e: PointerEvent<HTMLDivElement>) => {
|
||||
console.log("[ResizeRight] pointerDown", e.clientX, e.clientY)
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
const target = e.currentTarget
|
||||
const nodeEl = target.closest(".react-flow__node") as HTMLElement | null
|
||||
const nodeId = nodeEl?.getAttribute("data-id")
|
||||
console.log("[ResizeRight] nodeId", nodeId)
|
||||
if (!nodeId || !nodeEl) return
|
||||
target.setPointerCapture(e.pointerId)
|
||||
|
||||
const startX = e.clientX
|
||||
const zoom = getZoom() || 1
|
||||
const startWidth = parseFloat(getComputedStyle(nodeEl).width) / zoom
|
||||
|
||||
const onMove = (ev: globalThis.PointerEvent) => {
|
||||
const dx = (ev.clientX - startX) / zoom
|
||||
const next = Math.max(minWidth, Math.min(maxWidth, startWidth + dx))
|
||||
console.log("[ResizeRight] move", dx, next)
|
||||
setNodes((nodes) => nodes.map((n) => (n.id === nodeId ? { ...n, width: next, style: { ...n.style, width: next } } : n)))
|
||||
}
|
||||
const onUp = () => {
|
||||
console.log("[ResizeRight] up")
|
||||
window.removeEventListener("pointermove", onMove)
|
||||
window.removeEventListener("pointerup", onUp)
|
||||
try { target.releasePointerCapture(e.pointerId) } catch {}
|
||||
}
|
||||
window.addEventListener("pointermove", onMove)
|
||||
window.addEventListener("pointerup", onUp)
|
||||
}
|
||||
|
||||
return (
|
||||
<NodeResizeControl
|
||||
position="right"
|
||||
minWidth={minWidth}
|
||||
maxWidth={maxWidth}
|
||||
<div
|
||||
onPointerDown={onPointerDown}
|
||||
title="拖动调整宽度"
|
||||
className="nodrag absolute z-20 hover:bg-violet-400/60 active:bg-violet-400/80 transition rounded-r"
|
||||
style={{
|
||||
background: "transparent",
|
||||
border: "none",
|
||||
width: 10,
|
||||
height: "calc(100% - 24px)", // 留出顶部 source Handle 圆点的 hover 空间
|
||||
right: 0, // hit area 完全在节点内侧右边 10px(ReactFlow wrapper 不允许外溢)
|
||||
right: 0,
|
||||
top: 12,
|
||||
transform: "none",
|
||||
zIndex: 20, // 高于 ReactFlow handle 默认 z-index
|
||||
bottom: 12,
|
||||
width: 6,
|
||||
cursor: "ew-resize",
|
||||
touchAction: "none",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="absolute right-0 top-0 h-full w-1 hover:w-1.5 bg-transparent hover:bg-violet-400/70 active:bg-violet-400 transition-all rounded-r"
|
||||
style={{ cursor: "ew-resize" }}
|
||||
/>
|
||||
<div
|
||||
className="w-full h-full"
|
||||
style={{ cursor: "ew-resize" }}
|
||||
/>
|
||||
</NodeResizeControl>
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user