javascript - Hur man fixar Framer Motions `motion.div` `x, y` egenskaper så att de inte längre är relativa till behållarens positioner?
Jag har en anpassad markör gjord med Framer Motion, som placeras så här i en Next.js-app:
// app/layout.tsx
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import CustomCursor from "@/components/custom-cursor";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body className={inter.className}>{children}<CustomCursor /></body>
</html>
);
}
Min CustomCursor-komponent ser ut så här (lite förenklad):
"use client"
const CustomCursor = ({ }: CustomCursorProps) => {
const device = useDeviceDetection(); // for checking device type
const mousePosition = useMousePosition(); // hook for getting mouse position
const variants: Variants = {
default: {
x: mousePosition.x - 16,
y: mousePosition.y - 16,
},
pointer: {
x: mousePosition.x - 75,
y: mousePosition.y - 75,
width: 150,
height: 150,
}
};
const mouseVariant = useCursorStyleStore((state) => state.cursorStyle); // a zustand store for storing what type of cursor to use
if (device !== "desktop") return <></>; // no cursor on mobiles or tablets
return <div>
<div className="bg-white h-2 w-2 rounded-[50%] fixed pointer-events-none mix-blend-difference z-50" style={{ top: mousePosition.y - 4, left: mousePosition.x - 4 }}></div>
<motion.div className="bg-white h-8 w-8 rounded-[50%] fixed pointer-events-none mix-blend-difference z-40" variants={variants} animate={Object.keys(variants).includes(mouseVariant) ? mouseVariant : "default"} />
</div>
}
export default CustomCursor;
I komponenten ovan har div som representerar en markör som följer den faktiska markören exakt inga problem eftersom den använder top och bottom, medan motion.div använder x och y som använder translate om jag har rätt, och därför gör att den positionerar sig relativt förälderns(?) position.
Jag har försökt ändra förälderns div-position till relativ och absolut, men ingen av dem fungerar. Att ändra x och y till left respektive top gör att positionen för motion.div fungerar, men orsakar att den inte animerar heller. Jag har också försökt redigera varianterna för att se om något skulle hända.
REDIGERA 3: Jag har försökt ändra mitt svar enligt detta svar, och även om det fungerar för att positionera motion.div orsakar det en överflödning i dokumentet när markören förs till höger och nedre kanterna.
//....
return <div>
<div className="bg-white h-2 w-2 rounded-[50%] fixed pointer-events-none mix-blend-difference z-50" style={{ top: mousePosition.y - 4, left: mousePosition.x - 4 }}></div>
<motion.div className="absolute pointer-events-none mix-blend-difference z-40 top-0 bottom-0 left-0 right-0 w-fit h-fit" variants={variants} animate={Object.keys(variants).includes(mouseVariant) ? mouseVariant : "default"} >
<div className="bg-white h-8 w-8 absolute rounded-[50%]" />
</motion.div>
</div>