feat: show live window x/y/size debug readout inside plugin
- main.ts: track lastSize; GET_WINDOW_INFO handler returns x/y via
figma.ui.getPosition().canvasSpace (typed as any) + stored width/height
- ui.tsx: WINDOW_INFO listener, '🔍 Инфо' button, render x/y/w/h block
This commit is contained in:
1 parent
bc9b2e60e9
commit
ecbbd5d8c1
2 files changed
+48
-1
No files matched your search
+26
@@ -4,9 +4,14 @@ export default function () {
|
|||||||
// Глобальный ярлык relaunch в правой панели Figma (команда runAI из manifest.json)
|
// Глобальный ярлык relaunch в правой панели Figma (команда runAI из manifest.json)
|
||||||
figma.root.setRelaunchData({ runAI: '' })
|
figma.root.setRelaunchData({ runAI: '' })
|
||||||
|
|
||||||
|
// Последнее известное состояние окна (позиция в canvas-space + размер),
|
||||||
|
// чтобы UI могла запросить его через GET_WINDOW_INFO.
|
||||||
|
let lastSize = { width: 320, height: 200 }
|
||||||
|
|
||||||
// Ресайз окна плагина (drag за угол в UI -> useWindowResize -> RESIZE_WINDOW)
|
// Ресайз окна плагина (drag за угол в UI -> useWindowResize -> RESIZE_WINDOW)
|
||||||
on('RESIZE_WINDOW', function (windowSize: { width: number; height: number }) {
|
on('RESIZE_WINDOW', function (windowSize: { width: number; height: number }) {
|
||||||
const { width, height } = windowSize
|
const { width, height } = windowSize
|
||||||
|
lastSize = { width, height }
|
||||||
figma.ui.resize(width, height)
|
figma.ui.resize(width, height)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -15,6 +20,7 @@ export default function () {
|
|||||||
// Ширину панелей Figma API не отдаёт, поэтому прижимаем к bounds видимой области.
|
// Ширину панелей Figma API не отдаёт, поэтому прижимаем к bounds видимой области.
|
||||||
on('DOCK_WINDOW', function (payload: { position: 'left' | 'right' | 'center'; width: number; height: number }) {
|
on('DOCK_WINDOW', function (payload: { position: 'left' | 'right' | 'center'; width: number; height: number }) {
|
||||||
const { position, width, height } = payload
|
const { position, width, height } = payload
|
||||||
|
lastSize = { width, height }
|
||||||
figma.ui.resize(width, height)
|
figma.ui.resize(width, height)
|
||||||
const b = figma.viewport.bounds
|
const b = figma.viewport.bounds
|
||||||
let x = b.x
|
let x = b.x
|
||||||
@@ -28,5 +34,25 @@ export default function () {
|
|||||||
figma.ui.reposition(x, y)
|
figma.ui.reposition(x, y)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// UI запрашивает текущие x/y (canvas-space) и размеры окна для отладочного вывода.
|
||||||
|
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
|
||||||
|
}
|
||||||
|
emit('WINDOW_INFO', {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
width: lastSize.width,
|
||||||
|
height: lastSize.height
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
showUI({ width: 320, height: 200, themeColors: true, title: 'AI assistant (MVP)' })
|
showUI({ width: 320, height: 200, themeColors: true, title: 'AI assistant (MVP)' })
|
||||||
}
|
}
|
||||||
+22
-1
@@ -10,7 +10,7 @@ import {
|
|||||||
IconCollapse24,
|
IconCollapse24,
|
||||||
useWindowResize
|
useWindowResize
|
||||||
} from '@create-figma-plugin/ui'
|
} from '@create-figma-plugin/ui'
|
||||||
import { emit } from '@create-figma-plugin/utilities'
|
import { emit, on } from '@create-figma-plugin/utilities'
|
||||||
import { h, Fragment } from 'preact'
|
import { h, Fragment } from 'preact'
|
||||||
import { useState, useEffect } from 'preact/hooks'
|
import { useState, useEffect } from 'preact/hooks'
|
||||||
|
|
||||||
@@ -19,6 +19,7 @@ const MAX_WINDOW_SIZE = { width: 800, height: 800 }
|
|||||||
|
|
||||||
function Plugin () {
|
function Plugin () {
|
||||||
const [currentWindowSize, setCurrentWindowSize] = useState(MIN_WINDOW_SIZE)
|
const [currentWindowSize, setCurrentWindowSize] = useState(MIN_WINDOW_SIZE)
|
||||||
|
const [windowInfo, setWindowInfo] = useState<{ x: number; y: number; width: number; height: number } | null>(null)
|
||||||
|
|
||||||
// Нативный drag-ресайз окна Figma (тянуть за правый нижний угол).
|
// Нативный drag-ресайз окна Figma (тянуть за правый нижний угол).
|
||||||
// Опции min/max обязательны: без них хук берёт базу из window.innerWidth на момент
|
// Опции min/max обязательны: без них хук берёт базу из window.innerWidth на момент
|
||||||
@@ -50,6 +51,14 @@ function Plugin () {
|
|||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
// Слушаем ответ от main с актуальными x/y (canvas-space) и размерами окна
|
||||||
|
useEffect(function () {
|
||||||
|
const off = on('WINDOW_INFO', function (info: { x: number; y: number; width: number; height: number }) {
|
||||||
|
setWindowInfo(info)
|
||||||
|
})
|
||||||
|
return function () { off() }
|
||||||
|
}, [])
|
||||||
|
|
||||||
function toggleWindowSize () {
|
function toggleWindowSize () {
|
||||||
const isMaximized =
|
const isMaximized =
|
||||||
currentWindowSize.width >= MAX_WINDOW_SIZE.width &&
|
currentWindowSize.width >= MAX_WINDOW_SIZE.width &&
|
||||||
@@ -59,6 +68,10 @@ function Plugin () {
|
|||||||
emit('RESIZE_WINDOW', next)
|
emit('RESIZE_WINDOW', next)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function requestWindowInfo () {
|
||||||
|
emit('GET_WINDOW_INFO')
|
||||||
|
}
|
||||||
|
|
||||||
function dockWindow (position: 'left' | 'right' | 'center') {
|
function dockWindow (position: 'left' | 'right' | 'center') {
|
||||||
emit('DOCK_WINDOW', {
|
emit('DOCK_WINDOW', {
|
||||||
position,
|
position,
|
||||||
@@ -87,6 +100,7 @@ function Plugin () {
|
|||||||
<Button onClick={function () { dockWindow('left') }}>◧ Лево</Button>
|
<Button onClick={function () { dockWindow('left') }}>◧ Лево</Button>
|
||||||
<Button onClick={function () { dockWindow('center') }}>▣ Центр</Button>
|
<Button onClick={function () { dockWindow('center') }}>▣ Центр</Button>
|
||||||
<Button onClick={function () { dockWindow('right') }}>Право ◨</Button>
|
<Button onClick={function () { dockWindow('right') }}>Право ◨</Button>
|
||||||
|
<Button onClick={requestWindowInfo}>🔍 Инфо</Button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@@ -100,6 +114,13 @@ function Plugin () {
|
|||||||
<Text style={{ fontSize: '13px', fontWeight: 600 }}>Hello, Figma ✦</Text>
|
<Text style={{ fontSize: '13px', fontWeight: 600 }}>Hello, Figma ✦</Text>
|
||||||
<VerticalSpace space="small" />
|
<VerticalSpace space="small" />
|
||||||
<Muted>AI assistant (MVP) — bootstrap</Muted>
|
<Muted>AI assistant (MVP) — bootstrap</Muted>
|
||||||
|
{windowInfo != null && (
|
||||||
|
<div>
|
||||||
|
<VerticalSpace space="small" />
|
||||||
|
<Muted>x: {windowInfo.x} y: {windowInfo.y}</Muted>
|
||||||
|
<Muted>w: {windowInfo.width} h: {windowInfo.height}</Muted>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
{/* Декоративная иконка drag-хендла в правом нижнем углу (как в старом плагине).
|
{/* Декоративная иконка drag-хендла в правом нижнем углу (как в старом плагине).
|
||||||
|
|||||||
Reference in new issue
Block a user