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, прижатую к нужному краю).
|
// Возвращает размер (экранные px) и позицию (canvas-space, прижатую к нужному краю).
|
||||||
const DEFAULT_DOCK_EDGE = 320
|
const DEFAULT_DOCK_EDGE = 320
|
||||||
let dockEdgeSize = DEFAULT_DOCK_EDGE // редактируемая фикс-сторона для 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 b = figma.viewport.bounds
|
||||||
const zoom = figma.viewport.zoom || 1
|
const zoom = figma.viewport.zoom || 1
|
||||||
const maxW = Math.round(b.width * zoom)
|
const maxW = Math.round(b.width * zoom)
|
||||||
@@ -52,13 +57,13 @@ export default function () {
|
|||||||
let targetH = currentHeight
|
let targetH = currentHeight
|
||||||
if (isLeftRight) {
|
if (isLeftRight) {
|
||||||
targetW = dockEdgeSize
|
targetW = dockEdgeSize
|
||||||
targetH = maxH
|
targetH = canonical ? maxH : Math.min(currentHeight, maxH)
|
||||||
} else if (isTopBottom) {
|
} else if (isTopBottom) {
|
||||||
targetW = maxW
|
targetW = canonical ? maxW : Math.min(currentWidth, maxW)
|
||||||
targetH = dockEdgeSize
|
targetH = dockEdgeSize
|
||||||
} else if (isCenter) {
|
} else if (isCenter) {
|
||||||
targetW = Math.round(maxW / 2)
|
targetW = canonical ? Math.round(maxW / 2) : currentWidth
|
||||||
targetH = Math.round(maxH / 2)
|
targetH = canonical ? Math.round(maxH / 2) : currentHeight
|
||||||
} else if (isCorner) {
|
} else if (isCorner) {
|
||||||
// размер редактируется вручную, только клампим в пределы viewport
|
// размер редактируется вручную, только клампим в пределы viewport
|
||||||
targetW = Math.min(currentWidth, maxW)
|
targetW = Math.min(currentWidth, maxW)
|
||||||
@@ -82,13 +87,38 @@ export default function () {
|
|||||||
return { width: targetW, height: targetH, x, y }
|
return { width: targetW, height: targetH, x, y }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Применить состояние докинга: ресайзим окно (растяжение) + reposition (прижатие).
|
// Только позиция (без изменения размера) для данного размера — используется при
|
||||||
// Сначала resize, иначе reposition считает позицию для старого размера.
|
// ручном ресайзе, чтобы переприжать окно к док-краю/центру, сохранив ручной размер.
|
||||||
function applyDock (position: DockPosition, width: number, height: number) {
|
function computeDockPos (position: DockPosition, width: number, height: number) {
|
||||||
const state = computeDock(position, width, height)
|
const b = figma.viewport.bounds
|
||||||
figma.ui.resize(state.width, state.height)
|
const zoom = figma.viewport.zoom || 1
|
||||||
figma.ui.reposition(state.x, state.y)
|
const wCanvas = width / zoom
|
||||||
lastSize = { width: state.width, height: state.height }
|
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
|
return state
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +132,7 @@ export default function () {
|
|||||||
const key = `${b.x}|${b.y}|${b.width}|${b.height}`
|
const key = `${b.x}|${b.y}|${b.width}|${b.height}`
|
||||||
if (key !== lastBoundsKey) {
|
if (key !== lastBoundsKey) {
|
||||||
lastBoundsKey = key
|
lastBoundsKey = key
|
||||||
applyDock(dockedPosition, lastSize.width, lastSize.height)
|
applyDock(dockedPosition, lastSize.width, lastSize.height, false)
|
||||||
}
|
}
|
||||||
}, 250)
|
}, 250)
|
||||||
|
|
||||||
@@ -172,18 +202,13 @@ export default function () {
|
|||||||
const { width, height } = clampWindowSize(windowSize)
|
const { width, height } = clampWindowSize(windowSize)
|
||||||
lastSize = { width, height }
|
lastSize = { width, height }
|
||||||
figma.ui.resize(width, height)
|
figma.ui.resize(width, height)
|
||||||
// Если окно задокено — держим прижатым к краю при смене размера.
|
// Если окно задокено/в центре — переприжимаем ПОЗИЦИЮ к краю/центру, но размер
|
||||||
// При этом фикс-сторона edge-позиции (dockEdgeSize) ОБНОВЛЯЕТСЯ из ручного
|
// НЕ трогаем (canonical=false), чтобы ручной ресайз не сбрасывался на отпускании.
|
||||||
// ресайза, чтобы пользователь мог менять её (а не была заблокирована на 320).
|
|
||||||
if (dockedPosition !== null) {
|
if (dockedPosition !== null) {
|
||||||
const isLeftRight = dockedPosition === 'center-left' || dockedPosition === 'center-right'
|
applyDock(dockedPosition, width, height, false)
|
||||||
const isTopBottom = dockedPosition === 'top-center' || dockedPosition === 'bottom-center'
|
|
||||||
if (isLeftRight) dockEdgeSize = width
|
|
||||||
else if (isTopBottom) dockEdgeSize = height
|
|
||||||
applyDock(dockedPosition, width, height)
|
|
||||||
} else if (centerLocked) {
|
} else if (centerLocked) {
|
||||||
// Центр: позиция удерживается по центру при ресайзе (но не поллит за зумом/паном).
|
// Центр: позиция удерживается по центру при ресайзе (но не поллит за зумом/паном).
|
||||||
applyDock('center', width, height)
|
applyDock('center', width, height, false)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -195,14 +220,14 @@ export default function () {
|
|||||||
if (position === 'center') {
|
if (position === 'center') {
|
||||||
dockedPosition = null
|
dockedPosition = null
|
||||||
centerLocked = true
|
centerLocked = true
|
||||||
applyDock('center', width, height)
|
applyDock('center', width, height, true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Остальные позиции — удерживаем прижатым (поллинг пересчитывает при зуме/пане).
|
// Остальные позиции — удерживаем прижатым (поллинг пересчитывает при зуме/пане).
|
||||||
centerLocked = false
|
centerLocked = false
|
||||||
dockedPosition = position
|
dockedPosition = position
|
||||||
lastBoundsKey = '' // форсируем пересчёт на ближайшем тике
|
lastBoundsKey = '' // форсируем пересчёт на ближайшем тике
|
||||||
applyDock(position, width, height)
|
applyDock(position, width, height, true)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Останавливаем поллинг при закрытии плагина, чтобы не висел в памяти.
|
// Останавливаем поллинг при закрытии плагина, чтобы не висел в памяти.
|
||||||
|
|||||||
Reference in new issue
Block a user