React实现Logo随鼠标位置移动效果(复刻目标网站交互)
React实现Logo鼠标悬浮跟随交互(复刻目标效果)
核心思路
目标效果是Logo在鼠标悬浮时,跟随鼠标在限定范围内偏移,离开时平滑回归原位。关键要基于元素自身位置计算鼠标相对偏移,同时精准控制偏移范围与过渡动画的触发时机。
原代码问题分析
- 固定减去
55px未考虑元素自身位置/尺寸,不同布局场景下偏移会错位 - 使用百分比作为偏移单位,不符合像素级跟随的视觉逻辑
- 第一次移动的过渡控制逻辑冗余,可简化
优化后的完整实现
1. 组件代码实现
import { useState, useRef } from 'react'; const Logo = ({ icon }) => { // 存储Logo元素DOM引用,用于计算实时位置 const logoRef = useRef(null); // 控制Logo的偏移量 const [offset, setOffset] = useState({ x: 0, y: 0 }); // 标记是否处于悬浮状态,控制过渡动画 const [isHovered, setIsHovered] = useState(false); // 计算鼠标相对Logo中心的偏移 const handleMouseMove = (e) => { if (!logoRef.current) return; const rect = logoRef.current.getBoundingClientRect(); // 获取Logo元素的中心坐标 const centerX = rect.left + rect.width / 2; const centerY = rect.top + rect.height / 2; // 计算偏移并缩小比例,让移动更柔和 let x = (e.clientX - centerX) * 0.2; let y = (e.clientY - centerY) * 0.2; // 限制最大偏移范围,避免Logo移出可视区域 const maxOffset = 15; x = Math.max(Math.min(x, maxOffset), -maxOffset); y = Math.max(Math.min(y, maxOffset), -maxOffset); setOffset({ x, y }); }; // 鼠标进入时开启跟随模式 const handleMouseEnter = () => { setIsHovered(true); }; // 鼠标离开时重置偏移,触发回归动画 const handleMouseLeave = () => { setIsHovered(false); setOffset({ x: 0, y: 0 }); }; return ( <a ref={logoRef} draggable="false" href="/" className="h-[5.93vmin] w-[5.93vmin] inline-block" onMouseEnter={handleMouseEnter} onMouseMove={handleMouseMove} onMouseLeave={handleMouseLeave} style={{ transform: `translate(${offset.x}px, ${offset.y}px)`, // 悬浮跟随无过渡保证流畅性,离开时平滑回归 transition: isHovered ? 'none' : 'transform 0.2s ease-out' }} > <img draggable="false" src={icon} alt="Logo" className="w-full h-full" /> </a> ); }; export default Logo;
2. 关键改进点
- 用
useRef获取元素真实位置,基于Logo中心计算偏移,适配任意布局场景 - 加入偏移比例(0.2)让移动更自然,避免生硬的跟随效果
- 明确限制最大偏移值(15px),保证Logo始终在可控范围内
- 简化状态逻辑:用
isHovered直接控制过渡,移除冗余的isFirstTime状态 - 使用
px作为偏移单位,视觉效果更精准
效果说明
- 鼠标悬浮到Logo区域时,Logo会跟随鼠标在±15px范围内流畅移动
- 鼠标离开时,Logo通过过渡动画平滑回归原位
- 适配不同屏幕尺寸与元素布局,不会出现偏移错位问题
内容的提问来源于stack exchange,提问作者Patrick Jun
相关产品推荐
相关产品推荐

