0.2.0: polygon tool, mask editor preview, collapsible properties
- Polygon asset type with per-vertex animation: new sidebar button inserts a hexagon; vertex handles in the editor write per-keyframe `points` arrays that interpolate between keyframes (requires matching point counts). - Canvas mask preview: toggle in the zoom toolbar switches the stage between the editable ghost view and a rendered view that applies the actual masking via the shared canvas 2D path. - Properties panel is grouped into collapsible sections (Transform, Text, Appearance, Shadow, Mask) with per-section open/closed state persisted to localStorage. - Sidebar shape buttons are icon-only to reclaim width for the Polygon entry. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
03b1147a93
commit
a05396e734
12 files changed
+611
-173
No files matched your search
@@ -8,6 +8,7 @@ import {
|
||||
PhListBullets,
|
||||
PhPencilSimple,
|
||||
PhPlus,
|
||||
PhPolygon,
|
||||
PhSquare,
|
||||
PhTextT,
|
||||
PhTrash,
|
||||
@@ -56,6 +57,23 @@ function addSampleCircle() {
|
||||
store.addLayer(asset.id)
|
||||
}
|
||||
|
||||
function addSamplePolygon() {
|
||||
const radius = 60
|
||||
const sides = 6
|
||||
const points: { x: number; y: number }[] = []
|
||||
for (let i = 0; i < sides; i++) {
|
||||
const a = (i / sides) * Math.PI * 2 - Math.PI / 2
|
||||
points.push({ x: Math.cos(a) * radius, y: Math.sin(a) * radius })
|
||||
}
|
||||
const asset = store.addAsset({
|
||||
kind: 'polygon',
|
||||
name: 'Polygon',
|
||||
points,
|
||||
fill: '#9b7ede',
|
||||
})
|
||||
store.addLayer(asset.id)
|
||||
}
|
||||
|
||||
async function addSampleText() {
|
||||
const input = await promptDialog({
|
||||
title: t('sidebar.newTextDialog.title'),
|
||||
@@ -169,6 +187,7 @@ const assetIconMap: Record<Asset['kind'], typeof PhSquare> = {
|
||||
circle: PhCircle,
|
||||
image: PhImage,
|
||||
text: PhTextT,
|
||||
polygon: PhPolygon,
|
||||
}
|
||||
|
||||
const imageAssets = computed(() =>
|
||||
@@ -218,17 +237,17 @@ function onAssetDragStart(e: DragEvent, asset: Extract<Asset, { kind: 'image' }>
|
||||
</button>
|
||||
|
||||
<div class="actions">
|
||||
<button class="shape-btn" @click="addSampleRect">
|
||||
<PhSquare :size="14" />
|
||||
{{ t('sidebar.shape.rect') }}
|
||||
<button class="shape-btn" :title="t('sidebar.shape.rect')" @click="addSampleRect">
|
||||
<PhSquare :size="16" />
|
||||
</button>
|
||||
<button class="shape-btn" @click="addSampleCircle">
|
||||
<PhCircle :size="14" />
|
||||
{{ t('sidebar.shape.circle') }}
|
||||
<button class="shape-btn" :title="t('sidebar.shape.circle')" @click="addSampleCircle">
|
||||
<PhCircle :size="16" />
|
||||
</button>
|
||||
<button class="shape-btn" @click="addSampleText">
|
||||
<PhTextT :size="14" />
|
||||
{{ t('sidebar.shape.text') }}
|
||||
<button class="shape-btn" :title="t('sidebar.shape.text')" @click="addSampleText">
|
||||
<PhTextT :size="16" />
|
||||
</button>
|
||||
<button class="shape-btn" :title="t('sidebar.shape.polygon')" @click="addSamplePolygon">
|
||||
<PhPolygon :size="16" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -375,6 +394,8 @@ h4 {
|
||||
.shape-btn {
|
||||
flex: 1;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 6px 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user