[FEAT] Streamline UI

This commit is contained in:
2026-01-01 19:47:07 +01:00
parent 04f88dd878
commit e51cb4b334
9 changed files with 292 additions and 293 deletions

View File

@@ -24,32 +24,7 @@
</div>
<!-- Copy to Frame Modal -->
<div v-if="showCopyToFrameModal" class="fixed inset-0 bg-black/50 z-[60] flex items-center justify-center" @click.self="closeCopyToFrameModal">
<div class="bg-white dark:bg-gray-800 rounded-xl shadow-2xl p-6 min-w-[320px] max-w-md" @click.stop>
<h3 class="text-lg font-bold text-gray-900 dark:text-gray-100 mb-4">Copy Sprite to Frame</h3>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Target Frame</label>
<select v-model.number="copyTargetFrame" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500">
<option v-for="i in maxFrameCount" :key="i" :value="i - 1">Frame {{ i }}</option>
</select>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Target Layer</label>
<select v-model="copyTargetLayerId" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500">
<option v-for="layer in props.layers" :key="layer.id" :value="layer.id">{{ layer.name }}</option>
</select>
</div>
</div>
<div class="flex justify-end gap-3 mt-6">
<button @click="closeCopyToFrameModal" class="px-4 py-2 text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors">Cancel</button>
<button @click="confirmCopyToFrame" class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors">Copy</button>
</div>
</div>
</div>
<CopyToFrameModal :is-open="showCopyToFrameModal" :layers="props.layers" :initial-layer-id="copyTargetLayerId" @close="closeCopyToFrameModal" @copy="confirmCopyToFrame" />
</Teleport>
<div class="spritesheet-preview w-full h-full" @click="hideContextMenu">
@@ -308,6 +283,7 @@
import { useAnimationFrames } from '@/composables/useAnimationFrames';
import { useGridMetrics } from '@/composables/useGridMetrics';
import { useBackgroundStyles } from '@/composables/useBackgroundStyles';
import CopyToFrameModal from './utilities/CopyToFrameModal.vue';
const props = defineProps<{
layers: Layer[];
@@ -373,14 +349,8 @@
// Copy to frame modal state
const showCopyToFrameModal = ref(false);
const copyTargetFrame = ref(0);
const copyTargetLayerId = ref(props.activeLayerId);
const maxFrameCount = computed(() => {
const maxLen = Math.max(1, ...props.layers.map(l => l.sprites.length));
return maxLen + 1; // Allow copying to one frame beyond current max
});
// Drag and drop for new sprites
const onDragOver = () => {
isDragOver.value = true;
@@ -713,7 +683,6 @@
const openCopyToFrameModal = () => {
if (contextMenuSpriteId.value) {
copyTargetLayerId.value = contextMenuLayerId.value || props.activeLayerId;
copyTargetFrame.value = 0;
showCopyToFrameModal.value = true;
showContextMenu.value = false;
}
@@ -723,9 +692,9 @@
showCopyToFrameModal.value = false;
};
const confirmCopyToFrame = () => {
const confirmCopyToFrame = (targetLayerId: string, targetFrameIndex: number) => {
if (contextMenuSpriteId.value) {
emit('copySpriteToFrame', contextMenuSpriteId.value, copyTargetLayerId.value, copyTargetFrame.value);
emit('copySpriteToFrame', contextMenuSpriteId.value, targetLayerId, targetFrameIndex);
closeCopyToFrameModal();
contextMenuSpriteId.value = null;
}