profile picture

Chi Kin Tsang

Front-end Developer

Learn more about me.

Utrecht, The Netherlands

Recent Posts

25
Aug

Loading map...

is at

Restaurant Juliana

Dim Sum

Only one of the two spots in Utrecht where you can find traditional Hong Kong dim sum. A great amount of food for a fair price. The best part of dim sum is sharing the dishes and being able to get a taste of each and every one of them.

Loading images...

21
Aug

A New Journey

On September 15th, I’ll be starting a new journey as a developer at Enrise! Thanks, my future colleagues of Team Craft, for the warm welcome today.

September 15th can’t come soon enough!

Loading images...

19
Aug

Loading map...

is at

Japanse Tuin, Maximapark

Maximapark

It looks like the renovations to the Japanese Gardens in the Maximapark have been completed. The Japanese style bridges and pavillion they’ve added look absolutely stunning! It probably would look even better during spring with all the flowers around.

Loading images...

16
Aug

Testing the Elbow

I’ve just completed my first upper body workout in ages to see how the tennis elbow holds up after exercising.

1 minute rest per exercise and 3 minutes of rest between sets.

(21 Aug) Edit: I’m definitely still feeling the lingering effect of the workout. I’ll try to reduce the load in my next session to see if it has any effect.

1

1

10 reps

+ 8 kg

2

10 reps

+ 8 kg

3

10 reps

+ 8 kg

2

1

10 reps

2

10 reps

3

10 reps

3

1

10 reps

+ 8 kg

2

10 reps

+ 8 kg

3

10 reps

+ 8 kg

4

1

10 reps

+ 4.5 kg

2

10 reps

+ 4.5 kg

3

10 reps

+ 4.5 kg

5

1

10 reps

2

10 reps

3

10 reps

24
Jul

Infinite Marquee using React and Motion One

I'm sure you have seen them before. A continuous scrolling and looping animation, containing either text or images called a marquee. It's often used to show the logos of partners or as a picture gallery. Let's recreate this animation using React and Motion One!

Initializing the project

First, we will be creating our project and installing some packages.

  • Let's start with creating our app using NextJS by running npx create-next-app@latest in the terminal.
  • Next, for handling the animations we'll install the Motion library by running npm i motion.

Creating the layout

To create the layout, let's start with creating a list of images which we'll be using for the project.

Then we map over the list of images and return an image component to render those images.

  • The width of the images is calculated by dividing the width of the container (in this case the width of the viewport) by the amount of images in the list with logos.length.
  • We use flex-shrink-0 to prevent the images from shrinking and causing it to overlap with each other.

It should look like this:

Loading image...

The static marquee layout

Animating the Infinite Scrolling Marquee

To create the animation, we have to start with importing the motion component from the Motion One library.

Then we change the <div> element containing the images to a <motion.div> component. To make the images move horizontally, we have to animate the x-axis of the motion component. At last, we make it loop continuously at a steady pace by setting the ease to linear and repeat it endlessly with repeat: Infinity.

  • The animation starts off at x = "0" which is the default position and moves left until it reaches -100%, which means it'll move left until its entire width has moved out of the container.

Loading image...

An overview of the layout at the start and end of the animation. Do you spot a problem?

As you can see there is a big empty space left behind from the logos leaving the container when x reaches -100%. To fix this we have to duplicate our list of logos to fill in the empty gap.

This works, because the width is exactly double the size of the original list of logos.

Loading image...

The duplicate images will fill in the empty space

Let's put it all together and create the component.

It will look like this:

We can add a blur to the sides of the marquee for a subtle fade effect.

The end result will look like this: