format
This commit is contained in:
parent
3e849c0286
commit
5a7f7032ef
@ -113,7 +113,7 @@ export function createSpriteFromFile(file: File, index: number): Promise<Sprite>
|
||||
/**
|
||||
* Process multiple files and create sprites
|
||||
*/
|
||||
export async function processImageFiles(files: FileList): Promise<{ newSprites: Sprite[], errorCount: number }> {
|
||||
export async function processImageFiles(files: FileList): Promise<{ newSprites: Sprite[]; errorCount: number }> {
|
||||
const imageFiles = Array.from(files).filter(file => file.type.startsWith('image/'));
|
||||
|
||||
if (imageFiles.length === 0) {
|
||||
|
@ -46,6 +46,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted, onBeforeUnmount, watch, nextTick } from 'vue';
|
||||
import { useSpritesheetStore } from '../composables/useSpritesheetStore';
|
||||
import { logger, getPixelPerfectCoordinate } from '../application/utilities';
|
||||
|
||||
const store = useSpritesheetStore();
|
||||
const canvasEl = ref<HTMLCanvasElement | null>(null);
|
||||
@ -102,10 +103,9 @@
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
const setupCheckerboardPattern = () => {
|
||||
// Remove this function or leave it empty since we don't need it anymore
|
||||
};
|
||||
|
||||
/**
|
||||
* Update canvas size based on container dimensions
|
||||
*/
|
||||
const updateCanvasSize = () => {
|
||||
if (!canvasEl.value || !containerEl.value) return;
|
||||
|
||||
@ -114,11 +114,10 @@
|
||||
containerHeight.value = containerEl.value.clientHeight;
|
||||
|
||||
// Set the base canvas size to fill the container
|
||||
// These are the "unzoomed" dimensions
|
||||
baseCanvasWidth.value = Math.max(containerWidth.value, store.cellSize.width * Math.ceil(containerWidth.value / store.cellSize.width));
|
||||
baseCanvasHeight.value = Math.max(containerHeight.value, store.cellSize.height * Math.ceil(containerHeight.value / store.cellSize.height));
|
||||
|
||||
// Set the actual canvas dimensions - remove any zoom scaling here
|
||||
// Set the actual canvas dimensions
|
||||
canvasEl.value.width = baseCanvasWidth.value;
|
||||
canvasEl.value.height = baseCanvasHeight.value;
|
||||
|
||||
@ -146,6 +145,9 @@
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle mouse movement for tooltips and sprite dragging
|
||||
*/
|
||||
const handleMouseMove = (e: MouseEvent) => {
|
||||
// Don't process sprite movement or tooltips while panning
|
||||
if (isPanning.value) return;
|
||||
@ -153,14 +155,15 @@
|
||||
if (!canvasEl.value) return;
|
||||
|
||||
const rect = canvasEl.value.getBoundingClientRect();
|
||||
// Adjust coordinates for zoom
|
||||
// Adjust coordinates for zoom level
|
||||
const x = (e.clientX - rect.left) / store.zoomLevel.value;
|
||||
const y = (e.clientY - rect.top) / store.zoomLevel.value;
|
||||
|
||||
// Update tooltip
|
||||
// Update tooltip with cell coordinates
|
||||
const cellX = Math.floor(x / store.cellSize.width);
|
||||
const cellY = Math.floor(y / store.cellSize.height);
|
||||
|
||||
// Show tooltip if mouse is within canvas bounds
|
||||
if (canvasEl.value && cellX >= 0 && cellX < canvasEl.value.width / store.cellSize.width && cellY >= 0 && cellY < canvasEl.value.height / store.cellSize.height) {
|
||||
isTooltipVisible.value = true;
|
||||
tooltipText.value = `Cell: (${cellX}, ${cellY})`;
|
||||
@ -170,7 +173,7 @@
|
||||
isTooltipVisible.value = false;
|
||||
}
|
||||
|
||||
// Move the sprite if we're dragging one
|
||||
// Handle sprite dragging
|
||||
if (store.draggedSprite.value) {
|
||||
if (store.isShiftPressed.value) {
|
||||
// Free positioning within the cell bounds when shift is pressed
|
||||
@ -223,12 +226,11 @@
|
||||
const boundedCellX = Math.max(0, Math.min(newCellX, maxCellX));
|
||||
const boundedCellY = Math.max(0, Math.min(newCellY, maxCellY));
|
||||
|
||||
const oldX = store.draggedSprite.value.x;
|
||||
const oldY = store.draggedSprite.value.y;
|
||||
|
||||
// Update the sprite position
|
||||
store.draggedSprite.value.x = boundedCellX * store.cellSize.width;
|
||||
store.draggedSprite.value.y = boundedCellY * store.cellSize.height;
|
||||
// Update the sprite position with pixel-perfect coordinates
|
||||
const newX = boundedCellX * store.cellSize.width;
|
||||
const newY = boundedCellY * store.cellSize.height;
|
||||
store.draggedSprite.value.x = newX;
|
||||
store.draggedSprite.value.y = newY;
|
||||
|
||||
// When snapping to grid, reset any offsets for this sprite
|
||||
const spriteIndex = store.sprites.value.findIndex(s => s.id === store.draggedSprite.value.id);
|
||||
@ -258,6 +260,9 @@
|
||||
store.draggedSprite.value = null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle keyboard down events
|
||||
*/
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
if (e.key === 'Shift') {
|
||||
store.isShiftPressed.value = true;
|
||||
@ -268,7 +273,7 @@
|
||||
isAltPressed.value = true;
|
||||
}
|
||||
|
||||
// Add keyboard shortcuts for zooming
|
||||
// Handle keyboard shortcuts for zooming
|
||||
if (e.ctrlKey || e.metaKey) {
|
||||
if (e.key === '=' || e.key === '+') {
|
||||
e.preventDefault();
|
||||
@ -305,13 +310,18 @@
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle mouse movement on the canvas for panning and sprite interactions
|
||||
*/
|
||||
const handleCanvasMouseMove = (e: MouseEvent) => {
|
||||
if (isPanning.value && containerEl.value) {
|
||||
e.preventDefault();
|
||||
// Calculate the distance moved since last position
|
||||
const dx = e.clientX - lastPosition.value.x;
|
||||
const dy = e.clientY - lastPosition.value.y;
|
||||
|
||||
// Scroll the container in the opposite direction of the mouse movement
|
||||
// for natural panning behavior
|
||||
containerEl.value.scrollLeft -= dx;
|
||||
containerEl.value.scrollTop -= dy;
|
||||
|
||||
@ -337,8 +347,14 @@
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
/**
|
||||
* Set up all canvas event listeners
|
||||
*/
|
||||
const setupCanvasEvents = () => {
|
||||
if (!canvasEl.value) return;
|
||||
if (!canvasEl.value) {
|
||||
logger.warn('Cannot set up canvas events: canvas element not available');
|
||||
return;
|
||||
}
|
||||
|
||||
// Set up mouse events for the canvas
|
||||
canvasEl.value.addEventListener('mousedown', handleCanvasMouseDown);
|
||||
@ -353,35 +369,48 @@
|
||||
updateCanvasSize();
|
||||
};
|
||||
|
||||
/**
|
||||
* Component lifecycle hook - setup
|
||||
*/
|
||||
onMounted(async () => {
|
||||
// Set up global event listeners
|
||||
window.addEventListener('keydown', handleKeyDown);
|
||||
window.addEventListener('keyup', handleKeyUp);
|
||||
window.addEventListener('resize', handleResize);
|
||||
try {
|
||||
// Set up global event listeners
|
||||
window.addEventListener('keydown', handleKeyDown);
|
||||
window.addEventListener('keyup', handleKeyUp);
|
||||
window.addEventListener('resize', handleResize);
|
||||
|
||||
// Initialize the canvas
|
||||
await nextTick();
|
||||
initializeCanvas();
|
||||
// Initialize the canvas after DOM is updated
|
||||
await nextTick();
|
||||
initializeCanvas();
|
||||
|
||||
// Observe container size changes
|
||||
if ('ResizeObserver' in window) {
|
||||
const resizeObserver = new ResizeObserver(() => {
|
||||
updateCanvasSize();
|
||||
});
|
||||
// Set up ResizeObserver to handle container size changes
|
||||
if ('ResizeObserver' in window) {
|
||||
const resizeObserver = new ResizeObserver(() => {
|
||||
updateCanvasSize();
|
||||
});
|
||||
|
||||
if (containerEl.value) {
|
||||
resizeObserver.observe(containerEl.value);
|
||||
if (containerEl.value) {
|
||||
resizeObserver.observe(containerEl.value);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Error during component mount:', error);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Initialize the canvas and set up required event handlers
|
||||
*/
|
||||
const initializeCanvas = () => {
|
||||
if (!canvasEl.value || !containerEl.value) return;
|
||||
if (!canvasEl.value || !containerEl.value) {
|
||||
logger.error('Canvas or container element not available');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const context = canvasEl.value.getContext('2d');
|
||||
if (!context) {
|
||||
console.error('Failed to get 2D context from canvas');
|
||||
logger.error('Failed to get 2D context from canvas');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -389,9 +418,6 @@
|
||||
store.canvas.value = canvasEl.value;
|
||||
store.ctx.value = context;
|
||||
|
||||
// Set up the checkerboard pattern
|
||||
setupCheckerboardPattern();
|
||||
|
||||
// Set up canvas mouse events
|
||||
setupCanvasEvents();
|
||||
|
||||
@ -405,23 +431,30 @@
|
||||
store.renderSpritesheetPreview();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error initializing canvas:', error);
|
||||
logger.error('Error initializing canvas:', error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Component lifecycle hook - cleanup
|
||||
*/
|
||||
onBeforeUnmount(() => {
|
||||
// Remove global event listeners
|
||||
window.removeEventListener('keydown', handleKeyDown);
|
||||
window.removeEventListener('keyup', handleKeyUp);
|
||||
window.removeEventListener('resize', handleResize);
|
||||
try {
|
||||
// Remove global event listeners
|
||||
window.removeEventListener('keydown', handleKeyDown);
|
||||
window.removeEventListener('keyup', handleKeyUp);
|
||||
window.removeEventListener('resize', handleResize);
|
||||
|
||||
// Remove canvas event listeners
|
||||
if (canvasEl.value) {
|
||||
canvasEl.value.removeEventListener('mousedown', handleCanvasMouseDown);
|
||||
canvasEl.value.removeEventListener('mousemove', handleCanvasMouseMove);
|
||||
canvasEl.value.removeEventListener('mouseup', handleCanvasMouseUp);
|
||||
canvasEl.value.removeEventListener('mouseleave', handleCanvasMouseLeave);
|
||||
canvasEl.value.removeEventListener('contextmenu', preventContextMenu);
|
||||
// Remove canvas event listeners
|
||||
if (canvasEl.value) {
|
||||
canvasEl.value.removeEventListener('mousedown', handleCanvasMouseDown);
|
||||
canvasEl.value.removeEventListener('mousemove', handleCanvasMouseMove);
|
||||
canvasEl.value.removeEventListener('mouseup', handleCanvasMouseUp);
|
||||
canvasEl.value.removeEventListener('mouseleave', handleCanvasMouseLeave);
|
||||
canvasEl.value.removeEventListener('contextmenu', preventContextMenu);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Error during component unmount:', error);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
Loading…
x
Reference in New Issue
Block a user