hi, I am using the Spine Web player in the vue project, and the Spine material contains several animations, each of which has different sizes. For example, if there are animations move
and idle
, my demand is to play animation move
first and then idle
. Because they are different sizes, I need to set the size of the container.
Here's some of my code:
SpinePlayer component:
<template>
<div ref="spineContainer" class="spine"></div>
</template>
<script setup lang="ts">
import {
SpinePlayer,
type SpinePlayerConfig,
} from '@esotericsoftware/spine-player'
interface Props {
jsonPath: string
atlasPath: string
animations: string[]
}
const props = defineProps<Props>()
const emit = defineEmits(['complete'])
const spineContainer = ref<HTMLElement | null>(null)
let player: SpinePlayer | null = null
onMounted(() => {
if (!spineContainer.value) return
const config: SpinePlayerConfig = {
jsonUrl: props.jsonPath,
atlasUrl: props.atlasPath,
animations: props.animations,
alpha: true,
backgroundColor: '#00000000',
preserveDrawingBuffer: false,
showControls: false,
success: (player) => {
player.animationState?.setEmptyAnimation(0, 0)
player.animationState?.addListener({
complete: function (entry) {
emit('complete', entry)
},
})
},
}
player = new SpinePlayer(spineContainer.value, config)
return () => {
player?.dispose()
}
})
function playAnimation(animationName, loop) {
if (player) {
player.animationState?.clearTracks()
player.setAnimation(animationName, loop)
player.play()
}
}
defineExpose({
playAnimation,
})
</script>
vue page:
<Role
ref="role"
json-path="./spine/role.json"
atlas-path="./spine/role.atlas"
:animations="[]"
@complete="OnRoleComplete"
/>
function setRoleSize(animation) {
if (animation === 'move') {
role.style.width = '295px'
role.style.width = '222px'
} else if (animation === 'idle') {
role.style.width = '127px'
role.style.width = '185px'
}
}
// this doesn't matter. Just changing role position
function setRolePosition() {}
function rolePlay(animation) {
setRoleSize(animation)
setRolePosition()
role.value.playAnimation(animation, false)
}
function OnRoleComplete(entry: any): void {
if (entry.animation.name === 'move') {
animateSkyPlay('idle')
}
}
rolePlay('move')
Start with move animation, and after move is complete, start idle animation.
However, the problem is that when rolePlay('idle')
is started after the move is finished, because need set size first, the move will be displayed on the idle size canvas (that is, 127*185) first, and then play the idle animation, there will be a process of role reduction and then enlargement. How can I show the idle animation directly after the move animation?
Is it right to change containers to meet this requirement?
How do I switch between two different sized animations?