fix: account for 38px plugin header in gapB/center.y and vertical dock
This commit is contained in:
1 parent
b57cda16ec
commit
5984df1692
2 files changed
+17
-14
No files matched your search
+13
-10
@@ -20,16 +20,19 @@ export default function () {
|
|||||||
| 'center-left' | 'center' | 'center-right'
|
| 'center-left' | 'center' | 'center-right'
|
||||||
| 'bottom-left' | 'bottom-center' | 'bottom-right'
|
| 'bottom-left' | 'bottom-center' | 'bottom-right'
|
||||||
|
|
||||||
|
// Высота шапки окна плагина (title bar Figma с крестиком), экранные px.
|
||||||
|
// Окно плагина = шапка (PLUGIN_HEADER_PX) + iframe (height px). getPosition().y — это
|
||||||
|
// верх шапки, поэтому полная высота окна = (PLUGIN_HEADER_PX + height) / zoom.
|
||||||
|
const PLUGIN_HEADER_PX = 38
|
||||||
|
|
||||||
// Прижать окно к краю видимой области canvas (bounds) в canvas-space.
|
// Прижать окно к краю видимой области canvas (bounds) в canvas-space.
|
||||||
// ВАЖНО: reposition()/getPosition() и bounds — в canvas-space (единицы документа),
|
// ВАЖНО: reposition()/getPosition() и bounds — в canvas-space (единицы документа),
|
||||||
// а figma.ui.resize(width,height) — в ЭКРАННЫХ пикселях. Размер окна в canvas-units =
|
// а figma.ui.resize(width,height) — в ЭКРАННЫХ пикселях. Размер окна в canvas-units =\n // width / zoom (по ширине) и (PLUGIN_HEADER_PX + height) / zoom (по высоте, т.к. окно\n // включает шапку). Без учёта шапки прижатый к низу/центру окно висит на 38px выше нужного.
|
||||||
// width / zoom. Без этого деления при zoom≠100% окно прижимается с ошибкой
|
|
||||||
// (px-размер вычитается из canvas-ширины → уезжает пропорционально 1/zoom).
|
|
||||||
function applyDock (position: DockPosition, width: number, height: number) {
|
function applyDock (position: DockPosition, width: number, height: number) {
|
||||||
const b = figma.viewport.bounds
|
const b = figma.viewport.bounds
|
||||||
const zoom = figma.viewport.zoom || 1
|
const zoom = figma.viewport.zoom || 1
|
||||||
const wCanvas = width / zoom
|
const wCanvas = width / zoom
|
||||||
const hCanvas = height / zoom
|
const hCanvas = (PLUGIN_HEADER_PX + height) / zoom
|
||||||
let x = b.x
|
let x = b.x
|
||||||
let y = b.y
|
let y = b.y
|
||||||
// По горизонтали
|
// По горизонтали
|
||||||
@@ -38,7 +41,7 @@ export default function () {
|
|||||||
} else if (position === 'top-right' || position === 'center-right' || position === 'bottom-right') {
|
} else if (position === 'top-right' || position === 'center-right' || position === 'bottom-right') {
|
||||||
x = b.x + b.width - wCanvas
|
x = b.x + b.width - wCanvas
|
||||||
}
|
}
|
||||||
// По вертикали
|
// По вертикали (hCanvas учитывает шапку окна)
|
||||||
if (position === 'center-left' || position === 'center' || position === 'center-right') {
|
if (position === 'center-left' || position === 'center' || position === 'center-right') {
|
||||||
y = b.y + (b.height - hCanvas) / 2
|
y = b.y + (b.height - hCanvas) / 2
|
||||||
} else if (position === 'bottom-left' || position === 'bottom-center' || position === 'bottom-right') {
|
} else if (position === 'bottom-left' || position === 'bottom-center' || position === 'bottom-right') {
|
||||||
@@ -132,16 +135,16 @@ export default function () {
|
|||||||
// Размер окна в ЭКРАННЫХ пикселях (w/h) переводим в canvas-units через zoom,
|
// Размер окна в ЭКРАННЫХ пикселях (w/h) переводим в canvas-units через zoom,
|
||||||
// чтобы корректно вычитать из canvas-ширины bounds при любом зуме.
|
// чтобы корректно вычитать из canvas-ширины bounds при любом зуме.
|
||||||
const wCanvas = w / zoom
|
const wCanvas = w / zoom
|
||||||
const hCanvas = h / zoom
|
|
||||||
|
|
||||||
// Геометрия окна плагина относительно видимой области canvas (bounds).
|
// Геометрия окна плагина относительно видимой области canvas (bounds).
|
||||||
// gapL/gapR/gapT/gapB — отступы окна от левого/правого/верхнего/нижнего края canvas.
|
// Полная высота окна = шапка (PLUGIN_HEADER_PX) + iframe (h), поэтому по вертикали
|
||||||
|
// считаем от (PLUGIN_HEADER_PX + h)/zoom, а не от h/zoom (иначе gapB/center.y неверны).
|
||||||
|
const fullHCanvas = (PLUGIN_HEADER_PX + h) / zoom
|
||||||
const gapL = Math.round(x - b.x)
|
const gapL = Math.round(x - b.x)
|
||||||
const gapT = Math.round(y - b.y)
|
const gapT = Math.round(y - b.y)
|
||||||
const gapR = Math.round(b.x + b.width - (x + wCanvas))
|
const gapR = Math.round(b.x + b.width - (x + wCanvas))
|
||||||
const gapB = Math.round(b.y + b.height - (y + hCanvas))
|
const gapB = Math.round(b.y + b.height - (y + fullHCanvas))
|
||||||
const cx = Math.round(x + wCanvas / 2)
|
const cx = Math.round(x + wCanvas / 2)
|
||||||
const cy = Math.round(y + hCanvas / 2)
|
const cy = Math.round(y + fullHCanvas / 2)
|
||||||
|
|
||||||
// Нормализованная позиция окна относительно видимого viewport (левый верхний угол
|
// Нормализованная позиция окна относительно видимого viewport (левый верхний угол
|
||||||
// окна в координатах bounds). relX = x − bounds.x, relY = y − bounds.y. Это те же
|
// окна в координатах bounds). relX = x − bounds.x, relY = y − bounds.y. Это те же
|
||||||
|
|||||||
+4
-4
@@ -313,8 +313,8 @@ function Plugin () {
|
|||||||
/>
|
/>
|
||||||
<Field
|
<Field
|
||||||
name="gapB"
|
name="gapB"
|
||||||
formula="bounds.y + bounds.height − (y + h)"
|
formula="bounds.y + bounds.height − (y + header + h)"
|
||||||
subst={`${windowInfo.viewport.y} + ${windowInfo.viewport.height} − (${windowInfo.y} + ${Math.round(windowInfo.height / windowInfo.zoom)}) = ${windowInfo.gapB}`}
|
subst={`${windowInfo.viewport.y} + ${windowInfo.viewport.height} − (${windowInfo.y} + 38 + ${Math.round(windowInfo.height / windowInfo.zoom)}) = ${windowInfo.gapB}`}
|
||||||
value={windowInfo.gapB}
|
value={windowInfo.gapB}
|
||||||
/>
|
/>
|
||||||
<Field
|
<Field
|
||||||
@@ -325,8 +325,8 @@ function Plugin () {
|
|||||||
/>
|
/>
|
||||||
<Field
|
<Field
|
||||||
name="center.y"
|
name="center.y"
|
||||||
formula="y + h / 2"
|
formula="y + (header + h) / 2"
|
||||||
subst={`${windowInfo.y} + ${Math.round(windowInfo.height / windowInfo.zoom)} / 2 = ${windowInfo.center.y}`}
|
subst={`${windowInfo.y} + (38 + ${Math.round(windowInfo.height / windowInfo.zoom)}) / 2 = ${windowInfo.center.y}`}
|
||||||
value={windowInfo.center.y}
|
value={windowInfo.center.y}
|
||||||
/>
|
/>
|
||||||
</Section>
|
</Section>
|
||||||
|
|||||||
Reference in new issue
Block a user