Reputation: 150
Trying to make a different animation when on mobile or on desktop, to do so I'm using a useMediaQueryHoook and changing the variant in function of it. But the init animation seems to always assume that I'm on desktop. I guess because the useMediaQueryHook doesn't have time to actualise before the anim is launch. How can I deal with that issue ?
Btw I'm on nextjs :)
Here is my code :
const onMobile = useMediaQuery("(min-width : 428px)");
const wishCardVariant = {
hidden: (onMobile) => ({
opacity: 0,
y: onMobile ? "100%" : 0,
x: onMobile ? 0 : "100%",
transition,
}),
visible: (onMobile) => ({
opacity: 1,
x: 0,
y: 0,
}),
};
here is the hook :
import react, { useState, useEffect } from "react";
export default function useMediaQuery(query) {
const [matches, setMatches] = useState(false);
useEffect(() => {
const media = window.matchMedia(query);
if (media.matches !== matches) {
setMatches(media.matches);
}
const listener = () => {
setMatches(media.matches);
};
media.addListener(listener);
return () => media.removeListener(listener);
}, [matches, query]);
return matches;
}
Upvotes: 4
Views: 1713
Reputation: 1394
First check device isMobile.
Then apply style with conditional operator isMobile ? {} : {}
const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
return (
...
<motion.h2
className="absolute top-1/2 left-1/2 text-white text-2xl font-bold whitespace-nowrap p-2"
initial={isMobile ? false : {
background: "transparent"
}}
style={isMobile ? {
background: "rgba(0, 0, 0, 0.5)",
} : {
transformOrigin: "center center",
x: "-50%",
y: "-50%"
}}
variants={{
hover: {
scale: 1.2,
background: "rgba(0, 0, 0, 0.5)",
transition: { duration: 0.3 }
}
}}
>
{image.title}
</motion.h2>
)
Upvotes: 0
Reputation: 31
You could try using useLayoutEffect. I had a similar issue, where I wanted to apply a different style based on device type, and this worked for me
export default function useMediaQuery(query: string) {
const [matches, setMatches] = useState(false)
useLayoutEffect(() => {
const media = window.matchMedia(query)
if (media.matches !== matches) {
setMatches(media.matches)
}
const listener = () => {
setMatches(media.matches)
}
media.addEventListener('change', listener)
return () => media.removeEventListener('change', listener)
}, [matches, query])
return matches
}
Upvotes: 0