feat: perimeter handles do resize on drag, dock on click (center button-only)

This commit is contained in:
Hermes Agent committed 2026-09-10 15:18:32 +02:00
1 parent 6393c276a0
commit 2dcb572b12
1 file changed
+42 -8
+42 -8
View File
@@ -97,6 +97,40 @@ function Plugin () {
refreshInfo() refreshInfo()
} }
// Клик-или-драг на периметральной ручке:
// - смещение курсора > CLICK_THRESHOLD px → ресайз (startResize + live drag через глобальный onPointerMove)
// - иначе (чистый клик) → док в соответствующую позицию (dockWindow)
// Центр НЕ входит в периметр — только кнопкой.
const CLICK_THRESHOLD = 4
function onHandleDown (e: PointerEvent, dir: string, dockPos: DockPosition) {
e.preventDefault()
e.stopPropagation()
const startX = e.clientX
const startY = e.clientY
let started = false
function move (ev: PointerEvent) {
if (!started) {
const dx = ev.clientX - startX
const dy = ev.clientY - startY
if (Math.sqrt(dx * dx + dy * dy) < CLICK_THRESHOLD) return
started = true
startResize(ev, dir)
// Считаем ресайз от исходной точки (до порога), а не от текущей (>порога).
resizeRef.current.startX = startX
resizeRef.current.startY = startY
}
// Дальше drag ведёт глобальный onPointerMove (resizeRef.active уже true).
}
function up () {
window.removeEventListener('pointermove', move)
window.removeEventListener('pointerup', up)
if (started) onPointerUpResize()
else dockWindow(dockPos)
}
window.addEventListener('pointermove', move)
window.addEventListener('pointerup', up)
}
useEffect(function () { useEffect(function () {
window.addEventListener('pointermove', onPointerMove) window.addEventListener('pointermove', onPointerMove)
window.addEventListener('pointerup', onPointerUpResize) window.addEventListener('pointerup', onPointerUpResize)
@@ -399,14 +433,14 @@ function Plugin () {
</div> </div>
{/* Ручки по периметру (4 края + 4 угла) — клик = док в эту позицию. {/* Ручки по периметру (4 края + 4 угла) — клик = док в эту позицию.
ВИДИМЫЕ для отладки (фиолетовые). Центр НЕ входит в периметр — только кнопкой. */} ВИДИМЫЕ для отладки (фиолетовые). Центр НЕ входит в периметр — только кнопкой. */}
<div onPointerDown={function (e: PointerEvent) { e.preventDefault(); e.stopPropagation(); dockWindow('top-left') }} style={{ position: 'fixed', top: -3, left: -3, width: 12, height: 12, zIndex: 3, background: 'rgba(211,168,255,0.6)', cursor: 'pointer' }} aria-hidden="true" /> <div onPointerDown={function (e: PointerEvent) { onHandleDown(e, 'top-left', 'top-left') }} style={{ position: 'fixed', top: -3, left: -3, width: 12, height: 12, zIndex: 3, background: 'rgba(211,168,255,0.6)', cursor: 'nwse-resize' }} aria-hidden="true" />
<div onPointerDown={function (e: PointerEvent) { e.preventDefault(); e.stopPropagation(); dockWindow('top-center') }} style={{ position: 'fixed', top: -3, left: '50%', transform: 'translateX(-50%)', width: 32, height: 10, zIndex: 3, background: 'rgba(211,168,255,0.6)', cursor: 'pointer' }} aria-hidden="true" /> <div onPointerDown={function (e: PointerEvent) { onHandleDown(e, 'top', 'top-center') }} style={{ position: 'fixed', top: -3, left: '50%', transform: 'translateX(-50%)', width: 32, height: 10, zIndex: 3, background: 'rgba(211,168,255,0.6)', cursor: 'ns-resize' }} aria-hidden="true" />
<div onPointerDown={function (e: PointerEvent) { e.preventDefault(); e.stopPropagation(); dockWindow('top-right') }} style={{ position: 'fixed', top: -3, right: -3, width: 12, height: 12, zIndex: 3, background: 'rgba(211,168,255,0.6)', cursor: 'pointer' }} aria-hidden="true" /> <div onPointerDown={function (e: PointerEvent) { onHandleDown(e, 'top-right', 'top-right') }} style={{ position: 'fixed', top: -3, right: -3, width: 12, height: 12, zIndex: 3, background: 'rgba(211,168,255,0.6)', cursor: 'nesw-resize' }} aria-hidden="true" />
<div onPointerDown={function (e: PointerEvent) { e.preventDefault(); e.stopPropagation(); dockWindow('center-left') }} style={{ position: 'fixed', top: '50%', left: -3, transform: 'translateY(-50%)', width: 10, height: 32, zIndex: 3, background: 'rgba(211,168,255,0.6)', cursor: 'pointer' }} aria-hidden="true" /> <div onPointerDown={function (e: PointerEvent) { onHandleDown(e, 'left', 'center-left') }} style={{ position: 'fixed', top: '50%', left: -3, transform: 'translateY(-50%)', width: 10, height: 32, zIndex: 3, background: 'rgba(211,168,255,0.6)', cursor: 'ew-resize' }} aria-hidden="true" />
<div onPointerDown={function (e: PointerEvent) { e.preventDefault(); e.stopPropagation(); dockWindow('center-right') }} style={{ position: 'fixed', top: '50%', right: -3, transform: 'translateY(-50%)', width: 10, height: 32, zIndex: 3, background: 'rgba(211,168,255,0.6)', cursor: 'pointer' }} aria-hidden="true" /> <div onPointerDown={function (e: PointerEvent) { onHandleDown(e, 'right', 'center-right') }} style={{ position: 'fixed', top: '50%', right: -3, transform: 'translateY(-50%)', width: 10, height: 32, zIndex: 3, background: 'rgba(211,168,255,0.6)', cursor: 'ew-resize' }} aria-hidden="true" />
<div onPointerDown={function (e: PointerEvent) { e.preventDefault(); e.stopPropagation(); dockWindow('bottom-left') }} style={{ position: 'fixed', bottom: -3, left: -3, width: 12, height: 12, zIndex: 3, background: 'rgba(211,168,255,0.6)', cursor: 'pointer' }} aria-hidden="true" /> <div onPointerDown={function (e: PointerEvent) { onHandleDown(e, 'bottom-left', 'bottom-left') }} style={{ position: 'fixed', bottom: -3, left: -3, width: 12, height: 12, zIndex: 3, background: 'rgba(211,168,255,0.6)', cursor: 'nesw-resize' }} aria-hidden="true" />
<div onPointerDown={function (e: PointerEvent) { e.preventDefault(); e.stopPropagation(); dockWindow('bottom-center') }} style={{ position: 'fixed', bottom: -3, left: '50%', transform: 'translateX(-50%)', width: 32, height: 10, zIndex: 3, background: 'rgba(211,168,255,0.6)', cursor: 'pointer' }} aria-hidden="true" /> <div onPointerDown={function (e: PointerEvent) { onHandleDown(e, 'bottom', 'bottom-center') }} style={{ position: 'fixed', bottom: -3, left: '50%', transform: 'translateX(-50%)', width: 32, height: 10, zIndex: 3, background: 'rgba(211,168,255,0.6)', cursor: 'ns-resize' }} aria-hidden="true" />
<div onPointerDown={function (e: PointerEvent) { e.preventDefault(); e.stopPropagation(); dockWindow('bottom-right') }} style={{ position: 'fixed', bottom: -3, right: -3, width: 12, height: 12, zIndex: 3, background: 'rgba(211,168,255,0.6)', cursor: 'pointer' }} aria-hidden="true" /> <div onPointerDown={function (e: PointerEvent) { onHandleDown(e, 'bottom-right', 'bottom-right') }} style={{ position: 'fixed', bottom: -3, right: -3, width: 12, height: 12, zIndex: 3, background: 'rgba(211,168,255,0.6)', cursor: 'nwse-resize' }} aria-hidden="true" />
</Fragment> </Fragment>
) )
} }