Categories
React

Animation with the react-tweenful Library — Gradients and Rotation

With the react-tweenful library, we can render animations in our React app easily.

In this article, we’ll take a look at how to get started with the react-tweenful.

Gradients

We can add gradients animations with react-tweenful.

For example, we can write:

App.js

import React from "react";
import Tweenful, { elastic } from "react-tweenful";
import "./styles.css";

export default function App() {
  const elements = new Array(5)
    .fill(0)
    .map((_e, i) => (
      <Tweenful.div
        className={`gradient${i + 1} box`}
        loop={true}
        easing={elastic(1, 0.1)}
        duration={3000}
        delay={i * 100}
        endDelay={(10 - i) * 100}
        animate={[{ height: "20%" }, { height: ["20%", "auto"] }]}
        key={i}
      ></Tweenful.div>
    ));

  return (
    <div className="gradients-container">
      <div className="row">{elements}</div>
    </div>
  );
}

styles.css

.row {
  display: flex;
  flex-direction: row;
}

.gradient1.box {
  background-color: #fafa6e;
  height: 100px;
  width: 50px;
}

.gradient2.box {
  background-color: #d7f171;
  height: 100px;
  width: 50px;
}

.gradient3.box {
  background-color: #b5e877;
  height: 100px;
  width: 50px;
}

.gradient4.box {
  background-color: #95dd7d;
  height: 100px;
  width: 50px;
}

.gradient5.box {
  background-color: #77d183;
  height: 100px;
  width: 50px;
}

We create the elements with an array and map those to the Tweenful.div component.

We set the className of the div.

We set loop to true to loop the animation indefinitely.

easing has the easing function to apply.

delay has the start delay for the animation.

endDelay has the end delay duration for the animation.

animate has an array with the styles applied at the start of the animation and at the end respectively.

Then we render all that in the JSX.

In styles.css , we set the styles for the divs.

Rotation

We can add keyframes with react-tweenful to create more complex animations.

For example, we can write:

App.js

import React from "react";
import Tweenful, { percentage } from "react-tweenful";
import "./styles.css";

const rotate = percentage({
  "0%": { translate: "-50% -50%", rotate: "0deg" },
  "50%": { translate: "-50% -50%", rotate: "0deg" },
  "80%": { translate: "-50% -50%", rotate: "360deg" },
  "100%": { translate: "-50% -50%", rotate: "360deg" }
});
const dot1Animate = percentage({
  "0%": { scale: 1 },
  "20%": { scale: 1 },
  "45%": { translate: "16px 12px", scale: 0.45 },
  "60%": { translate: "160px 150px", scale: 0.45 },
  "80%": { translate: "160px 150px", scale: 0.45 },
  "100%": { translate: "0px 0px", scale: 1 }
});
const dot2Animate = percentage({
  "0%": { scale: 1 },
  "20%": { scale: 1 },
  "45%": { translate: "-16px 12px", scale: 0.45 },
  "60%": { translate: "-160px 150px", scale: 0.45 },
  "80%": { translate: "-160px 150px", scale: 0.45 },
  "100%": { translate: "0px 0px", scale: 1 }
});
export default function App() {
  return (
    <div className="loading-wrapper">
      <Tweenful.div
        className="loading-circles-container"
        duration={2000}
        loop={true}
        easing="easeInOutCubic"
        transform={{ translate: "-50% -50%" }}
        animate={rotate}
      >
        <Tweenful.div
          className="dot dot-1"
          duration={2000}
          easing="easeOutCubic"
          loop={true}
          transform={{ translate: "0px 0px", scale: 1 }}
          animate={dot1Animate}
        ></Tweenful.div>
        <Tweenful.div
          className="dot dot-2"
          duration={2000}
          easing="easeOutCubic"
          loop={true}
          transform={{ translate: "0px 0px", scale: 1 }}
          animate={dot2Animate}
        ></Tweenful.div>
      </Tweenful.div>
    </div>
  );
}

styles.css

.dot.dot-1 {
  background-color: red;
  width: 40px;
  height: 40px;
  border-radius: 50%;
}

.dot.dot-2 {
  background-color: green;
  width: 40px;
  height: 40px;
  border-radius: 50%;
}

We have the rotate , dot1Animate , and dot2Animate object that has the animation progress as the keys and the styles to apply at the given progress as the value.

We translate and rotate the elements that has the animate prop set to these objects.

In the Tweenful.div components, we set the transform prop to transform the items more.

We also set the easing and set loop to true to repeat the animation forever.

In styles.css , we add the styles for the divs.

Now we should see 2 rotating divs.

Conclusion

We can add gradients and rotation with react-tweenful.

Categories
React

Animation with the react-tweenful Library — Observers

With the react-tweenful library, we can render animations in our React app easily.

In this article, we’ll take a look at how to get started with the react-tweenful.

ObserverGroup

We can use the ObserverGroup component to watch for mounting and unmounting over a list of notifications.

For example, we can use it by writing:

import React, { useState } from "react";
import { ObserverGroup } from "react-tweenful";

const items = [
  { text: "foo", id: 1 },
  { text: "bar", id: 2 },
  { text: "baz", id: 3 }
];

export default function App() {
  const [notifications, setNotifications] = useState(items);

const removeNotification = (id) => {
    setNotifications((notifications) =>
      notifications.filter((n) => n.id !== id)
    );
  };

  return (
    <ObserverGroup
      config={{
        duration: 800,
        style: { overflow: "hidden" },
        mount: { opacity: [0, 1], height: ["0px", "auto"] },
        unmount: { opacity: [1, 0], height: ["auto", "0px"] },
        easing: "easeInOutCubic"
      }}
      skipInitial={true}
    >
      {notifications.map((notification) => (
        <div
          key={notification.id}
          onClick={removeNotification.bind(undefined, notification.id)}
        >
          {notification.text}
        </div>
      ))}
    </ObserverGroup>
  );
}

We have an items array which we use as the initial value of the notifications state.

Next, we add the removeNotification function that takes an id and removes the entry with the given id .

In the JSX, we use the ObserverGroup component to define our animation.

The config prop has various properties we set to add the animation.

duration has the duration of the animation.

style has style for the container.

mount has the styles to apply when we mount a component inside the ObserverGroup.

unmount has the styles to apply when we unmount a component inside the ObserverGroup .

The easing property has the easing function to apply.

skipInitial skips animation when the components loads when it’s set to true .

Now when we click on the div for the notifications entry, we should see the animation displayed.

Animate Route Transition

We can use react-tweenful to animate route transition.

For example, we can write:

App.js

import React from "react";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import { ObserverGroup, Observer } from "react-tweenful";
import "./styles.css";

const colors = {
  red: "#EE4266",
  yellow: "#FDB833",
  blue: "#296EB4",
  green: "#0EAD69"
};

const observerProps = {
  className: "key-wrapper",
  duration: 1000,
  style: { opacity: 0 },
  mount: { opacity: 1 },
  unmount: { opacity: 0 },
  easing: "easeOutQuad"
};

const Red = () => (
  <ObserverGroup>
    <Observer.div {...observerProps}>
      <div
        className="color-block"
        style={{ backgroundColor: colors.red }}
      ></div>
    </Observer.div>
  </ObserverGroup>
);
const Yellow = () => (
  <ObserverGroup>
    <Observer.div {...observerProps}>
      <div
        className="color-block"
        style={{ backgroundColor: colors.yellow }}
      ></div>
    </Observer.div>
  </ObserverGroup>
);
const Blue = () => (
  <ObserverGroup>
    <Observer.div {...observerProps}>
      <div
        className="color-block"
        style={{ backgroundColor: colors.blue }}
      ></div>
    </Observer.div>
  </ObserverGroup>
);
const Green = () => (
  <ObserverGroup>
    <Observer.div {...observerProps}>
      <div
        className="color-block"
        style={{ backgroundColor: colors.green }}
      ></div>
    </Observer.div>
  </ObserverGroup>
);

export default function App() {
  return (
    <div>
      <Router>
        <ul className="nav-links">
          <li>
            <Link to="/transition/red">Red</Link>
          </li>
          <li>
            <Link to="/transition/yellow">Yellow</Link>
          </li>
          <li>
            <Link to="/transition/blue">Blue</Link>
          </li>
          <li>
            <Link to="/transition/green">Green</Link>
          </li>
        </ul>
        <Switch>
          <Route exact path={`/transition/red`}>
            <Red />
          </Route>
          <Route exact path={`/transition/green`}>
            <Green />
          </Route>
          <Route exact path={`/transition/blue`}>
            <Blue />
          </Route>
          <Route exact path={`/transition/yellow`}>
            <Yellow />
          </Route>
        </Switch>
      </Router>
    </div>
  );
}

styles.css

.color-block {
  width: 100px;
  height: 100px;
}

We create the Red , Green , Blue , and Yellow components which we use as the route components.

We add them in between the Route components to use them as such.

Each of the component has the ObserverGroup and the Observer.div component to let us apply the animation effects specified in the observerProps object.

The colors object values are used in the same components to add colors.

We also have styles.css to change the size of the boxes in those components.

The Link component lets us load the routes when we click on the links.

Now we should see the boxes displayed with the color, and when they mount, we should see the transition.

Conclusion

We can use the ObserverGroup component to add transitions to groups of elements.

React-tweenful also works with React Router.

Categories
React

React Transition Group — SwitchTransition and TransitionGroup

With the react-spring library, we can render animations in our React app easily.

In this article, we’ll take a look at how to get started with the React Transition Group.

SwitchTransition

The SwitchTransition component lets us control render between state transitions.

For example, we can write:

App.js

import React, { useState } from "react";
import { CSSTransition, SwitchTransition } from "react-transition-group";
import "./styles.css";

export default function App() {
  const [state, setState] = useState(false);

  return (
    <div className="App">
      <SwitchTransition>
        <CSSTransition
          key={state ? "Goodbye, world!" : "Hello, world!"}
          addEndListener={(node, done) =>
            node.addEventListener("transitionend", done, false)
          }
          classNames="fade"
        >
          <button onClick={() => setState((state) => !state)}>
            {state ? "Goodbye, world!" : "Hello, world!"}
          </button>
        </CSSTransition>
      </SwitchTransition>
    </div>
  );
}

styles.css

fade-enter {
  opacity: 0;
}
.fade-exit {
  opacity: 1;
}
.fade-enter-active {
  opacity: 1;
}
.fade-exit-active {
  opacity: 0;
}
.fade-enter-active,
.fade-exit-active {
  transition: opacity 500ms;
}

We add the SwitchTransition and CSSTransition components to let us add transitions with external CSS styles.

The SwitchTransition component lets us render transitions when we toggle the state state.

CSSTransition shows the styles for each state transition.

The addEndListener prop has a function that calls done to end the transition.

TransitionGroup

The TransitionGroup component lets us manage a set of transition components.

For example, we can use it by writing:

App.js

import React, { useState } from "react";
import { CSSTransition, TransitionGroup } from "react-transition-group";
import { v4 as uuidv4 } from "uuid";
import "./styles.css";

export default function App() {
  const [items, setItems] = useState([
    { id: uuidv4(), text: "eat" },
    { id: uuidv4(), text: "drink" },
    { id: uuidv4(), text: "sleep" },
    { id: uuidv4(), text: "walk" }
  ]);
  return (
    <div className="App">
      <TransitionGroup className="todo-list">
        {items.map(({ id, text }) => (
          <CSSTransition key={id} timeout={500} classNames="item">
            <div>
              <button
                className="remove-btn"
                variant="danger"
                size="sm"
                onClick={() =>
                  setItems((items) => items.filter((item) => item.id !== id))
                }
              >
                &times;
              </button>
              {text}
            </div>
          </CSSTransition>
        ))}
      </TransitionGroup>
    </div>
  );
}

styles.css

.remove-btn {
  margin-right: 0.5rem;
}

.item-enter {
  opacity: 0;
}
.item-enter-active {
  opacity: 1;
  transition: opacity 500ms ease-in;
}
.item-exit {
  opacity: 1;
}
.item-exit-active {
  opacity: 0;
  transition: opacity 500ms ease-in;
}

We have an items state that has an array of items as its initial value.

Then we use that with the TransitionGroup component to display transitions for each item rendered inside it.

Inside it, we have th CSSTransition component to render the transition according to the styles.

When we click on the button, we remove the current item by calling setItems function.

Now when we click on the ‘x’, we see the transition as the item disappears.

Conclusion

We can add transitions to a group of items with the TransitionGroup component.

The SwitchTransition lets us render transitions between state changes.

Categories
React

React Transition Group — SwitchTransition and TransitionGroup

With the react-spring library, we can render animations in our React app easily.

In this article, we’ll take a look at how to get started with the React Transition Group.

SwitchTransition

The SwitchTransition component lets us control render between state transitions.

For example, we can write:

App.js

import React, { useState } from "react";
import { CSSTransition, SwitchTransition } from "react-transition-group";
import "./styles.css";

export default function App() {
  const [state, setState] = useState(false);

  return (
    <div className="App">
      <SwitchTransition>
        <CSSTransition
          key={state ? "Goodbye, world!" : "Hello, world!"}
          addEndListener={(node, done) =>
            node.addEventListener("transitionend", done, false)
          }
          classNames="fade"
        >
          <button onClick={() => setState((state) => !state)}>
            {state ? "Goodbye, world!" : "Hello, world!"}
          </button>
        </CSSTransition>
      </SwitchTransition>
    </div>
  );
}

styles.css

fade-enter {
  opacity: 0;
}
.fade-exit {
  opacity: 1;
}
.fade-enter-active {
  opacity: 1;
}
.fade-exit-active {
  opacity: 0;
}
.fade-enter-active,
.fade-exit-active {
  transition: opacity 500ms;
}

We add the SwitchTransition and CSSTransition components to let us add transitions with external CSS styles.

The SwitchTransition component lets us render transitions when we toggle the state state.

CSSTransition shows the styles for each state transition.

The addEndListener prop has a function that calls done to end the transition.

TransitionGroup

The TransitionGroup component lets us manage a set of transition components.

For example, we can use it by writing:

App.js

import React, { useState } from "react";
import { CSSTransition, TransitionGroup } from "react-transition-group";
import { v4 as uuidv4 } from "uuid";
import "./styles.css";

export default function App() {
  const [items, setItems] = useState([
    { id: uuidv4(), text: "eat" },
    { id: uuidv4(), text: "drink" },
    { id: uuidv4(), text: "sleep" },
    { id: uuidv4(), text: "walk" }
  ]);
  return (
    <div className="App">
      <TransitionGroup className="todo-list">
        {items.map(({ id, text }) => (
          <CSSTransition key={id} timeout={500} classNames="item">
            <div>
              <button
                className="remove-btn"
                variant="danger"
                size="sm"
                onClick={() =>
                  setItems((items) => items.filter((item) => item.id !== id))
                }
              >
                &times;
              </button>
              {text}
            </div>
          </CSSTransition>
        ))}
      </TransitionGroup>
    </div>
  );
}

styles.css

.remove-btn {
  margin-right: 0.5rem;
}

.item-enter {
  opacity: 0;
}
.item-enter-active {
  opacity: 1;
  transition: opacity 500ms ease-in;
}
.item-exit {
  opacity: 1;
}
.item-exit-active {
  opacity: 0;
  transition: opacity 500ms ease-in;
}

We have an items state that has an array of items as its initial value.

Then we use that with the TransitionGroup component to display transitions for each item rendered inside it.

Inside it, we have the CSSTransition component to render the transition according to the styles.

When we click on the button, we remove the current item by calling setItems function.

Now when we click on the ‘x’, we see the transition as the item disappears.

Conclusion

We can add transitions to a group of items with the TransitionGroup component.

The SwitchTransition lets us render transitions between state changes.

Categories
React

Add Animation with the React Transition Group Library

With the react-spring library, we can render animations in our React app easily.

In this article, we’ll take a look at how to get started with the React Transition Group.

Getting Started

We can install the library by running:

npm install react-transition-group --save

with NPM or:

yarn add react-transition-group

with Yarn.

Transition

We can add transitions by using the Transition component.

For example, we can write:

import React, { useState } from "react";
import { Transition } from "react-transition-group";

const duration = 300;

const defaultStyle = {
  transition: `opacity ${duration}ms ease-in-out`,
  opacity: 0
};

const transitionStyles = {
  entering: { opacity: 1 },
  entered: { opacity: 1 },
  exiting: { opacity: 0 },
  exited: { opacity: 0 }
};

const Fade = ({ in: inProp }) => (
  <Transition in={inProp} timeout={duration}>
    {(state) => (
      <div
        style={{
          ...defaultStyle,
          ...transitionStyles[state]
        }}
      >
        I'm a fade Transition!
      </div>
    )}
  </Transition>
);

export default function App() {
  const [show, setShow] = useState(false);

  return (
    <div className="App">
      <button onClick={() => setShow(!show)}>toggle</button>
      <Fade in={show} />
    </div>
  );
}

We create the Fade component with the Transition component inside it to create the transition.

We set the defaultStyle to set the default style.

Then transitionStyles has the styles to add based on the transition state.

The 2 styles together lets us apply the styles dynamically for to create the fade transition.

In the App component, we have the button to toggle the show state.

Then in the Fade transition, we pass the show state as the value of the in prop to show the enter transition when show is true .

The timeout sets the duration of the transition.

Now when we click on the toggle button, we see the item text toggled with the fade transition.

CSSTransition

The CSSTransition component lets us animate components with external CSS.

For example, we can write:

App.js

import React, { useState } from "react";
import { CSSTransition } from "react-transition-group";
import "./styles.css";

export default function App() {
  const [show, setShow] = useState(false);

  return (
    <div className="App">
      <button type="button" onClick={() => setShow(!show)}>
        toggle
      </button>
      <CSSTransition in={show} timeout={200} classNames="my-node">
        <div>I'll receive my-node-* classes</div>
      </CSSTransition>
    </div>
  );
}

styles.css

.my-node-enter {
  opacity: 0;
}
.my-node-enter-active {
  opacity: 1;
  transition: opacity 200ms;
}
.my-node-exit {
  opacity: 1;
}
.my-node-exit-active {
  opacity: 0;
  transition: opacity 200ms;
}

We have the show state again.

And we add the styles for each stage of the transition with the styles.css file.

The CSSTransition component takes the in prop as it does with the Transition component.

timeout has the duration of the transition duration.

classNames has the class name prefix for the transition.

Now when we click on the toggle button, we see the item text flash.

Conclusion

We can add transition effects easily with the React Transition Group library.