Categories
React

Create Auto-Resizeable Lists and Grid with the react-virtualized Library

The react-virtualized package lets us display a virtualized list.

We can use it with the AutoSizer component to create a virtualized list that resizes the item.

In this article, we’ll look at how to create automatically resizeable lists and grids with the react-virtualized library.

Installation

To install it, we run:

npm i react-virtualized

AutoSizer

We can use the AutoSizer component to add the auto-resizable list.

For example, we can write:

import React from "react";
import { AutoSizer, List } from "react-virtualized";
import "react-virtualized/styles.css";

const list = Array(1000)
  .fill(0)
  .map((_, i) => i);

function rowRenderer({ key, index, style }) {
  return (
    <div key={key} style={style}>
      {list[index]}
    </div>
  );
}

export default function App() {
  return (
    <div style={{ height: "100vh" }}>
      <AutoSizer>
        {({ height, width }) => (
          <List
            height={height}
            rowCount={list.length}
            rowHeight={20}
            rowRenderer={rowRenderer}
            width={width}
          />
        )}
      </AutoSizer>
    </div>
  );
}

We create a list with the AutoSizer component with a render prop inside it.

We get the height and width from the parameter and then pass that into the List component’s height component to set the width and height of the list.

We set the rowHeight prop to set the row height of each entry.

rowRendered has a function which has the key , index and style properties from the parameter and we use that to render the entry.

index has the index of the entry.

key has the unique key of the row.

Now when we resize the screen, we see the list resize with the screen.

Grid

We can add a grid with react-virtualize’s Grid component.

For instance, we can write:

import React from "react";
import "react-virtualized/styles.css";
import { Grid } from "react-virtualized";

let list = [];
let inner = [];
let width = 500;
let height = 100;
let xCoord = 0;
let yCoord = 0;

for (let i = 0; i < 1000; i++) {
  do {
    xCoord = Math.floor(Math.random() * width);
    yCoord = Math.floor(Math.random() * height);
  } while ((xCoord <= 0) | (yCoord <= 0));

if (xCoord > 0 && yCoord > 0) {
    inner.push(xCoord);
    inner.push(yCoord);
    list.push(inner);
  }

inner = [];
}

function cellRenderer({ columnIndex, key, rowIndex, style }) {
  return (
    <div key={key} style={style}>
      {list[rowIndex][columnIndex]}
    </div>
  );
}
export default function App() {
  return (
    <div>
      <Grid
        cellRenderer={cellRenderer}
        columnCount={list[0].length}
        columnWidth={100}
        height={300}
        rowCount={list.length}
        rowHeight={30}
        width={300}
      />
    </div>
  );
}

We have the data in the list nested array.

The cellRenderer component lets us render the nested array into the grid.

We also set the columnCount to the length of the first nested array.

And we set the columnWidth to set the column width.

The height is the height of the grid.

rowCount has the row count.

rowHeight has the row height.

width has the grid width.

Then we see the nested list rendered on the screen.

Conclusion

We can create an auto-resizable list and grids with the react-virtualized library.

Categories
React

Animation with the React Animation Library — Loading Animation and Easings

With the React Animation 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 Animation library.

HideUntilLoaded

We can hide the content until a URL is loaded with the HideUntilLoaded component.

For example, we can write:

import React from "react";
import { HideUntilLoaded } from "react-animation";

export default function App() {
  return (
    <>
      <HideUntilLoaded imageToLoad="https://i.picsum.photos/id/23/200/300.jpg?hmac=NFze_vylqSEkX21kuRKSe8pp6Em-4ETfOE-oyLVCvJo">
        your content
      </HideUntilLoaded>
    </>
  );
}

We use the HideUntilLoaded component with the imageToLoad prop to wait for the image with the given URL to load until the content inside it is displayed.

We can add a spinner that’s displayed when the image with the given URL is loaded with the Spinner prop.

For instance, we can write:

import React from "react";
import { HideUntilLoaded } from "react-animation";

export default function App() {
  return (
    <>
      <HideUntilLoaded
        imageToLoad="https://i.picsum.photos/id/23/200/300.jpg?hmac=NFze_vylqSEkX21kuRKSe8pp6Em-4ETfOE-oyLVCvJo"
        Spinner={() => <div>Loading...</div>}
      >
        your content
      </HideUntilLoaded>
    </>
  );
}

We add the Spinner prop with a function that returns the JSX for the loading indicator.

The animation effect can be changed with the animationIn prop.

For example, we can write:

import React from "react";
import { HideUntilLoaded } from "react-animation";

export default function App() {
  return (
    <>
      <HideUntilLoaded
        animationIn="bounceIn"
        imageToLoad="https://i.picsum.photos/id/23/200/300.jpg?hmac=NFze_vylqSEkX21kuRKSe8pp6Em-4ETfOE-oyLVCvJo"
        Spinner={() => <div>Loading...</div>}
      >
        your content
      </HideUntilLoaded>
    </>
  );
}

We change the animation effect that’s displayed when the content is loading with the animationIn prop.

AnimateGroup

The AnimateGroup component lets us animate components being added, removed, or modified within a group of components.

For instance, we can write:

import React, { useState, useEffect } from "react";
import { AnimateGroup } from "react-animation";

export default function App() {
  const [nums, setNums] = useState([1, 2]);

  useEffect(() => {
    const timer = setInterval(() => {
      setNums((nums) => [...nums, nums[nums.length - 1] + 1]);
    }, 1500);

    return () => clearInterval(timer);
  }, []);

  return (
    <>
      <ul>
        <AnimateGroup animation="bounce">
          {nums.map((word) => (
            <li key={word}>{word}</li>
          ))}
        </AnimateGroup>
      </ul>
    </>
  );
}

to add the nums state and animate it with the AnimationGroup .

We set the animation prop to 'bounce' so that when we add an entry to nums , we’ll see the bounce effect rendered on the entry being added.

The useEffect callback adds an entry to nums by calling the setNums function.

We add a new entry to nums every 1500ms by calling setInterval .

Animations

We can add animations with our own styling by using the anuimations object.

For example, we can write:

import React from "react";
import { animations } from "react-animation";

export default function App() {
  return (
    <>
      <div style={{ animation: animations.popIn }}>hello world</div>
    </>
  );
}

to render the popIn effect when we mount the div with the animation.popIn property.

popIn is 'pop-in 500ms cubic-bezier(0.19, 1, 0.22, 1) forwards’ .

Easings

We can set the timing function for our animation with the easings object.

To do this, we write:

import React from "react";
import { easings } from "react-animation";

const style = {
  animation: `pop-in ${easings.easeOutExpo} 500ms forwards`
};
export default function App() {
  return (
    <>
      <div style={style}>hello world</div>
    </>
  );
}

We pass the easings.easeOutExpo string into our animation style string.

Then we apply the easing in our animation.

Conclusion

We can apply various animation effects with the React Animation library.

Categories
React

Add Animation with the React Animation Library

With the React Animation 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 Animation library.

Installation

We can install the library by running:

npm install -s react-animation

Then we can use the provided components to add animation to our React apps.

AnimateOnChange

We can use the AnimateOnChange library to animate new content when the content changes.

We can a string or any child components inside it.

For example, we can write:

import React, { useState } from "react";
import { AnimateOnChange } from "react-animation";

export default function App() {
  const [count, setCount] = useState(0);

  return (
    <>
      <p>
        <button onClick={() => setCount((count) => count + 1)}>
          increment
        </button>
      </p>
      <AnimateOnChange>{count}</AnimateOnChange>
    </>
  );
}

We have the count state.

And the state is updated with the increment button.

We render the count in AnimateOnChange so we see some transition effect when we click the increment button.

The default transition effect is the fade effect.

We can set the duration of the animation with the durationOut prop:

import React, { useState } from "react";
import { AnimateOnChange } from "react-animation";

export default function App() {
  const [count, setCount] = useState(0);

  return (
    <>
      <p>
        <button onClick={() => setCount((count) => count + 1)}>
          increment
        </button>
      </p>
      <AnimateOnChange durationOut="1000">{count}</AnimateOnChange>
    </>
  );
}

The duration is in milliseconds.

The default value is 200.

We can change the animation effect rendered with the animationIn and animationOut props.

For example, we can write:

import React, { useState } from "react";
import { AnimateOnChange } from "react-animation";

export default function App() {
  const [count, setCount] = useState(0);

return (
    <>
      <p>
        <button onClick={() => setCount((count) => count + 1)}>
          increment
        </button>
      </p>
      <AnimateOnChange
        animationIn="bounceIn"
        animationOut="bounceOut"
        durationOut={500}
      >
        {count}
      </AnimateOnChange>
    </>
  );
}

We set the animationIn to set the effect to render when new content enters.

The animationOut sets the effect to render when existing content leaves.

Content is styled as inline-block by default, but we can override that by setting the style prop.

Custom Animations

We can add custom animations to the animationIn and animationOut props.

For instance, we can write:

import React, { useState } from "react";
import { AnimateOnChange } from "react-animation";

export default function App() {
  const [count, setCount] = useState(0);

  return (
    <>
      <p>
        <button onClick={() => setCount((count) => count + 1)}>
          increment
        </button>
      </p>
      <AnimateOnChange
        animationIn="custom-animation-in 500ms ease-out forwards"
        animationOut="custom-animation-out 500ms ease-out forwards"
        durationOut={500}
      >
        {count}
      </AnimateOnChange>
    </>
  );
}

We set the animationIn and animationOut props with the specific effects to render.

Then we would see them displayed when count changes.

Conclusion

We can add simple animations easily to our React app with the React Animation library.

Categories
React

Add Animation with the react-motion Library

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

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

Getting Started

We can install the package by running:

npm install --save react-motion

Motion

The Motion component lets us create the animation with the easing function of our choice.

For example, we can write:

import React, { useState } from "react";
import { Motion, spring } from "react-motion";

export default function App() {
  const [click, setClick] = useState(false);
  return (
    <>
      <button onClick={() => setClick(!click)}>toggle</button>
      <Motion defaultStyle={{ x: 0 }} style={{ x: spring(click ? 30 : 0) }}>
        {({ x }) => (
          <div
            style={{
              transform: `translateX(${x}px)`
            }}
          >
            hello world
          </div>
        )}
      </Motion>
    </>
  );
}

to move the div when we click on the toggle button.

The Motion component wraps around the items that we want to animate.

The defaultStyle prop has the default styles.

And the Motion component’s style prop has the style that’s applied when animation.

Then we can get the x value in the render prop and then use it in our content.

The spring function renders the x value that’s applied when we run the animation.

We can animate more than one style.

For example, we can write:

import React, { useState } from "react";
import { Motion, spring } from "react-motion";

export default function App() {
  return (
    <>
      <Motion
        defaultStyle={{ x: 0, y: 0 }}
        style={{ x: spring(10), y: spring(20) }}
      >
        {({ x, y }) => (
          <div
            style={{
              transform: `translateX(${x}px) translateY(${y}px)`
            }}
          >
            hello world
          </div>
        )}
      </Motion>
    </>
  );
}

to animate the x and y values and use them with the div.

StaggeredMotion

The StaggeredMotion component animates a collection of fixed lengths whose values depend on each other.

To use it, we can write:

import React from "react";
import { spring, StaggeredMotion } from "react-motion";

export default function App() {
  return (
    <>
      <StaggeredMotion
        defaultStyles={[{ h: 0 }, { h: 0 }, { h: 0 }]}
        styles={(prevInterpolatedStyles) =>
          prevInterpolatedStyles.map((_, i) => {
            return i === 0
              ? { h: spring(100) }
              : { h: spring(prevInterpolatedStyles[i - 1].h) };
          })
        }
      >
        {(interpolatingStyles) => (
          <div>
            {interpolatingStyles.map((style, i) => (
              <div key={i} style={{ border: "1px solid", height: style.h }} />
            ))}
          </div>
        )}
      </StaggeredMotion>
    </>
  );
}

to create 3 divs that are stacked on top of each other.

The height of each is animated so that their height increases up to 100px each.

We pass in an array to the defaultStyles prop to set the initial styles for each div,

Then in the styles prop, we create a function to get the previously interpolated styles from the parameter.

Then we return the object with the height style to animate with depending on the index of the element that’s animated.

In the render prop, we get the interpolatingStyles and apply them to the div.

Conclusion

We can create simple animations with the react-motion library.

Categories
React

Animation with the react-motion Library — Transitions

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

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

TransitionMotion

We can add component mounting and unmounting animation with the TransitionMotion component.

For instance, we can write:

import React, { useEffect, useState } from "react";
import { spring, TransitionMotion } from "react-motion";

export default function App() {
  const [items, setItems] = useState([
    { key: "a", size: 10 },
    { key: "b", size: 20 },
    { key: "c", size: 30 }
  ]);

  const willLeave = () => {
    return { width: spring(0), height: spring(0) };
  };

  useEffect(() => {
    setItems([
      { key: "a", size: 10 },
      { key: "b", size: 20 }
    ]);
  }, []);

  return (
    <>
      <TransitionMotion
        willLeave={willLeave}
        styles={items.map((item) => ({
          key: item.key,
          style: { width: item.size, height: item.size }
        }))}
      >
        {(interpolatedStyles) => (
          <div>
            {interpolatedStyles.map((config) => {
              return (
                <div
                  key={config.key}
                  style={{ ...config.style, border: "1px solid" }}
                />
              );
            })}
          </div>
        )}
      </TransitionMotion>
    </>
  );
}

We use the TransitionMotion component to render a transition effect that’s shown when we remove the bottom div.

We create the willLeave function to return the effect that we want to show.

And we pass that into the willLeave prop.

The styles prop has the styles for each item.

The key property is required to identify the correct item when animating.

We animate their width and height .

The render prop has the divs that we want to render.

We get their styles from the interpolatingStyles parameter.

And we apply the styles form them by passing that into he style prop.

We can change how the spring animation works by passing in a 2nd argument.

For instance, we can write:

import React, { useEffect, useState } from "react";
import { spring, TransitionMotion } from "react-motion";

export default function App() {
  const [items, setItems] = useState([
    { key: "a", size: 10 },
    { key: "b", size: 20 },
    { key: "c", size: 30 }
  ]);

  const willLeave = () => {
    return {
      width: spring(0, { stiffness: 120, damping: 17 }),
      height: spring(0, { stiffness: 120, damping: 17 })
    };
  };

  useEffect(() => {
    setItems([
      { key: "a", size: 10 },
      { key: "b", size: 20 }
    ]);
  }, []);

  return (
    <>
      <TransitionMotion
        willLeave={willLeave}
        styles={items.map((item) => ({
          key: item.key,
          style: { width: item.size, height: item.size }
        }))}
      >
        {(interpolatedStyles) => (
          <div>
            {interpolatedStyles.map((config) => {
              return (
                <div
                  key={config.key}
                  style={{ ...config.style, border: "1px solid" }}
                />
              );
            })}
          </div>
        )}
      </TransitionMotion>
    </>
  );
}

We set the stiffness and damping to change how the animation is rendered.

We can also add the precision property to specify both the rounding of the interpolated value and the speed.

Conclusion

We can use the TransitionComponent to render transition effects in our React component.