I am trying to create a stagger animation where three dots appear with a delay of 0.2s
This is the code I wrote for the first dot, it is supposed to go from opacity:0 to opacity: 1 (as the default opacity of the circle is 1) but the opacity remains 0 and never changed to 1
gsap.from(circle, {
duration: 0.2,
opacity: 0,
x: 20,
ease: "Power4.easeInOut",
});
I think it will fix
import { useLayoutEffect } from "react";
import "./App.css";
import gsap from "gsap";
function App() {
useLayoutEffect(() => {
let from = gsap.from(".circle", {
duration: 1.5,
opacity: 0,
stagger: 0.2,
immediateRender: false,
});
return () => {
from.kill();
};
});
return (
<div className="App">
<div className="_con">
<div className="circle"></div>
<div className="circle"></div>
<div className="circle"></div>
</div>
</div>
);
}
export default App;
Related
I am trying to use whileInView in order to animate some elements on scroll in react.
here is the codesandbox link: https://bz6msx.csb.app/
if you go and check the code then you see that while using whileInView it does not trigger the animation.
is there anything am I missing?
Thanks
I think you received an answer to this, here.
That is not bug. whileInView property is associated with Intersection
Observer API. In your CodeSandBox , h1 tag has initial state with x:
100vh. h1 tag not visible in viewport. only visible element activate
whileInView animation.
There are some tricks.
set 100vw to 95vw. Then element is visible.
<div className="App">
<motion.h1
initial={{
x: "95vw" // set 100vw to 95vw
}}
// This is not working
whileInView={{
x: 0,
transition: {
duration: 1,
type: "spring",
stiffness: 50
}
}}
>
Motion
</motion.h1>
</div>
Set WhileInView Property parent tag.
import "./styles.css";
import { motion } from "framer-motion";
import { useState } from "react";
export default function App() {
const [isInView, setIsInView] = useState(false);
return (
<motion.div
whileInView={() => {
// when element in viewport , set IsInView true!
setIsInView(true);
return {};
}}
className="App"
>
<motion.h1
initial={{
x: "100vw"
}}
// This is working
animate={
isInView && {
x: 0,
transition: {
duration: 1,
type: "spring",
stiffness: 50
}
}}
>
Motion
</motion.h1>
</motion.div>
);
}
I made a toggle function that calls from the button and i dont understand why the Jobs component who receives the styles appears suddenly without without transitioning.
I want that the opacity.
I want the opacity to increase until the component displays slowly.
import React, { Component } from 'react';
import { withTranslation } from 'react-i18next';
import './Experience.css';
class Experience extends Component {
constructor() {
super()
this.state = { display: 'none', opacity: 0 }
this.toggle = this.toggle.bind(this)
}
toggle() {
console.log("ENTRO EN TOOGLE")
if (this.state.display === 'none') {
this.setState({ display: 'block' })
setTimeout(() =>
this.setState({ opacity: 1 }), 300
)
}
else {
this.setState({ opacity: 0 })
setTimeout(() =>
this.setState({ display: 'none' }), 900
)
}
}
styles = (e) => {
console.log(e)
}
render() {
const styles = this.state;
const { t } = this.props;
return (
<div>
<div className="card">
<div className="card-content">
<div className="row mt-top">
<div className="col xl4 l4 m6 s12">
<button onClick={this.toggle}>DESPLEGAR</button>
</div>
<Jobs style={styles}></Jobs>
</div>
</div>
</div>
</div>
);
}
}
export default withTranslation()(Experience);
what you're attempting is like wanting to call a function without calling it when you want an element to transition you need to call the transition CSS property
something like this.
.name {
opacity: 0;
transition: opacity 0.5s ease;
}
.name:hover {
opacity: 1;
}
I am using React-spring for first time. I am trying to use transition hook on a side drawer on my page by toggling a button.
But when I am clicking on that button there is no animation as that side drawer opens instantly, but if I click second time then side drawer is closing with animation.
And also if I click that button before that drawer removed from DOM then slide from left animation is there. I can't figure it out where is the problem. Help me please. Thanks.
Here is my code:
import React, { useState } from "react";
import { useTransition, animated, config } from "react-spring";
const Transform = (props) => {
const myStyle = {
position: "fixed",
left: 0,
top: 0,
zIndex: 100,
backgroundColor: "black",
};
const [drawerIsOpen, setDrawerState] = useState(false);
const closeDrawerHandler = () => {
setDrawerState((v) => !v);
};
const transition = useTransition(drawerIsOpen, {
form: { transform: "translateX(-100%)", opacity: 0 },
enter: { transform: "translateX(0%)", opacity: 1 },
leave: { transform: "translateX(-100%)", opacity: 0 },
config: { duration: 2000 },
// config: config.molasses,
// openDrawerHandler: () => setDrawerState(true),
});
return (
<>
{transition((style, item) =>
item ? (
<animated.aside
className='bg-white h-100 w-70 shadow'
style={{ ...style, ...myStyle }}
onClick={closeDrawerHandler}
>
<nav className='h-100'>
<h2>It's a Side Drawer</h2>
</nav>
</animated.aside>
) : (
""
)
)}
<div className='d-flex justify-content-end'>
<button className='btn btn-primary ' onClick={closeDrawerHandler}>
Toggle Btn
</button>
</div>
</>
);
};
export default Transform;
Image of transition problem
I made spelling mistake. Silly one, I spelt from as form . That's why it was happening.
I have been trying to animate route transitions using framer-motion but can't wrap my head around the exit animations. Entry animations work as they should.
I want the component to slide in from the left and slide to the right when route changes.
I havewrapped the Switch component using AnimatedPresence from framer-motion and used a location object and taken its pathname as its key.
Wrapped all of this using BrowserRouter
Ensured I have used motion component from framer-motion at the root element of each of my functional components
Codesandbox
App.js
function App() {
const location = useLocation();
return (
<div className="App">
<AnimateTrans loc={location} />
</div>
);
}
AnimateTrans.jsx
export default function (props) {
return (
<AnimatePresence exitBeforeEnter>
<Switch location={props.loc} key={props.loc.pathname}>
<Route exact path="/">
<First />
</Route>
<Route exact path="/sec">
<Second />
</Route>
</Switch>
</AnimatePresence>
);
}
First.jsx
const transition = {
duration: 1,
type: "spring"
};
const transVariants = {
init: { scale: 0.3, opacity: 1, x: -400, transition: { transition } },
anim: { scale: 1, opacity: 1, x: 0, transition: { transition } },
exit: { scale: 0.4, opacity: 0, x: 400, transition: { transition } }
};
return (
<motion.div
variants={transVariants}
initial="init"
animate="anim"
exit="exit"
className="container"
>
<div className="content">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ1a79XgKvvi2VyAu54LI21MbKrfSlZTL9iPA&usqp=CAU" />
</div>
<div className="oth"></div>
d
</motion.div>
);
Second.jsx
const transition = {
duration: 1,
type: "spring"
};
const transVariants = {
initial: { scale: 0.3, opacity: 1, x: -400, transition: { transition } },
animate: { scale: 1, opacity: 1, x: 0, transition: { transition } },
exit1: { scale: 0.4, opacity: 0, x: 400, transition: { transition } }
};
return (
<motion.div
variants={transVariants}
initial="initial"
animate="animate"
exit="exit1"
className="container"
>
<div className="content">
<img src="https://fashioneditorials.com/wp-content/uploads/2017/10/i-D-Japan-Chanel-Haute-Couture-With-Nana-Komatsu-Angelo-Pennetta-1.jpg" />
</div>
<div className="oth"></div>
d
</motion.div>
);
}
Is my location object at fault here? Should I change the key or structure App.js differently?
You are using the <a> tag to route, you need to use Link from react-router-dom. Then It's gonna work.
I am making a hamburger menu animation in React using Framer Motion. When I click on the hamburger menu, the side drawer and the navigation items slide in from the left.
When I click on the close menu icon, then the whole side drawer slides out to the left(which means the exit prop on SideDrawer component is working).
What do I want?
When I click on the close icon, I want the navigation items to slide out first and then the side drawer. I have tried adding exit prop to children navigation items. But it does not work.
How can I achieve the desired effect?
Code snippets are as below:
src/App.js
import React, { useState } from "react";
import "./App.css";
import Menu from "./components/Menu";
import SideDrawer from "./components/SideDrawer";
import Overlay from "./components/Overlay";
const App = () => {
const [menuOpen, setMenuOpen] = useState(false);
const handleMenuClick = () => {
setMenuOpen(!menuOpen);
};
return (
<div className="App">
<Menu menuOpen={menuOpen} onMenuClick={handleMenuClick} />
<SideDrawer menuOpen={menuOpen} />
<Overlay menuOpen={menuOpen} />
</div>
);
};
export default App;
src/components/Menu.js
import React, { useState } from "react";
import { motion } from "framer-motion";
const lineOneVariants = {
initial: { rotate: "0deg" },
animate: { y: ".8rem", rotate: "45deg", transformOrigin: "center center" },
};
const lineTwoVariants = {
initial: { opacity: 1 },
animate: { opacity: 0 },
};
const lineThreeVariants = {
initial: { rotate: "0deg" },
animate: { y: "-.8rem", rotate: "-45deg", transformOrigin: "center center" },
};
const Menu = ({ onMenuClick, menuOpen }) => {
return (
<div className="hamburger_menu">
<div className="hamburger_menu-line-container" onClick={onMenuClick}>
<motion.div
variants={lineOneVariants}
initial="initial"
animate={menuOpen ? "animate" : "initial"}
className="hamburger_menu-line-1"
></motion.div>
<motion.div
variants={lineTwoVariants}
initial="initial"
animate={menuOpen ? "animate" : "initial"}
className="hamburger_menu-line-2"
></motion.div>
<motion.div
variants={lineThreeVariants}
initial="initial"
animate={menuOpen ? "animate" : "initial"}
className="hamburger_menu-line-3"
></motion.div>
</div>
</div>
);
};
export default Menu;
src/components/Overlay.js
import React from "react";
import { motion } from "framer-motion";
const overlayVariants = {
initial: { opacity: 0 },
animate: { opacity: 1 },
};
const Overlay = ({ menuOpen }) => {
return (
<motion.div
variants={overlayVariants}
initial="initial"
animate={menuOpen ? "animate" : "initial"}
className="overlay"
></motion.div>
);
};
export default Overlay;
src/components/SideDrawer.js
import React from "react";
import { motion, AnimatePresence } from "framer-motion";
const drawerVariants = {
initial: {
x: "-100vw",
opacity: 0,
},
animate: {
x: 0,
opacity: 1,
transition: {
type: "linear",
ease: "easeInOut",
staggerChildren: 0.1,
delayChildren: 0.15,
},
},
};
const drawerMenuVariants = {
initial: { x: "-5rem", opacity: 0 },
animate: {
x: 0,
opacity: 1,
transition: {
type: "linear",
ease: "easeInOut",
},
},
};
const SideDrawer = ({ menuOpen }) => {
return (
<AnimatePresence>
{menuOpen && (
<motion.div
variants={drawerVariants}
initial="initial"
animate="animate"
exit="initial"
className="sideDrawer"
>
<nav className="sideDrawer-menu">
<ul>
<motion.li
variants={drawerMenuVariants}
whileHover={{ scale: 1.05 }}
>
Register/Login
</motion.li>
<motion.li
variants={drawerMenuVariants}
whileHover={{ scale: 1.05 }}
>
About
</motion.li>
<motion.li
variants={drawerMenuVariants}
whileHover={{ scale: 1.05 }}
>
Projects
</motion.li>
<motion.li
variants={drawerMenuVariants}
whileHover={{ scale: 1.05 }}
>
CV
</motion.li>
</ul>
</nav>
</motion.div>
)}
</AnimatePresence>
);
};
export default SideDrawer;
You need to tell the side drawer to wait until the exit animation for the children finishes before starting its own exit animation.
You can do this by using the when property of the transition. See Orchestration in the docs.
In your case, you'd add it to the initial variant of your drawerVariants, since that's the variant you animate to on exit:
initial: {
x: "-100vw",
opacity: 0,
transition: {
when: "afterChildren"
}
},
You probably also want to add some staggering and easing there if you want to mirror the animate in behavior, but I'll leave that up to you.