diff --git a/src/components/PreviewModal.vue b/src/components/PreviewModal.vue index 4879456..92a5dda 100644 --- a/src/components/PreviewModal.vue +++ b/src/components/PreviewModal.vue @@ -73,6 +73,7 @@ const isModalOpen = computed(() => store.isModalOpen.value); const sprites = computed(() => store.sprites.value); const animation = computed(() => store.animation); + const previewBorder = computed(() => store.previewBorder); const currentFrame = ref(0); const position = ref({ x: 0, y: 0 }); @@ -268,6 +269,17 @@ { deep: true } ); + // Watch for changes in border settings to update the preview + watch( + () => previewBorder.value, + () => { + if (isModalOpen.value && sprites.value.length > 0) { + store.renderAnimationFrame(currentFrame.value); + } + }, + { deep: true } + ); + // Expose openModal for external use defineExpose({ openModal }); diff --git a/src/components/SettingsModal.vue b/src/components/SettingsModal.vue index aca5ffd..4327c0b 100644 --- a/src/components/SettingsModal.vue +++ b/src/components/SettingsModal.vue @@ -59,6 +59,36 @@ + +
+

Preview border

+
+
+ +
+ + +
+
+
+ +
+
+ + +
+
+ + +
+
+ +
+ Border will only be visible in the preview and won't be included in the downloaded spritesheet. +
+
+
+

Keyboard shortcuts

@@ -93,6 +123,7 @@ const store = useSpritesheetStore(); const sprites = computed(() => store.sprites.value); const isModalOpen = computed(() => store.isSettingsModalOpen.value); + const previewBorder = computed(() => store.previewBorder); // Column count control const columnCount = ref(store.columns.value); @@ -130,3 +161,47 @@ store.showNotification(`Column count updated to ${columnCount.value}`); }; + + diff --git a/src/composables/useSpritesheetStore.ts b/src/composables/useSpritesheetStore.ts index 6f193a0..6536888 100644 --- a/src/composables/useSpritesheetStore.ts +++ b/src/composables/useSpritesheetStore.ts @@ -41,6 +41,13 @@ const isSettingsModalOpen = ref(false); const isSpritesModalOpen = ref(false); const zoomLevel = ref(1); // Default zoom level (1 = 100%) +// Preview border settings +const previewBorder = reactive({ + enabled: false, + color: '#ff0000', // Default red color + width: 2 // Default width in pixels +}); + export function useSpritesheetStore() { const animation = reactive({ canvas: null, @@ -399,6 +406,10 @@ export function useSpritesheetStore() { animation.ctx.clearRect(0, 0, animation.canvas.width, animation.canvas.height); + // Draw background (transparent by default) + animation.ctx.fillStyle = 'transparent'; + animation.ctx.fillRect(0, 0, animation.canvas.width, animation.canvas.height); + const currentSprite = sprites.value[frameIndex % sprites.value.length]; const cellX = Math.floor(currentSprite.x / cellSize.width); @@ -408,6 +419,13 @@ export function useSpritesheetStore() { const offsetY = currentSprite.y - cellY * cellSize.height; animation.ctx.drawImage(currentSprite.img, offsetX, offsetY); + + // Draw border if enabled (only for preview, not included in download) + if (previewBorder.enabled) { + animation.ctx.strokeStyle = previewBorder.color; + animation.ctx.lineWidth = previewBorder.width; + animation.ctx.strokeRect(0, 0, animation.canvas.width, animation.canvas.height); + } } function animationLoop(timestamp?: number) { @@ -480,6 +498,7 @@ export function useSpritesheetStore() { animation, notification, zoomLevel, + previewBorder, addSprites, updateCellSize, updateCanvasSize,