Categories
Vue 3

Vue 3 — More Complex Props

Vue 3 is the up and coming version of Vue front end framework.

It builds on the popularity and ease of use of Vue 2.

In this article, we’ll look at how to use props with Vue 3.

Passing a Number

We can pass in numbers to props.

For instance, we can write:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://unpkg.com/vue@next"></script>
  </head>
  <body>
    <div id="app">
      <blog-post v-for="post of posts" :likes="post.likes"></blog-post>
    </div>
    <script>
      const app = Vue.createApp({
        data() {
          return {
            posts: [{ title: "hello world", author: "james", likes: 100 }]
          };
        }
      }); 
      app.component("blog-post", {
        props: {
          likes: Number
        },
        template: `<p>{{likes}}</p>`
      }); 
      app.mount("#app");
    </script>
  </body>
</html>

to create the blog-post component that takes the likes prop.

likes is a number, so we’ve to put the : before the likes to let us pass in an expression.

We can also pass in a number literal:

<blog-post :likes="100"></blog-post>

Passing a Boolean

To pass in a boolean, we can write:

<blog-post is-published></blog-post>

to pass in true to the is-published prop.

To pass in false , we’ve write out the whole expression:

<blog-post :is-published='false'></blog-post>

And we can pass in other expressions.

Passing an Array

We can pass in an array literal as a prop value.

So we can write:

<blog-post :comment-ids="[1, 2, 3]"></blog-post>

or we can write:

<blog-post :comment-ids="post.commentIds"></blog-post>

Passing an Object

Vue props can take objects.

So we can write:

<blog-post
  :author="{
    firstName: 'james',
    lastName: 'smith'
  }"
></blog-post>

We pass in an object to the author prop.

The : tells Vue that the object isn’t a string.

We can also pass in another expression that returns an object.

Passing the Properties of an Object

To pass in the properties of an object as props, we can use the v-bind without the argument.

For example, we can write:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://unpkg.com/vue@next"></script>
  </head>
  <body>
    <div id="app">
      <blog-post v-for="post of posts" v-bind="post"></blog-post>
    </div>
    <script>
      const app = Vue.createApp({
        data() {
          return {
            posts: [{ title: "hello world", author: "james", likes: 100 }]
          };
        }
      }); 
      app.component("blog-post", {
        props: {
          title: String,
          author: String,
          likes: Number
        },
        template: `
          <div>
            <h1>{{title}}</h1>
            <p>author: {{author}}</p>
            <p>likes: {{likes}}</p>
          </div>
        `
      }); 
      app.mount("#app");
    </script>
  </body>
</html>

Then the properties of post will be passed into blog-post as prop values.

The property names are the prop names.

This is a shorthand for:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://unpkg.com/vue@next"></script>
  </head>
  <body>
    <div id="app">
      <blog-post
        v-for="post of posts"
        :title="post.title"
        :author="post.author"
        :likes="post.likes"
      ></blog-post>
    </div>
    <script>
      const app = Vue.createApp({
        data() {
          return {
            posts: [{ title: "hello world", author: "james", likes: 100 }]
          };
        }
      }); 
      app.component("blog-post", {
        props: {
          title: String,
          author: String,
          likes: Number
        },
        template: `
          <div>
            <h1>{{title}}</h1>
            <p>author: {{author}}</p>
            <p>likes: {{likes}}</p>
          </div>
        `
      }); 
      app.mount("#app");
    </script>
  </body>
</html>

As we can see, it’s much longer and a lot more repetitive than the shorthand.

Conclusion

We can pass in various kinds of data easily with Vue components.

We just need to use v-bind or : for short.

Categories
React

Animate with the react-spring Library — Parallax Scrolling and Performance

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 react-spring.

Parallax

The Parallax component lets us create a scroll container.

Inside it, we add the ParallaxLayer component to let react-spring take care of moving them.

For example, we can write:

import React from "react";
import { Parallax, ParallaxLayer } from "react-spring/renderprops-addons";

export default function App() {
  return (
    <div>
      <Parallax
        pages={2}
        scrolling={false}
        horizontal
        ref={(ref) => (this.parallax = ref)}
      >
        <ParallaxLayer
          offset={0}
          speed={0.1}
          onClick={() => this.parallax.scrollTo(1)}
          style={{
            display: "flex",
            alignItems: "center",
            justifyContent: "center"
          }}
        >
          <img
            src="https://i.picsum.photos/id/23/200/300.jpg?hmac=NFze_vylqSEkX21kuRKSe8pp6Em-4ETfOE-oyLVCvJo"
            style={{ width: "20%" }}
          />
        </ParallaxLayer>

<ParallaxLayer
          offset={1}
          speed={0.1}
          onClick={() => this.parallax.scrollTo(0)}
          style={{
            display: "flex",
            alignItems: "center",
            justifyContent: "center"
          }}
        >
          <img
            src="https://i.picsum.photos/id/24/200/300.jpg?hmac=UogR0hFxP5yLDwcZpCawObw8Bzm9vnzci_7eMrbqn_s"
            style={{ width: "40%" }}
          />
        </ParallaxLayer>
      </Parallax>
    </div>
  );
}

to add images into our page.

When we click it, the this.parallax.scrollTo method runs, and we’ll go to the image with the given offset.

Improve Performance

We can improve performance with various tweaks.

We can add the native flag with expensive animations to improve animation performance.

For example, we can write:

import React from "react";
import { Spring, animated } from "react-spring/renderprops";

export default function App() {
  return (
    <div>
      <Spring native from={{ opacity: 0 }} to={{ opacity: 1 }}>
        {(props) => <animated.div style={props}>hello</animated.div>}
      </Spring>
    </div>
  );
}

We add the native prop to improve the performance of our animation.

This prop can also be used for inner text animation:

import React from "react";
import { Spring, animated } from "react-spring/renderprops";

export default function App() {
  return (
    <div>
      <Spring native from={{ number: 0 }} to={{ number: 1 }}>
        {(props) => <animated.div>{props.number}</animated.div>}
      </Spring>
    </div>
  );
}

And we can use it with scrolling animation:

import React from "react";
import { Spring, animated } from "react-spring/renderprops";

export default function App() {
  return (
    <div>
      <Spring native from={{ scroll: 0 }} to={{ scroll: 250 }}>
        {(props) => (
          <animated.div
            scrollTop={props.scroll}
            style={{ overflowY: "scroll", height: 300 }}
          >
            {Array(100)
              .fill()
              .map((_, i) => (
                <p key={i}>{i}</p>
              ))}
          </animated.div>
        )}
      </Spring>
    </div>
  );
}

We can also use it with Trail and Transition components.

Interpolation

We can also use the native prop with interpolation.

For example, we can write:

import React from "react";
import { Spring, animated, interpolate } from "react-spring/renderprops";

export default function App() {
  return (
    <div>
      <Spring
        native
        from={{ o: 0, xyz: [0, 0, 0], color: "red" }}
        to={{ o: 1, xyz: [10, 20, 5], color: "green" }}
      >
        {({ o, xyz, color }) => (
          <animated.div
            style={{
              color,
              background: o.interpolate((o) => `rgba(210, 57, 77, ${o})`),
              transform: xyz.interpolate(
                (x, y, z) => `translate3d(${x}px, ${y}px, ${z}px)`
              ),
              border: interpolate(
                [o, color],
                (o, c) => `${o * 10}px solid ${c}`
              ),
              padding: o
                .interpolate({ range: [0, 0.5, 1], output: [0, 0, 10] })
                .interpolate((o) => `${o}%`),
              opacity: o.interpolate([0.1, 0.2, 0.6, 1], [1, 0.1, 0.5, 1])
            }}
          >
            {o.interpolate((n) => n.toFixed(2))}
          </animated.div>
        )}
      </Spring>
    </div>
  );
}

We pass in a function to let us interpolate the styles for animation with the interpolate method.

And we add the native prop to speed that up.

Conclusion

We can add the native prop to speed up our react-spring animation.

Also, we can add parallax scrolling with the Parallax component.

Categories
React

Animate with the react-spring Library — Keyframes

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 react-spring.

Animate Mounting or Unmounting Components

We can animate mounting or unmounting components.

For example, we can write:

import React, { useState } from "react";
import { Transition } from "react-spring/renderprops";

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

  return (
    <div>
      <button onClick={() => set(!show)}>toggle</button>
      <Transition
        items={show}
        from={{ opacity: 0 }}
        enter={{ opacity: 1 }}
        leave={{ opacity: 0 }}
      >
        {(show) =>
          show &&
          ((props) => (
            <div style={props}>
              <span role="img" aria-label="smile">
                ✌
              </span>
              ️
            </div>
          ))
        }
      </Transition>
    </div>
  );
}

to show the emoji when the show state is true .

We get the show state from the Transition component’s items prop.

The from , enter , and leave props have the styles to show when the animation starts, when the item enters the screen, and when it leaves the screen respectively.

The props parameter has the styles that we’re rendering during animation.

Keyframes

The Keyframes component lets us chain, compose, and orchestrate animations.

For example, we can write:

import React from "react";
import { config, Keyframes } from "react-spring/renderprops";

const delay = (ms) => new Promise((resolve) => resolve, ms);

const Container = Keyframes.Spring({
  show: { opacity: 1 },
  showAndHide: [{ color: "green" }, { color: "red" }],
  wiggle: async (next, cancel, ownProps) => {
    await next({ x: 100, config: config.wobbly });
    await delay(1000);
    await next({ x: 0, config: config.gentle });
  }
});

export default function App() {
  return (
    <div>
      <Container state="showAndHide">
        {(styles) => <div style={styles}>Hello</div>}
      </Container>
    </div>
  );
}

Then we animate our text from green to red since we have the showAndHide property with an array of styles for the start and end of the animation respectively.

We use the Container component, which is created from the Keyframes.Spring function.

The state is set to the property name with the keyframes that we want to animate.

We can also specify one keyframe with an object, or an async function with the next , cancel , and ownProps parameters.

next is called with the animation config and styles to apply.

We can also pass in a function to Keyframes.Spring to create the animation.

For instance, we can write:

import React from "react";
import { Keyframes } from "react-spring/renderprops";

const Script = Keyframes.Spring(async (next) => {
  while (true) {
    await next({ color: "red", from: { color: "green" }, reset: true });
  }
});

export default function App() {
  return (
    <div>
      <Script>{(styles) => <div style={styles}>Hello</div>}</Script>
    </div>
  );
}

We pass the callback into Keyframes.Spring that calls next to toggles color between red and green.

Also, we can pass in an array into Keyframes.Spring to add the keyframes by writing:

import React from "react";
import { Keyframes } from "react-spring/renderprops";

const Chain = Keyframes.Spring([{ color: "red" }, { color: "green" }]);

export default function App() {
  return (
    <div>
      <Chain>{(styles) => <div style={styles}>Hello</div>}</Chain>
    </div>
  );
}

Conclusion

We can add keyframes to our animations with react-spring’s Keyframes.Spring function.

Categories
React

Animate with the react-spring Library — Trail and Transition Components

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 react-spring.

Trail

The Trail component is used to animate the first item of a list of elements.

The rest form a natural trail and follow the previous sibling.

For example, we can write:

import React from "react";
import { Trail } from "react-spring/renderprops";

const items = [
  { text: 1, key: 1 },
  { text: 2, key: 2 },
  { text: 3, key: 3 }
];

export default function App() {
  return (
    <div>
      <Trail
        items={items}
        keys={(item) => item.key}
        from={{ transform: "translate3d(0,-40px,0)" }}
        to={{ transform: "translate3d(0,0px,0)" }}
      >
        {(item) => (props) => <div style={props}>{item.text}</div>}
      </Trail>
    </div>
  );
}

We use the Trail component with the items prop to.

It takes an array of data we want to render.

keys takes a function which returns the key value.

from takes an object that lets us apply the styles at the start of the animation.

to has an object that lets us apply the styles at the end of the animation.

The render prop is a function that takes the item parameter and returns a function that takes the props parameter and returns the JSX to render.

props has the style that is applied during the animation.

Now we should see the numbers slide down to the page when we mount the component.

Transition

The Transition component animates the component lifecycles as the component mounts, unmounts, or changes.

For example, we can use it by writing:

import React from "react";
import { Transition } from "react-spring/renderprops";

const items = [
  { text: 1, key: 1 },
  { text: 2, key: 2 },
  { text: 3, key: 3 }
];

export default function App() {
  return (
    <div>
      <Transition
        items={items}
        keys={(item) => item.key}
        from={{ transform: "translate3d(0,-40px,0)" }}
        enter={{ transform: "translate3d(0,0px,0)" }}
        leave={{ transform: "translate3d(0,-40px,0)" }}
      >
        {(item) => (props) => <div style={props}>{item.text}</div>}
      </Transition>
    </div>
  );
}

We have the Transition component that takes the items with the items to render.

keys has a function to return the unique key from the object.

from has the styles when we start the animation.

enter has the styles when the items enter the screen.

And leave has the styles when the items leave the screen.

Now we should see the number slide down the screen.

We can also use it to animate toggling between components.

For instance, we can write:

import React, { useState } from "react";
import { Transition } from "react-spring/renderprops";

export default function App() {
  const [toggle, set] = useState(false);

return (
    <div>
      <button onClick={() => set(!toggle)}>toggle</button>
      <Transition
        items={toggle}
        from={{ position: "absolute", opacity: 0 }}
        enter={{ opacity: 1 }}
        leave={{ opacity: 0 }}
      >
        {(toggle) =>
          toggle
            ? (props) => (
                <div style={props}>
                  <span role="img" aria-label="smile">
                    ?
                  </span>
                </div>
              )
            : (props) => (
                <div style={props}>
                  <span role="img" aria-label="smile">
                    ?
                  </span>
                </div>
              )
        }
      </Transition>
    </div>
  );
}

We have the useState hook to create the toggle state.

We toggle that with the toggle button.

In the Transition component, we get the value of the toggle state.

Then we use that value to render the emoticon we want.

The enter and leave styles are set in the enter and leave props.

Conclusion

We can use the Trail component to render animation of multiple the first item with the rest following it.

The Transition component lets us render the component lifecycle.

Categories
React

Animate with the react-spring Library — Customize Spring Component

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 react-spring.

Spring Component and Interpolation

We can use the Spring component to interpolate anything.

For example, we can write:

import React from "react";
import { Spring } from "react-spring/renderprops";

export default function App() {
  return (
    <div>
      <Spring
        from={{
          width: 100,
          padding: 0,
          background: "linear-gradient(to right, #30e8bf, #ff8235)",
          transform: "translate3d(400px,0,0) scale(2) rotateX(90deg)",
          boxShadow: "0px 100px 150px -10px #2D3747",
          borderBottom: "0px solid white",
          shape: "M20,380 L380,380 L380,380 L200,20 L20,380 Z",
          textShadow: "0px 5px 0px white"
        }}
        to={{
          width: "auto",
          padding: 20,
          background: "linear-gradient(to right, #009fff, #ec2f4b)",
          transform: "translate3d(0px,0,0) scale(1) rotateX(0deg)",
          boxShadow: "0px 10px 20px 0px rgba(0,0,0,0.4)",
          borderBottom: "10px solid #2D3747",
          shape: "M20,20 L20,380 L380,380 L380,20 L20,20 Z",
          textShadow: "0px 5px 15px rgba(255,255,255,0.5)"
        }}
      >
        {(props) => <div style={props}></div>}
      </Spring>
    </div>
  );
}

We have the from prop with the initial styles that we apply to the render props function’s div.

We also have the to prop with the styles that are applied when the animation is done.

props has the styles that are computed during the animation.

And we apply them by passing them into the style prop.

Spring Component Config

We can configure the Spring component with some preset values.

They include:

  • config.default — { tension: 170, friction: 26 }
  • config.gentle — { tension: 120, friction: 14 }
  • config.wobbly — { tension: 180, friction: 12 }
  • config.stiff — { tension: 210, friction: 20 }
  • config.slow — { tension: 280, friction: 60 }
  • config.molasses — { tension: 280, friction: 120 }

For example, we can write:

import React from "react";
import { config, Spring } from "react-spring/renderprops";

export default function App() {
  return (
    <div>
      <Spring config={config.wobbly} from={{ opacity: 0 }} to={{ opacity: 1 }}>
        {(props) => <div style={props}>hello</div>}
      </Spring>
    </div>
  );
}

to set the configuration with the config prop.

The following properties can be configured:

  • mass — spring-mass, defaults to 1
  • tension —spring energetic load, default value 170
  • friction — spring resistance, default value 26
  • clamp — when true, stops the spring once it overshoots its boundaries, defaults to false
  • precision —precision, defaults to 0.01
  • velocity — initial velocity, defaults to 0
  • delay — delay, defaults to 0
  • duration — if > than 0 will switch to a duration-based animation instead of spring physics, defaults to undefined
  • easing —linear by default, you can use any easing you want, defaults value is t => t

We can configure it with our own object:

import React from "react";
import { Spring } from "react-spring/renderprops";

export default function App() {
  return (
    <div>
      <Spring
        config={{ tension: 0, friction: 2, precision: 0.1 }}
        from={{ opacity: 0 }}
        to={{ opacity: 1 }}
      >
        {(props) => <div style={props}>hello</div>}
      </Spring>
    </div>
  );
}

And we can configure it with our own function:

import React from "react";
import { config, Spring } from "react-spring/renderprops";

export default function App() {
  return (
    <div>
      <Spring
        to={{ opacity: 1, width: 100, backgroundColor: "red" }}
        config={(key) => (key === "width" ? config.slow : config.wobbly)}
        from={{ opacity: 0, width: 0, backgroundColor: "red" }}
      >
        {(props) => <div style={props}>hello</div>}
      </Spring>
    </div>
  );
}

We get the key from the styles and return the config based on that.

Conclusion

We can use the Spring component with various styles and config to customize our animation.