You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>
  );
}

关键说明

  1. 方向判断逻辑:通过计算鼠标位置与按钮中心的相对坐标,判断进入方向,保证填充动画从鼠标进入的一侧启动。
  2. 动画控制:利用CSS transform的位移实现填充效果,比width/height动画性能更优,避免重排。
  3. 可定制性:通过className和内联样式可以轻松修改按钮的边框色、文字色、尺寸等样式。

内容的提问来源于stack exchange,提问作者fr0standsn0w

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 09:53:25