This commit is contained in:
th committed 2026-04-19 22:32:06 +02:00
1 parent fcefd258eb
commit 6b6157d786
23 files changed
+1140 -237

No files matched your search

+34 -6
View File
@@ -6,6 +6,7 @@ import { useSceneStore } from '@/stores/scene'
import { sampleLayer } from '@/lib/interpolate'
import { loadImage } from '@/lib/fileLoader'
import type { AnimatableProps, Asset, Layer } from '@/types/scene'
import { t } from '@/i18n'
const store = useSceneStore()
@@ -606,6 +607,29 @@ function onContainerPointerUp(e: PointerEvent) {
if (container.value) container.value.style.cursor = ''
}
function onContainerDragOver(e: DragEvent) {
if (!e.dataTransfer) return
if (!e.dataTransfer.types.includes('application/x-animatr-asset')) return
e.preventDefault()
e.dataTransfer.dropEffect = 'copy'
}
function onContainerDrop(e: DragEvent) {
const assetId = e.dataTransfer?.getData('application/x-animatr-asset')
if (!assetId) return
e.preventDefault()
const rect = container.value?.getBoundingClientRect()
if (!rect) return
const sx = e.clientX - rect.left
const sy = e.clientY - rect.top
const worldX = (sx - viewX.value) / zoom.value
const worldY = (sy - viewY.value) / zoom.value
const layer = store.addLayer(assetId)
if (layer) {
store.upsertKeyframe(layer.id, 0, { x: worldX, y: worldY })
}
}
function zoomBy(factor: number) {
const cw = containerSize.value.width
const ch = containerSize.value.height
@@ -638,6 +662,8 @@ onMounted(() => {
container.value.addEventListener('pointermove', onContainerPointerMove)
container.value.addEventListener('pointerup', onContainerPointerUp)
container.value.addEventListener('pointercancel', onContainerPointerUp)
container.value.addEventListener('dragover', onContainerDragOver)
container.value.addEventListener('drop', onContainerDrop)
})
onBeforeUnmount(() => {
@@ -649,6 +675,8 @@ onBeforeUnmount(() => {
container.value?.removeEventListener('pointermove', onContainerPointerMove)
container.value?.removeEventListener('pointerup', onContainerPointerUp)
container.value?.removeEventListener('pointercancel', onContainerPointerUp)
container.value?.removeEventListener('dragover', onContainerDragOver)
container.value?.removeEventListener('drop', onContainerDrop)
})
</script>
@@ -736,21 +764,21 @@ onBeforeUnmount(() => {
</v-stage>
<div class="zoom-controls" @pointerdown.stop>
<button class="zc-btn" title="Zoom out" @click="zoomBy(1 / 1.25)">−</button>
<button class="zc-label" title="Fit to view" @click="fitToContainer">
<button class="zc-btn" :title="t('canvas.zoomOut')" @click="zoomBy(1 / 1.25)">−</button>
<button class="zc-label" :title="t('canvas.fitToView')" @click="fitToContainer">
{{ zoomPercent }}%
</button>
<button class="zc-btn" title="Zoom in" @click="zoomBy(1.25)">+</button>
<button class="zc-btn" :title="t('canvas.zoomIn')" @click="zoomBy(1.25)">+</button>
<div class="zc-sep"></div>
<button class="zc-btn wide" title="Zoom 1:1" @click="zoomToOne">1:1</button>
<button class="zc-btn" title="An Viewport anpassen" @click="fitToContainer">
<button class="zc-btn wide" :title="t('canvas.zoomOneToOne')" @click="zoomToOne">1:1</button>
<button class="zc-btn" :title="t('canvas.fitToView')" @click="fitToContainer">
<PhCornersIn :size="13" />
</button>
<div class="zc-sep"></div>
<button
class="zc-btn crop-btn"
:class="{ active: cropObjects }"
:title="cropObjects ? 'Alles zeigen' : 'Nur Bühnenausschnitt zeigen (crop)'"
:title="cropObjects ? t('canvas.cropOff') : t('canvas.cropOn')"
@click="cropObjects = !cropObjects"
>
<PhCrop :size="13" />