LoginSignup
1
1

More than 3 years have passed since last update.

Ionicアニメーションで遊ぼう

Last updated at Posted at 2021-05-09
1 / 25

はじめに

こんにちは!

最近はかっこいいアニメーションをするUIが多いですね。
UI/UXを考える上で、アニメーションは必須技術となっています。
そこで、今回はIonicアニメーションで遊んでみたいと思います。

元ネタは次のページです。詳しく学びたい方は次のリンクからどうぞ!


自己紹介

  • Twitter: s_kozake
  • 特技: 🍺が好きです

ジェスチャー

Ionicアニメーションで遊ぶ前に、ジェスチャーについて少し触れます。
アニメーションの動作させるには、ユーザーからの何らかの操作が起点となることが多いですので。
特にスマフォでは、スワイプやダブルタップ、ロングタップなど様々な操作があります。

このような複雑な操作をサポートするために、Ionicにはジェスチャーユーティリティが用意されています。
便利な世の中ですね!


ジェスチャーユーティリティのインストール

CDNからインストールすれば簡単です。
AngularとかReactなどのフレームワークがなくても使えるのは便利ですね!
もちろん、AngularやReact、Vueから使える手段も用意されています(むしろこちらが主流)。

import { createGesture } from 'https://cdn.jsdelivr.net/npm/@ionic/core@latest/dist/esm/index.mjs';

ジェスチャーの基本

createGesture 関数を使ってジェスチャーを作成します。
createGesture 関数の代表的なオプションは次のとおりです。

const gesture = createGesture({
  el: elementRef,              // ジェスチャーを受け取る対象要素
  disableScroll: false,        // ジェスチャーの間スクロールを無効にするかどうか
  direction: 'x',              // ジェスチャー検出を特定する軸
  gesturePriority: 0,          // ジェスチャーの優先度。高いものが優先される
  threshold: 15,               // ジェスチャー開始を判断する開始点からのポインタ移動量
  gestureName: 'my-gesture',   // ジェスチャーの名前
  onMove: ev => onMove(ev)     // ジェスチャー動作時に呼ばれるコールバック関数
});

ジェスチャーの基本

onMove に設定したコールバック関数に渡されるイベントでジェスチャー情報を取得できます。

const onMove = (detail) => {
  const type = detail.type;            // 検出されたジェスチャーのタイプ
  const startX = detail.startX;        // ジェスチャーを開始したx座標
  const currentX = detail.currentX;    // ジェスチャーの現在のx座標
  const deltaX = detail.deltaX;        // ジェスチャー開始点からのx軸上の移動距離
  const velocityX = detail.velocityX;  // ジェスチャーのx軸上の移動速度
}


ジェスチャーのデモ

See the Pen Ionic Gestures - Basic by Sinichi Kozake (@kozake) on CodePen.


アニメーション

では、Ionicアニメーションで遊んでいきましょう!
Ionicにはアニメーションを簡単に扱えるユーティリティが用意されています。
これを用いることで直感的にアニメーションを作成することができます。


アニメーションユーティリティのインストール

CDNからインストールすれば簡単です。
ジェスチャー同様、AngularやReact、Vueから使える手段も用意されています。

import { createAnimation } from 'https://cdn.jsdelivr.net/npm/@ionic/core@latest/dist/esm/index.mjs';

アニメーション(基本1)

createAnimation 関数を使ってアニメーションを作成します。

createAnimation()
  .addElement(document.querySelector('.square'))  // アニメーション対象要素
  .duration(1500)                                 // アニメーション間隔
  .iterations(1)                                  // アニメーション回数
  .fromTo('opacity', '1', '0.2');                 // 開始と終了

上記コードでは、1.5秒の間隔で透過が変化するアニメーションを作成しています。


アニメーション(基本1)のデモ

See the Pen Ionic Animations - Basic by Sinichi Kozake (@kozake) on CodePen.


アニメーション(基本2)

もっと複雑なアニメーションも簡単に作成できます!

const animation = createAnimation()
   .addElement(document.querySelector('.square'))
   .duration(1500)
   .iterations(Infinity)
   .direction('alternate')
   .fromTo('transform',
           'translateX(0px) scale(0.5) rotate(0)',
           'translateX(100px) scale(1) rotate(45deg)')
  .fromTo('opacity', '1', '0.2');

上記コードでは、1.5秒の間隔で透過や大きさ、傾きやX軸が変化するアニメーションを作成しています。
iterations(Infinity)と指定することで、アニメーションは停止するまで何度も繰り返されます。


アニメーション(基本2)のデモ

See the Pen Ionic Animations - Basic2 by Sinichi Kozake (@kozake) on CodePen.


アニメーション(キーフレーム)

キーフレームを使うと、さらに詳細にアニメーション動作を指定することができます!

const animation = createAnimation()
   .addElement(document.querySelector('.square'))
   .duration(1000)
   .keyframes([
     { offset: 0, transform: 'translateX(0px) rotate(0)' },
     { offset: 0.3, transform: 'translateX(150px) rotate(15deg)' },
     { offset: 1, transform: 'translateX(100px) rotate(0)' }
   ]);

上記コードでは、開始0.3秒後に右に150px移動し、45度回転します。
その後、0.7秒かけて左に50px移動して傾きも元に戻ります。


アニメーション(キーフレーム)のデモ

See the Pen Ionic Animations - Keyframes by Sinichi Kozake (@kozake) on CodePen.


アニメーション(グループ)

アニメーションをグループ指定することも出来ます!

const squareA = createAnimation()
  .addElement(document.querySelector('.square-a'))
  .keyframes([...]);

const squareB = createAnimation()
  .addElement(document.querySelector('.square-b'))
  .keyframes([...]);

const squareC = createAnimation()
  .addElement(document.querySelector('.square-c'))
  .duration(5000)
  .keyframes([...]);

const parent = createAnimation()
  .duration(2000)
  .iterations(Infinity)
  .addAnimation([squareA, squareB, squareC]);

上記コードでは、それぞれのアニメーションをまとめて動作させます。
squareAsquareBではアニメーション間隔を指定していないので、parentに指定された2秒が適用されますが、squareCでは指定した5秒間隔でアニメーションが実行されます。


アニメーション(グループ)のデモ

See the Pen Ionic Animations - Group by Sinichi Kozake (@kozake) on CodePen.


アニメーション(チェーン)

アニメーションを連鎖(チェーン)することもできます!

const squareA = createAnimation()
  .addElement(document.querySelector('.square-a'))
  .fill('none').duration(1000).keyframes([...]);

const squareB = createAnimation()
  .addElement(document.querySelector('.square-b'))
  .fill('none').duration(1000).keyframes([...]);

const squareC = createAnimation()
  .addElement(document.querySelector('.square-c'))
  .fill('none').duration(1000).keyframes([...]);

await squareA.play();
await squareB.play();
await squareC.play();

await でアニメーションの完了を待つだけです。簡単ですね!


アニメーション(チェーン)のデモ

See the Pen Ionic Animations - Chaining by Sinichi Kozake (@kozake) on CodePen.


アニメーション(ジェスチャー)のデモ

ジェスチャーと組み合わせた例が次のとおりです。
アニメーション動作をジェスチャーなどの情報と組み合わせて動作させることが出来ます。
下記のコードでは、四角をドラックして動かすことが出来ます。また、スワイプして動作させることも出来ます。

let initialStep = 0;
let started = false;

const square = document.querySelector('.square');
const MAX_TRANSLATE = 400;

const animation = createAnimation()
  .addElement(square)
  .duration(1000)
  .fromTo('transform', 'translateX(0)', `translateX(${MAX_TRANSLATE}px)`);

const gesture = createGesture({
  el: square,
  threshold: 0,
  gestureName: 'square-drag',
  onMove: ev: onMove(ev),
  onEnd: ev: onEnd(ev)
})

gesture.enable(true);

const onMove = (ev): {
  if (!started) {
    animation.progressStart();
    started = true;
  }

  animation.progressStep(getStep(ev));
}

const onEnd = (ev): {
  if (!started) { return; }

  gesture.enable(false);

  const step = getStep(ev);
  const shouldComplete = (Math.abs(ev.velocityX) > 0.2) ?
    initialStep == 0 : step > 0.5;

  animation
    .progressEnd((shouldComplete) ? 1 : 0, step)
    .onFinish((): { gesture.enable(true); });

  initialStep = (shouldComplete) ? MAX_TRANSLATE : 0;
  started = false;
}

const clamp = (min, n, max): {
  return Math.max(min, Math.min(n, max));
};

const getStep = (ev): {
  const delta = initialStep + ev.deltaX;
  return clamp(0, delta / MAX_TRANSLATE, 1);
}

アニメーション(ジェスチャー)のデモ

See the Pen Ionic Animations - Gesture by Sinichi Kozake (@kozake) on CodePen.


アニメーション(スクロール)

最後によくあるスクロールと連動してアニメーションするやつです。
画面下から出てくる四角がスクロールと連動して大きくなります。

const animation = createAnimation()
   .addElement(document.querySelector('.square'))
   .duration(1) 
   .fromTo('opacity', '0', '1')
   .fromTo('transform', 'scale(0)', 'scale(1)');

const square = document.querySelector('.square');

let started = false;

window.onscroll = () => {
  const documentHeight = document.documentElement.clientHeight;
  const scrollTop = document.documentElement.scrollTop;
  const targetPosition = square.offsetTop;

  const step = Math.min((scrollTop + documentHeight - targetPosition) / 200, 1);

  if(step > 0 && step < 1){
    if (!started) {
      animation.progressStart();
      started = true;
    }
    animation.progressStep(step);
  } else {
    if (started) {
      animation.progressEnd(step == 1 ? 1 : 0, step)
      started = false;
    }
  }
}

アニメーション(スクロール)のデモ

See the Pen Ionic Animations - Scroll by Sinichi Kozake (@kozake) on CodePen.


おわり

Ionicアニメーション楽しいですね!
色々と試して遊んでみてください🍻(´∀`*v)

1
1
0

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
1
1