Vue.jsでトランジションとアニメーションを使って画面に動きをつける

はじめに

Vue.jsの機能を使うことでv-ifv-showで表示を切り替える際の動きにトランジション・アニメーションを設定することができます。

cssだけでもトランジション・アニメーションを設定することはできますが、v-ifv-showtruefalseに切り替わるタイミングでトランジション・アニメーションを設定しようとすると複雑な処理が必要になります。しかしVue.jsの持つtransitionコンポーネントを使うことで、簡単にトランジション・アニメーションを設定することができます。

トランジションの使い方

v-ifで表示、非表示を切り替える場合のトランジションの適用方法を説明します。

<template>
  <div>
    <button @click="display = !display">
      表示切り替え
    </button>
    <transition name="opacity">
      <p style="margin-top:30px" v-if="display">表示箇所</p>
    </transition>
  </div>
</template>
<script>

export default {
  data(){
    return {
      display:true
    }
  }
}
</script>
<style scoped>
.opacity-enter{
  opacity: 0;
}
.opacity-enter-active{
  transition: opacity 1s;
}
.opacity-enter-to{
  opacity: 1;
}
.opacity-leave{
  opacity: 1;
}
.opacity-leave-active{
  transition: opacity 1s;
}
.opacity-leave-to{
  opacity: 0;
}
</style>

コンポーネントを1つ作成し、上記のソースコードを記述します。

 表示切り替えボタンのクリックイベントでdisplaytruefalseに切り替えており、pタグで囲まれた表示箇所v-if=” display”と指定して、文言の表示を切り替えを行っています。

表示箇所の切り替えにトランジションを適用させたい場合、<transition></transition>で囲み、name属性に任意の名前を指定します(name属性を指定しなかった場合、デフォルトで”v”が指定されます。)

<transition name="opacity">
  <p style="margin-top:30px" v-if="display">表示箇所</p>
</transition>

次に<style>内で6つのクラスを指定します。このクラスが重要で、v-iftruefalseに切り替わるときの動きを指定します。

6つのクラスはそれぞれ下記のように動くタイミングが異なっています。

  • {{name}}-enter //表示されるときの最初の状態
  • {{name}}-enter-active //表示されているときの状態
  • {{name}}-enter-enter-to//表示されるときの最後の状態
  • {{name}}-leave //消えるときの最初の状態
  • {{name}}-leave-active //消えているときの状態
  • {{name}}-leave-to //消えるときの最後の状態

{{name}}にはtransitionタグで指定したname属性が入ります。

 透過度をゆっくりと変えながら表示をしたい場合、{{name}}-enterクラスにopacity: 0;を、{{name}}-enter-toクラスにopacity: 1;を指定します。そして{{name}}-enter-activeクラスに切り替えにかかる時間を指定します。今回は1秒かけて切り替えたいのでtransition: opacity 1s;と指定します。

表示が消えるときのクラスも指定します。表示される場合と逆で、{{name}}-leaveクラスにopacity: 1;を、{{name}}-leave-toクラスにopacity: 0;を指定します。{{name}}-leave-activeクラスには表示されるときと同じように1秒かけて消したいのでtransition: opacity 1s;と指定します。

これでv-iftruefalseの切り替えにトランジションを適用させることができました。

アニメーションの使い方

アニメーションもトランジションのように<trainsition></trainsition>で囲むことで処理を適用させることができます。

先程の表示箇所をスライドさせるアニメーションを実装します。

<template>
  <div>
    <button @click="display = !display">
      表示切り替え
    </button>
    <transition name="animation">
      <p style="margin-top:30px" v-if="display">表示箇所</p>
    </transition>
  </div>
</template>
<script>

export default {
  data(){
    return {
      display:true
    }
  }
}
</script>
<style scoped>
.animation-enter-active{
  animation: slide 0.5s;
}
.animation-leave-active{
  animation: slide 0.5s reverse; 
 }

@keyframes slide {
  from {
    transform: translateX(200px);
  }
  to {
    transform: translateX(0);
  }
}
</style>

transitionタグのname属性を”animation”に変更しています。

 

<style>内でcssアニメーションの設定を行います。@keyframesでfromtoでアニメーションの開始と終わりの設定をします。fromtranslateX(200px)と指定することで開始位置に対して右側200pxから表示箇所がスライドしてくるアニメーションを設定します。

/@keyframes slide {
  from {
    transform: translateX(200px);
  }
  to {
    transform: translateX(0);
  }
}

クラスの指定も行います。トランジションと違い、開始と終わりの設定を@keyframesfrom{}to{}で設定しているため、作成するクラスは{{name}}-enter-active{{name}}-leave-activeの2つでOKです。今回はスライドにかかる時間を0.5秒にしたいため、animation: slide 0.5s; と指定します。{{name}}-leave-activeには reverse を付けることで表示が消える際の動きに指定することができます。

.animation-enter-active{
  animation: slide 0.5s;
}
.animation-leave-active{
  animation: slide 0.5s reverse; 
 }

これでv-iftruefalseの切り替えにアニメーションを適用させることができました。

トランジションとアニメーションの両方を適用する

先程のアニメーションのソースコードに、トランジションで指定したopacityの設定を追加することでアニメーションとトランジションの両方を適用させることができます。

/<template>
  <div>
    <button @click="display = !display">
      表示切り替え
    </button>
    <transition name="animation" type="animation">
      <p style="margin-top:30px" v-if="display">表示箇所</p>
    </transition>
  </div>
</template>
<script>

export default {
  data(){
    return {
      display:true
    }
  }
}
</script>
<style scoped>
.animation-enter{
  opacity: 0;
}
.animation-enter-active{
  animation: slide 1s;
  transition: opacity 3s;
}
.animation-enter-to{
  opacity: 1;
}
.animation-leave{
  opacity: 1;
}
.animation-leave-active{
  animation: slide 1s reverse; 
  transition: opacity 3s;
 }
.animation-leave-to{
  opacity: 0;
} 

@keyframes slide {
  from {
    transform: translateX(200px);
  }
  to {
    transform: translateX(0);
  }
}
</style>

下記のようにトランジションの記述を追加しています。

.animation-enter{
  opacity: 0;
}
.animation-enter-active{
  animation: slide 1s;
  transition: opacity 3s;
}
.animation-enter-to{
  opacity: 1;
}
.animation-leave{
  opacity: 1;
}
.animation-leave-active{
  animation: slide 1s reverse; 
  transition: opacity 3s;
 }
.animation-leave-to{
  opacity: 0;
} 

このままですとアニメーションでは1秒かけて実行しているのに対して、トランジションでは3秒かけて実行しているので2つの間に乖離があります。デフォルトでは時間が長いほうが適用されますが(今回ですとトランジション)、transitionコンポーネントのtype属性を指定することでどちらを優先するか指定することができます。

<transition name="animation" type="animation">
  <p style="margin-top:30px" v-if="display">表示箇所</p>
</transition>

今回はアニメーションをtype属性に指定しました。こうするとopacity0となる前にスライドで表示が消えていきます。


透過度が0に近づきながらスライドされる

これでトランジションとアニメーションの両方を適用することができました。

 

Smallitのサービス