概要
ちょっと前に、ページ内の画像を全てワニに変えるボタンの話がニュースになっていました。
そのサイトでは jQuery が使われていましたが、
Vue.js ならより直感的に作れそうだと思ったので、練習がてら作ってみました。
デモ
デモページ
(ワニ画像を集めるのが大変だったので、ねこにしました)
↓のページの画像が‥‥
緊急ボタンを押すとランダムなねこ画像に変化します。
実装の考え方
- 元画像のファイル名が入った配列を data につくる
src/App.vue
data () {
return {
imagePath: './static/images/',
imageNames: [
'dosukebe_1.jpg',
'dosukebe_2.jpg',
'dosukebe_3.jpg'
],
pageTitle: '秘密',
numberOfCatImages: 5, // ねこ画像総数
loading: true
}
},
- computed で「元画像のパスの配列」を作る
src/App.vue
computed: {
imageNamesWithPath: function () {
return this.imageNames.map((value) => {
return `${this.imagePath}${value}`
})
}
}
- 「パスの配列」の要素を、img タグにバインドする
src/App.vue
<div class="flex" id="images">
<img v-for="image in imageNamesWithPath" :src="image">
</div>
<button @click="changeImages()" :disabled="loading">緊急回避</button>
- 緊急ボタンを押したときに配列を書き換えれば、画像も書き換わる
src/App.vue
methods: {
changeImages: function () {
this.imagePath = './static/images/cat/'
this.imageNames = this.imageNames.map((value) => {
let randomNumber = this.getRandomNumber(1, this.numberOfCatImages)
return `cat${randomNumber}.jpg`
})
this.pageTitle = 'ねこ'
},
getRandomNumber: (min, max) => {
return Math.floor(Math.random() * (max + 1 - min)) + min
}
},
画像のローディングが長い問題
上記だけでも一応機能はするのですが、画像を書き換える際に読み込み時間が発生してしまいます。
それでは重要な局面で間に合わなくなる可能性が生じるため、
以下のように事前に全ねこ画像をキャッシュします。
src/App.vue
created: function(){
for(let i=1; i <= this.numberOfCatImages; i++) {
let img = new Image();
img.src = `./static/images/cat/cat${i}.jpg`; // キャッシュ!
//デモのため、画像読み込み完了後にボタンを有効化する
if(i === this.numberOfCatImages) {
img.onload = () => {
this.loading = false;
}
}
}
}
created に指定された関数は、Vue インスタンスが作成された直後に呼びだされます。
上では画像を順番に読み込んでいき、最後まで読み込み終わったら ”this.loading = false;” で緊急ボタンを有効化しています。
余談:隠しコマンド
ワニマガジン社のサイトのソースをのぞいていたら、
隠しコマンドがありました。
_emergency.js
jQuery(function($) {
'use strict';
$.fn.waniEmergency = function(args) {
var input = [];
var konami = [16, 16, 16];
var namco = [38, 38, 38];
var imgCache = [];
var config = $.extend({
src : 'src',
srcset: 'srcset',
target: '',
}, args);
var method = {
(中略)
checkCode: function(codeArray, _target) {
return codeArray.join('-').indexOf(_target.join('-')) >= 0;
}
};
(中略)
$(window).keyup(function(e) {
input.push(e.keyCode);
if (method.checkCode(input, konami)) {
method.push();
}
if (method.checkCode(input, namco)) {
method.pull();
}
});
Shiftキーを3連続で押すと緊急回避、↑キーを3連続で押すと元に戻るようです。
(コマンド名は konami と namco )
こういう遊び心はいいですね。