0.10.0: audio tracks — assets, per-scene lanes, editor + export playback

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
thandClaude Opus 4.7 committed 2026-04-22 11:53:41 +02:00
1 parent b9f2ba9e47
commit 04f867547d
14 files changed
+2057 -42

No files matched your search

+29 -2
View File
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { onBeforeUnmount, onMounted } from 'vue'
import { PhArrowClockwise, PhCaretLeft, PhCaretRight, PhImagesSquare } from '@phosphor-icons/vue'
import { PhArrowClockwise, PhCaretLeft, PhCaretRight, PhImagesSquare, PhMusicNote } from '@phosphor-icons/vue'
import { useClipartStore } from '@/stores/clipart'
import { t } from '@/i18n'
@@ -21,6 +21,11 @@ function onItemDragStart(e: DragEvent, index: number) {
e.dataTransfer.effectAllowed = 'copy'
e.dataTransfer.setData('application/x-animatr-clipart', String(index))
e.dataTransfer.setData('text/plain', item.name)
if (item.kind === 'audio') {
// No image ghost for audio — browsers render the row itself as the
// default drag preview, which is what we want.
return
}
// Use the actual image as drag ghost
const ghost = document.createElement('img')
ghost.src = item.url
@@ -83,11 +88,15 @@ function onItemDragStart(e: DragEvent, index: number) {
v-for="(item, i) in clipart.items"
:key="item.name + i"
class="tile"
:class="{ 'audio-tile': item.kind === 'audio' }"
v-tooltip="item.name"
draggable="true"
@dragstart="onItemDragStart($event, i)"
>
<img :src="item.url" :alt="item.name" />
<img v-if="item.kind === 'image'" :src="item.url" :alt="item.name" />
<div v-else class="audio-icon">
<PhMusicNote :size="28" weight="regular" />
</div>
<span class="tile-label">{{ item.name }}</span>
</div>
</div>
@@ -301,6 +310,24 @@ function onItemDragStart(e: DragEvent, index: number) {
user-select: none;
}
.audio-icon {
width: 72px;
height: 72px;
display: flex;
align-items: center;
justify-content: center;
color: #0ea5e9;
background: color-mix(in srgb, #0ea5e9 12%, transparent);
border-radius: var(--radius-sm);
pointer-events: none;
}
.tile.audio-tile {
/* Same 1fr grid slot but the content is smaller — keep the tile the
same size as an image tile so the grid stays on a clean rhythm. */
background: var(--bg);
}
.tile-label {
font-size: 10px;
color: var(--text-dim);