Vue.jsのscript setupでGSAPを扱おうとすると要素がないと怒られる
環境
npm
Vue.js(SFC/Composition API/Vite)
GSAP(npm)
└ ScrollTrigger
概要
下の、3つの特色(要素)を動かしたい。
https://scrapbox.io/files/653e3c2ef7a327001ccd99e4.png
ということで、Vue.js の <script setup lang="ts"> 内にこんなコードを書いてみた。※今回はTypeScriptなのでtsファイル。
code: ts
import { ref } from 'vue'
import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
gsap.registerPlugin(ScrollTrigger);
const cels = ref([
// v-forで使うために、特色の情報が定義されているが今回は関係ないので省略
])
// 要素「特色」が真ん中まで来たら中身を順番に表示
gsap.fromTo("#feature .col-xs-12", {
y: 40,
opacity: 0,
}, {
y: 0,
opacity: 1,
duration: .8,
stagger: .1,
ease: "power2.out",
scrollTrigger: {
trigger: "#feature",
start: "top center",
},
});
すると、コンソール側にこんなエラーが出ることに。
code:Console
つまり、GSAP から「そんな要素 どこにも見当たらないぜ……?!」と怒られたということ。
推測
HTML を見てみると、ガッツリ要素はある。ということは。
恐らく、GSAP 自体が発火したタイミングでは、本当にそんな要素がない。
このコードは <script setup> 直下にあるので、Vue がまだページを組み立てている最中、import やらが動いているライフサイクルだから……というのは十分考えられる。多分そう。
つまり、実行タイミングを「HTMLが組み立てられた後」にする必要がある。これで、GSAP側が要素を検知できる。
ライフサイクルフック
Vue.jsには、ライフサイクルフックというものがある。
ただし、Options API と Composition API の setup メソッドで使う名前は異なるので注意が必要。基本「on」が付く形になる。
ライフサイクルフック
↓ コンポーネント生成 → beforeCreate(※)
↓ └ データ初期化完了 → created(※)
↓ コンポーネントが紐づく前 → beforeMount(onBeforeMount)
↓ └ ページへマウントされた → mounted(onMounted)
↓ 描画開始
↓ ……
()内が setup メソッド
※このライフサイクルは setup メソッド直下と同じため、setup メソッドでのライフサイクルフックはない。
解決法
ということは、直下に書くと、コンポーネント生成やデータの初期化を行っている最中に GSAP が動くということになる。
コンポーネントがページへ紐づいたタイミングは「onMounted」なため、このタイミング以降に GSAP に要素を探してもらえばよいということになる。恐らく。
ということで、GSAP を onMounted 下で動かしてみた。
code:fix.ts
import { ref, onMounted } from 'vue'
import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
gsap.registerPlugin(ScrollTrigger);
const cels = ref([
// v-forで使うために、特色の情報が定義されているが今回は関係ないので省略
])
// 要素「特色」が真ん中まで来たら中身を順番に表示
// コンポーネントがページに紐づいた後に実行(実行タイミングによっては要素が探せないため)
onMounted(() => {
gsap.fromTo("#feature .col-xs-12", {
y: 40,
opacity: 0,
}, {
y: 0,
opacity: 1,
duration: .8,
stagger: .1,
ease: "power2.out",
scrollTrigger: {
trigger: "#feature",
start: "top center",
},
});
})
結果
エラーは解消され、GSAP によるアニメーションが動いた。やったね!
https://scrapbox.io/files/653e3e54a760bf001c2a298e.png
参考