ライブデモ Live Demo

ボタンをクリックすると、クリック位置から波紋が広がります。波紋のサイズと速度をカスタムプロパティで調整できます。

Click the button to see a ripple expand from the click position. Adjust ripple size and speed via custom properties.

0.6s

AI向け説明 AI Description

`I-002` はクリックイベントでクリック位置を取得し、その位置に `` 要素を作成して `@keyframes ripple` で拡大・フェードアウトさせます。アニメーション終了後に要素を削除します。

`I-002` captures click position and creates a `` element at that location, animating it with `@keyframes ripple` to expand and fade out. Removes element after animation completes.

調整可能パラメータ Adjustable Parameters

実装 Implementation

HTML + CSS + JS

<button class="ripple-button">Click Me</button>

<style>
.ripple-button {
  position: relative;
  overflow: hidden;
}

.ripple-effect {
  position: absolute;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.6);
  transform: scale(0);
  animation: ripple 0.6s ease-out;
}

@keyframes ripple {
  to {
    transform: scale(4);
    opacity: 0;
  }
}
</style>

<script>
const button = document.querySelector(".ripple-button");

button.addEventListener("click", (e) => {
  const rect = button.getBoundingClientRect();
  const x = e.clientX - rect.left;
  const y = e.clientY - rect.top;
  const ripple = document.createElement("span");
  ripple.className = "ripple-effect";
  ripple.style.left = `${x}px`;
  ripple.style.top = `${y}px`;
  button.appendChild(ripple);
  setTimeout(() => ripple.remove(), 600);
});
</script>

React (JSX + CSS)

// react/I-002.jsx
import { useState } from "react";
import "./I-002.css";

export default function ButtonRippleEffect({ children }) {
  const [ripples, setRipples] = useState([]);

  const handleClick = (e) => {
    const rect = e.currentTarget.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;
    const newRipple = { x, y, id: Date.now() };
    setRipples([...ripples, newRipple]);
    setTimeout(() => {
      setRipples((prev) => prev.filter((r) => r.id !== newRipple.id));
    }, 600);
  };

  return (
    <button className="ripple-button" onClick={handleClick}>
      {children}
      {ripples.map((ripple) => (
        <span
          key={ripple.id}
          className="ripple-effect"
          style={{ left: `${ripple.x}px`, top: `${ripple.y}px` }}
        />
      ))}
    </button>
  );
}
/* react/I-002.css */
.ripple-button {
  position: relative;
  overflow: hidden;
  padding: 12px 24px;
  background: linear-gradient(135deg, #5c6ac4, #22d3ee);
  color: #fff;
  border: none;
  border-radius: 8px;
  cursor: pointer;
}

.ripple-effect {
  position: absolute;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.6);
  width: 20px;
  height: 20px;
  transform: scale(0);
  animation: ripple 0.6s ease-out;
}

@keyframes ripple {
  to {
    transform: scale(4);
    opacity: 0;
  }
}

AIへの指示テンプレート AI Prompt Template

以下のテンプレートをコピーしてAIアシスタントに貼り付けると、このパターンの実装を依頼できます。 Copy the template below and paste it into your AI assistant to request an implementation of this pattern.

注意とバリエーション Notes & Variations

タッチデバイスでは `touchstart` イベントも処理してください。リップル要素のサイズはボタンの最大辺に合わせて動的に計算すると、どのサイズのボタンでも適切に動作します。

Handle `touchstart` events for touch devices. Calculate ripple size dynamically based on button's largest dimension for consistent behavior across button sizes.