Riotでアニメーションするriot-animoreを使う

はじめに

こんにちは、よっしーです。

フロントエンドではたくさんのフレームワークがありますが、小さなプロジェクトのときはRiotをよく使います。なにしろコンパクトで簡単ですからね。

でも、画面を切り替えたり、コンポーネントの表示・非表示にアニメーションが無いので、ちょっとつまらないなと思いませんか?。もちろん、そんなものはCSSで定義すればいいですけど・・・。でも簡単にアニメーションを設定したいですよね。

そういうわけで、今回はRiotでアニメーションする話です。

Riotのアニメーションモジュールriot/animore

Riotでアニメーションするライブラリを幾つか使ってみましたが、riot/animoreが一番しっくりくる感じでした。

https://github.com/riot/animore

タグの表示時(mount)と非表示時(unmount)にアニメーションの設定をすることができます。

インストールも簡単です。単に使いたいだけなら、GitHubからriot-animore.jsをダウンロードして、HTMLで読み込むだけです。

<script src="path/to/riot-animore.js"></script>

ドキュメントのところに、主な使い方とデモもあるので導入は簡単だと思います。

ただ、注意点が幾つかあります。基本的に自分で作ったカスタムタグにアニメーションの設定をすることができないみたいです。そのため、カスタムタグではない'divタグとかに、アニメーションを仕込むことになります。

ifを使ったアニメーション

riotでifを使ってタグを表示・非表示することはたくさんあります。それで、ifで制御しているところにアニメーションを仕込む例を作ってみました。

サンプルの実行例

サンプルはこちら

コードはこんな感じです。

index.html

<!DOCTYPE html>
<html>
  <head>
    <link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css'>
    </head>
  <body>

    <div class='container'>
      <my-tag></my-tag>
    </div>

    <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/riot@3.5/riot+compiler.min.js"></script>
    <script src="https://cdn.rawgit.com/riot/animore/master/riot-animore.js"></script>
    <script type="riot/tag" src="tags/my-tag.tag"></script>

    <script type="text/javascript">
      riot.mount('*')
    </script>


  </body>
</html>

tags/my-tag.tag

<my-tag>
  <h3>ifのアニメーション</h3>
  <div class='row'>
    <div class='col-sm-3'>
      <button class="btn btn-primary" data-toggle="button" aria-pressed="false" autocomplete="off" onclick={toggle}>
        toggle
      </button>
    </div>
    <div class='col-sm-9'>
      <!--      アニメーション付きで表示・非表示をする-->
      <div if={ isVisible } data-is="animore" 
       mount={{ duration: 500,rotateY :[-270,0],scale:[0.8,1],opacity:[0,1],maxHeight:[0, '500px'],easing: 'linear' }} 
       unmount={{duration: 500,opacity:0,scale:1.2,maxHeight:[ '500px',0],easing: 'linear' }}>
        <card></card>
      </div>
    </div>
  </div>

  <script>
    // カードの表示・非表示の制御
    this.isVisible = true
    toggle() {
      this.isVisible = !this.isVisible
    }

  </script>
</my-tag>


<card>
  <!-- ただのカード-->
  <div class="card" style="width: 18rem;">
    <img class="card-img-top" src="../img/morning-2550628_640.jpg" alt="Card image cap">
    <div class="card-body">
      <h5 class="card-title">Card title</h5>
      <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
    </div>
  </div>
</card>

長くなってしまいましたが、アニメーションをしている部分はシンプルです。

流れは、index.htmlで、riot,riot-animore,bootstrapを読み込んでいます。そして、タグを読み出しています。

my-tag.tagでタグの定義をしています。大事なところは

      <div if={ isVisible } data-is="animore" 
       mount={{ duration: 500,rotateY :[-270,0],scale:[0.8,1],opacity:[0,1],maxHeight:[0, '500px'],easing: 'linear' }} 
       unmount={{duration: 500,opacity:0,scale:1.2,maxHeight:[ '500px',0],easing: 'linear' }}>

という部分です。ここで、表示・非表示時のアニメーションを設定しています。

アニメーションをするタグには必ずdata-is="animore"を設定します。

次に、mountに表示時に行うアニメーションの設定をしています。

durationがアニメーションをする時間です。

rotateYがY軸を中心に回転するアニメーションです。-270度から0度に回転します。これでFlip動作の出来上がりです。

scaleでサイズを指定しています。0.8倍から1倍に大きさが変化します。

opacityで、半透明度合いの変化を記述します。

easingへ変化の方法です。linearは線形に変化します。他にもたくさんの変化の方法があります。詳しくはhttp://animejs.com/documentation/#pennerを見ると、たくさんの変化の方法が書いています。

unmountは非表示にするときに実行されます。今回は、フェードアウトしながら、大きくなるアニメーションにしています。

mount,ummount時に指定できるプロパティはたくさんあります。具体的なプロパティは、https://github.com/juliangarnier/animeやriot-animoreのページを参照してください。

ハマリポイント

ifで表示・非表示をさせるタグをアニメーションするのは簡単でした。
ここからは、riot-animoreを使ったときのハマリポイントの解説です。

カスタムタグに、直接アニメーションを指定できない

サンプルではdivタグにアニメーション設定をしました。riotであればカスタムタグにアニメーション設定をしたくなると思いますが、カスタムタグにはできないみたいです。

カスタムタグにする場合は、カスタムタグの中のdivタグ等に設定するのが良さそうです。

if以外にはmount時のアニメーションしかできないと思ったほうがいい

mountのアニメーションは、表示される瞬間に必ず実行されます。つまり、ifで制御されなくても表示さえされれば実行されます。

でも、unmountは違います。非表示時に実行されることはありますが、それはタグが生きている場合です。例えば、親のタグにifがついていて、アニメーションが設定されているタグは、unmountのアニメーションは実行されません。unmountのアニメーションを実行するときには、すでにタグが無いからです。

たとえば、こんな感じのものです。

<div if={条件}>
  <div data='animore'
    mount={{}}           <-- 実行される
    unmount={{}}>       <-- 実行されない
    内容
  </div>
</div>

ここを抑えておかないと思った動かないです。

まとめ

riotで簡単にアニメーション設定できるriot-animoreの紹介でした。
少しだけ癖がありますが、アニメーションを簡単に設定したいときに重宝するので使ってみてください。