[FEAT] Add sharing function, UI enhancement
This commit is contained in:
@@ -45,9 +45,9 @@
|
||||
</div>
|
||||
|
||||
<!-- Two-column layout: Left controls, Right preview -->
|
||||
<div v-if="layers.some(l => l.sprites.length)" class="flex flex-col flex-1 lg:grid lg:grid-cols-[380px_1fr] xl:grid-cols-[420px_1fr] lg:overflow-hidden">
|
||||
<div v-if="layers.some(l => l.sprites.length)" class="flex flex-col flex-1 lg:grid lg:grid-cols-[380px_1fr] xl:grid-cols-[420px_1fr] lg:overflow-hidden min-h-0">
|
||||
<!-- Left sidebar - Controls -->
|
||||
<div class="p-6 bg-gray-50/50 dark:bg-gray-900/30 border-b lg:border-b-0 lg:border-r border-gray-200 dark:border-gray-700 lg:overflow-y-auto lg:overflow-x-auto">
|
||||
<div class="p-6 bg-gray-50/50 dark:bg-gray-900/30 border-b lg:border-b-0 lg:border-r border-gray-200 dark:border-gray-700 lg:overflow-y-auto lg:overflow-x-auto lg:min-h-0">
|
||||
<div class="space-y-8">
|
||||
<!-- Upload Section -->
|
||||
<section>
|
||||
@@ -203,42 +203,58 @@
|
||||
<i class="fas fa-file-archive"></i>
|
||||
<span>ZIP</span>
|
||||
</button>
|
||||
<button @click="openShareModal" class="btn btn-dark btn-sm col-span-2" data-rybbit-event="share-spritesheet">
|
||||
<i class="fas fa-share-alt"></i>
|
||||
<span>Share</span>
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right panel - Tabs -->
|
||||
<div class="flex flex-col overflow-hidden">
|
||||
<div class="flex flex-col overflow-hidden min-h-0">
|
||||
<!-- Tab Navigation -->
|
||||
<div class="bg-gray-50/50 dark:bg-gray-900/30 border-b border-gray-200 dark:border-gray-700">
|
||||
<div class="flex gap-1 p-2">
|
||||
<button
|
||||
@click="activeTab = 'canvas'"
|
||||
class="border-gray-600 border"
|
||||
:class="['flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-lg transition-all cursor-pointer', activeTab === 'canvas' ? 'bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 shadow-sm' : 'text-gray-600 dark:text-gray-400 hover:bg-white/50 dark:hover:bg-gray-800/50']"
|
||||
>
|
||||
<i class="fas fa-th"></i>
|
||||
<span>Canvas</span>
|
||||
</button>
|
||||
<button
|
||||
@click="activeTab = 'preview'"
|
||||
class="border-gray-600 border"
|
||||
:class="['flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-lg transition-all cursor-pointer', activeTab === 'preview' ? 'bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 shadow-sm' : 'text-gray-600 dark:text-gray-400 hover:bg-white/50 dark:hover:bg-gray-800/50']"
|
||||
data-rybbit-event="preview-animation"
|
||||
>
|
||||
<i class="fas fa-play"></i>
|
||||
<span>Preview</span>
|
||||
<div class="flex items-center justify-between gap-1 p-2">
|
||||
<div class="flex gap-1">
|
||||
<button
|
||||
@click="activeTab = 'canvas'"
|
||||
class="border-gray-600 border"
|
||||
:class="[
|
||||
'flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-lg transition-all cursor-pointer',
|
||||
activeTab === 'canvas' ? 'bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 shadow-sm' : 'text-gray-600 dark:text-gray-400 hover:bg-white/50 dark:hover:bg-gray-800/50',
|
||||
]"
|
||||
>
|
||||
<i class="fas fa-th"></i>
|
||||
<span>Canvas</span>
|
||||
</button>
|
||||
<button
|
||||
@click="activeTab = 'preview'"
|
||||
class="border-gray-600 border"
|
||||
:class="[
|
||||
'flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-lg transition-all cursor-pointer',
|
||||
activeTab === 'preview' ? 'bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 shadow-sm' : 'text-gray-600 dark:text-gray-400 hover:bg-white/50 dark:hover:bg-gray-800/50',
|
||||
]"
|
||||
data-rybbit-event="preview-animation"
|
||||
>
|
||||
<i class="fas fa-play"></i>
|
||||
<span>Preview</span>
|
||||
</button>
|
||||
</div>
|
||||
<button @click="openShareModal" class="flex items-center gap-2 px-4 py-2 mr-2.5 text-sm font-medium rounded-lg bg-gradient-to-r from-blue-500 to-purple-600 text-white shadow-sm hover:shadow-md transition-all cursor-pointer" data-rybbit-event="share-spritesheet-header">
|
||||
<i class="fas fa-share-alt"></i>
|
||||
<span>Share spritesheet</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tab Content -->
|
||||
<div class="p-6 lg:flex-1 lg:overflow-auto">
|
||||
<div v-if="activeTab === 'canvas'">
|
||||
<div class="p-6 lg:flex-1 lg:overflow-auto lg:min-h-0">
|
||||
<div v-if="activeTab === 'canvas'" class="h-full">
|
||||
<sprite-canvas :layers="layers" :active-layer-id="activeLayerId" :columns="columns" @update-sprite="updateSpritePosition" @update-sprite-cell="updateSpriteCell" @remove-sprite="removeSprite" @replace-sprite="replaceSprite" @add-sprite="addSprite" />
|
||||
</div>
|
||||
<div v-if="activeTab === 'preview'">
|
||||
<div v-if="activeTab === 'preview'" class="h-full">
|
||||
<sprite-preview :layers="layers" :active-layer-id="activeLayerId" :columns="columns" @update-sprite="updateSpritePosition" @update-sprite-in-layer="updateSpriteInLayer" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -247,6 +263,7 @@
|
||||
|
||||
<SpritesheetSplitter :is-open="isSpritesheetSplitterOpen" :image-url="spritesheetImageUrl" :image-file="spritesheetImageFile" @close="closeSpritesheetSplitter" @split="handleSplitSpritesheet" />
|
||||
<GifFpsModal :is-open="isGifFpsModalOpen" @close="closeGifFpsModal" @confirm="downloadAsGif" :default-fps="10" />
|
||||
<ShareModal :is-open="isShareModalOpen" :share-function="shareFunction" @close="closeShareModal" />
|
||||
</main>
|
||||
</template>
|
||||
|
||||
@@ -257,7 +274,9 @@
|
||||
import SpritePreview from '@/components/SpritePreview.vue';
|
||||
import SpritesheetSplitter from '@/components/SpritesheetSplitter.vue';
|
||||
import GifFpsModal from '@/components/GifFpsModal.vue';
|
||||
import ShareModal from '@/components/ShareModal.vue';
|
||||
import { useExportLayers } from '@/composables/useExportLayers';
|
||||
import { useShare } from '@/composables/useShare';
|
||||
import { useLayers } from '@/composables/useLayers';
|
||||
import { getMaxDimensionsAcrossLayers } from '@/composables/useLayers';
|
||||
import { useSettingsStore } from '@/stores/useSettingsStore';
|
||||
@@ -299,6 +318,7 @@
|
||||
const activeTab = ref<'canvas' | 'preview'>('canvas');
|
||||
const isSpritesheetSplitterOpen = ref(false);
|
||||
const isGifFpsModalOpen = ref(false);
|
||||
const isShareModalOpen = ref(false);
|
||||
const uploadInput = ref<HTMLInputElement | null>(null);
|
||||
const jsonFileInput = ref<HTMLInputElement | null>(null);
|
||||
const spritesheetImageUrl = ref('');
|
||||
@@ -378,6 +398,23 @@
|
||||
isGifFpsModalOpen.value = false;
|
||||
};
|
||||
|
||||
// Share functionality
|
||||
const { share } = useShare(layers, columns, toRef(settingsStore, 'negativeSpacingEnabled'), toRef(settingsStore, 'backgroundColor'), toRef(settingsStore, 'manualCellSizeEnabled'), toRef(settingsStore, 'manualCellWidth'), toRef(settingsStore, 'manualCellHeight'));
|
||||
|
||||
const shareFunction = () => share();
|
||||
|
||||
const openShareModal = () => {
|
||||
if (!visibleLayers.value.some(l => l.sprites.length > 0)) {
|
||||
alert('Please upload or import sprites before sharing.');
|
||||
return;
|
||||
}
|
||||
isShareModalOpen.value = true;
|
||||
};
|
||||
|
||||
const closeShareModal = () => {
|
||||
isShareModalOpen.value = false;
|
||||
};
|
||||
|
||||
const handleSplitSpritesheet = (spriteFiles: SpriteFile[]) => {
|
||||
processImageFiles(spriteFiles.map(s => s.file));
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user