diff --git a/src/components/MainContent.vue b/src/components/MainContent.vue
index 56f9424..cdbeae4 100644
--- a/src/components/MainContent.vue
+++ b/src/components/MainContent.vue
@@ -6,252 +6,392 @@
Spritesheet
-
-
-
-
+
+ Zoom: {{ Math.round(store.zoomLevel.value * 100) }}%
+
+
+
-
-
-
-
- {{ tooltipText }}
+
+
\ No newline at end of file
diff --git a/src/components/Sidebar.vue b/src/components/Sidebar.vue
index 28f9dff..b7e4424 100644
--- a/src/components/Sidebar.vue
+++ b/src/components/Sidebar.vue
@@ -50,7 +50,22 @@
+
+
+
Zoom Controls
+
+
+
+
+
+
Keyboard Shortcuts
Shift
Fine-tune position
@@ -63,6 +78,30 @@
Esc
Close preview
+
+
+ Ctrl
+ +
+ +
+
+
Zoom in
+
+
+
+ Ctrl
+ +
+ -
+
+
Zoom out
+
+
+
+ Ctrl
+ +
+ 0
+
+
Reset zoom
+
@@ -104,5 +143,5 @@
};
// Expose store methods directly
- const { autoArrangeSprites, downloadSpritesheet } = store;
+ const { autoArrangeSprites, downloadSpritesheet, zoomIn, zoomOut, resetZoom } = store;
diff --git a/src/composables/useSpritesheetStore.ts b/src/composables/useSpritesheetStore.ts
index 8870169..32ca1e2 100644
--- a/src/composables/useSpritesheetStore.ts
+++ b/src/composables/useSpritesheetStore.ts
@@ -37,6 +37,7 @@ const draggedSprite = ref(null);
const dragOffset = reactive({ x: 0, y: 0 });
const isShiftPressed = ref(false);
const isModalOpen = ref(false);
+const zoomLevel = ref(1); // Default zoom level (1 = 100%)
export function useSpritesheetStore() {
const animation = reactive({
@@ -143,6 +144,11 @@ export function useSpritesheetStore() {
canvas.value.width = newWidth;
canvas.value.height = newHeight;
+
+ // Emit an event to update the wrapper dimensions
+ window.dispatchEvent(new CustomEvent('canvas-size-updated', {
+ detail: { width: newWidth, height: newHeight }
+ }));
} catch (error) {
console.error('Store: Error updating canvas size:', error);
}
@@ -206,6 +212,10 @@ export function useSpritesheetStore() {
// Clear the canvas
ctx.value.clearRect(0, 0, canvas.value.width, canvas.value.height);
+ // Apply zoom transformation
+ ctx.value.save();
+ ctx.value.scale(zoomLevel.value, zoomLevel.value);
+
if (showGrid) {
drawGrid();
}
@@ -226,7 +236,10 @@ export function useSpritesheetStore() {
// If image isn't loaded yet, set an onload handler
sprite.img.onload = () => {
if (ctx.value && canvas.value) {
+ ctx.value.save();
+ ctx.value.scale(zoomLevel.value, zoomLevel.value);
ctx.value.drawImage(sprite.img, sprite.x, sprite.y);
+ ctx.value.restore();
}
};
}
@@ -234,6 +247,9 @@ export function useSpritesheetStore() {
console.error(`Store: Error rendering sprite at index ${index}:`, spriteError);
}
});
+
+ // Restore the canvas state
+ ctx.value.restore();
} catch (error) {
console.error('Store: Error rendering spritesheet preview:', error);
}
@@ -243,21 +259,25 @@ export function useSpritesheetStore() {
if (!ctx.value || !canvas.value) return;
ctx.value.strokeStyle = '#333';
- ctx.value.lineWidth = 1;
+ ctx.value.lineWidth = 1 / zoomLevel.value; // Adjust line width based on zoom level
+
+ // Calculate the visible area based on zoom level
+ const visibleWidth = canvas.value.width / zoomLevel.value;
+ const visibleHeight = canvas.value.height / zoomLevel.value;
// Draw vertical lines
- for (let x = 0; x <= canvas.value.width; x += cellSize.width) {
+ for (let x = 0; x <= visibleWidth; x += cellSize.width) {
ctx.value.beginPath();
ctx.value.moveTo(x, 0);
- ctx.value.lineTo(x, canvas.value.height);
+ ctx.value.lineTo(x, visibleHeight);
ctx.value.stroke();
}
// Draw horizontal lines
- for (let y = 0; y <= canvas.value.height; y += cellSize.height) {
+ for (let y = 0; y <= visibleHeight; y += cellSize.height) {
ctx.value.beginPath();
ctx.value.moveTo(0, y);
- ctx.value.lineTo(canvas.value.width, y);
+ ctx.value.lineTo(visibleWidth, y);
ctx.value.stroke();
}
}
@@ -411,6 +431,27 @@ export function useSpritesheetStore() {
}, 3000);
}
+ function zoomIn() {
+ // Increase zoom level by 0.1, max 3.0 (300%)
+ zoomLevel.value = Math.min(3.0, zoomLevel.value + 0.1);
+ renderSpritesheetPreview();
+ showNotification(`Zoom: ${Math.round(zoomLevel.value * 100)}%`);
+ }
+
+ function zoomOut() {
+ // Decrease zoom level by 0.1, min 0.5 (50%)
+ zoomLevel.value = Math.max(0.5, zoomLevel.value - 0.1);
+ renderSpritesheetPreview();
+ showNotification(`Zoom: ${Math.round(zoomLevel.value * 100)}%`);
+ }
+
+ function resetZoom() {
+ // Reset to default zoom level (100%)
+ zoomLevel.value = 1;
+ renderSpritesheetPreview();
+ showNotification('Zoom reset to 100%');
+ }
+
return {
sprites,
canvas,
@@ -423,6 +464,7 @@ export function useSpritesheetStore() {
isModalOpen,
animation,
notification,
+ zoomLevel,
addSprites,
updateCellSize,
updateCanvasSize,
@@ -436,5 +478,8 @@ export function useSpritesheetStore() {
stopAnimation,
renderAnimationFrame,
showNotification,
+ zoomIn,
+ zoomOut,
+ resetZoom,
};
}