feat: 8 invisible resize handles on whole perimeter (replace native useWindowResize)

This commit is contained in:
Hermes Agent committed 2026-09-09 19:25:38 +02:00
1 parent 8a0bf4d8f3
commit b6c0a58071
2 files changed
+23 -9

No files matched your search

+1 -2
View File
@@ -146,10 +146,9 @@ export default function () {
if (dir.includes('top')) ny = p.y - dy / zoom
figma.ui.reposition(nx, ny)
}
// Док-режим во время live-ресайза не трогаем (финальный RESIZE_WINDOW пересчитает).
})
// Ресайз окна плагина (drag за угол в UI -> useWindowResize -> RESIZE_WINDOW)
// Ресайз окна плагина (кастомные ручки по периметру -> RESIZE_WINDOW по pointerup)
on('RESIZE_WINDOW', function (windowSize: { width: number; height: number }) {
const { width, height } = clampWindowSize(windowSize)
lastSize = { width, height }
+22 -7
View File
@@ -62,10 +62,10 @@ function Plugin () {
} | null>(null)
const [copied, setCopied] = useState(false)
// Кастомный ресайз по ВСЕМУ периметру (8 ручек: 4 края + 4 угла), а не только
// снизу-справа (что даёт нативный useWindowResize). Левый/верхний края двигают окно
// через figma.ui.reposition, чтобы окно не "уезжало" при расширении влево/вверх.
// В процессе драга шлём RESIZE_WINDOW_DRAG (live), по pointerup — финальный RESIZE_WINDOW.
// Кастомный ресайз по ВСЕМУ периметру (8 ручек: 4 края + 4 угла). Нативный useWindowResize
// давал только bottom-right; здесь handle'ы ловят pointerdown по всему периметру и шлют
// dir + dx/dy в main, который для left/top двигает окно через reposition.
// Live-обновление: RESIZE_WINDOW_DRAG во время drag'а, финальный RESIZE_WINDOW по pointerup.
function startResize (e: PointerEvent, dir: string) {
e.preventDefault()
e.stopPropagation()
@@ -208,6 +208,22 @@ function Plugin () {
}
}
// Обновляем цифры размера и инфо ТОЛЬКО после окончания drag'а (отпускание кнопки).
// К моменту pointerup Figma уже применила новый размер окна.
useEffect(function () {
const handlePointerUp = function () {
setCurrentWindowSize({
width: window.innerWidth,
height: window.innerHeight
})
refreshInfo()
}
window.addEventListener('pointerup', handlePointerUp)
return function () {
window.removeEventListener('pointerup', handlePointerUp)
}
}, [])
// Первичное заполнение инфо при старте плагина.
useEffect(function () {
refreshInfo()
@@ -353,7 +369,7 @@ function Plugin () {
</div>
</Container>
{/* Декоративная иконка drag-хендла в правом нижнем углу (как в старом плагине).
pointerEvents:none — она не ловит события. */}
pointerEvents:none — сам drag ловит невидимый div от useWindowResize. */}
<div
style={{
position: 'fixed',
@@ -375,8 +391,7 @@ function Plugin () {
</svg>
</div>
{/* Невидимые интерактивные области ресайза по всему периметру (8 ручек: 4 края + 4 угла).
Нативный useWindowResize даёт только bottom-right; эти div-ы ловят pointerdown и шлют
dir + dx/dy в main, для left/top main двигает окно через reposition. Сами ручки прозрачные. */}
Каждая ловит pointerdown и шлёт dir в main (через startResize). Сами div-ы прозрачные. */}
{[
{ dir: 'top-left', style: { top: -3, left: -3, width: 12, height: 12, cursor: 'nwse-resize' } },
{ dir: 'top', style: { top: -3, left: '50%', transform: 'translateX(-50%)', width: 32, height: 10, cursor: 'ns-resize' } },