1
0
forked from noxious/client
This commit is contained in:
Dennis Postma 2025-01-31 01:55:52 +01:00
parent 7fd334d414
commit 15f9e9861e
4 changed files with 105 additions and 68 deletions

View File

@ -225,8 +225,8 @@ export interface SpriteImage {
}
export type SpriteAction = {
id: UUID
sprite: Sprite
id: string
sprite: string
action: string
sprites: SpriteImage[]
originX: number
@ -237,7 +237,7 @@ export type SpriteAction = {
}
export type Chat = {
id: UUID
id: string
character: Character
map: Map
message: string

View File

@ -53,33 +53,17 @@
</form>
</template>
</Accordion>
<Modal :is-modal-open="isModalOpen" :modal-width="300" :modal-height="420" :bg-style="'none'" @modal:close="isModalOpen = false">
<template #modalHeader>
<h3 class="m-0 font-medium shrink-0 text-white">View sprite</h3>
</template>
<template #modalBody>
<div class="m-4 flex flex-col gap-4">
<div v-if="selectedAction" class="flex flex-col items-center">
<SpritePreview :sprites="selectedAction.sprites" :frame-rate="previewFps" />
<div class="w-full mt-4">
<label class="block mb-2 text-white">Frame Rate: {{ previewFps }} FPS</label>
<input type="range" v-model.number="previewFps" min="0" max="60" step="1" class="w-full accent-cyan-500" @input="updatePreviewFps" />
</div>
</div>
</div>
</template>
</Modal>
<SpritePreview v-if="selectedAction" :sprites="selectedAction.sprites" :frame-rate="selectedAction.frameRate" :is-modal-open="isModalOpen" @update:frame-rate="updateFrameRate" @update:is-modal-open="isModalOpen = $event" />
</div>
</div>
</template>
<script setup lang="ts">
import type { Sprite, SpriteAction } from '@/application/types'
import type { Sprite, SpriteAction, UUID } from '@/application/types'
import { uuidv4 } from '@/application/utilities'
import SpriteActionsInput from '@/components/gameMaster/assetManager/partials/sprite/partials/SpriteImagesInput.vue'
import SpritePreview from '@/components/gameMaster/assetManager/partials/sprite/partials/SpritePreview.vue'
import Accordion from '@/components/utilities/Accordion.vue'
import Modal from '@/components/utilities/Modal.vue'
import { useAssetManagerStore } from '@/stores/assetManagerStore'
import { useGameStore } from '@/stores/gameStore'
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
@ -91,6 +75,8 @@ const selectedSprite = computed(() => assetManagerStore.selectedSprite)
const spriteName = ref('')
const spriteActions = ref<SpriteAction[]>([])
const isModalOpen = ref(false)
const selectedAction = ref<SpriteAction | null>(null)
if (!selectedSprite.value) {
console.error('No sprite selected')
@ -168,8 +154,7 @@ function addNewImage() {
const newImage: SpriteAction = {
id: uuidv4(),
spriteId: selectedSprite.value.id,
sprite: selectedSprite.value,
sprite: selectedSprite.value.id,
action: 'new_action',
sprites: [],
originX: 0,
@ -191,36 +176,29 @@ function sortSpriteActions(actions: SpriteAction[]): SpriteAction[] {
return [...actions].sort((a, b) => a.action.localeCompare(b.action))
}
function openPreviewModal(action: SpriteAction) {
selectedAction.value = action
isModalOpen.value = true
}
function updateFrameRate(value: number) {
if (selectedAction.value) {
selectedAction.value.frameRate = value
}
}
watch(selectedSprite, (sprite: Sprite | null) => {
if (!sprite) return
spriteName.value = sprite.name
spriteActions.value = sortSpriteActions(sprite.spriteActions)
})
// View sprite modal logic
const isModalOpen = ref(false)
const selectedAction = ref<SpriteAction | null>(null)
const previewFps = ref(0)
function openPreviewModal(action: SpriteAction) {
selectedAction.value = action
previewFps.value = action.frameRate || 0
isModalOpen.value = true
}
watch(isModalOpen, (newValue) => {
if (!newValue) {
selectedAction.value = null
previewFps.value = 0
}
})
function updatePreviewFps() {
if (selectedAction.value) {
selectedAction.value.frameRate = previewFps.value
}
}
onMounted(() => {
if (!selectedSprite.value) return
})

View File

@ -18,7 +18,7 @@
<Modal :is-modal-open="selectedImageIndex === index" :modal-width="300" :modal-height="210" :is-resizable="false" :bg-style="'none'" @modal:close="closeOffsetModal">
<template #modalHeader>
<h3 class="m-0 font-medium shrink-0 text-white">Action offset</h3>
<h3 class="m-0 font-medium shrink-0 text-white">Action offset ({{ selectedImageIndex }})</h3>
</template>
<template #modalBody>
<div class="m-4">
@ -159,6 +159,7 @@ const saveOffset = (index: number) => {
...newImages[index],
offset: { ...tempOffset.value }
}
updateImages(newImages)
closeOffsetModal()
}
</script>

View File

@ -1,4 +1,10 @@
<template>
<Modal :is-modal-open="isModalOpen" :modal-width="700" :modal-height="330" :bg-style="'none'" @modal:close="closeModal">
<template #modalHeader>
<h3 class="m-0 font-medium shrink-0 text-white">View sprite</h3>
</template>
<template #modalBody>
<div class="m-4 flex gap-8">
<div class="relative">
<div
class="sprite-container bg-gray-800"
@ -18,26 +24,62 @@
position: 'absolute',
left: `${sprite.offset?.x || 0}px`,
bottom: `${sprite.offset?.y || 0}px`,
display: currentFrame === index ? 'block' : 'none'
display: currentFrame === index ? 'block' : 'none',
transform: `scale(${zoomLevel / 100})`,
transformOrigin: 'bottom left'
}"
@load="updateContainerSize"
/>
</div>
</div>
<div class="flex flex-col justify-center gap-8 flex-1">
<div class="flex flex-col">
<label class="block mb-2 text-white">Frame Rate: {{ frameRate }} FPS</label>
<input type="range" v-model.number="localFrameRate" min="0" max="60" step="1" class="w-full accent-cyan-500" @input="updateFrameRate" />
</div>
<div class="flex flex-col">
<label class="block mb-2 text-white">Frame: {{ currentFrame + 1 }} of {{ sprites.length }}</label>
<input
type="range"
v-model.number="currentFrame"
:min="0"
:max="sprites.length - 1"
step="1"
class="w-full accent-cyan-500"
@input="stopAnimation"
/>
</div>
<div class="flex flex-col">
<label class="block mb-2 text-white">Zoom: {{ zoomLevel }}%</label>
<input type="range" v-model.number="zoomLevel" min="10" max="200" step="10" class="w-full accent-cyan-500" />
</div>
</div>
</div>
</template>
</Modal>
</template>
<script setup lang="ts">
import type { SpriteImage } from '@/application/types'
import Modal from '@/components/utilities/Modal.vue'
import { onMounted, onUnmounted, ref, watch } from 'vue'
const props = defineProps<{
sprites: SpriteImage[]
frameRate: number
isModalOpen?: boolean
}>()
const emit = defineEmits<{
(e: 'update:frameRate', value: number): void
(e: 'update:isModalOpen', value: boolean): void
}>()
const currentFrame = ref(0)
const maxWidth = ref(250)
const maxHeight = ref(250)
const localFrameRate = ref(props.frameRate)
const zoomLevel = ref(100)
let animationInterval: number | null = null
function updateContainerSize(event: Event) {
@ -65,7 +107,23 @@ function stopAnimation() {
}
}
watch(() => props.frameRate, updateAnimation, { immediate: true })
function updateFrameRate() {
emit('update:frameRate', localFrameRate.value)
}
function closeModal() {
emit('update:isModalOpen', false)
}
watch(
() => props.frameRate,
(newValue) => {
localFrameRate.value = newValue
updateAnimation()
},
{ immediate: true }
)
watch(() => props.sprites, updateAnimation, { immediate: true })
onMounted(() => {