Initializing the project
Let's start the project by creating a Next.js application. We can do that by running npx create-next-app@latest client
inside of a terminal.
Adding the HTML and CSS
We can delete everything in the page.js
, global.css
and page.module.css
and add our own HTML and CSS, to start with a nice blank application.
- All the images are added inside a new folder:
/public/images
. - You can find the ones I used here.
Setting up the page.js
component
2
import styles from './page.module.css'
3
import Project from '../components/project';
5
export default function Home() {
11
src: "jomor_design.jpeg"
21
src: "deux_huit_huit.jpeg"
25
title2: "Design Studio",
26
src: "nothing_design_studio.png"
31
src: "mambo_mambo.jpeg"
36
<main className={styles.main}>
37
<div className={styles.gallery}>
40
projects.map( project => {
41
return <Project project={project}/>
Here we define the values we need for each project inside the projects array. We also map it and return a new component for each project.
Setting up the project.js
component
1
import styles from './Style.module.css';
3
export default function index({project}) {
4
const { title1, title2, src } = project;
6
<div className={styles.project}>
8
<div className={styles.imgContainer}>
9
<img src={`/medias/${src}`}></img>
Nothing too complicated here. One thing to note is we split the title with two different p
and put the image in between.
Animating the images
To animate the images, we will need to:
- Add some styling to the image container
- Install Framer motion and animate the
width: auto
npm i framer-motion
2
import styles from './style.module.css';
3
import { motion } from 'framer-motion';
4
import { useState } from 'react';
8
open: {width: "auto", transition: {duration: 0.4, ease: [0.23, 1, 0.32, 1]}},
12
export default function index({project}) {
14
const [isActive, setIsActive] = useState(false);
16
const { title1, title2, src } = project;
18
<div onMouseEnter={() => {setIsActive(true)}} onMouseLeave={() => {setIsActive(false)}} className={styles.project}>
20
<motion.div variants={anim} animate={isActive ? "open" : "closed"} className={styles.imgContainer}>
21
<img src={`/medias/${src}`}></img>
Couple of things to note about the code
display: flex
and justify-content: center
to make the div grow from its center.- We trigger the animation by toggling the
isActive
value when hovering the project.
Wrapping up
That was it for this animation! Very easy to animate the width: auto with the help of Framer-motion, and it allows us to create a simple yet eye pleasing animation.
Hope you learned a lot :)
-Oli