Kinetic Typography with ThreeJS

Pavel Laptev
Prototypr
Published in
6 min readOct 17, 2020

--

Hallo Leute! Today we will do some interesting stuff with ThreeJS and typography — we will make Kinetic Typography.

There are plenty of cool shots over the internet tagged as #kinetictypography. Here are some of them ↘

To be more specific and make this article shorter we will use only one method — a text texture on a mesh. A simple, but wide in its functionality method.

Set up Environment

React

We will use ThreeJS + React. So, first, create your app using create-react-app. Open a folder where you want to have your new project, then ↘

npx create-react-app my-app

Then drop the project folder into your IDE app. I'm using VS Code.

Three JS

Then install Three JS ↘

npm i three

Now we are ready to go.

Create kinetic typography

As the simplest example, we will recreate this shot

This is the final working demo

ThreeJS is always a canvas element. We will write our shot as a functional component. To me writing functional components a bit easier.

Here is how the naked shot structure looks like ↘

Or the full code ↘

But let’s start from the very begining.

0. Import things (React part)

Before we will write our code we need to import functions and components that we will use. Of course in real live you will do it step by step, during the code writing, but here let’s import everything at once.

1. React Refs

Declare the component — I called it ThreeShot.

And add refs for the main element — <CANVAS> and also we will add an input element to be able to change the text on our 3D ball.

Refs provide a way to access DOM nodes or React elements created in the render method.
React docs

2. React.useEffect

2a. Declare canvas, scene and renderer.

In this part we’re using React.useEffect. Its allows us to use methods that we use with plane JS like eventlisteners or select DOM elements. That’s why we added refs earlier.

The ThreeJS part is begging here within the useEffect.

We declare our canvas via React.ref and the scene size first.

The container for ThreeJS is canvas and the virtual wrapper for it will be a scene and renderer. We push everything that we want to show and have into the scene — camera, objects, lights.

2b. Create texture and material (ThreeJS part)

We will use a method that I described here, but little modified.

The function will generate alternating rows of text like on this texture

(Just added somewhere in the project)

This function takes two arguments — text string and object with colors which should include — main and the secondary color.

Here we declare color object → then we generate texture → set props for the texture like autoUpdate and the texture size → add this texture to the material as a map.

2c. Add an object (ThreeJS part)

For the Sphere geometry we need to pass 3 arguments — radius and amount of polygons — by X- and Y-axis.

Then add the geometry to the mesh wrapper and add the texture.

Adjust the rotation of the object if needed and add the mesh to the scene.

Steps for geometry — create SphereGeometry → then add it to the mesh wrapper → add material to the mesh → rotate and positioning of the mesh in the scene → and finally add the mesh to the scene.

2d. Add camera and light (ThreeJS part)

Nothing complex with the camera, you can play around with parameters. The camera we will add to the render, not to the scene.

Light. There are several types of lights in ThreeJS — we will choose AmbientLight. This light source will illuminate the model evenly, without shadows.

2e. Animate and render the scene (ThreeJS part)

Here is the function animate() with requestAnimationFrame that will redraw our scene with new params around 60 times a second.

Also in this function, we shift the texture and rotate the camera.

2f. Hadle Input changes (React part)

Here we wrote a function that will be triggered each time when we change a text in the input. and in the function, we will generate a texture for the material again with a new text.

3. Add return (React part)

return is the part where we actually render DOM elements. Here we have a wrapper that includes Input component and canvas.

That’s basically it. Now everything should work. I didn’t handle windowResize here, but it’s just to simplify the article and focus on the task only.

--

--