change opacity and animated that with react js - javascript

i started a simple project with react.in my project i have a paragraph and when mouse hover on paragraph (mouse enter event) a square appears under the paragraph and when hover out from paragraph(mouse leave event) that square disapear.but this occure so fast so i want changing this smoothly and i want use opacity and change that from 0 to 1 and reverse when my events occure.but I do not know what to do to change the opacity with animation in react.
this is my appjs
import './index.css';
import React, {useState} from "react";
function App() {
const [isShowSquare, setIsShowSquare] = useState(false);
const showSquare = () => {
setIsShowSquare(true);
}
const hideSquare = () => {
setIsShowSquare(false);
}
return (
<div>
<p onMouseEnter={showSquare} onMouseLeave={hideSquare} style={{display:'inline-block'}}>Hover Me</p>
{isShowSquare ?
<div className='square'>
</div>
: null
}
</div>
);
}
export default App;
and this is my index.css
*{
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.square{
width: 50px;
height: 50px;
background-color: #61dafb;
}
I would be very grateful if anyone could help me

Here is a method without using useState though.
I don't know if this part is important, but have a look at my
sandbox
First of all you need a css class to define the opacity the method and how much time it will take. Also, your first square class should have opacity: 0, meaning non visible.
When mouse is over text, then you add the extra class to the element.
const showSquare = () => {
div.current.classList.add("square-full");
};
const hideSquare = () => {
div.current.classList.remove("square-full");
};
.square.square-full {
opacity: 0.5;
transition: opacity 1s ease-out;
}
.square {
width: 50px;
height: 50px;
background-color: #61dafb;
opacity: 0;
}
Updated answer: No need for ref
Just use the following code
export default function App() {
const [ isShown, setShown ] = useState(false)
return (
<div>
<p
onMouseEnter={() => setShown(true)}
onMouseLeave={() => setShown(false)}
style={{ display: "inline-block" }}
class="paragraph"
>
Hover Me
</p>
<div className={`square ${isShown ? 'square-full' : ''}`}></div>
</div>
);
}
along with the extra class i mentioned before

Appearing is easy, and for disappearing I found a solution like this;
import { useState } from "react";
import "./styles.css";
export default function App() {
const [visible, setVisible] = useState(false)
const [disappear, setDisappear] = useState(false)
return (
<div className="App">
<p onMouseLeave={()=> {
setDisappear(true)
setTimeout(()=>{setVisible(false)
setDisappear(false)}
, 1000)
}} onMouseEnter={()=> setVisible(true)}>Hide/Show square </p>
{visible && <div className="square"
style={{
width: 100,
height: 100,
animation: disappear ? "disappear 1s ease" : "appear 1s ease"
}}> </div> }
</div>
);
}
For the animations in css ;
//style.css
.square {
background-color: red;
animation: appear 1s ease;
}
#keyframes appear {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#keyframes disappear {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
So what happens here is that we have a keyframe on our css for the opacity initially. So this works fine, tricky part is disappearing. When we set the visible state to false React immideately removes our element, so we have setTimeOut to stop React for 1 second. In that 1 second we apply our animations, it runs smoothly on me. Go ahead and try.

Related

How play/pause all animation css with components React.js?

I have created several CSS animations in my React.js project
I'm looking to put a general button to pause them if the user wants, because they can disturb or simply slow down the pc.
I have done this by targeting classes but it doesn't work at all :
Button.js :
import {useRef, useEffect} from 'react';
function Button() {
const ref = useRef(null);
useEffect(() => {
const el2 = ref.current;
console.log(el2);
const jstoggle = document.getElementById('js-toggle');
console.log(jstoggle)
jstoggle.addEventListener('click', () => {
const animations = document.querySelectorAll('.person-name', '.background-penny');
animations.forEach(animation => {
const running = animation.style.animationPlayState || 'running';
animation.style.animationPlayState = running === 'running' ? 'paused' : 'running';
})
});
}, []);
return (
<>
<button id="js-toggle" ref={ref} className="btn" type="button">PAUSE ANIMATION</button>
</>
);
}
export default Button
Animations CSS :
.person-name{
text-transform: capitalize;
background-image: linear-gradient(
-225deg,
#231557 0%,
#44107a 29%,
#ff1361 67%,
#fff800 100%
);
background-size: auto auto;
background-clip: border-box;
background-size: 200% auto;
color: #fff;
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
animation: textclip 2s linear infinite;
display: inline-block;
font-size: 19px;
padding-top: 5px;
}
#keyframes textclip {
to {
background-position: 200% center;
}
}
.background-penny{
padding: 20px;
animation: changecolor 3s infinite;
transition: none;
}
Thank you for the help !
It is working fine for me only difference is i have attached onClick event handler to button.
const handleClick = () => {
const animations = document.querySelectorAll('.person-name', '.background-penny');
animations.forEach(animation => {
const running = animation.style.animationPlayState || 'running';
animation.style.animationPlayState = running === 'running' ? 'paused' : 'running';
})
}
<button id="js-toggle" onClick={()=>handleClick()} ref={ref} className="btn" type="button">PAUSE ANIMATION</button>
Can you also check if changecolor animation is correctly implemented, textclip animation is working correctly.

ReactJS: Why is my custom functional toast component behaving so strangely upon attempting to automatically dismiss notification pop-ups?

My custom react toast component was working well until I tried to implement automatic dismissal of notifications after a set time.
I am trying to make it so that after a set time, the pop-up "toast" notifications will have a CSS fade-out animation play and then be deleted — unless the user is hovering over that notification, in which case it will hold off on dismissing that one until the user moves their mouse off of it.
Sometimes it works properly, other times it stops displaying anything and adds the notifications back one by one, other times it... well, it just behaves in a very strange and unexpected manner.
Here is my code:
Toast.css
.toast-container {
font-size: 24px;
box-sizing: border-box;
position: fixed;
z-index: 10;
}
.toast-popup {
padding: 12px;
display: flex;
align-items: center;
justify-content: space-between;
width: 500px;
border: solid #f2f2f2;
border-radius: 8px;
box-shadow: 0 0 10px #999;
margin-bottom: 1rem;
opacity: 0.9;
}
.toast-popup:hover {
box-shadow: 0 0 12px deepskyblue;
opacity: 1 !important;
animation-play-state: paused;
}
.success {
background-color: #5cb85c;
}
.info {
background-color: #5bc0de;
}
.warning {
background-color: #f0ad4e;
}
.danger {
background-color: #d9534f;
}
.toast-text {
justify-self: flex-start;
width: 100%;
padding: 6px 0 6px 6px;
opacity: 0.9;
}
.toast-title {
font-weight: 700;
font-size: 32px;
text-align: left;
padding-bottom: 0px;
color: #f2f2f2;
}
.toast-message {
padding-top: 0px;
text-align: left;
color: #f2f2f2;
}
.toast-icon {
float: left;
margin: 0 20px 0 10px;
opacity: 0.9;
}
.toast-icon img {
width: 50px;
height: 50px;
fill: #f2f2f2;
opacity: 0.9;
}
.close-button {
float: right;
align-self: flex-start;
font-weight: 600;
color: #f2f2f2;
background: none;
border: none;
opacity: 0.9;
cursor: pointer;
}
.top-right {
top: 2rem;
right: 2rem;
}
.top-right-slide {
top: 2rem;
right: 2rem;
transition: transform .6s ease-in-out;
animation: toast-in-right .7s;
}
.bottom-right {
bottom: 2rem;
right: 2rem;
}
.bottom-right-slide {
bottom: 2rem;
right: 2rem;
transition: transform .6s ease-in-out;
animation: toast-in-right .7s;
}
.top-left {
top: 2rem;
left: 2rem;
}
.top-left-slide {
top: 2rem;
left: 2rem;
transition: transform .6s ease-in;
animation: toast-in-left .7s;
}
.bottom-left {
bottom: 2rem;
left: 2rem;
}
.bottom-left-slide {
bottom: 2rem;
left: 2rem;
transition: transform .6s ease-in;
animation: toast-in-left .7s;
}
.fadeout {
animation: 4s linear 5s 1 normal forwards running toast-fadeout;
}
#keyframes toast-in-right {
from { transform: translateX(100%); }
to { transform: translateX(0); }
}
#keyframes toast-in-left {
from { transform: translateX(-100%); }
to { transform: translateX(0); }
}
#keyframes toast-fadeout {
from { opacity: 0.9; }
to { opacity: 0; }
}
Toast.js - Please excuse the generous peppering of console.logs...
import React, {useEffect, useState} from 'react';
import icon_success from './icons/feathericons/check-circle.svg';
import icon_info from './icons/feathericons/info.svg';
import icon_warning from './icons/feathericons/alert-triangle.svg';
import icon_danger from './icons/feathericons/alert-octagon.svg';
import './Toast.css';
const Toast = (props) => {
const {toastList, position} = props;
const [list, setList] = useState(toastList);
const [prevId, setPrevId] = useState(0);
// This useEffect updates the list of toasts to display
useEffect(() => {
console.log('useEffect()');
console.log('useEffect() toastList:');
console.log(toastList);
setList([...toastList]);
}, [toastList]);
const markForDeletion = (toast) => {
if( toast.isDeleting ) {
return;
}
console.log(`toast ${toast.id} marked for deletion`)
toast.isDeleting = true;
setTimeout(() => {attemptDeletion(toast)}, 5000);
}
const attemptDeletion = (toast) => {
console.log(`attempting to delete toast ${toast.id}. canDelete = ${toast.canDelete}`);
if( toast.canDelete ) {
deleteToast(toast.id);
}
else {
console.log(`cannot delete toast ${toast.id}. `);
}
}
const getIcon = (variant) => {
switch( variant ) {
case 'success':
return icon_success;
break;
case 'info':
return icon_info;
break;
case 'warning':
return icon_warning;
break;
case 'danger':
return icon_danger;
break;
}
}
const generateId = (toast) => {
if( typeof(toast.id) === 'number' ) {
return toast.id;
}
toast.id = prevId + 1;
setPrevId(toast.id);
return toast.id;
}
const deleteToast = (id) => {
console.log(`deleting toast ${id}`);
const deletionIdxList = list.findIndex(e => e.id === id);
const deletionIdxToastList = toastList.findIndex(e => e.id === id);
console.log(`deletionIdxToastList: ${deletionIdxToastList}`);
if(deletionIdxList == null || deletionIdxList === -1) {
console.log(`cannot find list idx of id ${id}`);
console.log('list:');
console.log(list);
return;
}
if(deletionIdxToastList == null || deletionIdxToastList === -1) {
console.log(`cannot find toastList idx of id ${id}`);
console.log('toastList:');
console.log(toastList);
return;
}
console.log('list before deletion:');
console.log(list);
console.log('toastList before deletion:');
console.log(toastList);
console.log('list[deletionIdxList]:');
console.log(list[deletionIdxList]);
list.splice(deletionIdxList, 1);
console.log('toastList[deletionIdxToastList]:');
console.log(toastList[deletionIdxToastList]);
toastList.splice(deletionIdxToastList, 1);
setList([...list]);
console.log(`toast ${id} deleted successfully`);
console.log('list after deletion:');
console.log(list);
console.log('toastList after deletion:');
console.log(toastList);
}
return (
<>
<div className={`toast-container ${position}`} >
{
list.map((toast, i) => (
<div
key={i}
className={`toast-popup ${toast.variant} ${toast.isDeleting ? (position + ' fadeout') : (position + '-slide')}`}
onLoad={() => {
if( !toast.isLoaded ) {
toast.Id = generateId(toast);
toast.canDelete = true;
toast.isDeleting = false;
toast.isLoaded = true;
console.log(`on load ${toast.id}`);
setTimeout(() => markForDeletion(toast), 500);
}
}}
onMouseOver={() => {
toast.canDelete === true ? toast.canDelete = false : null;
toast.isDeleting === true ? toast.isDeleting = false : null;
console.log(`mouse over ${toast.id}`);
}}
onMouseLeave={() => {
toast.canDelete === false ? toast.canDelete = true : null;
markForDeletion(toast);
console.log(`mouse leave ${toast.id}`);
}}
>
<div className={'toast-icon'}>
<img src={getIcon(toast.variant)} />
</div>
<div className={'toast-text'}>
<div className={'toast-title'}>
{toast.variant.charAt(0).toUpperCase() + toast.variant.slice(1)}
</div>
<div className={'toast-message'}>{toast.message}</div>
</div>
<button
className={'close-button'}
onClick={() => {
toast.canDelete = true;
deleteToast(toast.id)
}
}>
X
</button>
</div>
))
}
</div>
</>
)
}
Toast.defaultProps = {
position: 'bottom-right'
}
export default Toast;
Snippet of Home.js where I am testing this new Toast component - A class component as I'm working on updating a pre-existing application to remove dependency on the react-toastify library
// Leaving out constructor and other irrelevant code...
toastSuccess() {
const newToast = {
variant: 'success',
message: 'This is a test of the success variant toast pop-up.'
}
this.setState({
toastList: [...this.state.toastList, newToast]
});
}
toastInfo() {
const newToast = {
variant: 'info',
message: 'This is a test of the info variant toast pop-up.'
}
this.setState({
toastList: [...this.state.toastList, newToast]
});
}
toastWarning() {
const newToast = {
variant: 'warning',
message: 'This is a test of the warning variant toast pop-up.'
}
this.setState({
toastList: [...this.state.toastList, newToast]
});
}
toastDanger() {
const newToast = {
variant: 'danger',
message: 'This is a test of the danger variant toast pop-up.'
}
this.setState({
toastList: [...this.state.toastList, newToast]
});
}
render() {
return (
<div className="Home" style={{height:'100%'}}>
<Toast
toastList={this.state.toastList}
position={'bottom-right'}
/>
<div style={{display:'flex', justifyContent:'center'}}>
<Button onClick={() => this.toastSuccess()}>Success</Button>
<Button onClick={() => this.toastInfo()}>Info</Button>
<Button onClick={() => this.toastWarning()}>Warning</Button>
<Button onClick={() => this.toastDanger()}>Danger</Button>
</div>
{// ...}
</div>
);
}
Let me know if there's a way to get this code running here on StackOverflow using that Code Snippet feature, as that would be really helpful so that you readers can see the issue first-hand. Unfortunately I've never had any luck getting it to work, but I'll keep trying for a bit to see if I can figure it out.
EDIT:
Thanks to #Cristian-FlorinCalina for recommending StackBlitz as a good shareable test environment. I've got it set up there now, here's a link:
https://react-ts-ybunlg.stackblitz.io
First problem that I see with your code is that you are keeping two sources of truth for toast list. One is passed from the parent via props, and one is the internal state list in the Toast component. This is an antipattern that can generate a lot of issues.
Second BIG issue is that you are altering the list that you receive from the parent. That is a huge antipattern in React since props are readonly -- All React components must act like pure functions with respect to their props. (since you are altering an object inside an array apparently it works for the load update but it does not work when you are trying to call splice on the list -- this is why even if you deleted the element and applied the deletion effect, when it gets updated on the parent (next render) -> it will come back without it being removed and clicking again on another toast generate button will show you the previously deleted toast as well).
I think the big problem here is that you are not using composition properly. Instead of passing the toast list to the Toast component, you should keep the list on the parent, move the map from the child inside the parent. You will have one instance of Toast component per each element in the list.
Maybe you can have a ToastList component as well, that handles Toast compoonents based on their position... So when you click on Upper Left Toast Generator for example, it will add a new entry inside an array of toasts, with a position key. That array will be sent to the ToastList component, which will generate Toast components that handle their state internally (deletion, etc) and do not update the actual list. You can pass a function to the Toast component called onDelete that will be called by the Toast component on deletion, and you will update the ToastList state based on those events (probably propagate the delete event to the parent to update the list there).
Hope it makes sense.

React color background on event

I use the npm package use-dark-mode as the name implies, it makes it possible to change the theme to light or dark, The problem is that I want to change the background-color of some blocks when changing the theme to dark, and vice versa, return the old color when I switch to light mode, for example, my block background is orange, I switch to dark mode, it turns red and when I switch to light mode, it returns old orange
App.js
import React from 'react';
import './App.css'
import Content from "./components/Content/Content";
import Dark_Mode from "./components/Dark Mode/Dark_Mode";
const App = () => {
return(
<div>
<Dark_Mode />
<Content />
</div>
);
};
export default App;
Content.jsx
import React from 'react';
import './style.css'
const Content = () => {
return (
<>
<div className={"content_container"}>
<h3>Hello from React.JS</h3>
</div>
</>
);
};
export default Content;
Dark_Mode.jsx
import React from 'react';
import useDarkMode from 'use-dark-mode';
const DarkModeToggle = () => {
const darkMode = useDarkMode(false);
return (
<div>
<button type="button" onClick={darkMode.disable}>
☀
</button>
<button type="button" onClick={darkMode.enable}>
☾
</button>
</div>
);
};
export default DarkModeToggle;
style.css
#import '../../App.css';
.content_container {
margin: auto;
width: 500px;
max-width: 100%;
background: orange;
}
.content_container h3 {
text-align: center;
}
App.css
body.light-mode {
background-color: #fff;
color: #333;
transition: background-color 0.3s ease;
}
body.dark-mode {
background-color: #1a1919;
color: #999;
}
:root {
--color-orange: orange;
}
As you can see, I have App.css when the theme changes, it changes the background of the <body>, I still have Content.jsx when switching theme I want to change the background of the block with the className content_container which is connected to style.css, In addition, you may have noticed that I tried to use global styles, but I failed. Finally, I would like to show a screenshot on the site for a clear understanding of everything.
You could give the root element a class on theme change and use css variables in root, but be class specific:
Dark_mode.jsx:
function setTheme(themeName) {
document.documentElement.classList.remove('light-theme', 'dark-theme');
document.documentElement.classList.add(themeName);
}
const DarkModeToggle = () => {
const activateDarkTheme = () => setTheme('dark-theme');
const activateLightTheme = () => setTheme('light-theme');
return (
<div>
<button type="button" onClick={activateDarkTheme}>
☀
</button>
<button type="button" onClick={activateLightTheme}>
☾
</button>
</div>
);
};
Styles:
:root, // this is used for the default theme, will be overwritten by other styles with classes because of specifity
:root.dark-theme {
--color-bg: #000;
}
:root.light-theme {
--color-bg: #fff;
}
I found a more convenient solution! although it is my fault, I was a little inattentive and did not study the documentation of this package that I use in my project, here is a simple solution
Content.jsx
import './Content.css'
import useDarkMode from 'use-dark-mode';
export default function Content () {
const { value } = useDarkMode(false);
return <div>
<div className={value ? 'Dark_Mode' : 'Light_Mode'}>
<h3>Hello from React.JS</h3>
</div>
</div>
}
Content.css
.Dark_Mode {
margin: auto;
max-width: 100%;
width: 400px;
height: 275px;
background-color: orange;
}
.Light_Mode {
margin: auto;
max-width: 100%;
width: 400px;
height: 275px;
background-color: rgb(24, 106, 199);
}

Use Css modules add conditional transition styling to my side navigation

I would like to add some transition styling to my side navigation on my app. I am able to do this using normal classes however in this tutorial they use css modules and i am unsure how to do this using css modules.
I would like my nav to glide in and out, at the moment it jumps statically when the onClick function fires - toggleSideDrawer.
I have used this logic but I am not sure if it is doing anything:
className={props.toggleSideDrawer ? classes.SideDrawerOpen : classes.SideDrawer
Essentially i want that when the user clicks the toggle, the transform property switches from translateX(-100%) to translateX(0) but this is not happening.
Side nav code:
import React from "react";
import Logo from "../../Logo/Logo";
import NavigationItems from "../NavigationItems/NavigationItems";
import Backdrop from "../../UI/Backdrop/Backdrop";
import Aux from "../../../hoc/Aux";
import classes from "./SideDrawer.css";
const SideDrawer = props => {
return (
<Aux classname={classes.SideDrawer}>
<Backdrop
showBackdrop={props.showSideDrawer}
clicked={props.toggleSideDrawer}
/>
{props.showSideDrawer && (
<div
onClick={props.toggleSideDrawer}
className={
props.toggleSideDrawer ? classes.SideDrawerOpen : classes.SideDrawer
}
>
<div className={classes.Logo}>
<Logo />
</div>
<nav>
<NavigationItems />
</nav>
</div>
)}
</Aux>
);
};
export default SideDrawer;
Where the code is used in my Layout component:
import React, { useState } from "react";
import Aux from "../Aux";
import classes from "./Layout.css";
import Toolbar from "../../components/Navigation/Toolbar/Toolbar";
import SideDrawer from "../../components/Navigation/SideDrawer/SideDrawer";
const layout = props => {
const [showSideDrawer, setShowSideDrawer] = useState(false);
return (
<Aux>
<SideDrawer
showSideDrawer={showSideDrawer}
toggleSideDrawer={() => {
setShowSideDrawer(!showSideDrawer);
}}
/>
<Toolbar
onMenuClick={() => {
setShowSideDrawer(!showSideDrawer);
}}
/>
<main className={classes.mainContent}> {props.children} </main>
</Aux>
);
};
export default layout;
CSS:
.SideDrawer {
position: fixed;
width: 280px;
max-width: 70%;
height: 100%;
left: 0;
top: 0;
z-index: 200;
background-color: white;
padding: 32px 16px;
box-sizing: border-box;
transform: translateX(-100%);
}
#media (min-width: 500px) {
.SideDrawer {
display: none;
}
}
.Logo {
height: 11%;
text-align: center;
}
.SideDrawerOpen {
position: fixed;
width: 280px;
max-width: 70%;
height: 100%;
left: 0;
top: 0;
z-index: 200;
padding: 32px 16px;
box-sizing: border-box;
background-color: red;
transform: translateX(0);
transition: transform 0.3s ease-out;
}
The thing is that you need the element will has the transition rule all the time.
My suggestion is to set a static class which which will hold all the styles and addd another one only for overriding transform to make it move.
Something like that (it uses scss but it's easy to do it with css)
.SideDrawer {
position: fixed;
width: 280px;
max-width: 70%;
height: 100%;
left: 0;
top: 0;
z-index: 200;
background-color: white;
padding: 32px 16px;
box-sizing: border-box;
transition: transform .3s ease;
transform: translateX(-100%);
&.show {
transform: translateX(0);
}
}
export const App = () => {
const [showSideDrawer, setShowSideDrawer] = useState(false);
const sidebarClasses = classname([
styles.SideDrawer,
{
[styles.show]: showSideDrawer
}
]);
const ToggleSidebar = () => {
return (
<button onClick={() => setShowSideDrawer(!showSideDrawer)}>
Toggle Sidebar
</button>
);
};
return (
<Fragment>
<h1>App</h1>
<div className={sidebarClasses}>
<div>Sidebar content</div>
<ToggleSidebar />
</div>
<ToggleSidebar />
</Fragment>
);
};
https://codesandbox.io/s/xenodochial-framework-04sbe?file=/src/App.jsx
#MoshFeu helped me fix this.
The problem is that you render the drawer only when showSideDrawer so before it becomes true, the sidebar is not in the DOM yet so the transition is not affecting it.
The solution is to keep it in the DOM all the time but toggle . Open class to change the style.
There are libraries that knows to make the transition works even for elements that are not in the DOM but it's a bit more complicated.
code fix for SideDrawer.js without the conditional within the return
class SideDrawer extends Component {
render() {
let sideDrawerClass = [classes.SideDrawer];
// SideDrawer will now be an array with the side drawer classes and the open class
if (this.props.showSideDrawer) {
sideDrawerClass.push(classes.Open);
}
return (
<Aux classname={classes.SideDrawer}>
<Backdrop
showBackdrop={this.props.showSideDrawer}
clicked={this.props.toggleSideDrawer}
/>
<div
className={sideDrawerClass.join(" ")}
onClick={this.props.toggleSideDrawer}
>
<div className={classes.Logo}>
<Logo />
</div>
<nav>
<NavigationItems />
</nav>
</div>
</Aux>
);
}
}
export default SideDrawer;

ReactCssTransitionGroup not fading in

I'm building a personal site w/ React and trying to get some h2's to fade in after a couple of seconds after load. I'm using ReactCssTransitionGroup on the following Component:
import React, { Component } from 'react';
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
class TitleArea extends Component {
constructor(props) {
super(props);
this.state = {
ids: ['h2-one', 'h2-two', 'h2-three'],
h2Texts: ['Text1', 'Text2', 'Text3']
};
}
render() {
const descriptionDivs = this.state.ids.map( (id, index)=> {
return(<h2 key={id} id={id}>
{this.state.h2Texts[index]}
</h2>)
})
return (
<div className='row odd'>
<h1> MYNAMEHERE </h1>
<div className='description-container'>
<ReactCSSTransitionGroup
transitionName="descriptions"
transitionEnterTimeout={500}
transitionLeaveTimeout={300}>
{descriptionDivs}
</ReactCSSTransitionGroup>
</div>
</div>
);
}
}
export default TitleArea;
CSS/SASS:
.site-container {
text-align: center;
font-family: 'Source Code Pro', monospace;
h1 {
font-size: 50px;
font-family: 'Arvo', serif;
h2 {
font-size: 25px;
}
}
.descriptions-enter {
opacity: 0.01;
}
.descriptions-enter.descriptions-enter-active {
opacity: 1;
transition: opacity 500ms ease-in;
}
I'd ideally want each h2 to transition in one after another, but I'm trying to get a handle on the react-addons first before I jump to staggering the fade-ins. Does anyone have any experience with css transitions in React. Tried following the docs but got a bit lost. Any insight greatly appreciated! Thanks

Categories

Resources