profile picture of Olivier Larose

Olivier Larose

May 28, 2023

/

Intermediate

/

Short

Infinite Text Move On Scroll

How to make an infinite text moving animation with React and Next.js

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

Live DemoSource codeVideo Tutorial
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.

  • The background image is added inside a new /public/images.
  • You can find the one I used here.

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.

  • Let's also add margin: 0px on the body in the globals.css to make everything clean.

Setting up the page.js component

page.js

page.mod...

1

'use client'

2

import Image from 'next/image'

3

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

4

import { useRef } from 'react';

5

6

export default function Home() {

7

8

const firstText = useRef(null);

9

const secondText = useRef(null);

10

const slider = useRef(null);

11

12

return (

13

<main className={styles.main}>

14

<Image

15

src="/images/background.jpg"

16

fill={true}

17

alt="background"

18

/>

19

<div className={styles.sliderContainer}>

20

<div ref={slider} className={styles.slider}>

21

<p ref={firstText}>Freelance Developer -</p>

22

<p ref={secondText}>Freelance Developer -</p>

23

</div>

24

</div>

25

</main>

26

)

27

}

Couple of important things to note about the code above:

  • The second p is set in position absolute with a left: 100%so that it's perfectly placed at the right of the first.
  • white-space: nowrap so the text overflows outside the window.

We should have something like this:

Creating the infinite move

To move the texts, we'll basically use requestAnimationFrame and at each frame we will move the texts by 0.1% to the right.

We will also use the GSAP Library to set xPercent value of the texts.

page.js

1

...

2

let xPercent = 0;

3

4

useEffect( () => {

5

gsap.set(secondText.current, {left: secondText.current.getBoundingClientRect().width})

6

requestAnimationFrame(animate);

7

}, [])

8

9

const animate = () => {

10

if(xPercent > 0){

11

xPercent = -100;

12

}

13

gsap.set(firstText.current, {xPercent: xPercent})

14

gsap.set(secondText.current, {xPercent: xPercent})

15

requestAnimationFrame(animate);

16

xPercent += 0.1;

17

}

18

...
  • Initially, the xPercent is set at -100%, and is gradually incremented to 0%, when it reaches 0%, it gets reset back to -100%.

We should have something like this:

Adding scroll interaction

With the scroll, we can now change direction depending on the scroll direction.

We can also add an extra move on the texts when scrolling to make everything more responsive to the scroll.

To do that, we will use the ScrollTrigger library from GSAP.

page.js

1

...

2

let direction = -1;

3

4

useEffect( () => {

5

gsap.registerPlugin(ScrollTrigger);

6

gsap.to(slider.current, {

7

scrollTrigger: {

8

trigger: document.documentElement,

9

scrub: 0.5,

10

start: 0,

11

end: window.innerHeight,

12

onUpdate: e => direction = e.direction * -1

13

},

14

x: "-500px",

15

})

16

requestAnimationFrame(animate);

17

}, [])

18

19

const animate = () => {

20

if(xPercent < -100){

21

xPercent = 0;

22

}

23

else if(xPercent > 0){

24

xPercent = -100;

25

}

26

gsap.set(firstText.current, {xPercent: xPercent})

27

gsap.set(secondText.current, {xPercent: xPercent})

28

requestAnimationFrame(animate);

29

xPercent += 0.1 * direction;

30

}

31

...

Couple notes about the code above:

  • ScrollTrigger allows us to set translate the texts by 500px depending on the progress of the start(0) and the end(window.innerHeight).
  • ScrollTrigger also allows us to easly read the direction of the scroll.

And here we should have the final animation:

Wrapping up

That was it for this animation! Very interesting to know how to move text on an infinite basis, it's actually quite easy when leveraging CSS values with percentage. It's a good animation to know and it's quite a popular one as well!

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 13, 2023

Image slide project gallery

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/