fix: manual resize no longer resets on pointerup (canonical vs hold mode)
This commit is contained in:
1 parent
20777fb0de
commit
6901c5e0cd
1 file changed
+49
-24
+49
-24
@@ -38,7 +38,12 @@ export default function () {
|
||||
// Возвращает размер (экранные px) и позицию (canvas-space, прижатую к нужному краю).
|
||||
const DEFAULT_DOCK_EDGE = 320
|
||||
let dockEdgeSize = DEFAULT_DOCK_EDGE // редактируемая фикс-сторона для edge-позиций (320 по умолч.)
|
||||
function computeDock (position: DockPosition, currentWidth: number, currentHeight: number) {
|
||||
// computeDock считает целевой размер+позицию для док-позиции.
|
||||
// canonical=true — НАЖАТИЕ кнопки дока: задаём канонический размер
|
||||
// (edge: фикс-сторона dockEdgeSize, другая = max viewport; center: 50%).
|
||||
// canonical=false — удержание/ресайз: сохраняем РУЧНОЙ размер (currentW/H),
|
||||
// только клампим в пределы viewport. Так ручной ресайз "прилипает" и не сбрасывается.
|
||||
function computeDock (position: DockPosition, currentWidth: number, currentHeight: number, canonical: boolean = false) {
|
||||
const b = figma.viewport.bounds
|
||||
const zoom = figma.viewport.zoom || 1
|
||||
const maxW = Math.round(b.width * zoom)
|
||||
@@ -52,13 +57,13 @@ export default function () {
|
||||
let targetH = currentHeight
|
||||
if (isLeftRight) {
|
||||
targetW = dockEdgeSize
|
||||
targetH = maxH
|
||||
targetH = canonical ? maxH : Math.min(currentHeight, maxH)
|
||||
} else if (isTopBottom) {
|
||||
targetW = maxW
|
||||
targetW = canonical ? maxW : Math.min(currentWidth, maxW)
|
||||
targetH = dockEdgeSize
|
||||
} else if (isCenter) {
|
||||
targetW = Math.round(maxW / 2)
|
||||
targetH = Math.round(maxH / 2)
|
||||
targetW = canonical ? Math.round(maxW / 2) : currentWidth
|
||||
targetH = canonical ? Math.round(maxH / 2) : currentHeight
|
||||
} else if (isCorner) {
|
||||
// размер редактируется вручную, только клампим в пределы viewport
|
||||
targetW = Math.min(currentWidth, maxW)
|
||||
@@ -82,13 +87,38 @@ export default function () {
|
||||
return { width: targetW, height: targetH, x, y }
|
||||
}
|
||||
|
||||
// Применить состояние докинга: ресайзим окно (растяжение) + reposition (прижатие).
|
||||
// Сначала resize, иначе reposition считает позицию для старого размера.
|
||||
function applyDock (position: DockPosition, width: number, height: number) {
|
||||
const state = computeDock(position, width, height)
|
||||
figma.ui.resize(state.width, state.height)
|
||||
figma.ui.reposition(state.x, state.y)
|
||||
lastSize = { width: state.width, height: state.height }
|
||||
// Только позиция (без изменения размера) для данного размера — используется при
|
||||
// ручном ресайзе, чтобы переприжать окно к док-краю/центру, сохранив ручной размер.
|
||||
function computeDockPos (position: DockPosition, width: number, height: number) {
|
||||
const b = figma.viewport.bounds
|
||||
const zoom = figma.viewport.zoom || 1
|
||||
const wCanvas = width / zoom
|
||||
const hCanvas = (PLUGIN_HEADER_PX + height) / zoom
|
||||
let x = b.x
|
||||
let y = b.y
|
||||
if (position === 'top-center' || position === 'center' || position === 'bottom-center') {
|
||||
x = b.x + (b.width - wCanvas) / 2
|
||||
} else if (position === 'top-right' || position === 'center-right' || position === 'bottom-right') {
|
||||
x = b.x + b.width - wCanvas
|
||||
}
|
||||
if (position === 'center-left' || position === 'center' || position === 'center-right') {
|
||||
y = b.y + (b.height - hCanvas) / 2
|
||||
} else if (position === 'bottom-left' || position === 'bottom-center' || position === 'bottom-right') {
|
||||
y = b.y + b.height - hCanvas
|
||||
}
|
||||
return { x, y }
|
||||
}
|
||||
|
||||
// Применить состояние докинга.
|
||||
// canonical=true (нажатие кнопки): computeDock задаёт канонический размер.
|
||||
// canonical=false (удержание/ресайз): сохраняем РУЧНОЙ размер, только переприжимаем позицию.
|
||||
function applyDock (position: DockPosition, width: number, height: number, canonical: boolean = false) {
|
||||
const state = computeDock(position, width, height, canonical)
|
||||
// Размер меняем, только если канон (иначе ручной ресайз сбросится на отпускании).
|
||||
if (canonical) figma.ui.resize(state.width, state.height)
|
||||
const pos = canonical ? { x: state.x, y: state.y } : computeDockPos(position, width, height)
|
||||
figma.ui.reposition(pos.x, pos.y)
|
||||
lastSize = { width: canonical ? state.width : width, height: canonical ? state.height : height }
|
||||
return state
|
||||
}
|
||||
|
||||
@@ -102,7 +132,7 @@ export default function () {
|
||||
const key = `${b.x}|${b.y}|${b.width}|${b.height}`
|
||||
if (key !== lastBoundsKey) {
|
||||
lastBoundsKey = key
|
||||
applyDock(dockedPosition, lastSize.width, lastSize.height)
|
||||
applyDock(dockedPosition, lastSize.width, lastSize.height, false)
|
||||
}
|
||||
}, 250)
|
||||
|
||||
@@ -172,18 +202,13 @@ export default function () {
|
||||
const { width, height } = clampWindowSize(windowSize)
|
||||
lastSize = { width, height }
|
||||
figma.ui.resize(width, height)
|
||||
// Если окно задокено — держим прижатым к краю при смене размера.
|
||||
// При этом фикс-сторона edge-позиции (dockEdgeSize) ОБНОВЛЯЕТСЯ из ручного
|
||||
// ресайза, чтобы пользователь мог менять её (а не была заблокирована на 320).
|
||||
// Если окно задокено/в центре — переприжимаем ПОЗИЦИЮ к краю/центру, но размер
|
||||
// НЕ трогаем (canonical=false), чтобы ручной ресайз не сбрасывался на отпускании.
|
||||
if (dockedPosition !== null) {
|
||||
const isLeftRight = dockedPosition === 'center-left' || dockedPosition === 'center-right'
|
||||
const isTopBottom = dockedPosition === 'top-center' || dockedPosition === 'bottom-center'
|
||||
if (isLeftRight) dockEdgeSize = width
|
||||
else if (isTopBottom) dockEdgeSize = height
|
||||
applyDock(dockedPosition, width, height)
|
||||
applyDock(dockedPosition, width, height, false)
|
||||
} else if (centerLocked) {
|
||||
// Центр: позиция удерживается по центру при ресайзе (но не поллит за зумом/паном).
|
||||
applyDock('center', width, height)
|
||||
applyDock('center', width, height, false)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -195,14 +220,14 @@ export default function () {
|
||||
if (position === 'center') {
|
||||
dockedPosition = null
|
||||
centerLocked = true
|
||||
applyDock('center', width, height)
|
||||
applyDock('center', width, height, true)
|
||||
return
|
||||
}
|
||||
// Остальные позиции — удерживаем прижатым (поллинг пересчитывает при зуме/пане).
|
||||
centerLocked = false
|
||||
dockedPosition = position
|
||||
lastBoundsKey = '' // форсируем пересчёт на ближайшем тике
|
||||
applyDock(position, width, height)
|
||||
applyDock(position, width, height, true)
|
||||
})
|
||||
|
||||
// Останавливаем поллинг при закрытии плагина, чтобы не висел в памяти.
|
||||
|
||||
Reference in new issue
Block a user