Ripple Effect 02
Ripple Effect 02 é um componente de efeito para React e Tailwind CSS, da biblioteca Bund UI, com licença MIT. Copia e cola no teu projeto.
Bund UI
MIT
effects
O que é
Ripple Effect 02 é um componente de efeito para React e Tailwind CSS, da biblioteca Bund UI, com licença MIT. Copia e cola no teu projeto.
Como usar
Abre o componente no catálogo, carrega em copiar, e cola no teu projeto. O prompt copiado leva o código e as regras para o teu agente o reproduzir sem alterar nada.
Cinco cópias grátis por mês. Sem cartão.
Precisa de
npm i motion
Licença
Este componente vem de Bund UI e é redistribuído sob a licença MIT, que permite uso comercial. O aviso de copyright viaja com o código.
Ripple Effect 02
import { RippleEffect } from "./ripple-effect";
import { Button } from "@/components/ui/button";
export default function RippleEffectButton() {
return (
<RippleEffect>
<img
className="aspect-square max-w-80 object-cover"
src="/images/products/list10.png"
alt="..."
/>
</RippleEffect>
);
}
"use client";
import React from "react";
import { motion, AnimatePresence } from "motion/react";
interface RippleProps {
children: React.ReactNode;
color?: string;
duration?: number;
className?: string;
}
interface RipplePosition {
x: number;
y: number;
size: number;
id: number;
}
export const RippleEffect = ({
children,
color = "rgba(255, 255, 255, 0.7)",
duration = 0.8,
className
}: RippleProps) => {
const [ripples, setRipples] = React.useState<RipplePosition[]>([]);
const containerRef = React.useRef<HTMLDivElement>(null);
const handleClick = (e: React.MouseEvent<HTMLDivElement>) => {
if (!containerRef.current) return;
const rect = containerRef.current.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
const size = Math.max(rect.width, rect.height);
const newRipple: RipplePosition = {
x,
y,
size: size * 2,
id: Date.now()
};
setRipples((prevRipples) => [...prevRipples, newRipple]);
setTimeout(() => {
setRipples((prevRipples) => prevRipples.filter((ripple) => ripple.id !== newRipple.id));
}, duration * 1000);
};
return (
<div
ref={containerRef}
className={`relative inline-flex overflow-hidden rounded-lg ${className}`}
onMouseDown={handleClick}>
{children}
<AnimatePresence>
{ripples.map((ripple) => (
<motion.div
key={ripple.id}
initial={{
width: 0,
height: 0,
x: ripple.x,
y: ripple.y,
opacity: 0.5,
borderRadius: "100%"
}}
animate={{
width: ripple.size,
height: ripple.size,
x: ripple.x - ripple.size / 2,
y: ripple.y - ripple.size / 2,
opacity: 0,
borderRadius: "100%"
}}
exit={{ opacity: 0 }}
transition={{ duration, ease: "easeOut" }}
style={{
position: "absolute",
backgroundColor: color,
pointerEvents: "none"
}}
/>
))}
</AnimatePresence>
</div>
);
};