diff --git a/src/assets/main.css b/src/assets/main.css index 2f3280f..cca2bc0 100644 --- a/src/assets/main.css +++ b/src/assets/main.css @@ -9,6 +9,14 @@ html { scroll-behavior: smooth; } +/* Disable selection on images and canvases */ +img, +canvas { + user-select: none; + -webkit-user-select: none; + -webkit-user-drag: none; +} + body { @apply bg-gray-50 text-gray-900 dark:bg-gray-950 dark:text-gray-100 antialiased font-sans; min-height: 100vh; diff --git a/src/components/SpritePreview.vue b/src/components/SpritePreview.vue index cf53eb3..46d891b 100644 --- a/src/components/SpritePreview.vue +++ b/src/components/SpritePreview.vue @@ -85,13 +85,12 @@ - + + + + @@ -320,6 +336,17 @@ }); const getVisibleLayers = () => props.layers.filter(l => l.visible); + // Reversed order so active layer renders on top for drag operations + const getVisibleLayersReversed = () => { + const visible = props.layers.filter(l => l.visible); + // Put active layer last so it renders on top + const activeIdx = visible.findIndex(l => l.id === props.activeLayerId); + if (activeIdx > -1) { + const active = visible.splice(activeIdx, 1)[0]; + visible.push(active); + } + return visible; + }; const maxFrames = () => Math.max(0, ...getVisibleLayers().map(l => l.sprites.length)); const { currentFrameIndex, isPlaying, fps, hiddenFrames, visibleFrames, visibleFramesCount, visibleFrameIndex, visibleFrameNumber, togglePlayback, nextFrame, previousFrame, handleSliderInput, toggleHiddenFrame, showAllFrames, hideAllFrames, stopAnimation } = useAnimationFrames({ diff --git a/src/views/EditorView.vue b/src/views/EditorView.vue index 00f0de0..fd01b77 100644 --- a/src/views/EditorView.vue +++ b/src/views/EditorView.vue @@ -615,27 +615,27 @@ flipX: false, flipY: false, }; - const insertIndex = frameIndex + fileIdx; - if (insertIndex < layer.sprites.length) { - layer.sprites = [...layer.sprites.slice(0, insertIndex), sprite, ...layer.sprites.slice(insertIndex + 1)]; - } else { - while (layer.sprites.length < insertIndex) { - layer.sprites.push({ - id: crypto.randomUUID(), - file: new File([], 'empty'), - img: new Image(), - url: '', - width: 0, - height: 0, - x: 0, - y: 0, - rotation: 0, - flipX: false, - flipY: false, - }); - } - layer.sprites = [...layer.sprites, sprite]; + const targetIndex = frameIndex + fileIdx; + + // Extend the array with empty slots if needed + while (layer.sprites.length <= targetIndex) { + layer.sprites.push({ + id: crypto.randomUUID(), + file: new File([], 'empty'), + img: new Image(), + url: '', + width: 0, + height: 0, + x: 0, + y: 0, + rotation: 0, + flipX: false, + flipY: false, + }); } + + // Now replace at target index (either existing sprite or empty placeholder) + layer.sprites = [...layer.sprites.slice(0, targetIndex), sprite, ...layer.sprites.slice(targetIndex + 1)]; }; img.src = url; };