ReactJS实现鼠标进入侧触发的按钮填充效果
React+CSS实现方向触发的按钮填充动画
实现思路
通过React监听鼠标进入按钮时的位置,判断进入方向(左/右/上/下),给按钮添加对应方向类,再通过CSS伪元素的位移动画实现从进入侧填充的效果。
React组件代码
import { useState } from 'react'; import './DirectionalFillButton.css'; const DirectionalFillButton = ({ children, className = '' }) => { const [direction, setDirection] = useState(''); const handleMouseEnter = (e) => { const button = e.currentTarget; const rect = button.getBoundingClientRect(); const centerX = rect.left + rect.width / 2; const centerY = rect.top + rect.height / 2; const deltaX = e.clientX - centerX; const deltaY = e.clientY - centerY; // 判断进入方向:优先判断左右(x轴绝对值更大),否则判断上下 if (Math.abs(deltaX) > Math.abs(deltaY)) { setDirection(deltaX > 0 ? 'right' : 'left'); } else { setDirection(deltaY > 0 ? 'bottom' : 'top'); } }; const handleMouseLeave = () => { setDirection(''); }; return ( <button className={`directional-fill-button ${className} ${direction}`} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave} > <span className="button-content">{children}</span> </button> ); }; export default DirectionalFillButton;
对应的CSS样式(DirectionalFillButton.css)
.directional-fill-button { position: relative; padding: 12px 28px; border: 2px solid #2d2d2d; background: transparent; color: #2d2d2d; font-size: 16px; font-weight: 500; cursor: pointer; overflow: hidden; transition: color 0.3s ease; } /* 保证按钮文字在填充层上方 */ .button-content { position: relative; z-index: 1; } /* 填充背景层 */ .directional-fill-button::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: #2d2d2d; transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1); z-index: 0; } /* 左进入:初始在左侧外,hover时移入 */ .directional-fill-button.left::before { transform: translateX(-100%); } .directional-fill-button.left:hover::before { transform: translateX(0); } /* 右进入:初始在右侧外,hover时移入 */ .directional-fill-button.right::before { transform: translateX(100%); } .directional-fill-button.right:hover::before { transform: translateX(0); } /* 上进入:初始在顶部外,hover时移入 */ .directional-fill-button.top::before { transform: translateY(-100%); } .directional-fill-button.top:hover::before { transform: translateY(0); } /* 下进入:初始在底部外,hover时移入 */ .directional-fill-button.bottom::before { transform: translateY(100%); } .directional-fill-button.bottom:hover::before { transform: translateY(0); } /* hover时切换文字颜色 */ .directional-fill-button:hover { color: #fff; }
使用示例
import DirectionalFillButton from './DirectionalFillButton'; function App() { return ( <div style={{ padding: '40px', display: 'flex', gap: '20px' }}> <DirectionalFillButton>Estimate Project</DirectionalFillButton> <DirectionalFillButton style={{ borderColor: '#0071e3', color: '#0071e3' }}> Custom Style Button </DirectionalFillButton> </div> ); }
关键说明
- 方向判断逻辑:通过计算鼠标位置与按钮中心的相对坐标,判断进入方向,保证填充动画从鼠标进入的一侧启动。
- 动画控制:利用CSS
transform的位移实现填充效果,比width/height动画性能更优,避免重排。 - 可定制性:通过className和内联样式可以轻松修改按钮的边框色、文字色、尺寸等样式。
内容的提问来源于stack exchange,提问作者fr0standsn0w
相关产品推荐
相关产品推荐

