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)' }) }