Files
figma-ai-plugin/src/main.ts
T
Hermes Agent dcfb235d06 feat: show derived window data (zoom, viewport, gaps, center)
- 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 🔍 Инфо
2026-09-09 13:18:32 +02:00

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