所以我试图重新创建您在悬停时通过成帧器运动看到的那些很酷的自定义光标。所以基本上我有一个 div,每当您将鼠标悬停在 div 上时,光标应该消失,而是应该出现一个中等大小的圆圈并跟随鼠标。我让它有点工作,但圆圈的运动非常不稳定,它似乎正试图返回角落。
这是组件:
"use client";
import { useState } from "react";
import { motion } from "framer-motion";
type Position = {
x: number;
y: number;
};
function BigBlockImage() {
const [isHovering, setIsHovering] = useState(false);
const [position, setPosition] = useState<Position>({ x: 0, y: 0 });
return (
<div
className="w-full aspect-video bg-placeholder relative cursor-none"
onMouseEnter={(e) => {
setIsHovering(true);
}}
onMouseLeave={(e) => {
setIsHovering(false);
}}
onMouseMove={(e) => {
const rect = e.target.getBoundingClientRect();
const x = e.clientX - rect.left - 57;
const y = e.clientY - rect.top - 57;
console.log(x, y);
setPosition({
x,
y,
});
}}
>
{isHovering && (
<motion.div
animate={{ x: position.x, y: position.y }}
transition={{ type: "tween", ease: "backOut" }}
className="absolute w-[114px] aspect-square bg-accent rounded-full flex justify-center items-center uppercase text-primary pt-1"
>
VIEW
</motion.div>
)}
</div>
);
}
export default BigBlockImage;
我不确定这是否是在如此短的时间内多次设置状态的问题,或者我是否以错误的方式进行操作。任何帮助表示赞赏。谢谢你
使用
e.currentTarget
代替 e.target
。
<div
onMouseMove={(e) => {
const rect = e.currentTarget.getBoundingClientRect();
...
}}
>
...
</div>
发生的事情是事件冒泡的结果。当您将鼠标移到 BigBlockImage 上时,自定义光标 div 会移动到光标的位置。这使得您的光标现在位于自定义光标 div 上。当您再次移动鼠标时,
onMouseMove
事件处理程序将从自定义光标 div 冒泡到主包装 div,并以自定义光标 div 作为 onMouseMove
触发 target
。然后,这会导致 rect
成为自定义光标 div 的测量值,而不是您想要的主 div。
currentTarget
属性“标识已附加事件处理程序的元素”,而target
是“对向其分派事件的对象的引用。”
我创建了这个工作示例,其中包含修复程序以及问题所在的示例。