0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ボタンをクリックしたら星が飛び散るようなアニメーションをする

Last updated at Posted at 2024-12-20

はじめに

こんにちは、エンジニアのkeitaMaxです。

今回はAnime.jsを使用してクリックした時にアニメーションが走るようなボタンを作成してみようと思います。

Next.jsとTailwindCSSを使用します。

インストール

以下コマンドでインストールします。

npm install animejs --save

実装

import React, { useRef, useState, useEffect } from "react"
import anime from "animejs"

export const AnimeButton = React.memo(function AnimeButton() {
  const [stars, setStars] = useState<
    { id: number; x: number; y: number }[]
  >([])
  const containerRef = useRef<HTMLDivElement>(null)

  const handleClick = () => {
    if (!containerRef.current) return

    const containerRect = containerRef.current.getBoundingClientRect()
    const x = containerRect.width / 2
    const y = containerRect.height / 2

    // 新しい星を追加
    const newStars = Array.from({ length: 10 }, (_, i) => ({
      id: Date.now() + i,
      x,
      y,
    }))
    setStars((prevStars) => [...prevStars, ...newStars])
  }

  useEffect(() => {
    if (stars.length > 0) {
      stars.forEach((star) => {
        anime({
          targets: `#star-${star.id}`,
          translateX: {
            value: () => Math.random() * 200 - 100, // -100〜100のランダムなX方向
            duration: 1000,
          },
          translateY: {
            value: () => Math.random() * 200 - 100, // -100〜100のランダムなY方向
            duration: 1000,
          },
          opacity: {
            value: 0,
            duration: 1000,
          },
          easing: "easeOutQuad",
          complete: () => {
            setStars((prevStars) => prevStars.filter((s) => s.id !== star.id))
          },
        })
      })
    }
  }, [stars])

  return (
    <div
      ref={containerRef}
      className="relative flex h-screen items-center justify-center bg-gray-100"
    >
      <button
        onClick={handleClick}
        className="rounded-lg bg-blue-500 px-6 py-3 font-semibold text-white shadow-lg transition-all hover:shadow-xl"
      >
        Click Me!
      </button>
      {stars.map((star) => (
        <div
          key={star.id}
          id={`star-${star.id}`}
          className="absolute size-2 rounded-full bg-yellow-400 shadow-md"
          style={{
            left: star.x,
            top: star.y,
          }}
        ></div>
      ))}
    </div>
  )
})

export default AnimeButton

こんな感じにしました。

ボタンを押した時に黄色い玉をボタンの真ん中からランダムな方向に飛ばすようなものを作成しました。

動かしてみる

starbutton.gif

こんな感じで面白いボタンが出来上がりました。

おわりに

アニメーションを簡単に作成できるので、自分のサイトを豪華にしたい時に使えそうです。

この記事での質問や、間違っている、もっといい方法があるといったご意見などありましたらご指摘していただけると幸いです。

最後まで読んでいただきありがとうございました!

参考

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?