2022.12.13
jQueryのあの動きをVue.jsでやってみた
モダンな開発を導入して脱jQueryの観点で普段何気なく使っているjQueryをプレーンなJavaScriptないしフレームワークに沿った書き方に置き換える必要性が出てきます。例えば、Vue.jsで要素の動きを再現しようとすると、案の定盲点が多く、「あれ?これjQueryコピペで作れちゃうけどVueだとどうやって書けば良いの?」という事案が自分の中で多発しています。
最近特にサイトの動きやエフェクトについて改めて整理したいと思い、学習メモとして残すためにも、こちらのシリーズを書くことにしました!同じ勉強をしている人の役に立てればと思います。
最初の一回目は、要素が「ランダムにふわっとfadeUp」する動きをVueで再現するコードとその気付きを書きたいと思います。
この記事の目次
まずは完成した全体像をこちらからご覧ください。
https://codepen.io/sue0606777/pen/vYdVRrG
*CodePenに遷移します
前提:この記事はVue.jsをある程度習得した方向けです。Vue.jsの基礎について解説しません。
【ランダムにふわっとfadeUp編 その①】
サイトを見る時よくあるふわっとフェードアップして現れる要素の動きをVue+GSAPで再現します。ただここのこだわりポイントは、一斉にフェードアップでも、順番にフェードアップでもなく、ランダムに!!です。
random_fadeUp.html
<div id="app">
<p>ページに遷移すると、ランダムに現れる</p>
<!--読み込みしてふわっと-->
<transition-group appear
tag="ul"
class="randomBox"
@before-enter="beforeEnter"
@enter="enter"
@leave="leave"
:css="false"
>
<li class="box" v-for="(moveData,index) in moveDatas" :key="moveData" :data-index="randomsA[index]">{{ moveData }}</li>
</transition-group>
</div>
まずは要素のlistを<li>で用意し、トランジションを付与する<transition-group>で包みます。appear属性を入れることで、要素が読み込まれた瞬間一回だけtransitionが発動するというわけです。
一旦jsのほうを見てみましょう。
random_fadeUp.js
const app = new Vue({
el: '#app',
data: {
moveDatas: ['a','b','c','d','e'],
randomsA: [],
},
created(){
this.randomCreat(this.moveDatas,this.randomsA)
},
mounted(){
},
methods: {
randomCreat(n,m){
/** 最小値と最大値 */
let min = 0, max = n.length;
/** 重複チェックしながら乱数作成 */
for(i = min; i <= max; i++){
while(true){
var tmp = this.intRandom(min, max);
if(!m.includes(tmp)){
m.push(tmp);
break;
}
}
}
},
/** min以上max以下の整数値の乱数を返す */
intRandom(min, max){
return Math.floor( Math.random() * (max - min + 1)) + min;
},
///アニメ挙動//
beforeEnter(el) {
el.style.opacity = 0
el.style.transform = 'translateY(100px)'
},
enter(el, done) {
gsap.to(el, {
opacity: 1,
y: 0,
delay: el.dataset.index * 0.15,
onComplete: done
})
},
leave(el, done) {
gsap.to(el, {
opacity: 0,
y: 100,
delay: el.dataset.index * 0.15,
onComplete: done
})
}
}
})
ここのポイントは:
- <li>のdata-index属性にランダムの値を入れ、それぞれのdata-index属性値によって、delay: el.dataset.index * 0.15の結果がランダムになり、アニメーションが発動するタイミングもランダムになります。
- 関数randomCreatはmountedの中ではなく、createdの中に入れないと、ライフサイクル上、要素がhtmlとして作られる前にdata-index属性に入れる値を作ることができないため、うまく動きません。
以上、「ランダムにふわっとfadeUp」を作ることができました。
【ランダムにふわっとfadeUp編 その②】
次は応用編で、スクロールしたらふわっとフェードアップして現れる要素の動きもVue+GSAPで再現します。
random_fadeUp.html
<!--スクロールしてふわっと-->
<transition-group
tag="ul"
class="randomScroll"
id="randomScroll"
@before-enter="beforeEnter"
@enter="enter"
@leave="leave"
:css="false"
>
<li class="box" v-for="(scrollData,index) in scrollDatas" :key="scrollData" :data-index="randomsB[index]" v-show="isScroll">{{ scrollData }}</li>
</transition-group>
こちらも①とほぼ変わらず、まずは要素のlistを<li>で用意し、トランジションを付与する<transition-group>で包みます。ここではappear属性を入れません。id="randomScroll"と<li>のv-show="isScroll"も追加します。
jsのほうは①をベースに必要なdata(scrollDatas、randoms2、isScroll)と関数(handleScroll)、イベントリスナー(window.addEventListener)を追加します。
random_fadeUp.js
const app = new Vue({
el: '#app',
data: {
moveDatas: ['a','b','c','d','e'],
scrollDatas: ['a','b','c','d','e','f','g'],
randomsA: [],
randomsB: [],
isScroll: false
},
created(){
this.randomCreat(this.moveDatas,this.randomsA)
this.randomCreat(this.scrollDatas,this.randomsB)
},
mounted(){
let that = this
window.addEventListener('scroll', function(){that.handleScroll('randomScroll')})
},
destroyed() {
window.removeEventListener('scroll', function(){that.handleScroll('randomScroll')})
},
methods: {
handleScroll(n) {
const t = document.getElementById(n)
const d = t.offsetTop - window.pageYOffset + 100
if (d < window.innerHeight ) {
this.isScroll = true
} else {
this.isScroll = false
}
},
randomCreat(n,m){
/** 最小値と最大値 */
let min = 0, max = n.length;
/** 重複チェックしながら乱数作成 */
for(i = min; i <= max; i++){
while(true){
var tmp = this.intRandom(min, max);
if(!m.includes(tmp)){
m.push(tmp);
break;
}
}
}
},
/** min以上max以下の整数値の乱数を返す */
intRandom(min, max){
return Math.floor( Math.random() * (max - min + 1)) + min;
},
///アニメ挙動//
beforeEnter(el) {
el.style.opacity = 0
el.style.transform = 'translateY(100px)'
},
enter(el, done) {
gsap.to(el, {
opacity: 1,
y: 0,
delay: el.dataset.index * 0.15,
onComplete: done
})
},
leave(el, done) {
gsap.to(el, {
opacity: 0,
y: 100,
delay: el.dataset.index * 0.15,
onComplete: done
})
}
}
})
ここのポイントは:
- 関数handleScrollでスクロールイベントを発火させるトリガーをセットします。もちろんほかのスクロール系プラグインでセットするのも良いです。
- 注意が必要なのは、v-showは<li>に付与することです。筆者は<transition-group>にv-showを当て、そもそもdisplay:noneの状態でoffsetTopを取れるはずないし
- …初歩的なミスにだいぶハマってしまいました。
以上、「要素がふわっとランダムにfadeUpする」トランジションについてのVueの書き方でした!
この記事を書いた人
許綴綴
BU8-2所属のデザイナーです。メインの業務はデザイナーですが、フロントエンドが好きで普段色々と勉強しています。特にVue.jsを愛用し、最近はJamstackで自作CMSを模索しています。