- main.ts GET_WINDOW_INFO: add zoom, viewport bounds, gaps L/R/T/B, center
computed from figma.viewport + plugin window geometry
- ui.tsx: render additional readout lines under 🔍 Инфо
87 lines
3.4 KiB
TypeScript
87 lines
3.4 KiB
TypeScript
import { emit, on, showUI } from '@create-figma-plugin/utilities'
|
|
|
|
export default function () {
|
|
// Глобальный ярлык relaunch в правой панели Figma (команда runAI из manifest.json)
|
|
figma.root.setRelaunchData({ runAI: '' })
|
|
|
|
// Последнее известное состояние окна (позиция в canvas-space + размер),
|
|
// чтобы UI могла запросить его через GET_WINDOW_INFO.
|
|
let lastSize = { width: 320, height: 200 }
|
|
|
|
// Ресайз окна плагина (drag за угол в UI -> useWindowResize -> RESIZE_WINDOW)
|
|
on('RESIZE_WINDOW', function (windowSize: { width: number; height: number }) {
|
|
const { width, height } = windowSize
|
|
lastSize = { width, height }
|
|
figma.ui.resize(width, height)
|
|
})
|
|
|
|
// Эмуляция докинга: прижать окно плагина к краям canvas (left/right/center).
|
|
// reposition() принимает canvas-space координаты (как figma.viewport.center).
|
|
// Ширину панелей Figma API не отдаёт, поэтому прижимаем к bounds видимой области.
|
|
on('DOCK_WINDOW', function (payload: { position: 'left' | 'right' | 'center'; width: number; height: number }) {
|
|
const { position, width, height } = payload
|
|
lastSize = { width, height }
|
|
figma.ui.resize(width, height)
|
|
const b = figma.viewport.bounds
|
|
let x = b.x
|
|
let y = b.y
|
|
if (position === 'right') {
|
|
x = b.x + b.width - width
|
|
} else if (position === 'center') {
|
|
x = b.x + (b.width - width) / 2
|
|
y = b.y + (b.height - height) / 2
|
|
}
|
|
figma.ui.reposition(x, y)
|
|
})
|
|
|
|
// UI запрашивает текущие x/y (canvas-space) и размеры окна для отладочного вывода,
|
|
// а также производные данные, вычислимые из figma.viewport.
|
|
on('GET_WINDOW_INFO', function () {
|
|
let x = 0
|
|
let y = 0
|
|
try {
|
|
// getPosition() есть в рантайме Figma, но отсутствует в @figma/plugin-typings
|
|
const pos = (figma.ui as any).getPosition()
|
|
x = Math.round(pos.canvasSpace.x)
|
|
y = Math.round(pos.canvasSpace.y)
|
|
} catch (e) {
|
|
// getPosition может быть недоступен в некоторых версиях — оставляем 0
|
|
}
|
|
|
|
const zoom = figma.viewport.zoom
|
|
const b = figma.viewport.bounds
|
|
const w = lastSize.width
|
|
const h = lastSize.height
|
|
|
|
// Геометрия окна плагина относительно видимой области canvas (bounds).
|
|
// gapL/gapR/gapT/gapB — отступы окна от левого/правого/верхнего/нижнего края canvas.
|
|
const gapL = Math.round(x - b.x)
|
|
const gapT = Math.round(y - b.y)
|
|
const gapR = Math.round(b.x + b.width - (x + w))
|
|
const gapB = Math.round(b.y + b.height - (y + h))
|
|
const cx = Math.round(x + w / 2)
|
|
const cy = Math.round(y + h / 2)
|
|
|
|
emit('WINDOW_INFO', {
|
|
x,
|
|
y,
|
|
width: w,
|
|
height: h,
|
|
zoom: Math.round(zoom * 100) / 100,
|
|
viewport: {
|
|
x: Math.round(b.x),
|
|
y: Math.round(b.y),
|
|
width: Math.round(b.width),
|
|
height: Math.round(b.height)
|
|
},
|
|
gapL,
|
|
gapR,
|
|
gapT,
|
|
gapB,
|
|
center: { x: cx, y: cy }
|
|
})
|
|
})
|
|
|
|
showUI({ width: 320, height: 200, themeColors: true, title: 'AI assistant (MVP)' })
|
|
}
|