Categories
React

Framer Motion — Keyframes and Gestures

With the Framer 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 Framer Motion.

Animation

We can use the animate prop to specify how to animate an element.

For example, we can write:

import React from "react";
import { motion } from "framer-motion";

export default function App() {
  return (
    <motion.div
      style={{ backgroundColor: "red", width: 100, height: 100 }}
      animate={{ scale: 2 }}
      transition={{ duration: 0.5 }}
    />
  );
}

We set animate to { scale: 2 } to double the size of the div.

The transition component is set to { duration: 0.5 } to set the duration of the animation in seconds.

Keyframes

We can add keyframes to create more complex animations.

For example, we can write:

import React from "react";
import { motion } from "framer-motion";

export default function App() {
  return (
    <motion.div
      style={{ backgroundColor: "red", width: 100, height: 100 }}
      animate={{
        scale: [1, 2, 2, 1, 1],
        rotate: [0, 0, 270, 270, 0],
        borderRadius: ["30%", "30%", "50%", "50%", "40%"]
      }}
    />
  );
}

We add the scale property to set the quality to scale the div by in each frame.

rotate sets the rotation of the div in degrees in each frame.

borderRadius sets the border radius of the div in each frame.

Each entry an array is a quantity in a frame.

Variants

We can set predefined visual states in which a component can be in.

For instance, we can write:

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

const variants = {
  open: { opacity: 1, x: 0 },
  closed: { opacity: 0, x: "-100%" }
};

export default function App() {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <>
      <button onClick={() => setIsOpen(!isOpen)}>toggle</button>
      <motion.nav animate={isOpen ? "open" : "closed"} variants={variants}>
        <p>foo</p>
      </motion.nav>
    </>
  );
}

to add animation when we toggle click on the toggle button to toggle the nav on and off.

The variants object have the style that the motion.nav can be in in different animation stages.

If it’s open , then opacity is 1, and x is 0.

And if it’s closed , then opacity is 0 and x is '-100%' .

Now we should see the ‘foo’ text move when we click on toggle.

Gesture Animations

We can listen to various gestures and animate elements when various gestures are applied.

For instance, we can write:

import React from "react";
import { motion } from "framer-motion";

export default function App() {
  return (
    <>
      <motion.div
        whileHover={{ scale: 1.1 }}
        whileTap={{ scale: 0.9 }}
        style={{ backgroundColor: "red", width: 100, height: 100 }}
      ></motion.div>
    </>
  );
}

to listen for hovers with the whileHover prop.

And we listen to taps with the whileTap prop.

Then we set the scale to change the size of the div when those gestures are applied.

Conclusion

We can add complex animations with keyframes, and animate when gestures are applied with Framer Motion.

Categories
React

Framer Motion — Animations and Gestures

With the Framer 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 Framer Motion.

Motion Components

We can add motion components to add elements that we can animate.

For example, we can write:

import React from "react";
import { motion } from "framer-motion";

export default function App() {
  return (
    <div className="App">
      <motion.div
        animate={{ scale: 0.5 }}
        style={{ backgroundColor: "red", width: 100, height: 100 }}
      />
    </div>
  );
}

to create a div that shrinks to half of the size that is specified in the style prop.

scale set to 0.5 does the shrinking with animation.

Animation

The animate prop lets us animate an element.

For example, we can write:

import React from "react";
import { motion } from "framer-motion";

export default function App() {
  const variants = {
    hidden: { opacity: 0 },
    visible: { opacity: 1 }
  };

  return (
    <motion.div
      initial="hidden"
      animate="visible"
      variants={variants}
      style={{ backgroundColor: "red", width: 100, height: 100 }}
    />
  );
}

to create a div with the motion.div component.

And we animate from opacity 0 to opacity 1.

The initial prop has the name of the initial state of the div.

animate has the name of the style of the div after the animation.

The variants prop has the variants object, which specifies the animation style for each state.

Gestures

Framer Motion can direct hover, tap, pan and drag gestures automatically.

So we can do things to an element when these gestures are applied.

For example, we can write:

import React from "react";
import { motion } from "framer-motion";

export default function App() {
  return (
    <motion.div
      drag="x"
      dragConstraints={{ left: -100, right: 100 }}
      whileHover={{ scale: 1.1 }}
      whileTap={{ scale: 0.9 }}
      style={{ backgroundColor: "red", width: 100, height: 100 }}
    />
  );
}

to let us drag the red div horizontally with the drag and dragConstraints props.

drag set to 'x' lets us drag horizontally. And dragConstraints lets us drag within the given bounds.

left sets the left limit and right sets the right limit.

whileHover has the style to change when we hover over the div.

whileTap lets us change the style when we tap on the div.

MotionValue

We can set motion values to set the style we want.

For example, we can write:

import React from "react";
import { motion, useMotionValue, useTransform } from "framer-motion";

export default function App() {
  const x = useMotionValue(0);
  const opacity = useTransform(x, [-200, 0, 200], [0, 1, 0]);

  return (
    <motion.div
      style={{ x, opacity, backgroundColor: "red", width: 100, height: 100 }}
      drag="x"
    />
  );
}

to let us animate the red div by changing the opacity when we drag it.

The useMotionValue prop creates a reactive property to watch form.

x is the horizontal position of the div.

The 2nd argument is the distance values.

And the 3rd argument is the opacity values that correspond to the distance values in the 2nd argument.

Conclusion

We can add basic animations with size and opacity changes and drag and drop effects with Framer Motion.

Categories
React

Add Animation to Our React App with the Framer Motion Library

With the Framer 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 Framer Motion.

Installation

We can install Framer Motion by running:

npm install framer-motion

Getting Started

We can create a div that moves by writing”

import React from "react";
import { motion } from "framer-motion";

export default function App() {
  return (
    <div className="App">
      <motion.div
        animate={{ x: 100 }}
        style={{ width: 100, height: 100, backgroundColor: "red" }}
      />
    </div>
  );
}

We set the animate prop to an object with the x property to move it horizontally.

Draggable Element

We can make an element draggable by using the drag and dragConstraints props.

To use them, we write:

import React from "react";
import { motion } from "framer-motion";

export default function App() {
  return (
    <div className="App">
      <motion.div
        drag="x"
        dragConstraints={{ left: -100, right: 100 }}
        style={{ width: 100, height: 100, backgroundColor: "red" }}
      />
    </div>
  );
}

We set drag to 'x' to let us drag and div horizontally.

And we add the dragConstraint prop to let us drag left 100px to right 100px.

We can animate lists by using the motion.ul and motion.li components.

For example, we can write:

import React from "react";
import { motion } from "framer-motion";

export default function App() {
  const list = { hidden: { opacity: 0 } };
  const item = { hidden: { x: -10, opacity: 0 } };

  return (
    <motion.ul animate="hidden" variants={list}>
      <motion.li variants={item}>foo</motion.li>
      <motion.li variants={item}>bar</motion.li>
      <motion.li variants={item}>baz</motion.li>
    </motion.ul>
  );
}

We set the variants prop to objects to let us hide the elements with various styles.

animate is set to hidden , which is the name of the animation.

We set the opacity to 0 to hide the items.

The x property is set to -10 to move the li elements 10px to the left.

We can combine drag and drop with animation by using various hooks that comes with Framer Motion.

For example, we can write:

import React from "react";
import { motion, useMotionValue, useTransform } from "framer-motion";

export default function App() {
  const x = useMotionValue(0);
  const opacity = useTransform(x, [-100, 0, 100], [0, 1, 0]);

  return (
    <motion.div
      drag="x"
      style={{ x, opacity, width: 100, height: 100, backgroundColor: "red" }}
    />
  );
}

to create a red div that animate when we drag it.

The useMotionValue prop lets us create a distance value that we pass into the style prop.

useTransform lets us change the opacity as the div is animated.

The first argument is the quantity to change.

The 2nd argument is the distance values.

And the 3rd argument is the opacity values that correspond to the distance values in the 2nd argument.

So when we drag left or right, the opacity of the div becomes 0.

Conclusion

We can add basic animations and drag and drop effects with Framer Motion.

Categories
Preact

Preact — Shallow Rendering, Pretty Print, and External DOM Mutations

Preact is a front end web framework that’s similar to React.

It’s smaller and less complex than React.

In this article, we’ll look at how to get started with front end development with Preact.

Shallow Rendering

We can shallow render one level of a component only with shallow rendering.

For example, we can write:

import { shallowRender } from "preact-render-to-string";
import { h } from "preact";

const Foo = () => <div>foo</div>;
const App = (
  <div class="foo">
    <Foo />
  </div>
);

console.log(shallowRender(App));

to render the App component without rendering the Foo component.

Then when we log the returned string, we get:

'<div class="foo"><Foo></Foo></div>'

logged.

Pretty Mode

We can render the string in a more human-friendly way with the pretty option.

To use it, we write:

import { render } from "preact-render-to-string";
import { h } from "preact";

const Foo = () => <div>foo</div>;
const App = (
  <div class="foo">
    <Foo />
  </div>
);

console.log(render(App, {}, { pretty: true }));

Then we see:

<div class="foo">
 <div>foo</div>
</div>

logged.

JSX Mode

The JSX rendering mode is useful if we’re doing any kind of snapshot testing.

It renders the output as if it’s written with JSX.

For example, we can write:

import render from "preact-render-to-string/jsx";
import { h } from "preact";

const App = <div data-foo={true} />;

console.log(render(App));

Then we see:

<div data-foo={true}></div>

logged.

External DOM Mutations

We can add external DOM mutation code in our component.

To do this, we have to disable the virtual DOM rendering and diffing algorithm so that it won’t undo any external DOM manipulations in a component.

For example, we can write:

import { Component, render } from "preact";

class Example extends Component {
  shouldComponentUpdate() {
    return false;
  }

  componentDidMount() {
    let thing = document.createElement("maybe-a-custom-element");
    this.base.appendChild(thing);
  }

  componentWillUnmount() {}

  render() {
    return <div class="example" />;
  }
}

const App = () => <Example />;

if (typeof window !== "undefined") {
  render(<App />, document.getElementById("root"));
}

We return false in shouldComponentUpdate to disable the virtual DOM diffing algorithm.

Then in componentDidMount , we call document.createElement to add a new element into the DOM.

Conclusion

We can shallow render and pretty print components rendered in a string.

Also, we can manipulate the DOM directly in our Preact components.

Categories
Preact

Preact — Create Web Component and Server Side Rendering

Preact is a front end web framework that’s similar to React.

It’s smaller and less complex than React.

In this article, we’ll look at how to get started with front end development with Preact.

Creating a Web Component

We can convert a Preact component into a web component with the preact-custom-element package.

For example, we can write:

import { render } from "preact";
import register from "preact-custom-element";

const Greeting = ({ name = "World" }) => <p>Hello, {name}!</p>;

register(Greeting, "x-greeting", ["name"]);

export default function App() {
  return <x-greeting name="Jane"></x-greeting>;
}

if (typeof window !== "undefined") {
  render(<App />, document.getElementById("root"));
}

to import the register function to register our Preact component as a web component.

We have the Greeting component which we register as the x-greeting custom element.

The 3rd argument has the attribute that x-greeting takes, which is the name attribute.

It’ll be interpolated into the p element in Greeting like we have with a regular Preact component.

In App , we use th x-greeting web component with the name prop set.

Then we see:

Hello, Jane!

displayed.

Observed Attributes

We have to make attributes observable so that it can respond to value changes.

To make them observable, we can write:

import { Component, render } from "preact";
import register from "preact-custom-element";

class Greeting extends Component {
  static tagName = "x-greeting";
  static observedAttributes = ["name"];

  render({ name }) {
    return <p>Hello, {name}!</p>;
  }
}
register(Greeting);

export default function App() {
  return <x-greeting name="Jane"></x-greeting>;
}

if (typeof window !== "undefined") {
  render(<App />, document.getElementById("root"));
}

We create our Greeting component.

Then we set the tagName static property to set its tag name.

And we set the observedAttributes to an array of attribute names to watch.

In App , we use the x-greeting component the same way.

If no observableAttributes are specified, then the data type of the attributes will be inferred from the keys of propTypes .

Setting the propTypes will make them observable.

For example, if we have:

import { render } from "preact";
import register from "preact-custom-element";

function FullName({ first, last }) {
  return (
    <span>
      {first} {last}
    </span>
  );
}

FullName.propTypes = {
  first: Object,
  last: Object
};

register(FullName, "full-name");
export default function App() {
  return <full-name first="Jane" last="Smith"></full-name>;
}

if (typeof window !== "undefined") {
  render(<App />, document.getElementById("root"));
}

We set the first and last prop types to Object and they’ll be made observable.

Server-Side Rendering

We can render Preact components to strings.

This lets us render content on the server-side, which is useful for increasing performance.

For example, we can write:

import render from "preact-render-to-string";

const App = <div class="foo">content</div>;

console.log(render(App));

render renders the App component to a string.

Now we should see:

<div class="foo">content</div>

logged in the console log.

Conclusion

We can create web components from Preact components.

Also, we can render components to strings.