zukucode
主にWEB関連の情報を技術メモとして発信しています。

Vue.js 数値の変化をドラムロールアニメーションする

Vue.jsの公式ドキュメントの状態のトランジションで紹介されている数値のドラムロールアニメーションをコンポーネントとして実装します。

公式のサンプルではTween.jsを使用していますが、今回は外部ライブラリを使用せずに作成します。

AnimatedNumber.vue
<template>
  <span>{{ animated_number }}</span>
</template>

<style scoped>
/*必要に応じて追加*/
</style>

<script>
export default {
  props: {
    value: {
      type: Number,
      required: true
    }
  },
  data () {
    return {
      animated_number: 0
    };
  },
  watch: {
    value (newValue, oldValue) {
      let timeCnt = 0;
      let timer;
      const animate = () => {
        timeCnt++;
        if (timeCnt <= 60) {
          this.animated_number = Math.floor((newValue - oldValue) * timeCnt / 60) + oldValue;
          timer = setTimeout(() => {
            animate();
          }, 10);
        } else {
          clearTimeout(timer);
          timer = null;
          this.animated_number = newValue;
        }
      };
      animate();
    }
  },
  mounted () {
    this.animated_number = this.value;
  }
};
</script>
使用方法
<template>
  <div>
    <input v-model.number="num" type="number">
    <AnimatedNumber :value="num"></AnimatedNumber>
  </div>
</template>

<style scoped>
</style>

<script>
import AnimatedNumber from './AnimatedNumber.vue';
export default {
  components: { AnimatedNumber },
  data () {
    return {
      num: 0,
    };
  }
};
</script>

解説

propsで親から渡された値(value)をwatchで監視します。

valueが変更されるたびにwatch処理でanimated_numberを徐々に変化させます。

valueではなくanimated_numbertemplateで表示するようにすれば、徐々に変化する様子(アニメーション)が表示されるようになります。

ドラムロール

Tween.jsを使わずにドラムロール処理を実装しました。

1〜10に変化する時と、1〜1000に変化するときでアニメーションの長さが変わらないように、1ステップあたりの数値の変化量を工夫しています。

watchの処理ではアローファンクションを使っているのでthisのスコープには注意が必要です。


関連記事

  • webpack lessをImportしてビルドする

    Vue.js lessを使いwebpackでビルドするでvueファイルの中でlessを実装してビルドする方法を紹介しました。htmlやbodyなどに適用するベースのクラスを外部のlessファイルに実装...


  • ExtractTextPluginでcssファイルを出力する

    webpackのプラグインExtractTextPluginを使って、ビルドされたjsファイルからstyleの部分を抽出してcssファイルで出力します。extract-text-webpack-plu...


  • webpack-dev-serverで開発サーバーを起動する

    webpack-dev-serverで開発サーバーを起動します。ファイルやフォルダ構成などの環境はvueファイル(単一ファイルコンポーネント)をwebpackでビルドで紹介したものと同様とします。we...


  • webpack モジュールのパスを絶対パスで指定する方法

    自分で作成したモジュールをインポートするときはインポートするファイルを基準に相対パスで指定する必要があります。フォルダ構成によっては深く階層を辿らないといけないので、フォルダ構成が変わってしまうと大変...


  • Vuex 厳格(strict)モードでエラーになるよくある原因

    Vuexの厳格(strict)モードでエラーになってしまう原因でよくあるパターンです。stateに格納した配列をソートして表示するときに、stateの値をcomputedやgettersでそのままソー...


  • Vuex stateを作成して各コンポーネントで参照する

    Vue.jsにVuexを導入するでVuexの導入が完了しました。実際にstoreを作成して、各コンポーネントでその値を参照できるようにします。最初にstoreを作成します。mutations.jsにs...


  • Vuex mutationでstateの値を変更する

    Vuex stateを作成して各コンポーネントで参照するでstateを作成して各コンポーネントで参照できるようになりました。stateはmutationの処理でしか変更できません。コンポーネントからm...


  • Vuex moduleに定義したstateをコンポーネントで簡単に取得する

    Vuexのモジュールに定義したstateを各コンポーネントで参照する方法を紹介します。以下のようにmoduleが定義されているとします。各コンポーネントではthis.$store.state.モジュー...


  • Vuexとaxiosを連携する

    Vuex actionでローディングアイコンを表示するで、actionの処理でローディングの表示非表示を制御するmutationを実行するようにしました。ajaxの処理が増えるたびに同じmutatio...


  • Vuex モジュールのactionの処理で別モジュールのactionをコールする

    Vuexのモジュール内のactionの処理で別モジュールのactionをコールする方法を紹介します。ルートのactionの場合、moduleで定義したactionをコールする場合は、以下のようにモジュ...