表題の通りなのですが、imgにkeyの設定さえしておけば、srcの書き換えでもtransitionアニメーションをさせることができたので、いろいろと遊んでみました。
サンプル
こちら
画像切り替えです。
仕組み
コードは1ファイル完結なので、HTMLのソースを見てもらうと良いと思います。
画像のデータが全て入った配列から表示分と残りの2つ配列を作り、2つの配列からそれぞれランダムに項目を選んで交換するという処理を一定時間ごとに行っています。
HTML
<div v-for="(image,index) in active" class="img" v-bind:class="'img'+index">
<transition name="imgFade" mode="out-in">
<img v-bind:src="image" alt="" v-bind:key="image" width="100">
</transition>
</div>
active(表示分の配列)をv-forループで表示させます。
v-bind:key="image"
がミソなので、これは必ず設定しておきます。
今回は非表示アニメーション→表示アニメーションを順番に行いたかったため、mode="out-in"
を設定しました。
CSS
アニメーションは2パターン作ってみました。
シンプルにフェードイン・アウトと、裏返って新しい画像が表示されるものです。
transition用スタイルは↓のような感じ。
.imgFade-enter-active, .imgFade-leave-active {
transition: opacity .5s;
}
.imgFade-enter, .imgFade-leave-to{
opacity: 0;
position: absolute;
}
.imgRotate-enter-active, .imgRotate-leave-active {
transition: .3s linear;
}
.imgRotate-enter, .imgRotate-leave-to{
transform:rotateY(90deg);
position: absolute;
}
JS
基本はVue.jsで、配列のシャッフルはUnderscore.jsが簡単そうだったのでこちらも使ってみました。
シャッフル動作は下記の一行のみでできてしまいます。
this.images = _.shuffle(this.images)
配列の値の変更について
下記の記事を参考にさせていただきました。どうもありがとうございます。
Vue.jsは気難しい(配列編)
変数のように代入する形では値の変更ができなかったので、spliceを使用しています。
self.active.splice(self.activeChoice.new, 1, self.inactive[self.inactiveChoice]);
self.inactive.splice(self.inactiveChoice, 1, self.temp);
VueでsetInterval、setTimeoutを使うときのthis
setInterval、setTimeout内でのthisはWindowになってしまいます。
methodsで定義した関数を呼び出したいため、下記のように記述しています。
mounted:function(){
let self = this;
setInterval(function(){
self.changeImg()
},1500)
},
感想
着々と脱jQueryの準備を進めております。。
まだ実案件までには踏み込めていないのですが、そろそろどこかで試してみたいです。
とりあえずお遊びという感じで作ってしまったので、SEO面はあまり気にしてないです。
ちゃんとするならaltの情報を配列に持たせて適用するだとか、特に意味のない要素として割り切りこのままにするかの選択が必要ですかね。
見せ方としてはおもちゃ感が強めなので、後者で問題ないかもしれませんね。
写真はうちの猫です(今月で1歳になりました!)。