GatsbyJS static site generator is awesome for creating super fast sites. With full performance setup your pages should load straight away. Sometimes you need a bit of animation to make the site that little bit more interesting and with Pose we can do exactly that.
Gatsby already has a sweet plugin for page transitions but for in-page animations were going to have a look at Pose by Popmotion which sells itself as “a truly simple animation library for React, React Native, and Vue”.
In this example I’m going to use a basic template that GatsbyJS provides with the Kaldi theme. It provides us with a few pages including a blog and a couple of forms. It’s basically a fully responsive website that we can add some animations to.
Installation
First we need to install pose to our site with
yarn add react-pose
or
npm install react-pose --save
We’ll need to import Pose for each component that we want to add animations to with import posed from 'react-pose';
Hover animations
We can use posed
to create any animated HTML or SVG element, here we’ll use it to create a div.
const Box = posed.div({
});
Then in the render we include the Box element we just created. We’ll wrap each blog post within this Box
<Box className="box">
...
</Box>
Next up is adding the animation to the box we created:
const Box = posed.div({
hoverable: true,
init: {
scale: 1,
boxShadow: "0px 0px 0px rgba(0,0,0,0)"
},
hover: {
scale: 1.1,
boxShadow: "0px 5px 10px rgba(0,0,0,0.3)"
}
});
This will increase the scale of the box when hovered. It’s a pretty simple and neat example of how we can quickly add a hover effect to our elements in a static website.
It turns out quite well, and the code is pretty easy to follow.
Image Zoom
One example on the Pose documentation shows how we can zoom into an image on click and zoom back out again when the image is clicked again. This seems like a nice light and simple alternative to a lightbox.
The images we’ll be zooming are on the products page of the gatsby-starter template: https://gatsbyjs-pose.netlify.com/products
We’ll make a new component called ImageZoom
that uses the PreviewCompatibleImage
component that came with the gatsby-starter.
import React from "react";
import PreviewCompatibleImage from "../components/PreviewCompatibleImage";
class ImageZoom extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<div>
<PreviewCompatibleImage imageInfo={this.props.imageInfo} />
</div>
);
}
}
export default ImageZoom;
We need to import posed again, define our animated posed.div
to create our new Zoomable
div.
const Zoomable = posed.div({
fullscreen: {
position: "fixed",
top: 0,
left: 0,
width: "100vw"
height: "100vh"
flip: true,
zIndex: "1"
},
idle: {
position: "static",
width: "100%",
height: "auto",
flip: true,
zIndex: "1"
}
});
Read more about the FLIP technique here
We’re going to use state to control when the image is zoomed in or not so we’ll set the active state.
state = {
active: false
};
We can wrap our new Zoomable
item around the image with the pose settings and onClick
function.
render() {
return (
<Zoomable
className="zoomable"
pose={this.state.active ? "fullscreen" : "idle"}
onClick={this.toggleZoom}
>
<PreviewCompatibleImage imageInfo={this.props.imageInfo} />
</Zoomable>
);
}
And set up our functions for swapping the state when our Zoomable
item is clicked.
zoomIn() {
this.setState({ active: true });
}
zoomOut = () => {
this.setState({ active: false });
};
toggleZoom = () => (this.state.active ? this.zoomOut() : this.zoomIn());
Now that our new component is ready to use, let’s import it into the products page and use this instead of the PreviewCompatibleImage
.
...
<article className="tile is-child">
<ImageZoom imageInfo={main.image1} />
</article>
...
That’s it, a really simple lightbox effect with Pose within our GatsbyJS static site. Here’s the result and the code.
Other inspiration and useful links
There’s a lot that you can do with Pose and after having a small play around with it I think it has it’s part to play in simple animations for websites. Here’s a really nice example of Vince Parulan creating a lovely animated menu with Pose.
An article by Google on CSS Versus JavaScript Animations.