ライブデモ Live Demo
ボタンをクリックすると、クリック位置から波紋が広がります。波紋のサイズと速度をカスタムプロパティで調整できます。
Click the button to see a ripple expand from the click position. Adjust ripple size and speed via custom properties.
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
- --ripple-duration — リップルアニメーションの継続時間 ripple animation duration
- --ripple-color — リップルの色 ripple color
- ripple size — 最終的な拡大サイズ(scale値) final expansion size (scale value)
- multiple ripples — 連続クリックで複数のリップルを表示 show multiple ripples on rapid clicks
実装 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.