LoginSignup
17
14

More than 5 years have passed since last update.

ページ内の画像をワニに変えるボタンを Vue.js でつくってみた

Last updated at Posted at 2018-07-24

概要

ちょっと前に、ページ内の画像を全てワニに変えるボタンの話がニュースになっていました。

そのサイトでは jQuery が使われていましたが、
Vue.js ならより直感的に作れそうだと思ったので、練習がてら作ってみました。

デモ

デモページ
(ワニ画像を集めるのが大変だったので、ねこにしました)

↓のページの画像が‥‥

無題.png

緊急ボタンを押すとランダムなねこ画像に変化します。

無題2.png

実装の考え方

  • 元画像のファイル名が入った配列を 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 )

こういう遊び心はいいですね。

17
14
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
14