diff --git a/src/components/SpritePreview.vue b/src/components/SpritePreview.vue index 6125e1f..4831b86 100644 --- a/src/components/SpritePreview.vue +++ b/src/components/SpritePreview.vue @@ -164,6 +164,7 @@ import { useCanvas2D } from '@/composables/useCanvas2D'; import { useZoom } from '@/composables/useZoom'; import { useAnimationFrames } from '@/composables/useAnimationFrames'; + import { calculateNegativeSpacing } from '@/composables/useNegativeSpacing'; const props = defineProps<{ sprites: Sprite[]; @@ -209,18 +210,6 @@ // Canvas drawing - // Calculate negative spacing based on sprite dimensions - function calculateNegativeSpacing(): number { - if (!settingsStore.negativeSpacingEnabled || props.sprites.length === 0) return 0; - - const { maxWidth, maxHeight } = getMaxDimensions(props.sprites); - const minWidth = Math.min(...props.sprites.map(s => s.width)); - const minHeight = Math.min(...props.sprites.map(s => s.height)); - const widthDiff = maxWidth - minWidth; - const heightDiff = maxHeight - minHeight; - return Math.max(widthDiff, heightDiff); - } - function drawPreviewCanvas() { if (!previewCanvasRef.value || !canvas2D.ctx.value || props.sprites.length === 0) return; @@ -228,7 +217,7 @@ if (!currentSprite) return; const { maxWidth, maxHeight } = getMaxDimensions(props.sprites); - const negativeSpacing = calculateNegativeSpacing(); + const negativeSpacing = calculateNegativeSpacing(props.sprites, settingsStore.negativeSpacingEnabled); const cellWidth = maxWidth + negativeSpacing; const cellHeight = maxHeight + negativeSpacing; @@ -272,7 +261,7 @@ const mouseY = ((event.clientY - rect.top) / zoom.value) * scaleY; const sprite = props.sprites[currentFrameIndex.value]; - const negativeSpacing = calculateNegativeSpacing(); + const negativeSpacing = calculateNegativeSpacing(props.sprites, settingsStore.negativeSpacingEnabled); // Check if click is on sprite (accounting for negative spacing offset) const spriteCanvasX = negativeSpacing + sprite.x; @@ -303,7 +292,7 @@ if (!sprite || sprite.id !== activeSpriteId.value) return; const { maxWidth, maxHeight } = getMaxDimensions(props.sprites); - const negativeSpacing = calculateNegativeSpacing(); + const negativeSpacing = calculateNegativeSpacing(props.sprites, settingsStore.negativeSpacingEnabled); const cellWidth = maxWidth + negativeSpacing; const cellHeight = maxHeight + negativeSpacing; diff --git a/src/composables/useDragSprite.ts b/src/composables/useDragSprite.ts index 9ec5923..cfbd6ff 100644 --- a/src/composables/useDragSprite.ts +++ b/src/composables/useDragSprite.ts @@ -1,6 +1,7 @@ import { ref, computed, type Ref, type ComputedRef } from 'vue'; import type { Sprite } from '@/types/sprites'; import { getMaxDimensions } from './useSprites'; +import { calculateNegativeSpacing } from './useNegativeSpacing'; export interface CellPosition { col: number; @@ -74,17 +75,8 @@ export function useDragSprite(options: DragSpriteOptions) { lastMaxWidth.value = baseMaxWidth; lastMaxHeight.value = baseMaxHeight; - // Calculate negative spacing based on sprite size differences - let negativeSpacing = 0; - if (negativeSpacingEnabled && sprites.length > 0) { - // Find the smallest sprite dimensions - const minWidth = Math.min(...sprites.map(s => s.width)); - const minHeight = Math.min(...sprites.map(s => s.height)); - // Negative spacing is the difference between max and min dimensions - const widthDiff = baseMaxWidth - minWidth; - const heightDiff = baseMaxHeight - minHeight; - negativeSpacing = Math.max(widthDiff, heightDiff); - } + // Calculate negative spacing using shared composable + const negativeSpacing = calculateNegativeSpacing(sprites, negativeSpacingEnabled); // Add negative spacing to expand each cell const maxWidth = baseMaxWidth + negativeSpacing; diff --git a/src/composables/useExport.ts b/src/composables/useExport.ts index 364b173..90108c1 100644 --- a/src/composables/useExport.ts +++ b/src/composables/useExport.ts @@ -4,19 +4,9 @@ import gifWorkerUrl from 'gif.js/dist/gif.worker.js?url'; import JSZip from 'jszip'; import type { Sprite } from '../types/sprites'; import { getMaxDimensions } from './useSprites'; +import { calculateNegativeSpacing } from './useNegativeSpacing'; export const useExport = (sprites: Ref, columns: Ref, negativeSpacingEnabled: Ref) => { - // Calculate negative spacing based on sprite dimensions - const calculateNegativeSpacing = (): number => { - if (!negativeSpacingEnabled.value || sprites.value.length === 0) return 0; - - const { maxWidth, maxHeight } = getMaxDimensions(sprites.value); - const minWidth = Math.min(...sprites.value.map(s => s.width)); - const minHeight = Math.min(...sprites.value.map(s => s.height)); - const widthDiff = maxWidth - minWidth; - const heightDiff = maxHeight - minHeight; - return Math.max(widthDiff, heightDiff); - }; const downloadSpritesheet = () => { if (!sprites.value.length) { alert('Please upload or import sprites before downloading the spritesheet.'); @@ -24,7 +14,7 @@ export const useExport = (sprites: Ref, columns: Ref, negative } const { maxWidth, maxHeight } = getMaxDimensions(sprites.value); - const negativeSpacing = calculateNegativeSpacing(); + const negativeSpacing = calculateNegativeSpacing(sprites.value, negativeSpacingEnabled.value); const cellWidth = maxWidth + negativeSpacing; const cellHeight = maxHeight + negativeSpacing; const rows = Math.ceil(sprites.value.length / columns.value); @@ -147,7 +137,7 @@ export const useExport = (sprites: Ref, columns: Ref, negative } const { maxWidth, maxHeight } = getMaxDimensions(sprites.value); - const negativeSpacing = calculateNegativeSpacing(); + const negativeSpacing = calculateNegativeSpacing(sprites.value, negativeSpacingEnabled.value); const cellWidth = maxWidth + negativeSpacing; const cellHeight = maxHeight + negativeSpacing; const canvas = document.createElement('canvas'); @@ -187,7 +177,7 @@ export const useExport = (sprites: Ref, columns: Ref, negative const zip = new JSZip(); const { maxWidth, maxHeight } = getMaxDimensions(sprites.value); - const negativeSpacing = calculateNegativeSpacing(); + const negativeSpacing = calculateNegativeSpacing(sprites.value, negativeSpacingEnabled.value); const cellWidth = maxWidth + negativeSpacing; const cellHeight = maxHeight + negativeSpacing; const canvas = document.createElement('canvas'); diff --git a/src/composables/useNegativeSpacing.ts b/src/composables/useNegativeSpacing.ts new file mode 100644 index 0000000..58865e4 --- /dev/null +++ b/src/composables/useNegativeSpacing.ts @@ -0,0 +1,21 @@ +import type { Sprite } from '@/types/sprites'; +import { getMaxDimensions } from './useSprites'; + +/** + * Calculate negative spacing to add to top-left of cells. + * Uses half the available space so spacing is equal on all sides. + */ +export function calculateNegativeSpacing(sprites: Sprite[], enabled: boolean): number { + if (!enabled || sprites.length === 0) return 0; + + const { maxWidth, maxHeight } = getMaxDimensions(sprites); + const minWidth = Math.min(...sprites.map(s => s.width)); + const minHeight = Math.min(...sprites.map(s => s.height)); + + // Available space is the gap between cell size and smallest sprite + const availableWidth = maxWidth - minWidth; + const availableHeight = maxHeight - minHeight; + + // Use half to balance spacing equally on all sides + return Math.floor(Math.min(availableWidth, availableHeight) / 2); +}