profile picture of Olivier Larose

Olivier Larose

May 13, 2023

/

Beginner

/

Medium

Image slide project gallery

How to animate width: auto using React, Next.js and Framer Motion

A project gallery animation featuring an image slide effect using the width auto animation of Framer Motion. Made with React and Next.js. Inspired by https://locomotive.ca/

Live DemoSource code
background video

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

page.js

page.mod...

1

'use client'

2

import styles from './page.module.css'

3

import Project from '../components/project';

4

5

export default function Home() {

6

7

const projects = [

8

{

9

title1: "Jomor",

10

title2: "Design",

11

src: "jomor_design.jpeg"

12

},

13

{

14

title1: "La",

15

title2: "Grange",

16

src: "la_grange.jpeg"

17

},

18

{

19

title1: "Deux Huit",

20

title2: "Huit",

21

src: "deux_huit_huit.jpeg"

22

},

23

{

24

title1: "Nothing",

25

title2: "Design Studio",

26

src: "nothing_design_studio.png"

27

},

28

{

29

title1: "Mambo",

30

title2: "Mambo",

31

src: "mambo_mambo.jpeg"

32

}

33

]

34

35

return (

36

<main className={styles.main}>

37

<div className={styles.gallery}>

38

<p>Featured Work</p>

39

{

40

projects.map( project => {

41

return <Project project={project}/>

42

})

43

}

44

</div>

45

</main>

46

)

47

}

48

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

project....

style.mo...

1

import styles from './Style.module.css';

2

3

export default function index({project}) {

4

const { title1, title2, src } = project;

5

return (

6

<div className={styles.project}>

7

<p>{title1}</p>

8

<div className={styles.imgContainer}>

9

<img src={`/medias/${src}`}></img>

10

</div>

11

<p>{title2}</p>

12

</div>

13

)

14

}

Nothing too complicated here. One thing to note is we split the title with two different p and put the image in between.

Screenshot of the HTML and CSS results

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

project....

style.mo...

1

'use client'

2

import styles from './style.module.css';

3

import { motion } from 'framer-motion';

4

import { useState } from 'react';

5

6

const anim = {

7

initial: {width: 0},

8

open: {width: "auto", transition: {duration: 0.4, ease: [0.23, 1, 0.32, 1]}},

9

closed: {width: 0}

10

}

11

12

export default function index({project}) {

13

14

const [isActive, setIsActive] = useState(false);

15

16

const { title1, title2, src } = project;

17

return (

18

<div onMouseEnter={() => {setIsActive(true)}} onMouseLeave={() => {setIsActive(false)}} className={styles.project}>

19

<p>{title1}</p>

20

<motion.div variants={anim} animate={isActive ? "open" : "closed"} className={styles.imgContainer}>

21

<img src={`/medias/${src}`}></img>

22

</motion.div>

23

<p>{title2}</p>

24

</div>

25

)

26

}

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

Related Animations

image

Jul 24, 2023

Awwwards Landing Page

An Awwwards portfolio landing page rebuild. Originally made by Dennis Snellenberg, he won an awwwards with his amazing portoflio. Remade the landing page using Next.js, Framer Motion and GSAP. See the original: https://dennissnellenberg.com/

image

June 11, 2023

Project Gallery Mouse Hover

An awwwards winning website tutorial with a project gallery featuring a hover animation using Nextjs, GSAP and Framer Motion. Inspired by: https://dennissnellenberg.com/

image

May 28, 2023

Infinite Text Move On Scroll

An infinite text moving animation with scroll interaction using React and Next.js. Picture by Eric Asamoah.