【もりけん塾 @JS課題33】Animation APIを使用した遷移アニメーションの実装

JavaScript


現在、もりけん塾で
マークアップエンジニアの方がフロントエンドエンジニアになる為の課題に取り組んでいます。
今回は課題33の実装で学んだことをブログへまとめます

課題33

ドロワーメニュー内の要素をクリックするとドロワーメニューが閉じコンテンツに遷移するようにする
遷移する際は何かしらのアニメーションをつけること

以前実装したドロワーメニューをもとに、アニメーションの実装を行いました

制作物

codesandbox

Lesson33 - CodeSandbox
Lesson33 by sae-code using chance, date-fns, vite

Animations API

Animations APIを使用しアニメーションの実装を行いました

ウェブアニメーション API の使用 - Web API | MDN
ウェブアニメーション API により、JavaScript でアニメーションを構築したり、再生を制御したりすることができます。この記事では「ふしぎの国のアリス」を利用した楽しいデモとチュートリアルで正しい利用方法を説明します。

CSS アニメーション vs JavaScript のアニメーション

アニメーションを実装する際に悩んだのが、CSSとJavaScriptの使い分けです
以下の参考記事を読んで、その使い分けやAnimations APIのパフォーマンスについて学ぶことができました

Animating like you just don’t care with Element.animate – Mozilla Hacks - the Web developer blog
In Firefox 48 we're shipping the Element.animate() API — a new way to programmatically animate DOM elements using JavaScript. Let’s pause for a second — “big de...
CSS versus JavaScript animations  |  Articles  |  web.dev
You can animate with CSS or JavaScript. Which should you use, and why?

FadeIn

フェードインの実装をJavaScriptとCSSで行いました
fadeInさせたい親要素にfade-inクラスを付与しました

<body class="fade-in">
</body>

CSSで 全体に覆うようにコンテンツを表示させます

.fade-in::after {
  content: "";
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: skyblue;
  pointer-events: none;
  opacity: 1;
  z-index: 50;
}

JavaScriptでfadeInAnimationを定義、実行しopacityでふわっと表示する感じを実装しました
fade-inクラスを外し、表示したいコンテンツが現れます

const fadeInAnimation = (element, duration) => {
  element.animate([{ opacity: 0 }, { opacity: 1 }], duration);
};

fadeInAnimation(body, 300);
body.classList.remove("fade-in");

transform

ドロワーメニュー内の要素がクリックされた際に出現する
うさぎの画像を、右から左に移動させるアニメーションを定義しました

const transformLoadingAnimation = (element, duration) => {
  return element.animate(
    [
      { transform: "translate(0,-50%)" },
      { transform: "translate(-100%,-50%)" }
    ],
    duration
  );
};

うさぎの画像はあらかじめHTMLで実装しました

<div class="transition-loading" id="js-transition-loading">
   <img src="../img/transition-loading.png" alt="" />
</div>

.transition-loading {
  width: 30%;
  display: none;
  max-width: 300px;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-100%, -50%);
  z-index: 60;
}

.transition-animation .transition-loading {
  display: block;
}

ドロワーメニュー内の要素をクリックした時のイベント…

drawerMenuNavigation.forEach((nav) => {
  nav.addEventListener("click", (event) => {
    event.preventDefault();
    toggleDrawerMenu();   // ドロワーメニューを閉じる処理
    transitionPageAnimation(event.currentTarget.href); 
  });
});

アニメーションの終了イベントハンドラーである”finish”を使用して
アニメーションを終了後、ページを遷移します

const transitionPageAnimation = (href) => {
  body.classList.add("fade-in", "transition-animation");
  const loading = document.getElementById("js-transition-loading");
  const loadingAnimation = transformLoadingAnimation(loading, 500);
  loadingAnimation.addEventListener("finish", () => (window.location.href = href));
};

まとめ

アニメーションってHTML・CSS・JavaScriptの総合力が より 試される気がした…
アニメーションの引き出しがなさすぎて、あまりオシャレな感じにできませんでしたが、
Animations APIについて学ぶことができ、アニメーションを実装する手段を一つ知ることができました。


コメント

タイトルとURLをコピーしました