POC
This commit is contained in:
@@ -100,7 +100,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, watch, onUnmounted, toRef } from 'vue';
|
||||
import { ref, onMounted, watch, onUnmounted, toRef, computed } from 'vue';
|
||||
import { useSettingsStore } from '@/stores/useSettingsStore';
|
||||
import type { Sprite } from '@/types/sprites';
|
||||
import { useCanvas2D } from '@/composables/useCanvas2D';
|
||||
@@ -108,8 +108,11 @@
|
||||
import { useDragSprite } from '@/composables/useDragSprite';
|
||||
import { useFileDrop } from '@/composables/useFileDrop';
|
||||
|
||||
import type { Layer } from '@/types/sprites';
|
||||
|
||||
const props = defineProps<{
|
||||
sprites: Sprite[];
|
||||
layers: Layer[];
|
||||
activeLayerId: string;
|
||||
columns: number;
|
||||
}>();
|
||||
|
||||
@@ -158,7 +161,7 @@
|
||||
findSpriteAtPosition,
|
||||
calculateMaxDimensions,
|
||||
} = useDragSprite({
|
||||
sprites: toRef(props, 'sprites'),
|
||||
sprites: computed(() => (props.layers.find(l => l.id === props.activeLayerId)?.sprites ?? [])),
|
||||
columns: toRef(props, 'columns'),
|
||||
zoom,
|
||||
allowCellSwap,
|
||||
@@ -169,8 +172,10 @@
|
||||
onDraw: drawCanvas,
|
||||
});
|
||||
|
||||
const activeSprites = computed(() => props.layers.find(l => l.id === props.activeLayerId)?.sprites ?? []);
|
||||
|
||||
const { isDragOver, handleDragOver, handleDragEnter, handleDragLeave, handleDrop } = useFileDrop({
|
||||
sprites: props.sprites,
|
||||
sprites: activeSprites,
|
||||
onAddSprite: file => emit('addSprite', file),
|
||||
onAddSpriteWithResize: file => emit('addSpriteWithResize', file),
|
||||
});
|
||||
@@ -280,7 +285,8 @@
|
||||
const { maxWidth, maxHeight, negativeSpacing } = calculateMaxDimensions();
|
||||
|
||||
// Set canvas size
|
||||
const rows = Math.max(1, Math.ceil(props.sprites.length / props.columns));
|
||||
const maxLen = Math.max(1, ...props.layers.map(l => (l.visible ? l.sprites.length : 1)));
|
||||
const rows = Math.max(1, Math.ceil(maxLen / props.columns));
|
||||
canvas2D.setCanvasSize(maxWidth * props.columns, maxHeight * rows);
|
||||
|
||||
// Clear canvas
|
||||
@@ -307,42 +313,42 @@
|
||||
|
||||
// If showing all sprites, draw all sprites with transparency in each cell
|
||||
if (showAllSprites.value) {
|
||||
for (let cellIndex = 0; cellIndex < props.sprites.length; cellIndex++) {
|
||||
const total = Math.max(...props.layers.map(l => (l.visible ? l.sprites.length : 0)));
|
||||
for (let cellIndex = 0; cellIndex < total; cellIndex++) {
|
||||
const cellCol = cellIndex % props.columns;
|
||||
const cellRow = Math.floor(cellIndex / props.columns);
|
||||
const cellX = Math.floor(cellCol * maxWidth);
|
||||
const cellY = Math.floor(cellRow * maxHeight);
|
||||
|
||||
// Draw all sprites with transparency in this cell
|
||||
// Position at bottom-right with negative spacing offset
|
||||
props.sprites.forEach((sprite, spriteIndex) => {
|
||||
if (spriteIndex !== cellIndex) {
|
||||
canvas2D.drawImage(sprite.img, cellX + negativeSpacing + sprite.x, cellY + negativeSpacing + sprite.y, 0.3);
|
||||
}
|
||||
props.layers.forEach(layer => {
|
||||
if (!layer.visible) return;
|
||||
const sprite = layer.sprites[cellIndex];
|
||||
if (sprite) canvas2D.drawImage(sprite.img, cellX + negativeSpacing + sprite.x, cellY + negativeSpacing + sprite.y, 0.35);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Draw sprites normally
|
||||
props.sprites.forEach((sprite, index) => {
|
||||
// Skip the active sprite if we're showing a ghost instead
|
||||
if (activeSpriteId.value === sprite.id && ghostSprite.value) {
|
||||
return;
|
||||
}
|
||||
// Draw layers in order; active layer will be interactable
|
||||
props.layers.forEach(layer => {
|
||||
if (!layer.visible) return;
|
||||
layer.sprites.forEach((sprite, index) => {
|
||||
// Skip the active sprite if we're showing a ghost instead
|
||||
if (activeSpriteId.value === sprite.id && ghostSprite.value) return;
|
||||
|
||||
const col = index % props.columns;
|
||||
const row = Math.floor(index / props.columns);
|
||||
const col = index % props.columns;
|
||||
const row = Math.floor(index / props.columns);
|
||||
|
||||
const cellX = Math.floor(col * maxWidth);
|
||||
const cellY = Math.floor(row * maxHeight);
|
||||
const cellX = Math.floor(col * maxWidth);
|
||||
const cellY = Math.floor(row * maxHeight);
|
||||
|
||||
// Draw sprite with negative spacing offset (bottom-right positioning)
|
||||
canvas2D.drawImage(sprite.img, cellX + negativeSpacing + sprite.x, cellY + negativeSpacing + sprite.y);
|
||||
const alpha = layer.id === props.activeLayerId ? 1 : 0.85;
|
||||
canvas2D.drawImage(sprite.img, cellX + negativeSpacing + sprite.x, cellY + negativeSpacing + sprite.y, alpha);
|
||||
});
|
||||
});
|
||||
|
||||
// Draw ghost sprite if we're dragging between cells
|
||||
if (ghostSprite.value && activeSpriteId.value) {
|
||||
const sprite = props.sprites.find(s => s.id === activeSpriteId.value);
|
||||
const sprite = activeSprites.value.find(s => s.id === activeSpriteId.value);
|
||||
if (sprite) {
|
||||
canvas2D.drawImage(sprite.img, ghostSprite.value.x, ghostSprite.value.y, 0.6);
|
||||
}
|
||||
@@ -362,7 +368,8 @@
|
||||
const imagesWithListeners = new WeakSet<HTMLImageElement>();
|
||||
|
||||
const attachImageListeners = () => {
|
||||
canvas2D.attachImageListeners(props.sprites, handleForceRedraw, imagesWithListeners);
|
||||
const sprites = props.layers.flatMap(l => l.sprites);
|
||||
canvas2D.attachImageListeners(sprites, handleForceRedraw, imagesWithListeners);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
Reference in New Issue
Block a user