Bett
This commit is contained in:
parent
293bed9135
commit
8eec236105
@ -80,7 +80,7 @@
|
|||||||
<div class="flex flex-col justify-center items-center bg-gray-700 p-6 rounded mb-6 relative overflow-auto flex-grow">
|
<div class="flex flex-col justify-center items-center bg-gray-700 p-6 rounded mb-6 relative overflow-auto flex-grow">
|
||||||
<!-- Tooltip for dragging instructions -->
|
<!-- Tooltip for dragging instructions -->
|
||||||
<div class="text-xs text-gray-400 mb-2" v-if="sprites.length > 0">
|
<div class="text-xs text-gray-400 mb-2" v-if="sprites.length > 0">
|
||||||
<span>Position: {{ Math.round(spriteOffset.x) }}px, {{ Math.round(spriteOffset.y) }}px (drag to move within cell)</span>
|
<span>Position: {{ Math.round(spriteOffset?.x ?? 0) }}px, {{ Math.round(spriteOffset?.y ?? 0) }}px (drag to move within cell)</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@ -129,6 +129,9 @@
|
|||||||
const store = useSpritesheetStore();
|
const store = useSpritesheetStore();
|
||||||
const animCanvas = ref<HTMLCanvasElement | null>(null);
|
const animCanvas = ref<HTMLCanvasElement | null>(null);
|
||||||
|
|
||||||
|
// Add this constant for pan amount
|
||||||
|
const panAmount = 10; // pixels to pan per keypress
|
||||||
|
|
||||||
const isModalOpen = computed({
|
const isModalOpen = computed({
|
||||||
get: () => store.isModalOpen.value,
|
get: () => store.isModalOpen.value,
|
||||||
set: value => {
|
set: value => {
|
||||||
@ -150,20 +153,18 @@
|
|||||||
get: () => {
|
get: () => {
|
||||||
// Get the offset for the current frame
|
// Get the offset for the current frame
|
||||||
const frameOffset = store.getSpriteOffset(currentFrame.value);
|
const frameOffset = store.getSpriteOffset(currentFrame.value);
|
||||||
// Update the current offset for UI display
|
// Return the frame-specific offset directly
|
||||||
store.currentSpriteOffset.x = frameOffset.x;
|
return frameOffset;
|
||||||
store.currentSpriteOffset.y = frameOffset.y;
|
|
||||||
return store.currentSpriteOffset;
|
|
||||||
},
|
},
|
||||||
set: val => {
|
set: val => {
|
||||||
// Update both the current offset and the frame-specific offset
|
// Update the frame-specific offset directly
|
||||||
store.currentSpriteOffset.x = val.x;
|
|
||||||
store.currentSpriteOffset.y = val.y;
|
|
||||||
|
|
||||||
// Get the frame-specific offset and update it
|
|
||||||
const frameOffset = store.getSpriteOffset(currentFrame.value);
|
const frameOffset = store.getSpriteOffset(currentFrame.value);
|
||||||
frameOffset.x = val.x;
|
frameOffset.x = val.x;
|
||||||
frameOffset.y = val.y;
|
frameOffset.y = val.y;
|
||||||
|
|
||||||
|
// Also update the current offset for UI consistency
|
||||||
|
store.currentSpriteOffset.x = val.x;
|
||||||
|
store.currentSpriteOffset.y = val.y;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const isCanvasDragging = ref(false);
|
const isCanvasDragging = ref(false);
|
||||||
@ -184,7 +185,7 @@
|
|||||||
|
|
||||||
// Computed property to check if sprite has been moved from original position
|
// Computed property to check if sprite has been moved from original position
|
||||||
const hasSpriteOffset = computed(() => {
|
const hasSpriteOffset = computed(() => {
|
||||||
return spriteOffset.x !== 0 || spriteOffset.y !== 0;
|
return spriteOffset.value.x !== 0 || spriteOffset.value.y !== 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
// applyOffsetsToMainView function removed
|
// applyOffsetsToMainView function removed
|
||||||
@ -298,10 +299,6 @@
|
|||||||
frameOffset.y = centerY;
|
frameOffset.y = centerY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the current offset for UI display
|
|
||||||
store.currentSpriteOffset.x = frameOffset.x;
|
|
||||||
store.currentSpriteOffset.y = frameOffset.y;
|
|
||||||
|
|
||||||
// Render with the frame-specific offset
|
// Render with the frame-specific offset
|
||||||
store.renderAnimationFrame(0, showAllSprites.value, frameOffset);
|
store.renderAnimationFrame(0, showAllSprites.value, frameOffset);
|
||||||
}
|
}
|
||||||
@ -357,9 +354,8 @@
|
|||||||
animation.value.currentFrame = currentFrame.value;
|
animation.value.currentFrame = currentFrame.value;
|
||||||
animation.value.manualUpdate = true;
|
animation.value.manualUpdate = true;
|
||||||
|
|
||||||
// Get the frame-specific offset
|
// Use the computed spriteOffset directly
|
||||||
const frameOffset = store.getSpriteOffset(currentFrame.value);
|
store.renderAnimationFrame(currentFrame.value, showAllSprites.value, spriteOffset.value);
|
||||||
store.renderAnimationFrame(currentFrame.value, showAllSprites.value, frameOffset);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleFrameRateChange = () => {
|
const handleFrameRateChange = () => {
|
||||||
@ -438,14 +434,8 @@
|
|||||||
const centerX = Math.max(0, Math.floor((store.cellSize.width - currentSprite.width) / 2));
|
const centerX = Math.max(0, Math.floor((store.cellSize.width - currentSprite.width) / 2));
|
||||||
const centerY = Math.max(0, Math.floor((store.cellSize.height - currentSprite.height) / 2));
|
const centerY = Math.max(0, Math.floor((store.cellSize.height - currentSprite.height) / 2));
|
||||||
|
|
||||||
// Reset the sprite offset for the current frame to the center position
|
// Update the sprite offset using the computed property setter
|
||||||
const frameOffset = store.getSpriteOffset(currentFrame.value);
|
spriteOffset.value = { x: centerX, y: centerY };
|
||||||
frameOffset.x = centerX;
|
|
||||||
frameOffset.y = centerY;
|
|
||||||
|
|
||||||
// Also update the current offset
|
|
||||||
store.currentSpriteOffset.x = centerX;
|
|
||||||
store.currentSpriteOffset.y = centerY;
|
|
||||||
|
|
||||||
// Update the frame to reflect the change
|
// Update the frame to reflect the change
|
||||||
updateFrame();
|
updateFrame();
|
||||||
@ -497,9 +487,6 @@
|
|||||||
// Only move when delta exceeds the threshold for one pixel movement at current zoom
|
// Only move when delta exceeds the threshold for one pixel movement at current zoom
|
||||||
const pixelThreshold = previewZoom.value; // One pixel at current zoom level
|
const pixelThreshold = previewZoom.value; // One pixel at current zoom level
|
||||||
|
|
||||||
// Get the frame-specific offset
|
|
||||||
const frameOffset = store.getSpriteOffset(currentFrame.value);
|
|
||||||
|
|
||||||
// Calculate the maximum allowed offset
|
// Calculate the maximum allowed offset
|
||||||
const maxOffsetX = Math.max(0, store.cellSize.width - currentSprite.width);
|
const maxOffsetX = Math.max(0, store.cellSize.width - currentSprite.width);
|
||||||
const maxOffsetY = Math.max(0, store.cellSize.height - currentSprite.height);
|
const maxOffsetY = Math.max(0, store.cellSize.height - currentSprite.height);
|
||||||
@ -507,8 +494,8 @@
|
|||||||
// Move one pixel at a time when threshold is reached
|
// Move one pixel at a time when threshold is reached
|
||||||
if (Math.abs(deltaX) >= pixelThreshold) {
|
if (Math.abs(deltaX) >= pixelThreshold) {
|
||||||
const pixelsToMove = Math.sign(deltaX);
|
const pixelsToMove = Math.sign(deltaX);
|
||||||
const newX = frameOffset.x + pixelsToMove;
|
const newX = spriteOffset.value.x + pixelsToMove;
|
||||||
frameOffset.x = Math.max(0, Math.min(maxOffsetX, newX));
|
spriteOffset.value.x = Math.max(0, Math.min(maxOffsetX, newX));
|
||||||
|
|
||||||
// Reset the start X position for next pixel move
|
// Reset the start X position for next pixel move
|
||||||
canvasDragStart.value.x = e.clientX;
|
canvasDragStart.value.x = e.clientX;
|
||||||
@ -516,17 +503,13 @@
|
|||||||
|
|
||||||
if (Math.abs(deltaY) >= pixelThreshold) {
|
if (Math.abs(deltaY) >= pixelThreshold) {
|
||||||
const pixelsToMove = Math.sign(deltaY);
|
const pixelsToMove = Math.sign(deltaY);
|
||||||
const newY = frameOffset.y + pixelsToMove;
|
const newY = spriteOffset.value.y + pixelsToMove;
|
||||||
frameOffset.y = Math.max(0, Math.min(maxOffsetY, newY));
|
spriteOffset.value.y = Math.max(0, Math.min(maxOffsetY, newY));
|
||||||
|
|
||||||
// Reset the start Y position for next pixel move
|
// Reset the start Y position for next pixel move
|
||||||
canvasDragStart.value.y = e.clientY;
|
canvasDragStart.value.y = e.clientY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the current offset to match
|
|
||||||
store.currentSpriteOffset.x = frameOffset.x;
|
|
||||||
store.currentSpriteOffset.y = frameOffset.y;
|
|
||||||
|
|
||||||
// Update the frame
|
// Update the frame
|
||||||
updateFrame();
|
updateFrame();
|
||||||
|
|
||||||
@ -651,7 +634,7 @@
|
|||||||
if (isModalOpen.value && newSprites.length > 0) {
|
if (isModalOpen.value && newSprites.length > 0) {
|
||||||
updateCanvasSize();
|
updateCanvasSize();
|
||||||
updateCanvasContainerSize();
|
updateCanvasContainerSize();
|
||||||
store.renderAnimationFrame(currentFrame.value, showAllSprites.value, spriteOffset.value);
|
updateFrame();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
@ -670,7 +653,7 @@
|
|||||||
() => previewBorder.value,
|
() => previewBorder.value,
|
||||||
() => {
|
() => {
|
||||||
if (isModalOpen.value && sprites.value.length > 0) {
|
if (isModalOpen.value && sprites.value.length > 0) {
|
||||||
store.renderAnimationFrame(currentFrame.value, showAllSprites.value, spriteOffset.value);
|
updateFrame();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
@ -681,7 +664,7 @@
|
|||||||
() => showAllSprites.value,
|
() => showAllSprites.value,
|
||||||
() => {
|
() => {
|
||||||
if (isModalOpen.value && sprites.value.length > 0) {
|
if (isModalOpen.value && sprites.value.length > 0) {
|
||||||
store.renderAnimationFrame(currentFrame.value, showAllSprites.value, spriteOffset.value);
|
updateFrame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -259,9 +259,21 @@ export function useSpritesheetStore() {
|
|||||||
// Get the frame-specific offset for this sprite
|
// Get the frame-specific offset for this sprite
|
||||||
const frameOffset = getSpriteOffset(index);
|
const frameOffset = getSpriteOffset(index);
|
||||||
|
|
||||||
// Apply the frame-specific offset to the sprite position
|
// Calculate the maximum allowed offset based on sprite and cell size
|
||||||
const finalX = x + frameOffset.x;
|
const maxOffsetX = Math.max(0, cellSize.width - sprite.width);
|
||||||
const finalY = y + frameOffset.y;
|
const maxOffsetY = Math.max(0, cellSize.height - sprite.height);
|
||||||
|
|
||||||
|
// Constrain the offset to prevent out-of-bounds positioning
|
||||||
|
const constrainedOffsetX = Math.max(0, Math.min(maxOffsetX, frameOffset.x));
|
||||||
|
const constrainedOffsetY = Math.max(0, Math.min(maxOffsetY, frameOffset.y));
|
||||||
|
|
||||||
|
// Update the frame offset with the constrained values
|
||||||
|
frameOffset.x = constrainedOffsetX;
|
||||||
|
frameOffset.y = constrainedOffsetY;
|
||||||
|
|
||||||
|
// Apply the constrained offset to the sprite position
|
||||||
|
const finalX = x + constrainedOffsetX;
|
||||||
|
const finalY = y + constrainedOffsetY;
|
||||||
|
|
||||||
// Draw the image at its final position with pixel-perfect rendering
|
// Draw the image at its final position with pixel-perfect rendering
|
||||||
ctx.value!.imageSmoothingEnabled = false; // Keep pixel art sharp
|
ctx.value!.imageSmoothingEnabled = false; // Keep pixel art sharp
|
||||||
@ -277,9 +289,21 @@ export function useSpritesheetStore() {
|
|||||||
// Get the frame-specific offset for this sprite
|
// Get the frame-specific offset for this sprite
|
||||||
const frameOffset = getSpriteOffset(index);
|
const frameOffset = getSpriteOffset(index);
|
||||||
|
|
||||||
// Apply the frame-specific offset to the sprite position
|
// Calculate the maximum allowed offset based on sprite and cell size
|
||||||
const finalX = x + frameOffset.x;
|
const maxOffsetX = Math.max(0, cellSize.width - sprite.width);
|
||||||
const finalY = y + frameOffset.y;
|
const maxOffsetY = Math.max(0, cellSize.height - sprite.height);
|
||||||
|
|
||||||
|
// Constrain the offset to prevent out-of-bounds positioning
|
||||||
|
const constrainedOffsetX = Math.max(0, Math.min(maxOffsetX, frameOffset.x));
|
||||||
|
const constrainedOffsetY = Math.max(0, Math.min(maxOffsetY, frameOffset.y));
|
||||||
|
|
||||||
|
// Update the frame offset with the constrained values
|
||||||
|
frameOffset.x = constrainedOffsetX;
|
||||||
|
frameOffset.y = constrainedOffsetY;
|
||||||
|
|
||||||
|
// Apply the constrained offset to the sprite position
|
||||||
|
const finalX = x + constrainedOffsetX;
|
||||||
|
const finalY = y + constrainedOffsetY;
|
||||||
|
|
||||||
ctx.value.imageSmoothingEnabled = false; // Keep pixel art sharp
|
ctx.value.imageSmoothingEnabled = false; // Keep pixel art sharp
|
||||||
ctx.value.drawImage(sprite.img, finalX, finalY, sprite.width, sprite.height);
|
ctx.value.drawImage(sprite.img, finalX, finalY, sprite.width, sprite.height);
|
||||||
@ -432,11 +456,33 @@ export function useSpritesheetStore() {
|
|||||||
// Ensure pixel art remains sharp in the downloaded file
|
// Ensure pixel art remains sharp in the downloaded file
|
||||||
tempCtx.imageSmoothingEnabled = false;
|
tempCtx.imageSmoothingEnabled = false;
|
||||||
|
|
||||||
sprites.value.forEach(sprite => {
|
sprites.value.forEach((sprite, index) => {
|
||||||
// Use rounded coordinates for pixel-perfect rendering
|
// Get the frame-specific offset for this sprite
|
||||||
const x = Math.round(sprite.x);
|
const frameOffset = getSpriteOffset(index);
|
||||||
const y = Math.round(sprite.y);
|
|
||||||
tempCtx.drawImage(sprite.img, x, y);
|
// Calculate the cell coordinates for this sprite
|
||||||
|
const cellX = Math.floor(sprite.x / cellSize.width);
|
||||||
|
const cellY = Math.floor(sprite.y / cellSize.height);
|
||||||
|
|
||||||
|
// Calculate the base position within the cell
|
||||||
|
const baseX = cellX * cellSize.width;
|
||||||
|
const baseY = cellY * cellSize.height;
|
||||||
|
|
||||||
|
// Calculate the maximum allowed offset based on sprite and cell size
|
||||||
|
// This prevents sprites from going out of bounds
|
||||||
|
const maxOffsetX = Math.max(0, cellSize.width - sprite.width);
|
||||||
|
const maxOffsetY = Math.max(0, cellSize.height - sprite.height);
|
||||||
|
|
||||||
|
// Constrain the offset to prevent out-of-bounds positioning
|
||||||
|
const constrainedOffsetX = Math.max(0, Math.min(maxOffsetX, frameOffset.x));
|
||||||
|
const constrainedOffsetY = Math.max(0, Math.min(maxOffsetY, frameOffset.y));
|
||||||
|
|
||||||
|
// Apply the constrained offset to the base position
|
||||||
|
const finalX = baseX + constrainedOffsetX;
|
||||||
|
const finalY = baseY + constrainedOffsetY;
|
||||||
|
|
||||||
|
// Draw the sprite at the calculated position
|
||||||
|
tempCtx.drawImage(sprite.img, finalX, finalY, sprite.width, sprite.height);
|
||||||
});
|
});
|
||||||
|
|
||||||
const link = document.createElement('a');
|
const link = document.createElement('a');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user