Animated 3D Models

Make animated 3D models using a simple JavaScript library

wollygfx@wollygfx

We all have wanted to make 3D models at some point, and although it seems to be complicated, it’s not! In this workshop, we will be using a simple JavaScript library named Zdog that will let us make anything we want to in a matter of minutes.

At the end of this workshop, you will be able to make 3D models like this one:

examples

Here's a live demo of what we will make, you can also find the final code there.

Hack Club 3D logo

Set Up

This workshop requires a very basic knowledge of the following languages: HTML & JS. Don’t worry if you get stuck at some point in the workshop, everything is explained the best way for you to understand!

For this workshop we will use Repl.it, click here to create a coding environment right for this workshop.

Setup

HTML part

Alright, let’s start! First, we want to create inside of the tag a in which, the 3D model we are going to create will render. Then, put a class; feel free to name it as however you want to… I will name it with the class model.

<canvas class="model"></canvas>

Now we have to put the following code inside of the tag, this code allows us to use the Zdog library without having to download it. Learn about CDN here.

<script src="https://unpkg.com/zdog@1/dist/zdog.dist.min.js"></script>

In the end, your code should look something like this:

<body>
  <canvas class="model"></canvas>
  <script src="https://unpkg.com/zdog@1/dist/zdog.dist.min.js"></script>
  <script src="script.js"></script>
</body>

Note: It’s very important to keep this order to make sure everything works perfectly

JS part

Now that we have our html file ready to go, we gotta work on our JavaScript file.

Cool gif

Setting up the canvas

We are going to start with the fun part. First, let’s create the main variable and let’s give it a name, I will name it as “ws”

const ws = new Zdog.Illustration({
  element: '.model',
  resize: 'fullscreen',
})

Let's break this down:

  1. Illustration is the top-level class that handles dealing with the element, holding all the shapes in the scene, and displaying those shapes in the element
  2. element we use this element to match the render with the canvas tag
  3. resize is used to modify the size in which the model will be rendered, in this case, the 3D model will render on the whole screen. If you want to, you can remove this element

At this point nothing shows up yet, so let’s create our first 3D model.

Creating the model

Now, we’re gonna create a shape, for this workshop I want to make a simple cube, but you can create whatever you want to. Here is a list of shapes you can create with Zdog.

Note: Every shape has its own properties or elements, you can check the full list here.

Let’s add the following code to our JS file:

new Zdog.Box({
  addTo: ws,
  width: 100,
  height: 100,
  depth: 100,
  stroke: false,
  leftFace: '#da0',
  rightFace: '#e62',
  topFace: '#ed0',
  bottomFace: '#636',
})

Explanation:

  1. Box is a shape class, you can replace this for the shape you want to use…

  2. We made the 3D model (cube) a child to the main Zdog Illustration (ws) using the addTo element. This element must be there, otherwise the 3D model will not render.

  3. The width, height and depth elements can either stretch or shrink the shape of your box:

    • Width: Sets the width of the cube
    • Height: Sets the height of the cube
    • Depth: Sets the depth of the cube. If the value is 0, the cube will render as a 2d square; so make sure to give it a value.
  4. The Stroke element gives the 3D model a stroke, it works as an external layer that you can use to give your 3D model a rounded look. Play around with it!

  5. leftFace, rightFace, topFace & bottomFace elements give color to each face of the 3D model, try using different colors for each face, so that you can appreciate way better the animations you make.

Rendering

Now that we have created our 3D model, let’s render it. Use the following line of code to render the cube we just created.

ws.updateRenderGraph()

This code updates and render your Zdog illustration that was declared in the first variable, so make sure to write the correct name in.

Now let's click on the Run button to see what happens…

Render image

Congrats, you just made your first 3D model… Yeah, maybe not what you were expecting. Let’s fix this by animating it.

woah gif

Animating it

Add the following code to our JS file:

function animateModel() {
  ws.rotate.y += 0.01
  ws.rotate.x += 0.01
  ws.updateRenderGraph()
  requestAnimationFrame(animateModel)
}

animateModel()

Explanation:

  1. We just created a function that will make the 3D model rotate, you can name this function to whatever you want.

  2. rotate.x and rotate.y set’s the velocity to the rotation of the model:

    • The cube will move up and down depending on the given value (- or +, respectively)
    • The cube will move to the right and to the left depending on the given value (- or +, respectively)
  3. ws.updateRenderGraph() updates and render your Zdog illustration that was declared in the first variable, make sure to write the correct name in.

  4. requestAnimationFrame(animatemodel) this is like a loop, basically it makes the model rotates every time by creating frames.

  5. animateModel() calls the function.

Now you can click on run again!

Animated model

Amazing, huh?

Amazing gif

Multiple Shapes

If you want to try and make more complex models you will need to use multiple shapes, here are some examples of what you can create:

examples

Making multiple shapes is very easy, it’s as simple as putting multiple shapes together until you get what you want. The hardest part of this is to put everything where it must be, we can do this using the property: “translate”. Let’s see how it works!

I wanna try making the Hack Club logo, but you can make whatever you want! Click here to see the final code.

First, let's change the class of our canvas in the index.html file from model to hackclub.

...
<canvas class="hackclub"></canvas>
...

And add a background color for our project in the style.css file.

.hackclub {
  background: #FDB;
}

After that, let's go back to the script.js file and change the element selected by Zdog from .template to .hackclub and add the dragRotate property with the value set to true so we can rotate our creation.

const ws = new Zdog.Illustration({
  element: '.hackclub',
  resize: 'fullscreen',
  dragRotate: true
})

Next, let's change the properties of our cube so that it turns into a red square:

new Zdog.Box({
  addTo: ws,
  width: 100,
  height: 100,
  color: '#ec3750',
  stroke: 20,
  translate: { z: -18 },
})
  1. As seen before, the addTo property puts the made shape inside of the main Zdog Illustration.
  2. Used the width and height properties to make a perfect square, i didn't give it a depth because it was not needed.
  3. The whole square will have the same color (red), so we can use the color property to give the whole shape a single color instead of assigning a color to each face.
  4. As mentioned before, the stroke property helps the shape to look a little rounded.
  5. The translate property moves the square -18 within the z-axis. You can interpret this as if you were giving a shape a depth, so the shape is moved backwards.

When running these few lines, we will get this:

red square

That looks perfect! Now I will create the letter h, so I am gonna need 3 more boxes:

new Zdog.Box({
  addTo: ws,
  depth: 20,
  width: 20,
  height: 80,
  color: '#fff',
  translate: { z: 18, x: -20 },
})
  • This time, the shape is moved forward… This creates an space between the red square and this new shape.
  • The shape is moved to the left within the x-axis

result 1

new Zdog.Box({
  addTo: ws,
  depth: 20,
  width: 20,
  height: 40,
  color: '#fff',
  translate: { z: 18, y: 20, x: 20 },
})
  • This time, we created a new box but way smaller.
  • We moved it to the right within x-axis and a little bit down within the y-axis.

result 2

new Zdog.Box({
  addTo: ws,
  depth: 20,
  width: 40,
  height: 20,
  color: '#fff',
  translate: { z: 18, x: 10 },
})

In this last one, all we had to do was to move the box to the right within the x-axis, so that it blends with the box in the right.

result 3

Now let's update the animation function with some simple properties:

function animateModel() {
  ws.rotate.y += 0.01
  ws.updateRenderGraph()
  requestAnimationFrame(animateModel)
}

animateModel()

Here's the final result:

final result

Hack It

Congratulations! You just learned the basics of Zdog, feel free to check the resources below to improve your knowledge...

Congrats gif

Make your own 3D Model and share it in the Hack Club Slack, I would love to see what you can create using what you've learned in this workshop!

Other examples

Check out these cool 3D models made by other people:

Resources

Edit this page on GitHub