Finish clean, add negative spacing toggle
This commit is contained in:
@@ -30,6 +30,7 @@ export interface DragSpriteOptions {
|
||||
columns: Ref<number> | number;
|
||||
zoom?: Ref<number>;
|
||||
allowCellSwap?: Ref<boolean>;
|
||||
negativeSpacingEnabled?: Ref<boolean>;
|
||||
getMousePosition: (event: MouseEvent, zoom?: number) => { x: number; y: number } | null;
|
||||
onUpdateSprite: (id: string, x: number, y: number) => void;
|
||||
onUpdateSpriteCell?: (id: string, newIndex: number) => void;
|
||||
@@ -44,6 +45,7 @@ export function useDragSprite(options: DragSpriteOptions) {
|
||||
const getColumns = () => (typeof options.columns === 'number' ? options.columns : options.columns.value);
|
||||
const getZoom = () => options.zoom?.value ?? 1;
|
||||
const getAllowCellSwap = () => options.allowCellSwap?.value ?? false;
|
||||
const getNegativeSpacingEnabled = () => options.negativeSpacingEnabled?.value ?? false;
|
||||
|
||||
// Drag state
|
||||
const isDragging = ref(false);
|
||||
@@ -65,28 +67,47 @@ export function useDragSprite(options: DragSpriteOptions) {
|
||||
|
||||
const calculateMaxDimensions = () => {
|
||||
const sprites = getSprites();
|
||||
const negativeSpacingEnabled = getNegativeSpacingEnabled();
|
||||
const base = getMaxDimensions(sprites);
|
||||
const maxWidth = Math.max(1, base.maxWidth, lastMaxWidth.value);
|
||||
const maxHeight = Math.max(1, base.maxHeight, lastMaxHeight.value);
|
||||
lastMaxWidth.value = maxWidth;
|
||||
lastMaxHeight.value = maxHeight;
|
||||
return { maxWidth, maxHeight };
|
||||
const baseMaxWidth = Math.max(1, base.maxWidth, lastMaxWidth.value);
|
||||
const baseMaxHeight = Math.max(1, base.maxHeight, lastMaxHeight.value);
|
||||
lastMaxWidth.value = baseMaxWidth;
|
||||
lastMaxHeight.value = baseMaxHeight;
|
||||
|
||||
// Calculate negative spacing based on sprite size differences
|
||||
let negativeSpacing = 0;
|
||||
if (negativeSpacingEnabled && sprites.length > 0) {
|
||||
// Find the smallest sprite dimensions
|
||||
const minWidth = Math.min(...sprites.map(s => s.width));
|
||||
const minHeight = Math.min(...sprites.map(s => s.height));
|
||||
// Negative spacing is the difference between max and min dimensions
|
||||
const widthDiff = baseMaxWidth - minWidth;
|
||||
const heightDiff = baseMaxHeight - minHeight;
|
||||
negativeSpacing = Math.max(widthDiff, heightDiff);
|
||||
}
|
||||
|
||||
// Add negative spacing to expand each cell
|
||||
const maxWidth = baseMaxWidth + negativeSpacing;
|
||||
const maxHeight = baseMaxHeight + negativeSpacing;
|
||||
return { maxWidth, maxHeight, negativeSpacing };
|
||||
};
|
||||
|
||||
// Computed sprite positions
|
||||
const spritePositions = computed<SpritePosition[]>(() => {
|
||||
const sprites = getSprites();
|
||||
const columns = getColumns();
|
||||
const { maxWidth, maxHeight } = calculateMaxDimensions();
|
||||
const { maxWidth, maxHeight, negativeSpacing } = calculateMaxDimensions();
|
||||
|
||||
return sprites.map((sprite, index) => {
|
||||
const col = index % columns;
|
||||
const row = Math.floor(index / columns);
|
||||
|
||||
// With negative spacing, sprites are positioned at bottom-right of cell
|
||||
// (spacing added to top and left)
|
||||
return {
|
||||
id: sprite.id,
|
||||
canvasX: col * maxWidth + sprite.x,
|
||||
canvasY: row * maxHeight + sprite.y,
|
||||
canvasX: col * maxWidth + negativeSpacing + sprite.x,
|
||||
canvasY: row * maxHeight + negativeSpacing + sprite.y,
|
||||
cellX: col * maxWidth,
|
||||
cellY: row * maxHeight,
|
||||
width: sprite.width,
|
||||
@@ -162,7 +183,7 @@ export function useDragSprite(options: DragSpriteOptions) {
|
||||
if (!activeSpriteId.value) return;
|
||||
const sprites = getSprites();
|
||||
const columns = getColumns();
|
||||
const { maxWidth, maxHeight } = calculateMaxDimensions();
|
||||
const { maxWidth, maxHeight, negativeSpacing } = calculateMaxDimensions();
|
||||
|
||||
// Use the sprite's current index in the array to calculate cell position
|
||||
const cellCol = spriteIndex % columns;
|
||||
@@ -170,11 +191,15 @@ export function useDragSprite(options: DragSpriteOptions) {
|
||||
const cellX = cellCol * maxWidth;
|
||||
const cellY = cellRow * maxHeight;
|
||||
|
||||
const newX = mouseX - cellX - dragOffsetX.value;
|
||||
const newY = mouseY - cellY - dragOffsetY.value;
|
||||
// Calculate new position relative to cell origin (without the negative spacing offset)
|
||||
// The sprite's x,y is stored relative to where it would be drawn after the negativeSpacing offset
|
||||
const newX = mouseX - cellX - negativeSpacing - dragOffsetX.value;
|
||||
const newY = mouseY - cellY - negativeSpacing - dragOffsetY.value;
|
||||
|
||||
const constrainedX = Math.floor(Math.max(0, Math.min(maxWidth - sprites[spriteIndex].width, newX)));
|
||||
const constrainedY = Math.floor(Math.max(0, Math.min(maxHeight - sprites[spriteIndex].height, newY)));
|
||||
// The sprite can move within the full expanded cell area
|
||||
// Allow negative values up to -negativeSpacing so sprite can fill the expanded area
|
||||
const constrainedX = Math.floor(Math.max(-negativeSpacing, Math.min(maxWidth - negativeSpacing - sprites[spriteIndex].width, newX)));
|
||||
const constrainedY = Math.floor(Math.max(-negativeSpacing, Math.min(maxHeight - negativeSpacing - sprites[spriteIndex].height, newY)));
|
||||
|
||||
onUpdateSprite(activeSpriteId.value, constrainedX, constrainedY);
|
||||
onDraw();
|
||||
|
||||
Reference in New Issue
Block a user