Animation made using framer motion looks too lagged in reactjs - reactjs

Here is the website link and as you can see, the intro animations look too laggy. Here is the code:
<motion.div className='pic' initial={{x:window.innerWidth < 996?'0%':'100%'}} animate={{x:'0%'}} transition={{delay:'1.6', type:'spring'}}><img src={blob} alt='hero section image'></img></motion.div>
Even the animations after the hero section don't look nice. I have used the react-intersection-observer to activate the animation on scrolling in this particular code.
<motion.div className='detailed' ref={refdetail} initial={{x:'100%', opacity:'0%'}} animate={{x: inViewdetail? '0%': '100%', opacity:inViewdetail? '100%': '0%'}} transition={{ delay:'1.5'}}>

Recently I have worked with framer.motion and it worked well out in my side.
I think that problem is related to the delay sub-prop you used in transition prop.
Here is my tested codebase with motion.framer which works fine in my side.
<motion.div
key={"setuplayout_motion"}
exit={{ opacity: 0 }}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
>
<SetupLayout setCurrentStep={setCurrentStep} />
</motion.div>
<motion.div
animate={{
x: authType === "sign-in" ? "10px" : "70px",
}}
transition={{
x: { type: "spring", stiffness: 100 },
duration: 0.8,
delay: 0.2,
}}
/>

Related

Transition and Initial are not working - Framer motion

If I manually set scale and opacity in my css, the animation is working.
It's why I think that my initial value don't work, and it's really weird because in another file i'm not facing this issue with the same code.
<motion.a
href="#"
className="file"
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
transition={{ delay: 3, duration: 3 }}
variants={{
visible: { opacity: 1, scale: 1 },
hidden: { opacity: 0, scale: 0 },
}}
>
© Sb_2K22<span className="end">.txt</span>
</motion.a>
Also the delay and duration are not working too...
Tell me if you need more information please

React / Framer Motion - why are my child elements not staggered?

I'm building a balance overview within a financial services application. The content is rendered by passing props into a single <BalanceEntry> component and then mapping all available entries into the page.
Using Framer Motion, I want to stagger the entry animation of each rendered <BalanceEntry> as a child by 0.2 seconds.
<div className="pt-16">
<motion.div
initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, x: 1 }}
transition={{
delay: 0.3,
default: { ease: 'easeInOut' },
staggerChildren: 0.2,
}}
>
{TransactionData.map((item) => {
return (
<div key={item.id}>
<motion.div variants={BalanceEntryVariants}>
<BalanceEntry
transactionDate={item.transactionDate}
transactionType={item.transactionType}
transactionID={item.transactionID}
transactionAmount={item.transactionAmount}
transactionIcon={item.transactionIcon}
/>
</motion.div>
</div>
);
})}
</motion.div>
</div>
);
I have created two motion.divs based on multiple suggestions here on SO to achieve the staggering, but I still fail to have each BalanceEntry component animated with staggering, instead they are always animated as a group:
The variants are setup like this:
const BalanceEntryVariants = {
hidden: {
opacity: 0,
y: -20,
},
visible: {
opacity: 1,
x: 1,
transition: {
ease: 'easeInOut',
},
},
};
Where is my mistake to render each individual BalanceEntry staggered happening?
It seems that this can be solved by defining a variant for the parent motion.div as well, perhaps try something like:
const parent = {
visible: {
opacity: 1,
y: -20,
transition: {
when: 'beforeChildren',
staggerChildren: 0.2,
delay: 0.3,
},
},
hidden: {
opacity: 0,
x: 1,
transition: {
when: 'afterChildren',
},
},
};
Add the variant to parent motion.div:
<motion.div initial="hidden" animate="visible" variants={parent}>
...
</motion.div>
Here is a minimized example running on: stackblitz
There might be other issues as well (not sure about the purpose of y: -20 and x: 1), but hopefully this would still help.

100vh element spilling over address bar Chrome / Safari

I have a React / Tailwind component with a full screen element. On desktop it works as intended however on mobile the address bars of either chrome of safari cause part of the element to be shown underneath it. Giving the impression that the element isn't correctly centered.
I have researched this issue for a while now and have found no solid answer on how to fix it in React.
I have tried various combinations of height: --webkit-fill-available height: 100vh height: 100% ,with min-height also, on HTML, Root, Body in my main CSS file. Additionally I have tried several different JS functions that calculate the inner height of the document (the height of the document with the address bar excluded.) As well as not using height: 100vh on my targeted element and instead using a combination of height: 100% and fixed positioning. None of these methods have worked in any way at all.
Im hoping for a more React oriented fix to this issue instead of a plain HTML method.
Please note: motion. to anyone unfamiliar is part of Framer Motion and has no effect on the targeted element outside of using Framer properties.
Heres the component:
import * as React from 'react';
import { useEffect } from 'react';
import { motion } from 'framer-motion';
export default function LoadingScreen() {
useEffect(() => {
window.scrollTo(0, 0)
}, [])
return(
<motion.div
className="fixed z-50 w-full bg-tertiary"
initial= {{ opacity: 1 }}
animate={{ opacity: 0 }}
transition={{ duration: 0.3, delay: 2.5, ease: 'easeInOut' }}
>
{/* Image container */}
<motion.div
className="flex justify-center items-center"
initial= {{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 1, ease: 'easeInOut' }}
>
<motion.img
src="../Images/icon.png"
className="h-[80px] absolute left-0 right-0 top-[50%] -translate-y-[50%] px-5 mx-auto"
initial= {{ opacity: 1 }}
animate={{ opacity: 0 }}
transition={{ duration: 1, delay: 1, ease: 'easeInOut' }}
></motion.img>
<motion.img
src="../Images/icon-primary.png"
className="h-[80px] absolute left-0 right-0 top-[50%] -translate-y-[50%] px-5 mx-auto"
initial= {{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 1, delay: 1.5, ease: 'easeInOut' }}
></motion.img>
</motion.div>
</motion.div>
)
};
Not sure what kind of the result you're looking for?
If you want to make it center both horizontally and vertically, you need to add the device height in the outer layer so it has the space to center.
<motion.div
className="bg-tertiary fixed z-50 h-screen w-full"
initial={{ opacity: 1 }}
animate={{ opacity: 0 }}
transition={{ duration: 0.3, delay: 2.5, ease: "easeInOut" }}
>
{/* Image container */}
<motion.div
className="flex items-center justify-center"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 1, ease: "easeInOut" }}
>
<motion.img
src="../Images/icon.png"
className="absolute left-0 right-0 top-[50%] mx-auto h-[80px] -translate-y-[50%] px-5"
initial={{ opacity: 1 }}
animate={{ opacity: 0 }}
transition={{ duration: 1, delay: 1, ease: "easeInOut" }}
></motion.img>
<motion.img
src="../Images/icon.png"
className="absolute left-0 right-0 top-[50%] mx-auto h-[80px] -translate-y-[50%] px-5"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 1, delay: 1.5, ease: "easeInOut" }}
></motion.img>
</motion.div>
</motion.div>

Framer-Motion AnimatePresence Choppy Animation

I want to use framer-motion to create a transition where element 2 slides in from the bottom as element 1 slides out to the top when I click next.
I'm using AnimatePresence component to achieve this, but the result is a strangely choppy transition where Element 2 appears in the final position briefly before it starts animating from the bottom.
Code:
<AnimatePresence exitBeforeEnter>
{
active === 0 ? (
<motion.div
key='id_1'
initial={{ opacity: 0 }}
animate={{ opacity: 1, backgroundColor: 'green' }}
exit={{ y: '-100%' }}
transition={{ duration: 2 }}>
Element 1
</motion.div>
)
: (
<motion.div
key='id_2'
initial={{ y: '100%' }}
animate={{ y: 0 }}
transition={{ duration: 2 }}
style={{
backgroundColor: 'purple'
}}>
Element 2
</motion.div>
)
}
</AnimatePresence>
Why does the second element appear briefly at first completely ignoring the initial state?

Animation duration in React Spring

I have a fairly simple fade-in scenario, where I want to control the duration of the animation. But cannot wrap around my head around how to accomplish this.
Code excerpt:
function BoxA() {
return (
<Spring from={{ opacity: 0.2 }} to={{ opacity: 1 }}>
{props => (
<div
style={{
height: 100,
width: 100,
backgroundColor: "pink",
color: "#fff",
...props
}}
>
1
</div>
)}
</Spring>
);
}
Complete code example: https://codesandbox.io/s/n7pw660264
You have to set the config property for the duration.
<Spring config={{duration: 5000}} from={{ opacity: 0.2 }} to={{ opacity: 1 }}>
You can use delay property to control the animation,
According to documentation
Delay in ms before the animation starts (config.delay takes precedence
if present) */
like this
<Spring from={{ opacity: 0.2 }} delay={1000} to={{ opacity: 1 }}></Spring>
Demo
Source

Resources