Export negative offset bug fixes
This commit is contained in:
@@ -135,7 +135,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { ref, onMounted, toRef } from 'vue';
|
||||
import FileUploader from './components/FileUploader.vue';
|
||||
import SpriteCanvas from './components/SpriteCanvas.vue';
|
||||
import Modal from './components/utilities/Modal.vue';
|
||||
@@ -147,11 +147,13 @@
|
||||
import DarkModeToggle from './components/utilities/DarkModeToggle.vue';
|
||||
import { useSprites } from './composables/useSprites';
|
||||
import { useExport } from './composables/useExport';
|
||||
import { useSettingsStore } from './stores/useSettingsStore';
|
||||
import type { SpriteFile } from './types/sprites';
|
||||
|
||||
const settingsStore = useSettingsStore();
|
||||
const { sprites, columns, updateSpritePosition, updateSpriteCell, removeSprite, replaceSprite, addSprite, addSpriteWithResize, processImageFiles, alignSprites } = useSprites();
|
||||
|
||||
const { downloadSpritesheet, exportSpritesheetJSON, importSpritesheetJSON, downloadAsGif, downloadAsZip } = useExport(sprites, columns);
|
||||
const { downloadSpritesheet, exportSpritesheetJSON, importSpritesheetJSON, downloadAsGif, downloadAsZip } = useExport(sprites, columns, toRef(settingsStore, 'negativeSpacingEnabled'));
|
||||
const isPreviewModalOpen = ref(false);
|
||||
const isHelpModalOpen = ref(false);
|
||||
const isFeedbackModalOpen = ref(false);
|
||||
|
||||
@@ -5,7 +5,18 @@ import JSZip from 'jszip';
|
||||
import type { Sprite } from '../types/sprites';
|
||||
import { getMaxDimensions } from './useSprites';
|
||||
|
||||
export const useExport = (sprites: Ref<Sprite[]>, columns: Ref<number>) => {
|
||||
export const useExport = (sprites: Ref<Sprite[]>, columns: Ref<number>, negativeSpacingEnabled: Ref<boolean>) => {
|
||||
// Calculate negative spacing based on sprite dimensions
|
||||
const calculateNegativeSpacing = (): number => {
|
||||
if (!negativeSpacingEnabled.value || sprites.value.length === 0) return 0;
|
||||
|
||||
const { maxWidth, maxHeight } = getMaxDimensions(sprites.value);
|
||||
const minWidth = Math.min(...sprites.value.map(s => s.width));
|
||||
const minHeight = Math.min(...sprites.value.map(s => s.height));
|
||||
const widthDiff = maxWidth - minWidth;
|
||||
const heightDiff = maxHeight - minHeight;
|
||||
return Math.max(widthDiff, heightDiff);
|
||||
};
|
||||
const downloadSpritesheet = () => {
|
||||
if (!sprites.value.length) {
|
||||
alert('Please upload or import sprites before downloading the spritesheet.');
|
||||
@@ -13,22 +24,25 @@ export const useExport = (sprites: Ref<Sprite[]>, columns: Ref<number>) => {
|
||||
}
|
||||
|
||||
const { maxWidth, maxHeight } = getMaxDimensions(sprites.value);
|
||||
const negativeSpacing = calculateNegativeSpacing();
|
||||
const cellWidth = maxWidth + negativeSpacing;
|
||||
const cellHeight = maxHeight + negativeSpacing;
|
||||
const rows = Math.ceil(sprites.value.length / columns.value);
|
||||
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
if (!ctx) return;
|
||||
|
||||
canvas.width = maxWidth * columns.value;
|
||||
canvas.height = maxHeight * rows;
|
||||
canvas.width = cellWidth * columns.value;
|
||||
canvas.height = cellHeight * rows;
|
||||
ctx.imageSmoothingEnabled = false;
|
||||
|
||||
sprites.value.forEach((sprite, index) => {
|
||||
const col = index % columns.value;
|
||||
const row = Math.floor(index / columns.value);
|
||||
const cellX = Math.floor(col * maxWidth);
|
||||
const cellY = Math.floor(row * maxHeight);
|
||||
ctx.drawImage(sprite.img, Math.floor(cellX + sprite.x), Math.floor(cellY + sprite.y));
|
||||
const cellX = Math.floor(col * cellWidth);
|
||||
const cellY = Math.floor(row * cellHeight);
|
||||
ctx.drawImage(sprite.img, Math.floor(cellX + negativeSpacing + sprite.x), Math.floor(cellY + negativeSpacing + sprite.y));
|
||||
});
|
||||
|
||||
const link = document.createElement('a');
|
||||
@@ -133,20 +147,23 @@ export const useExport = (sprites: Ref<Sprite[]>, columns: Ref<number>) => {
|
||||
}
|
||||
|
||||
const { maxWidth, maxHeight } = getMaxDimensions(sprites.value);
|
||||
const negativeSpacing = calculateNegativeSpacing();
|
||||
const cellWidth = maxWidth + negativeSpacing;
|
||||
const cellHeight = maxHeight + negativeSpacing;
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
if (!ctx) return;
|
||||
canvas.width = maxWidth;
|
||||
canvas.height = maxHeight;
|
||||
canvas.width = cellWidth;
|
||||
canvas.height = cellHeight;
|
||||
ctx.imageSmoothingEnabled = false;
|
||||
|
||||
const gif = new GIF({ workers: 2, quality: 10, width: maxWidth, height: maxHeight, workerScript: gifWorkerUrl });
|
||||
const gif = new GIF({ workers: 2, quality: 10, width: cellWidth, height: cellHeight, workerScript: gifWorkerUrl });
|
||||
|
||||
sprites.value.forEach(sprite => {
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.fillStyle = '#f9fafb';
|
||||
ctx.fillRect(0, 0, maxWidth, maxHeight);
|
||||
ctx.drawImage(sprite.img, Math.floor(sprite.x), Math.floor(sprite.y));
|
||||
ctx.fillRect(0, 0, cellWidth, cellHeight);
|
||||
ctx.drawImage(sprite.img, Math.floor(negativeSpacing + sprite.x), Math.floor(negativeSpacing + sprite.y));
|
||||
gif.addFrame(ctx, { copy: true, delay: 1000 / fps });
|
||||
});
|
||||
|
||||
@@ -170,18 +187,21 @@ export const useExport = (sprites: Ref<Sprite[]>, columns: Ref<number>) => {
|
||||
|
||||
const zip = new JSZip();
|
||||
const { maxWidth, maxHeight } = getMaxDimensions(sprites.value);
|
||||
const negativeSpacing = calculateNegativeSpacing();
|
||||
const cellWidth = maxWidth + negativeSpacing;
|
||||
const cellHeight = maxHeight + negativeSpacing;
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
if (!ctx) return;
|
||||
canvas.width = maxWidth;
|
||||
canvas.height = maxHeight;
|
||||
canvas.width = cellWidth;
|
||||
canvas.height = cellHeight;
|
||||
ctx.imageSmoothingEnabled = false;
|
||||
|
||||
sprites.value.forEach((sprite, index) => {
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.fillStyle = '#f9fafb';
|
||||
ctx.fillRect(0, 0, maxWidth, maxHeight);
|
||||
ctx.drawImage(sprite.img, Math.floor(sprite.x), Math.floor(sprite.y));
|
||||
ctx.fillRect(0, 0, cellWidth, cellHeight);
|
||||
ctx.drawImage(sprite.img, Math.floor(negativeSpacing + sprite.x), Math.floor(negativeSpacing + sprite.y));
|
||||
const dataURL = canvas.toDataURL('image/png');
|
||||
const binary = atob(dataURL.split(',')[1]);
|
||||
const buf = new ArrayBuffer(binary.length);
|
||||
|
||||
Reference in New Issue
Block a user