[FEAT] add grid metrics
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import { ref, computed, type Ref, type ComputedRef } from 'vue';
|
||||
import type { Sprite, Layer } from '@/types/sprites';
|
||||
import { getMaxDimensions } from './useSprites';
|
||||
import { calculateNegativeSpacing } from './useNegativeSpacing';
|
||||
import { useGridMetrics, type GridMetrics } from './useGridMetrics';
|
||||
|
||||
export interface CellPosition {
|
||||
col: number;
|
||||
@@ -70,70 +69,42 @@ export function useDragSprite(options: DragSpriteOptions) {
|
||||
const ghostSprite = ref<{ id: string; x: number; y: number } | null>(null);
|
||||
const highlightCell = ref<CellPosition | null>(null);
|
||||
|
||||
// Cache for max dimensions
|
||||
const lastMaxWidth = ref(1);
|
||||
const lastMaxHeight = ref(1);
|
||||
// Use the new useGridMetrics composable for consistent calculations
|
||||
const gridMetricsComposable = useGridMetrics({
|
||||
layers: options.layers,
|
||||
sprites: options.sprites,
|
||||
negativeSpacingEnabled: options.negativeSpacingEnabled,
|
||||
manualCellSizeEnabled: options.manualCellSizeEnabled,
|
||||
manualCellWidth: options.manualCellWidth,
|
||||
manualCellHeight: options.manualCellHeight,
|
||||
});
|
||||
|
||||
const calculateMaxDimensions = () => {
|
||||
const negativeSpacingEnabled = getNegativeSpacingEnabled();
|
||||
const manualCellSizeEnabled = getManualCellSizeEnabled();
|
||||
|
||||
// If manual cell size is enabled, use manual dimensions
|
||||
if (manualCellSizeEnabled) {
|
||||
const maxWidth = getManualCellWidth();
|
||||
const maxHeight = getManualCellHeight();
|
||||
// When manual cell size is used, negative spacing is not applied
|
||||
const negativeSpacing = 0;
|
||||
// Don't update lastMaxWidth/lastMaxHeight when in manual mode
|
||||
return { maxWidth, maxHeight, negativeSpacing };
|
||||
}
|
||||
|
||||
// Get all sprites to calculate dimensions from
|
||||
// If layers are provided, use ALL layers (regardless of visibility) to keep canvas size stable
|
||||
const layers = getLayers();
|
||||
const spritesToMeasure = layers ? layers.flatMap(l => l.sprites) : getSprites();
|
||||
|
||||
// Otherwise, calculate based on sprite dimensions across all visible layers
|
||||
const base = getMaxDimensions(spritesToMeasure);
|
||||
// When switching back from manual mode, reset to actual sprite dimensions
|
||||
const baseMaxWidth = Math.max(1, base.maxWidth);
|
||||
const baseMaxHeight = Math.max(1, base.maxHeight);
|
||||
lastMaxWidth.value = baseMaxWidth;
|
||||
lastMaxHeight.value = baseMaxHeight;
|
||||
|
||||
// Calculate negative spacing using shared composable
|
||||
const negativeSpacing = Math.round(calculateNegativeSpacing(spritesToMeasure, negativeSpacingEnabled));
|
||||
|
||||
// Add negative spacing to expand each cell
|
||||
const maxWidth = Math.round(baseMaxWidth + negativeSpacing);
|
||||
const maxHeight = Math.round(baseMaxHeight + negativeSpacing);
|
||||
return { maxWidth, maxHeight, negativeSpacing };
|
||||
const calculateMaxDimensions = (): GridMetrics => {
|
||||
return gridMetricsComposable.calculateCellDimensions();
|
||||
};
|
||||
|
||||
// Computed sprite positions
|
||||
const spritePositions = computed<SpritePosition[]>(() => {
|
||||
const sprites = getSprites();
|
||||
const columns = getColumns();
|
||||
const { maxWidth, maxHeight, negativeSpacing } = calculateMaxDimensions();
|
||||
const metrics = calculateMaxDimensions();
|
||||
|
||||
return sprites.map((sprite, index) => {
|
||||
const col = index % columns;
|
||||
const row = Math.floor(index / columns);
|
||||
const cellPos = gridMetricsComposable.getCellPosition(index, columns, metrics);
|
||||
const canvasPos = gridMetricsComposable.getSpriteCanvasPosition(sprite, index, columns, metrics);
|
||||
|
||||
// With negative spacing, sprites are positioned at bottom-right of cell
|
||||
// (spacing added to top and left)
|
||||
return {
|
||||
id: sprite.id,
|
||||
canvasX: Math.round(col * maxWidth + negativeSpacing + sprite.x),
|
||||
canvasY: Math.round(row * maxHeight + negativeSpacing + sprite.y),
|
||||
cellX: Math.round(col * maxWidth),
|
||||
cellY: Math.round(row * maxHeight),
|
||||
canvasX: canvasPos.canvasX,
|
||||
canvasY: canvasPos.canvasY,
|
||||
cellX: canvasPos.cellX,
|
||||
cellY: canvasPos.cellY,
|
||||
width: Math.round(sprite.width),
|
||||
height: Math.round(sprite.height),
|
||||
maxWidth: Math.round(maxWidth),
|
||||
maxHeight: Math.round(maxHeight),
|
||||
col,
|
||||
row,
|
||||
maxWidth: metrics.maxWidth,
|
||||
maxHeight: metrics.maxHeight,
|
||||
col: cellPos.col,
|
||||
row: cellPos.row,
|
||||
index,
|
||||
x: sprite.x,
|
||||
y: sprite.y,
|
||||
|
||||
Reference in New Issue
Block a user