You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Vue/Nuxt中通过Pinia共享GSAP主时间线异常问题

Nuxt3 + Pinia + GSAP 主时间线无法播放子时间线问题解决

问题核心原因

GSAP时间线是带有内部状态的复杂实例,直接将其存入Pinia的state时,Vue的响应式系统会自动包装该实例,这会干扰GSAP内部的动画调度逻辑,导致主时间线无法触发更新、完成回调,子时间线也无法正常运行。

解决步骤

  1. 用markRaw标记GSAP时间线,跳过响应式包装
    在你的Pinia store文件(stores/AnimationStore.ts)中,初始化主时间线时使用Vue的markRaw方法,避免Vue对GSAP实例做响应式处理:
import { defineStore } from 'pinia'
import gsap from 'gsap'
import { markRaw } from 'vue'

export const useAnimationStore = defineStore('animation', {
  state: () => ({
    // 用markRaw包装GSAP时间线,规避响应式干扰
    master: markRaw(gsap.timeline({
      onStart: () => console.log('Master started'),
      onUpdate: () => console.log('Master updated'),
      onComplete: () => console.log('Master completed')
    }))
  }),
  actions: {
    addToMaster(timeline: gsap.core.Timeline) {
      this.master.add(timeline)
    },
    playMaster() {
      this.master.play()
    }
  }
})
  1. 确保子时间线在DOM挂载后创建
    Nuxt3组件的DOM元素需在onMounted钩子后才会完全挂载到页面,若在组件初始化阶段创建子时间线,可能因目标元素不存在导致动画无效。调整app.vue代码,在onMounted中创建并添加子时间线:
<script setup>
import { useAnimationStore } from '~/stores/AnimationStore'
import gsap from 'gsap'
import { onMounted } from 'vue'

const animationStore = useAnimationStore()

onMounted(() => {
  // 确认DOM元素存在后创建子时间线
  const subTimeline = gsap.timeline()
  // 示例动画:移动id为box的元素
  subTimeline.to('#box', { x: 200, duration: 1 })
  
  animationStore.addToMaster(subTimeline)
  animationStore.playMaster()
})
</script>

<template>
  <!-- 添加动画目标元素 -->
  <div id="box" style="width: 100px; height: 100px; background-color: red;"></div>
</template>
  1. 检查时间线配置
    确认主时间线初始化时无paused: true以外的异常配置,子时间线未被手动暂停、无无效动画目标。

验证效果

完成上述调整后,播放主时间线时应正常触发onUpdate和onComplete日志,子时间线的动画也会正常执行。

内容的提问来源于stack exchange,提问作者Lutz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 08:57:27