ホバーすると桜が舞うアニメーションをCSSとJSで実装する方法

CSSとJavaScriptで、マウスホバー時に桜が舞うアニメーションを実装してみました。

この記事を読むことで、以下のようなアニメーションを作成することができます。

\ ホバーしてください /

CHERRY BLOSSOM

マウスカーソルを当てると桜が降り、離せばストップするアニメーションが確認できたかと思います。

  • jQueryなし
  • プラグインやライブラリなし
  • コピペOK

jQueryなどのライブラリやプラグインは使用せず、素のJavaScriptで自作しました。

コピペするとすぐに使えるようにしていますので、よければ参考にしてみてください。

目次

ホバー時に桜が舞うアニメーションのDEMO

今回の記事では、以下のようなシンプルなカードを作成していきます。

マウスカーソルを当てて確認してみてください。

テキスト
  • マウスホバーすると桜が発生し、離すとストップする
  • 花びらのサイズと発生位置はランダム(最大・最小サイズを設定可能)

主な仕様は上記の通りです。

次で実際のコードをみていきましょう。

【コピペ用】ホバー時に桜が舞うアニメーションの全体の実装コード

HTML, CSS, JavaScriptの全体コードを用意しました。

それぞれのファイルを作成し、コピペしてお使いください。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>ホバー時に桜が舞うアニメーションのDEMO</title>
    <!-- CSS読み込み -->
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <a href="#" class="cherry-card js-cherry">テキスト</a>

    <!-- JS読み込み -->
    <script src="script.js"></script>
  </body>
</html>
.cherry-card {
  /* 必須 */
  position: relative;
  overflow: hidden;
  /* 任意 */
  width: 400px;
  height: 300px;
  display: flex;
  justify-content: center;
  align-items: center;
  border: 1px solid #fa8095;
  color: #fa8095;
  transition: all 0.6s;
}

.cherry-card:hover {
  box-shadow: 0 0 20px rgba(250, 128, 149, 0.2);
  border-color: #fff;
}

/* 桜の花びらのスタイル */
.petal {
  position: absolute;
  background-color: #ffc0cb; /* 花びらの色 */
  border-radius: 150% 0 150% 0;
  animation: animate-petal 6s linear;
}

.petal::after {
  content: "";
  position: absolute;
  top: -14%;
  left: -10%;
  display: block;
  width: 100%;
  height: 100%;
  background-color: #ffc0cb;
  border-radius: 150% 0 150% 0;
  transform: rotate(15deg);
}

/* 花びらが降るアニメーション */
@keyframes animate-petal {
  0% {
    top: 0;
    transform: rotate(0deg);
  }
  90% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    top: 100vh;
    transform: rotate(2000deg);
  }
}
// 'js-cherry'クラスがついた要素を全て取得
const cherryEls = document.querySelectorAll(".js-cherry");

// 取得した要素をArrayに変換
const cherryElsArr = Array.prototype.slice.call(cherryEls);

// 取得した要素ひとつひとつに処理を行う
cherryElsArr.forEach((cherryEl) => {
  let interval;

  // マウスホバー時に桜を降らせる
  cherryEl.addEventListener("mouseenter", () => {
    interval = setInterval(createPetal.bind(undefined, cherryEl), 500);
  });

  // マウスを離すと停止
  cherryEl.addEventListener("mouseleave", () => {
    clearInterval(interval);
  });
});

// 花びらを生成する関数
const createPetal = (el) => {
  const petalEl = document.createElement("span");
  petalEl.className = "petal";
  const minSize = 10;
  const maxSize = 15;
  const size = Math.random() * (maxSize + 1 - minSize) + minSize;
  petalEl.style.width = `${size}px`;
  petalEl.style.height = `${size}px`;
  petalEl.style.left = Math.random() * el.clientWidth + "px";
  el.appendChild(petalEl);

  // 一定時間が経てば花びらを消す
  setTimeout(() => {
    petalEl.remove();
  }, 6000);
};

ホバー時に桜が舞うアニメーションの実装手順とコードの解説

ここからは、実装コードの解説をしていきます。

コードの中身を理解したい方、カスタマイズしたい方はぜひ読んでみてください。

\ DEMO /

テキスト

HTML

<a href="#" class="cherry-card js-cherry">テキスト</a>

今回はリンクカードを想定しているので、aタグで実装します。

タグの中には必要な文章やコンテンツを入れてください。

cherry-cardjs-cherryの2つのクラスを指定していますが、それぞれ以下の役割ごとに分けています。

  • cherry-card・・・カードのスタイルを設定するためのクラス
  • js-cherry・・・JavaScriptで取得するためのクラス

これでHTMLは終わりです!

CSS

/* カードのスタイル */
.cherry-card {
  /* 必須 */
  position: relative;
  overflow: hidden;
  /* 任意 */
  width: 400px;
  height: 300px;
  display: flex;
  justify-content: center;
  align-items: center;
  border: 1px solid #fa8095;
  color: #fa8095;
  transition: all 0.6s;
}

/* カードをホバーしたときのスタイル */
.cherry-card:hover {
  box-shadow: 0 0 20px rgba(250, 128, 149, 0.2);
  border-color: #fff;
}

/* 桜の花びらのスタイル */
.petal {
  position: absolute;
  background-color: #ffc0cb; /* 花びらの色 */
  border-radius: 150% 0 150% 0;
  animation: animate-petal 6s linear;
}

.petal::after {
  content: "";
  position: absolute;
  top: -14%;
  left: -10%;
  display: block;
  width: 100%;
  height: 100%;
  background-color: #ffc0cb;
  border-radius: 150% 0 150% 0;
  transform: rotate(15deg);
}

/* 花びらが降るアニメーション */
@keyframes animate-petal {
  0% {
    top: 0;
    transform: rotate(0deg);
  }
  90% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    top: 100vh;
    transform: rotate(2000deg);
  }
}

こちらが全体のCSSです。少し長いので、いくつかに分けて解説していきます。

CSSパート1. カードのスタイル

まずはカードの部分のスタイルからみていきます。

/* カードのスタイル */
.cherry-card {
  /* 必須 */
  position: relative; /* static以外の値を設定 */
  overflow: hidden; /* はみ出した花びらを非表示に */
  /* 任意 */
  width: 400px; /* 横幅 */
  height: 300px; /* 縦幅 */
  display: flex;
  justify-content: center;
  align-items: center;
  border: 1px solid #fa8095; /* 枠線 */
  color: #fa8095; /* 文字色 */
  transition: all 0.6s;
}

/* カードをホバーしたときのスタイル */
.cherry-card:hover {
  box-shadow: 0 0 20px rgba(250, 128, 149, 0.2);
  border-color: #fff;
}

横幅・縦幅・色などは、自由にカスタマイズしてください。

ここで必須なのはpositionoverflowプロパティなので、この2つのみ解説します。

まずpositionプロパティにはrelativeを指定しています。

花びらの要素はposition: absoluteで動かすため、基準となるカードにstatic以外の値を指定することで、カードを基準に花びらを降らせることができますね。

次にoverflowプロパティには、hiddenを指定します。

こうすることで、カードからはみ出した花びらを非表示にすることができます。

CSSパート2. 花びらのスタイル

桜の花びらの部分は、CSSで表現しています。

/* 桜の花びらのスタイル */
.petal {
  position: absolute;
  background-color: #ffc0cb; /* 花びらの色 */
  border-radius: 150% 0 150% 0;
  animation: animate-petal 6s linear;
}

.petal::after {
  content: "";
  position: absolute;
  top: -14%;
  left: -10%;
  display: block;
  width: 100%;
  height: 100%;
  background-color: #ffc0cb;
  border-radius: 150% 0 150% 0;
  transform: rotate(15deg);
}

上記のコードで、以下のような見た目の花びらを作ることができます。

簡単に説明すると、

  1. span要素と擬似要素::afterで2つの形を作成
  2. それぞれの角度を調整して重ねる

という手順で実装しています。

仕組みを詳しく知りたい方は以下の記事で図解付きで解説しているので、そちらを参照してください。

CSSパート3. 花びらが舞うアニメーションを作成

最後に、花びらが舞うアニメーションを指定していきます。

/* 花びらが降るアニメーション */
@keyframes animate-petal {
  0% {
    top: 0;
    transform: rotate(0deg);
  }
  90% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    top: 100vh;
    transform: rotate(2000deg);
  }
}

ここでは、以下の3つのアニメーションを指定しています。

  • 花びらを上から下に移動させる
  • 花びらを回転させる
  • アニメーション終了時にフェードアウトさせる
花びらを上から下に移動させるアニメーションを指定
@keyframes animate-petal {
  0% {
    top: 0;
  }
  100% {
    top: 100vh;
  }
}

花びらを上から下に降らせるアニメーションは、topプロパティを調整して行います。

まず0%の時点では値が0なので、花びらはカードの一番上に表示されます。

そしてアニメーション終了時である100%の時点では100vhを指定しているので、開始から終了までに100vh分下に移動させるという意味になります。

ここの100%の値は、カードの高さによって変える必要があるので、各自調整してください。

花びらを回転させるアニメーションを指定
@keyframes animate-petal {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(2000deg);
  }
}

花びらを回転させるには、transformプロパティのrotate関数を使用します。

ここでは開始時に0deg、終了時に2000degという値を指定しています。

360degでちょうど一回転するので、2000degなら5回転半させるという意味になりますね。

回転数を変更したい場合は、この値を調整してください。

花びらがフェードアウトするアニメーションを指定
@keyframes animate-petal {
  90% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}

アニメーションの終盤で徐々に透明にしていくことで、フェードアウトのアニメーションを実装しています。

  • 0% ~ 90%まで:不透明のまま
  • 90% ~ 100%まで:徐々に透明にする

この指定をすることで、アニメーション終了時に花びらが一瞬で消えてしまうのを防ぐことができます。

CSSの解説は以上で終わりです!

JavaScript

最後にJavaScriptの解説をしていきます。

以下が全体のコードになります。

// 'js-cherry'クラスがついた要素を全て取得
const cherryEls = document.querySelectorAll(".js-cherry");

// 取得した要素をArrayに変換
const cherryElsArr = Array.prototype.slice.call(cherryEls);

// 取得した要素ひとつひとつに処理を行う
cherryElsArr.forEach((cherryEl) => {
  let interval;

  // マウスホバー時に桜を降らせる
  cherryEl.addEventListener("mouseenter", () => {
    interval = setInterval(createPetal.bind(undefined, cherryEl), 500);
  });

  // マウスを離すと停止
  cherryEl.addEventListener("mouseleave", () => {
    clearInterval(interval);
  });
});

// 花びらを生成する関数
const createPetal = (el) => {
  const petalEl = document.createElement("span");
  petalEl.className = "petal";
  const minSize = 10;
  const maxSize = 15;
  const size = Math.random() * (maxSize + 1 - minSize) + minSize;
  petalEl.style.width = `${size}px`;
  petalEl.style.height = `${size}px`;
  petalEl.style.left = Math.random() * el.clientWidth + "px";
  el.appendChild(petalEl);

  // 一定時間が経てば花びらを消す
  setTimeout(() => {
    petalEl.remove();
  }, 6000);
};

コードを分割しつつ解説していきますね。

JSパート1. 桜を降らせる要素を取得

まず最初に、桜を降らせる要素をquerySelectorAllで全て取得します。

const cherryEls = document.querySelectorAll(".js-cherry");

ここでは、js-cherryクラスがついた要素全てを取得するということですね。

次に、取得した要素をArrayに変換します。

const cherryElsArr = Array.prototype.slice.call(cherryEls);

querySelectorAllで取得した要素の型はNodeListなので、特定のブラウザではforEachメソッドを使うことができません。

そのため、NodeListをArrayに変換する必要があります。

JSパート2. マウスホバー時とホバー終了時の動作を設定

cherryElsArr.forEach((cherryEl) => {
  let interval;

  // マウスホバー時に桜を降らせる
  cherryEl.addEventListener("mouseenter", () => {
    interval = setInterval(createPetal.bind(undefined, cherryEl), 500);
  });

  // マウスを離すと停止
  cherryEl.addEventListener("mouseleave", () => {
    clearInterval(interval);
  });
});

ここでは実際のホバー時・ホバー終了時の挙動を指定していきます。

まずは先ほど取得した全ての要素の配列にforEachメソッドを使用します。

cherryElsArr.forEach((cherryEl) => {
  // ...
}

次にホバー時とホバー解除時の動作を指定していきます。

これらには、以下の2つのイベントを使用します。

  • mouseenter…マウスカーソルが要素の領域に入ったとき
  • mouseleave…マウスカーソルが要素の領域から出たとき

CSSの:hover擬似クラスと似たような挙動ですね。

それぞれ以下のような書き方で指定します。

cherryEl.addEventListener("mouseenter", () => {
  // マウスカーソルが要素の領域に入ったときの処理
});

cherryEl.addEventListener("mouseleave", () => {
  // マウスカーソルが要素の領域から出た時の処理
});

ここでホバー時とホバー解除時の処理を見ていきましょう。

  • ホバー時…花びらを一定間隔で自動生成する
  • ホバー解除時…花びらの自動生成をストップする

この処理にはsetIntervalclearIntervalを使用します。

cherryElsArr.forEach((cherryEl) => {
  let interval;

  // マウスホバー時に桜を降らせる
  cherryEl.addEventListener("mouseenter", () => {
    interval = setInterval(createPetal.bind(undefined, cherryEl), 500);
  });

  // マウスを離すと停止
  cherryEl.addEventListener("mouseleave", () => {
    clearInterval(interval);
  });
});

ホバー時はsetIntervalを使ってcreatePetal関数を500ミリ秒間隔で呼び出します。

このcreatePetalは次で詳しく解説しますが、花びらを自動生成する関数です。

これを0.5秒ごとに呼び出すことで、花びらが一定間隔で生成されるということになりますね。

ホバー解除時はclearIntervalでタイマーを解除することで、花びらの生成がストップします。

これでホバー時・ホバー解除時の処理は終わりです。

JSパート3. 桜の花びらを生成する関数を定義

最後は、花びらを自動生成する関数createPetalを見ていきましょう。

// 花びらを生成する関数
const createPetal = (el) => {
  // ①spanタグを生成&クラス付与
  const petalEl = document.createElement("span");
  petalEl.className = "petal";

  // ②最大値・最小値を指定
  const minSize = 10;
  const maxSize = 15;

  // ③最小値~最大値でランダムな数値をwidthとheightに指定
  const size = Math.random() * (maxSize + 1 - minSize) + minSize;
  petalEl.style.width = `${size}px`;
  petalEl.style.height = `${size}px`;

  // ④ランダムな数値をleftプロパティに指定
  petalEl.style.left = Math.random() * el.clientWidth + "px";

  // ⑤完成した花びらを親要素に挿入
  el.appendChild(petalEl);

  // ⑥一定時間が経てば花びらを消す
  setTimeout(() => {
    petalEl.remove();
  }, 6000);
};

この関数では、以下のことが起こっています。

  1. span要素を生成して.petalクラスをつける
  2. 花びらの最小サイズ・最大サイズを設定する
  3. 最小値~最大値の間でランダムな数値を花びらの横幅と縦幅にセットする
  4. 花びらの水平方向の位置をleftプロパティにランダムでセットする
  5. 完成した花びらの要素を親要素に挿入する
  6. 一定時間がたつと花びらを削除する

この関数をパート2で解説したsetIntervalに渡すことで、一定間隔でランダムサイズ・位置の花びらを自動生成することができます!

これでJavaScriptの解説は以上です。

ホバー時に桜が舞うアニメーションのカスタマイズ方法

ここでは、サンプルのコードのカスタマイズ方法を解説していきます。

コードのどの部分を変更すればいいかを説明していますので、あまり知識がない方でも調整可能です。

以上でカスタマイズ方法の解説は終わりです!

※もし他にもカスタマイズしたい項目がありましたら、コメント欄にて受け付けています。

【まとめ】ホバー時に桜が舞うアニメーションをCSSとJSで実装する方法

テキスト

ホバーすると桜が舞うアニメーションを実装する方法を紹介しました。

CSSとVanilla JavaScriptのみで簡単に実装できるので、ぜひ試してみてください。

関連記事

Web制作に関する
記事案を募集中!

Web制作について知りたいこと、質問等ありましたら、以下のフォームから気軽に投稿してください。
要望が多かったものは解説記事を作成します。

よかったらシェアしてね!

コメント

コメントする

目次
閉じる