I have a slider in my react app that slides my card components when any of the icon buttons are clicked. When clicked I want each card to show the fade animation but it only works when the page reloads. I am using css animation. I am using the following code
<div className={classes.root}>
<div className={classes.slider}>
<Card image={carddata[slider].image} slider />
</div>
<ArrowBackIosIcon
fontSize="large"
style={{ left: 0 }}
className={classes.arrow}
onClick={prevSlide}
/>
<ArrowForwardIosIcon
fontSize="large"
style={{ right: 0 }}
className={classes.arrow}
onClick={nextSlide}
/>
</div>
The CSS class is following
slider: {
animation: 'fadeeffect 3000ms linear 250ms',
},
#keyframes fadeeffect: {
"0%": {
opacity: 0,
},
"25%": {
opacity: 0.25,
},
"50%": {
opacity: 0.5,
},
"100%": {
opacity: 1,
},
},
You must add slider class when you want to show the image, but you are adding it on the load e.g on click. I have provided a sandbox example to show you how to do it:
import { useRef } from "react";
const myRef = useRef(null);
const handleClick = ()=>{
myRef.current.classList.add('slider');
}
<div className={classes.root}>
<button onClick={handleClick}>Show The Element</button>
<div /*className={classes.slider}*/ ref={myRef} >
<Card image={carddata[slider].image} slider />
</div>
<ArrowBackIosIcon
fontSize="large"
style={{ left: 0 }}
className={classes.arrow}
onClick={prevSlide}
/>
<ArrowForwardIosIcon
fontSize="large"
style={{ right: 0 }}
className={classes.arrow}
onClick={nextSlide}
/>
</div>
Related
I have a container which can possible display several child containers based on state. When the state changes (based on a button click), I would like:
The current container to fade out
The height of the main container to animate to the be the height of its new child container
The new child container to fade in
I feel like I'm on the right track with my demo, but the AnimatePresence seems to be ignored as none of the opacity animations are working. I'm hoping someone can please take a look and let me know what I need to adjust?
https://codesandbox.io/s/animating-shared-layouts-with-content-changing-h8hvq?file=/src/App.js
function Home() {
return (
<div>
<div className="row" />
<div className="row" />
</div>
);
}
function Contact() {
return (
<div>
<div className="row" />
<div className="row" />
<div className="row" />
<div className="row" />
<div className="row" />
</div>
);
}
const sections = {
home: "Home",
contact: "Contact"
};
export default function App() {
const [activeSection, setActiveSection] = useState(sections.home);
return (
<div className="outer-container">
<AnimateSharedLayout>
<motion.div layout initial={{ borderRadius: 25 }}>
<h3>Text on top</h3>
<AnimatePresence key={activeSection} exitBeforeEnter initial={false}>
<motion.div
initial={{ opacity: 0 }}
animate={{
opacity: 1,
transition: { delay: 1.2, duration: 1 }
}}
exit={{
opacity: 0,
transition: { delay: 0, duration: 1 }
}}
>
<div className="inner-container">
<div className="content">
<div className="avatar" />
{activeSection === sections.home && <Home />}
{activeSection === sections.contact && <Contact />}
</div>
</div>
</motion.div>
</AnimatePresence>
</motion.div>
</AnimateSharedLayout>
<button
type="button"
onClick={() =>
setActiveSection(
activeSection === sections.home ? sections.contact : sections.home
)
}
>
Go to {activeSection === sections.home ? "Contact" : "Home"} section
</button>
</div>
);
}
So I've got this accordion-layout working with react-router-dom using a rather unconventional markup structure.
Demo:
https://codesandbox.io/s/falling-violet-kvqn2?file=/src/Case.js
Shortened code for one accordion header:
<motion.div
layout
transition={transition}
key={item.id}
style={{
flex: isActive ? 1 : 0,
flexBasis: isActive ? null : 56,
...
}}
>
<NavLink
style={{
...
}}
exact={true}
to={item.url}
/>
<Route exact path={item.url}>
<motion.div
transition={{ delay: 1, ...transition }}
variants={{
open: { opacity: 1 },
collapsed: { opacity: 0 }
}}
initial="collapsed"
animate="open"
exit="collapsed"
layout
style={{
...
}}
>
<Home />
</motion.div>
</Route>
</motion.div>
And I'm trying to get framer-motion to animate between the accordion pages. Like in the gif below
You can see that it works fine to animate the in transition. But struggles to animate the exit prop on page change. Clicking on an accordion header, the content is abruptly hidden. Looks like it is being removed from the DOM without any consideration to AnimateSharedLayout or AnimatePresence. I tried adding in exitBeforeEnter props but it doesnβt work.
Any ideas?
You will need to make some changes in your code:
Work with variants -> you can orchestration animations start:
By default, all these animations will start simultaneously. But by using variants, we gain access to extra transition props like when, delayChildren, and staggerChildren that can let parents orchestrate the execution of child animations.
Also, looks like you will need to work with width to change div sizes. I tried to do with flexBasis but i really couldnt do it, the transition just doesnt work.
Remove <Route> as a "wrapper" of motion.div. It also stops the motion to do the animations/transitions.
Add <AnimatePresence> as a wrapper of motion.div children. You can check more here
So, my code looks like this:
I create this 2 variants:
const divVariants = {
expanded: {
width: "55%",
transition: {
duration: 1.2,
ease: [0.83, 0, 0.17, 1]
}
},
collapsed: {
width: "15%",
transition: {
duration: 1.2,
ease: [0.83, 0, 0.17, 1]
}
}
};
const tagVariants = {
show: {
opacity: 1,
transition: {
delay: 1,
duration: 1.2,
ease: [0.83, 0, 0.17, 1]
}
},
hidden: {
opacity: 0,
transition: {
duration: 1.2,
ease: [0.83, 0, 0.17, 1]
}
}
};
motion.div :
<!-- Parent -->
<motion.div
layout
variants={divVariants}
animate={isActive ? "expanded" : "collapsed"}
initial={false}
data-section={item.id}
key={item.id}
style={{
overflow: "hidden",
zIndex: i,
display: "flex",
position: "relative",
backgroundColor: `hsl(${i * 20},100%,50%)`
}}
>
<!-- Children -->
<AnimatePresence>
{isActive && (
<motion.div
layout
variants={tagVariants}
initial="hidden"
animate="show"
exit="hidden"
style={{
padding: 20,
maxWidth: "100%",
maxHeight: "100%",
width: "100%",
height: "100%",
overflowY: "hidden",
overflowX: "hidden"
}}
>
<Tag data={data} />
</motion.div>
)}
</AnimatePresence>
I also added some inline styles to all Cases:
<div
<!-- Avoid div to wrap when it is collapsing -->
style={{
whiteSpace: "nowrap",
overflow: "hidden"
}}
>
home 0
</div>
And finally
You can check the code here!
I want to change the icon when I click on it with react spring. For example, when I click on "π€ͺ", it will change into "π". In the documentation of react spring, it's possible to make it with the transition props, but how do I toggle it with onClick?
https://www.react-spring.io/docs/props/transition
the following codes are provided by react spring
<Transition
items={toggle}
from={{ position: 'absolute', opacity: 0 }}
enter={{ opacity: 1 }}
leave={{ opacity: 0 }}>
{toggle =>
toggle
? props => <div style={props}>π</div>
: props => <div style={props}>π€ͺ</div>
}
</Transition>
create a button and change toggle value on click:
function App() {
const [toggle, setToggle] = React.useState(false);
return (
<>
<button onClick={() => setToggle(!toggle)}>toggle</button>
<Transition
items={toggle}
from={{ position: "absolute", opacity: 0 }}
enter={{ opacity: 1 }}
leave={{ opacity: 0 }}
>
{toggle =>
toggle
? props => <div style={props}>π</div>
: props => <div style={props}>π€ͺ</div>
}
</Transition>
</>
);
}
I am trying to rotate this ccs art 360 degrees on mouse hover, but for some reason, the whole div seems to reflect under the origin position. I am fairly new to react and css, so I am honestly not sure why the image vertically flipping when I hover over it
DefaultView.css:
.LilGuy:hover{
-moz-transform: rotate(360deg) ;
-webkit-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
transition: all 2s ease;
transform-origin: center center;
}
DefaultView.js:
import React from 'react';
import './DefaultView.css'
export default class DefaultView extends React.Component {
render(){
return(
<div
style={{
height:"100%",
width:"100%",
position:"absolute",
overflow:"hidden"
}}>
<div
className="bg"
style={{
background:"radial-gradient(#034FFF,#021645)",
position:"relative",
width:"100%",
height:"100%"
}}
/>
<div className="LilGuy">
<div
className="LilDudeOutLine"
style={{
background:"#FFFF",
position:"absolute",
width:"510px",
height:"510px",
top:"50%",
left:"50%",
transform:"translate(-50%,-50%)",
borderRadius:"50px"
}}
/>
<div
className="LilDude"
style={{
background:"#012787",
position:"absolute",
width:"500px",
height:"500px",
top:"50%",
left:"50%",
transform:"translate(-50%,-50%)",
borderRadius:"50px"
}}
/>
<div
className="eye-left"
style={{
background:"#034FFF",
position:"absolute",
width:"75px",
height:"75px",
top:"40%",
left:"44%",
transform:"translate(-50%,-50%)",
borderRadius:"125px"
}}
/>
<div
className="eye-right"
style={{
background:"#034FFF",
position:"absolute",
width:"75px",
height:"75px",
top:"40%",
left:"56%",
transform:"translate(-50%,-50%)",
borderRadius:"125px"
}}
/>
<div
className="pupil-left"
style={{
background:"#FFFF",
position:"absolute",
width:"28px",
height:"30px",
top:"38.6%",
left:"43.99999999%",
transform:"translate(-50%,-50%)",
borderRadius:"60px"
}}
/>
<div
className="pupil-right"
style={{
background:"#FFFF",
position:"absolute",
width:"28px",
height:"30px",
top:"38.6%",
left:"56%",
transform:"translate(-50%,-50%)",
borderRadius:"60px"
}}
/>
<div
className="mouth"
style={{
background:"#FFFF",
position:"absolute",
width:"150px",
height:"50px",
top:"50%",
left:"50%",
transform:"translate(-50%,-50%)",
borderRadius: '10px',
borderBottomLeftRadius: '40px',
borderBottom: '4px solid #034FFF',
borderBottomRightRadius: '40px'
}}
/>
</div>
</div>
)
}
}
https://gyazo.com/595b80ee2affbf4678d5f6453dd7175f
Thanks for any help!
I did bit of styling and tried with different transform-base numbers, it is more close to what you need. You would still have to try out more set of numbers for transform-origin numbers, the one in .LilGuy:hover class.
here is codesandbox link
https://codesandbox.io/embed/6vz0nn2x1z
it would still blink if you hover over some part of it because that div has big size and when you hover over in the part of div from where div would be moved on hover, which leads to end a hover effect and try to put div back in place, so in that case it would blink a bit. However you can change the transform-origin numbers I used to fit your need.
I want to implement a navbar like component in reactjs. but pesudo-classes(:hover) for css seem not to be supported by react(css-in-js). I try the another way out to solve the problem using li and state control.
Another problem for this solution is that i can't ripped off the unordered bullet list using display:inline-block or list-style:none because it make the sub-menu items to be disappear when moving my pointer down to them.I am using material-ui/core as UI libraryAn example of my code:
showMenu = () =>{
this.setState({showMenu: true});
}
hideMenu = () =>{
this.setState({showMenu: false});
}
html, css
dropdownMenu:{
position: "absolute",
fontSize: "0.9rem",
marginTop: 0,
right: 15,
left: "auto",
top: "63px",
backgroundColor:"white",
border:"1px solid #D9E4E3",
boxShadow: "0px 3px 21px 0px rgba(0, 0, 0, 0.2)",
animationDuration: "0.25s",
animationFillMode: "both",
},
<div>
<li onMouseLeave={this.hideMenu}>
<div className={classes.sectionDesktop} onMouseEnter={this.showMenu}>
<Avatar style={{backgroundColor: "transparent"}}><Icon>account_circle</Icon></Avatar>
<span style={{fontWeight: 500, margin: "0px .5rem", lineHeight: "40px"}}>Louis Barnett</span>
</div>
{this.state.showMenu &&
<div className={classes.dropdownMenu} >
<SideMenuItem label="My Profile" icon={this.renderIcon('person')} onClick={() => this.handleMenuClick("/me")}/>
<SideMenuItem label="Settings" icon={this.renderIcon('settings')} />
<SideMenuItem label="Logout" icon={this.renderIcon('exit_to_app')} onClick={this.handleSignoutClick}/>
</div>
}
</li>
</div>
SideMenuItem Component
render() {
const selected = this.props.location.pathname === this.props.path;
return(
<ListItem button dense selected={selected} onClick={this.handleOnClick}>
<ListItemIcon>
{this.props.open || !this.props.label ? this.props.icon : <Tooltip title={this.props.label}>{this.props.icon}</Tooltip>}
</ListItemIcon>
<ListItemText primary={this.props.label}/>
</ListItem>
);
}
Hello mate the :hover styling should work in this case. Just try specifying it in a style-sheet instead of inline style.
Sample code
yourCssFile.css
.my-button {
background-color: yellow;
}
In your component
import './path_to_css/yourCssFile.css';
In the button
<button class="my-button">Click me</button>
This will apply your styles for your button. Similarly you can try out hover.Check out the reference!