在正在观看 vuex 状态的观察者中切换 GSAP 动画的问题
Problem with toggling a GSAP animation in a watcher that is watching vuex state
我正在尝试切换内联 svg 的动画,一旦从 vuex 存储中检索到的某个状态发生变化。为此,我用观察者观察状态,并根据状态向前或向后播放动画。这很好用,除非在第一次加载应用程序之后。当观察者第一次注意到状态的变化时,svg 会跳转到新位置而不是动画。第二个和所有进一步的切换工作良好并且动画流畅。我错过了什么?
示例代码:
<template>
<div class="example">
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48" fill="none" aria-labelledby="menu" role="presentation">
<line ref="top" x1="28" y1="18" x2="28" :y2="18" stroke-width="2" stroke="currentColor"/>
</svg>
</div>
</template>
<script>
import { mapState } from 'vuex'
import { TimelineLite} from 'gsap'
export default {
name: 'AnimatedIconExample',
computed: {
...mapState({
isActive: state => state.ui.isActive
})
},
data: function(){
return {
timeline: new TimelineLite()
},
}
},
watch: {
isActive(newValue, oldValue){
if(newValue){
this.timeline.to( this.$refs.top, 0.3, { attr: {x1: 10, y1: 18, x2: 25, y2: 18 }})
this.timeline.play()
}else{
this.timeline.reverse()
}
}
}
您的 watch 属性 在对象的范围之外。尝试:
<template>
<div class="example">
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48" fill="none" aria-labelledby="menu" role="presentation">
<line ref="top" x1="28" y1="18" x2="28" :y2="18" stroke-width="2" stroke="currentColor"/>
</svg>
</div>
</template>
<script>
import { mapState } from 'vuex'
import { TimelineLite} from 'gsap'
export default {
name: 'AnimatedIconExample',
data () {
return {
timeline: new TimelineLite()
}
},
computed: {
...mapState({
isActive: state => state.ui.isActive
})
},
watch: {
isActive(newValue, oldValue){
if(newValue){
this.timeline.to( this.$refs.top, 0.3, { attr: {x1: 10, y1: 18, x2: 25, y2: 18 }})
this.timeline.play()
} else{
this.timeline.reverse()
}
}
}
}
我终于通过在 mounted()
钩子上添加一个初始状态的补间来解决它。
mounted(){
this.timeline.to( this.$refs.top, 0.3, { attr: {x1: 28, y1: 18, x2: 28, y2: 18 }})
}
我正在尝试切换内联 svg 的动画,一旦从 vuex 存储中检索到的某个状态发生变化。为此,我用观察者观察状态,并根据状态向前或向后播放动画。这很好用,除非在第一次加载应用程序之后。当观察者第一次注意到状态的变化时,svg 会跳转到新位置而不是动画。第二个和所有进一步的切换工作良好并且动画流畅。我错过了什么?
示例代码:
<template>
<div class="example">
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48" fill="none" aria-labelledby="menu" role="presentation">
<line ref="top" x1="28" y1="18" x2="28" :y2="18" stroke-width="2" stroke="currentColor"/>
</svg>
</div>
</template>
<script>
import { mapState } from 'vuex'
import { TimelineLite} from 'gsap'
export default {
name: 'AnimatedIconExample',
computed: {
...mapState({
isActive: state => state.ui.isActive
})
},
data: function(){
return {
timeline: new TimelineLite()
},
}
},
watch: {
isActive(newValue, oldValue){
if(newValue){
this.timeline.to( this.$refs.top, 0.3, { attr: {x1: 10, y1: 18, x2: 25, y2: 18 }})
this.timeline.play()
}else{
this.timeline.reverse()
}
}
}
您的 watch 属性 在对象的范围之外。尝试:
<template>
<div class="example">
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48" fill="none" aria-labelledby="menu" role="presentation">
<line ref="top" x1="28" y1="18" x2="28" :y2="18" stroke-width="2" stroke="currentColor"/>
</svg>
</div>
</template>
<script>
import { mapState } from 'vuex'
import { TimelineLite} from 'gsap'
export default {
name: 'AnimatedIconExample',
data () {
return {
timeline: new TimelineLite()
}
},
computed: {
...mapState({
isActive: state => state.ui.isActive
})
},
watch: {
isActive(newValue, oldValue){
if(newValue){
this.timeline.to( this.$refs.top, 0.3, { attr: {x1: 10, y1: 18, x2: 25, y2: 18 }})
this.timeline.play()
} else{
this.timeline.reverse()
}
}
}
}
我终于通过在 mounted()
钩子上添加一个初始状态的补间来解决它。
mounted(){
this.timeline.to( this.$refs.top, 0.3, { attr: {x1: 28, y1: 18, x2: 28, y2: 18 }})
}