[FEAT] add grid metrics

This commit is contained in:
2026-01-01 17:14:21 +01:00
parent 281a37fa7e
commit 1f9fc4d5bb
5 changed files with 352 additions and 128 deletions

View File

@@ -204,6 +204,8 @@
import type { Sprite } from '@/types/sprites';
import { useDragSprite } from '@/composables/useDragSprite';
import { useFileDrop } from '@/composables/useFileDrop';
import { useGridMetrics } from '@/composables/useGridMetrics';
import { useBackgroundStyles } from '@/composables/useBackgroundStyles';
import type { Layer } from '@/types/sprites';
@@ -315,8 +317,16 @@
}
);
// Grid metrics
const gridMetrics = computed(() => calculateMaxDimensions());
// Use the new useGridMetrics composable for consistent calculations
const { gridMetrics: gridMetricsRef, getCellPosition: getCellPositionHelper } = useGridMetrics({
layers: toRef(props, 'layers'),
negativeSpacingEnabled: toRef(settingsStore, 'negativeSpacingEnabled'),
manualCellSizeEnabled: toRef(settingsStore, 'manualCellSizeEnabled'),
manualCellWidth: toRef(settingsStore, 'manualCellWidth'),
manualCellHeight: toRef(settingsStore, 'manualCellHeight'),
});
const gridMetrics = gridMetricsRef;
const totalCells = computed(() => {
// Use all layers regardless of visibility to keep canvas size stable
@@ -335,47 +345,20 @@
});
const getCellPosition = (index: number) => {
const col = index % props.columns;
const row = Math.floor(index / props.columns);
return {
x: Math.round(col * gridMetrics.value.maxWidth),
y: Math.round(row * gridMetrics.value.maxHeight),
};
return getCellPositionHelper(index, props.columns, gridMetrics.value);
};
const getCellBackground = () => {
const bg = settingsStore.backgroundColor;
if (bg === 'transparent') {
return 'transparent';
}
return bg;
};
// Use the new useBackgroundStyles composable for consistent background styling
const { backgroundColor: cellBackgroundColor, backgroundImage: cellBackgroundImage, backgroundSize: cellBackgroundSize, backgroundPosition: cellBackgroundPosition } = useBackgroundStyles({
backgroundColor: toRef(settingsStore, 'backgroundColor'),
checkerboardEnabled: toRef(settingsStore, 'checkerboardEnabled'),
darkMode: toRef(settingsStore, 'darkMode'),
});
const getCellBackgroundImage = () => {
const bg = settingsStore.backgroundColor;
if (bg === 'transparent' && settingsStore.checkerboardEnabled) {
// Checkerboard pattern for transparent backgrounds (dark mode friendly)
const color = settingsStore.darkMode ? '#4b5563' : '#d1d5db';
return `linear-gradient(45deg, ${color} 25%, transparent 25%), linear-gradient(-45deg, ${color} 25%, transparent 25%), linear-gradient(45deg, transparent 75%, ${color} 75%), linear-gradient(-45deg, transparent 75%, ${color} 75%)`;
}
return 'none';
};
const getCellBackgroundSize = () => {
const bg = settingsStore.backgroundColor;
if (bg === 'transparent') {
return '20px 20px';
}
return 'auto';
};
const getCellBackgroundPosition = () => {
const bg = settingsStore.backgroundColor;
if (bg === 'transparent') {
return '0 0, 0 10px, 10px -10px, -10px 0px';
}
return '0 0';
};
const getCellBackground = () => cellBackgroundColor.value;
const getCellBackgroundImage = () => cellBackgroundImage.value;
const getCellBackgroundSize = () => cellBackgroundSize.value;
const getCellBackgroundPosition = () => cellBackgroundPosition.value;
const startDrag = (event: MouseEvent) => {
// If the click originated from an interactive element (button, link, input), ignore drag handling