概要
アイテム一覧にアイテムを追加したときにフェードインのアニメーションを適用するデモアプリケーションです。
なおVue.jsのトランジション機能を利用したごく普通のアニメーションになります。
環境
- Windows 10 Professional
- Node.js 6.11.5
- Vue.js 2.5.16
- Vuetify
- Visual Studio Code 1.23.0
参考
- [Enter/Leave とトランジション一覧] (https://jp.vuejs.org/v2/guide/transitions.html)
- [Animate.css] (https://daneden.github.io/animate.css/)
アイテム一覧
- アイテムデータの持ち方とアイテムの追加処理はダミーです。
アイテム一覧を表示するコンポーネント
<template>
<div class="cards">
<slot name="nav"></slot>
<div id="e3" style="max-width: 500px; margin: 20px auto;" class="grey lighten-3">
<v-card>
<v-container fluid style="min-height: 0; text-align: left;" grid-list-lg>
<transition-group name="card-anim">
<v-layout row wrap v-for="(item, index) in items" v-bind:key="index">
<component v-bind:is="cardType(item)" v-bind:item="item" />
</v-layout>
</transition-group>
</v-container>
</v-card>
<div>
<v-container fluid style="min-height: 0;">
<v-layout row>
<v-flex xs12>
<v-btn color="success" v-on:click="addList">More</v-btn>
</v-flex>
</v-layout>
</v-container>
</div>
</div>
<slot name="footer"></slot>
</div>
</template>
<script>
import NormalCard from '@/components/NormalCard'
import ImageCard from '@/components/ImageCard'
export default {
name: 'Cards',
components: {
'normal-card': NormalCard,
'image-card': ImageCard
},
data () {
return {
itemMaster: [],
items: [],
itemIndex: 0
}
},
mounted () {
this.itemMaster = [
{ title: 'ゼルダの伝説', description: '任天堂から発売されたゲームソフト。ゼルダの伝説シリーズの一作目にあたる。', color: 'green darken-4' },
{ title: 'リンクの冒険', description: '任天堂より昭和62年1月14日に発売されたファミリーコンピュータ ディスクシステム用アクションアドベンチャーゲーム。', color: 'light-green darken-4' },
{ title: 'ゼルダの伝説 神々のトライフォース', description: '平成3年11月21日に任天堂から発売されたスーパーファミコン用ゲームソフト。', color: 'green accent-4' },
{ title: 'ゼルダの伝説 夢をみる島', description: '任天堂から平成5年6月6日に発売されたゲームボーイ用アクションアドベンチャーゲーム。', color: 'orange darken-4' },
{ title: 'ゼルダの伝説 時のオカリナ', description: '平成9年11月21日に任天堂より発売されたNINTENDO64(N64)用アクションアドベンチャーゲーム、アクションRPG。', color: 'lime darken-4' },
{ title: 'ゼルダの伝説 ムジュラの仮面', description: '任天堂より平成12年4月27日に発売されたNINTENDO64用3DアクションRPG。', color: 'deep-purple darken-4' }
]
this.items.push(this.itemMaster[0])
this.items.push(this.itemMaster[1])
this.itemIndex = this.items.length
},
methods: {
addList () {
if (this.itemMaster.length > this.itemIndex) {
this.items.push(this.itemMaster[this.itemIndex++])
}
},
cardType (item) {
if (item.image) {
return ImageCard
} else {
return NormalCard
}
}
}
}
</script>
<style scoped>
.card-anim-enter-active {
animation: fadeInUp .7s;
animation-delay: .4s;
opacity: 0;
}
@keyframes fadeInUp {
0% {
transform: translateY(60px);
opacity: 0;
}
60% {
opacity: .3;
}
100% {
transform: translateY(0px);
opacity: 1;
}
}
</style>
アイテム1件分を表示するコンポーネント
<template>
<v-flex xs12>
<v-card v-bind:color="item.color" class="white--text" v-bind:tile="false" v-bind:hover="true">
<v-card-title primary-title>
<div class="headline">{{ item.title }}</div>
<div>{{ item.description }}</div>
</v-card-title>
<v-card-actions>
<v-btn flat dark>Details</v-btn>
</v-card-actions>
</v-card>
</v-flex>
</template>
<script>
export default {
name: 'NormalCard',
props: {
'item': {
type: Object,
required: true
}
}
}
</script>
アニメーションのポイント
その1
繰り返し要素にアニメーションを適用するにはtransition-groupを使用します。
<transition-group name="card-anim">
<v-layout row wrap v-for="(item, index) in items" v-bind:key="index">
<component v-bind:is="cardType(item)" v-bind:item="item" />
</v-layout>
</transition-group>
その2
Vue.jsのトランジションには決められた6つのCSSクラスがあります。クラス名にはtransition又はtransition-groupのname属性がprefixとして付きます。(name属性を省略するとv-
になります。)
この記事の例では、transition-groupのname属性に"card-anim"を指定してるので、6つのクラス名は以下のようになります。
- card-anim-enter
- enterの開始状態
- card-anim-enter-active
- enterの活性状態
- card-anim-enter-to
- enterの終了状態
- card-anim-leave
- leaveの開始状態
- card-anim-leave-active
- leaveの活性状態
- card-anim-leave-to
- leaveの終了状態
それぞれの状態時に発生させるアニメーションをCSSで定義します。この例ではアイテム追加時に下(60pxずれた位置)から上へ縦方向にフェードインするアニメーションを適用しています。
translateY
をtranslateX
に変えると横方向にフェードインするようになります。
.card-anim-enter-active {
animation: fadeInUp .7s;
animation-delay: .4s;
opacity: 0;
}
@keyframes fadeInUp {
0% {
transform: translateY(60px);
opacity: 0;
}
60% {
opacity: .3;
}
100% {
transform: translateY(0px);
opacity: 1;
}
}
アイテムを削除したときにフェードアウトのアニメーションを適用したい場合は、下記のように"leave-active"のanimationにreverseを付けてエフェクトを反転させます。
.card-anim-leave-active {
animation: fadeInUp .7s reverse;
}
アニメーションの様子
アニメーションの様子をgifにしました。
最初に2件表示されている状態から、MOREボタンを押して1件ずつアイテムを追加している様子です。