feat: 9-position dock grid (4 corners + 4 edges + center)
This commit is contained in:
1 parent
0aeaf9f831
commit
d29654b8d5
2 files changed
+36
-12
No files matched your search
+19
-7
@@ -12,25 +12,37 @@ export default function () {
|
|||||||
// Пока не null — позиция пересчитывается при каждом изменении viewport
|
// Пока не null — позиция пересчитывается при каждом изменении viewport
|
||||||
// (через поллинг, т.к. события viewportchange в API нет), иначе
|
// (через поллинг, т.к. события viewportchange в API нет), иначе
|
||||||
// canvas-space-точка "уплывает" на экране при смене зума/пана.
|
// canvas-space-точка "уплывает" на экране при смене зума/пана.
|
||||||
let dockedPosition: 'left' | 'right' | 'center' | null = null
|
let dockedPosition: DockPosition | null = null
|
||||||
|
|
||||||
|
// 9 позиций докинга: 4 угла + 4 края + центр.
|
||||||
|
type DockPosition =
|
||||||
|
| 'top-left' | 'top-center' | 'top-right'
|
||||||
|
| 'center-left' | 'center' | 'center-right'
|
||||||
|
| 'bottom-left' | 'bottom-center' | 'bottom-right'
|
||||||
|
|
||||||
// Прижать окно к краю видимой области 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 =
|
||||||
// width / zoom. Без этого деления при zoom≠100% окно прижимается с ошибкой
|
// width / zoom. Без этого деления при zoom≠100% окно прижимается с ошибкой
|
||||||
// (px-размер вычитается из canvas-ширины → уезжает пропорционально 1/zoom).
|
// (px-размер вычитается из canvas-ширины → уезжает пропорционально 1/zoom).
|
||||||
function applyDock (position: 'left' | 'right' | 'center', 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 = height / zoom
|
||||||
let x = b.x
|
let x = b.x
|
||||||
let y = b.y
|
let y = b.y
|
||||||
if (position === 'right') {
|
// По горизонтали
|
||||||
x = b.x + b.width - wCanvas
|
if (position === 'top-center' || position === 'center' || position === 'bottom-center') {
|
||||||
} else if (position === 'center') {
|
|
||||||
x = b.x + (b.width - wCanvas) / 2
|
x = b.x + (b.width - wCanvas) / 2
|
||||||
|
} else if (position === 'top-right' || position === 'center-right' || position === 'bottom-right') {
|
||||||
|
x = b.x + b.width - wCanvas
|
||||||
|
}
|
||||||
|
// По вертикали
|
||||||
|
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') {
|
||||||
|
y = b.y + b.height - hCanvas
|
||||||
}
|
}
|
||||||
figma.ui.reposition(x, y)
|
figma.ui.reposition(x, y)
|
||||||
}
|
}
|
||||||
@@ -77,8 +89,8 @@ export default function () {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Эмуляция докинга: прижать окно к краям canvas (left/right/center).
|
// Эмуляция докинга: прижать окно к краям canvas (9 позиций).
|
||||||
on('DOCK_WINDOW', function (payload: { position: 'left' | 'right' | 'center'; width: number; height: number }) {
|
on('DOCK_WINDOW', function (payload: { position: DockPosition; width: number; height: number }) {
|
||||||
const { position } = payload
|
const { position } = payload
|
||||||
const { width, height } = clampWindowSize(payload)
|
const { width, height } = clampWindowSize(payload)
|
||||||
lastSize = { width, height }
|
lastSize = { width, height }
|
||||||
|
|||||||
+17
-5
@@ -201,7 +201,13 @@ function Plugin () {
|
|||||||
refreshInfo()
|
refreshInfo()
|
||||||
}
|
}
|
||||||
|
|
||||||
function dockWindow (position: 'left' | 'right' | 'center') {
|
// 9 позиций докинга: 4 угла + 4 края + центр.
|
||||||
|
type DockPosition =
|
||||||
|
| 'top-left' | 'top-center' | 'top-right'
|
||||||
|
| 'center-left' | 'center' | 'center-right'
|
||||||
|
| 'bottom-left' | 'bottom-center' | 'bottom-right'
|
||||||
|
|
||||||
|
function dockWindow (position: DockPosition) {
|
||||||
emit('DOCK_WINDOW', {
|
emit('DOCK_WINDOW', {
|
||||||
position,
|
position,
|
||||||
width: currentWindowSize.width,
|
width: currentWindowSize.width,
|
||||||
@@ -240,10 +246,16 @@ function Plugin () {
|
|||||||
</IconButton>
|
</IconButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: 'flex', gap: '4px', flexWrap: 'wrap' }}>
|
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '4px' }}>
|
||||||
<Button onClick={function () { dockWindow('left') }}>◧ Лево</Button>
|
<Button onClick={function () { dockWindow('top-left') }}>◤</Button>
|
||||||
<Button onClick={function () { dockWindow('center') }}>▣ Центр</Button>
|
<Button onClick={function () { dockWindow('top-center') }}>▬</Button>
|
||||||
<Button onClick={function () { dockWindow('right') }}>Право ◨</Button>
|
<Button onClick={function () { dockWindow('top-right') }}>◥</Button>
|
||||||
|
<Button onClick={function () { dockWindow('center-left') }}>▏</Button>
|
||||||
|
<Button onClick={function () { dockWindow('center') }}>⊕</Button>
|
||||||
|
<Button onClick={function () { dockWindow('center-right') }}>▕</Button>
|
||||||
|
<Button onClick={function () { dockWindow('bottom-left') }}>◣</Button>
|
||||||
|
<Button onClick={function () { dockWindow('bottom-center') }}>▭</Button>
|
||||||
|
<Button onClick={function () { dockWindow('bottom-right') }}>◢</Button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
|
|||||||
Reference in new issue
Block a user