react实现点击波纹效果
实现点击波纹效果的方法
在React中实现点击波纹效果可以通过CSS和JavaScript结合完成。以下是两种常见的方法:
使用CSS动画和React事件
创建一个自定义按钮组件,利用CSS动画实现波纹效果。
import React from 'react';
import './RippleButton.css';
const RippleButton = ({ children, onClick }) => {
const createRipple = (event) => {
const button = event.currentTarget;
const circle = document.createElement('span');
const diameter = Math.max(button.clientWidth, button.clientHeight);
const radius = diameter / 2;
circle.style.width = circle.style.height = `${diameter}px`;
circle.style.left = `${event.clientX - button.getBoundingClientRect().left - radius}px`;
circle.style.top = `${event.clientY - button.getBoundingClientRect().top - radius}px`;
circle.classList.add('ripple');
const ripple = button.getElementsByClassName('ripple')[0];
if (ripple) {
ripple.remove();
}
button.appendChild(circle);
if (onClick) onClick(event);
};
return (
<button className="ripple-button" onClick={createRipple}>
{children}
</button>
);
};
export default RippleButton;
对应的CSS文件:

.ripple-button {
position: relative;
overflow: hidden;
padding: 12px 24px;
border: none;
border-radius: 4px;
background-color: #6200ee;
color: white;
cursor: pointer;
outline: none;
}
.ripple {
position: absolute;
border-radius: 50%;
background-color: rgba(255, 255, 255, 0.7);
transform: scale(0);
animation: ripple 600ms linear;
pointer-events: none;
}
@keyframes ripple {
to {
transform: scale(4);
opacity: 0;
}
}
使用Material-UI的Ripple效果
如果项目中使用Material-UI,可以直接使用其提供的ButtonBase组件,它内置了波纹效果。
import React from 'react';
import Button from '@material-ui/core/Button';
const RippleButton = () => {
return (
<Button variant="contained" color="primary">
Click for Ripple
</Button>
);
};
export default RippleButton;
Material-UI的按钮默认已经实现了Material Design规范的波纹效果,无需额外配置。

自定义Hook实现
创建一个可复用的useRipple钩子,方便在任何元素上添加波纹效果。
import { useRef } from 'react';
const useRipple = () => {
const ref = useRef(null);
const applyRipple = (e) => {
const target = ref.current;
const rect = target.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
const diameter = Math.max(target.clientWidth, target.clientHeight);
const ripple = document.createElement('div');
ripple.style.width = ripple.style.height = `${diameter}px`;
ripple.style.left = `${x - diameter/2}px`;
ripple.style.top = `${y - diameter/2}px`;
ripple.classList.add('ripple-effect');
target.appendChild(ripple);
setTimeout(() => {
ripple.remove();
}, 600);
};
return [ref, applyRipple];
};
export default useRipple;
使用示例:
import React from 'react';
import useRipple from './useRipple';
import './RippleEffect.css';
const RippleComponent = () => {
const [rippleRef, applyRipple] = useRipple();
return (
<div
ref={rippleRef}
onClick={applyRipple}
className="ripple-container"
>
Click Me
</div>
);
};
export default RippleComponent;
对应的CSS:
.ripple-container {
position: relative;
overflow: hidden;
padding: 20px;
background-color: #2196f3;
color: white;
cursor: pointer;
}
.ripple-effect {
position: absolute;
border-radius: 50%;
background-color: rgba(255, 255, 255, 0.7);
animation: ripple-animation 0.6s linear;
pointer-events: none;
}
@keyframes ripple-animation {
from {
transform: scale(0);
opacity: 1;
}
to {
transform: scale(4);
opacity: 0;
}
}
以上方法提供了不同复杂度的实现方案,可以根据项目需求选择最适合的方式。纯CSS+React的方案适合轻量级实现,而Material-UI的方案适合遵循Material Design规范的项目,自定义Hook则提供了最大的灵活性。





