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:
Here's a live demo of what we will make, you can also find the final code there.
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.
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.
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:
- 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
- element we use this element to match the render with the canvas tag
- 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:
const cube = new Zdog.Box({
addTo: ws,
width: 100,
height: 100,
depth: 100,
stroke: false,
leftFace: '#da0',
rightFace: '#e62',
topFace: '#ed0',
bottomFace: '#636',
})
Explanation:
-
Box is a shape class, you can replace this for the shape you want to use…
-
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.
-
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.
-
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!
-
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…
Congrats, you just made your first 3D model… Yeah, maybe not what you were expecting. Let’s fix this by animating it.
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:
-
We just created a function that will make the 3D model rotate, you can name this function to whatever you want.
-
rotate.x
androtate.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)
-
ws.updateRenderGraph()
updates and render your Zdog illustration that was declared in the first variable, make sure to write the correct name in. -
requestAnimationFrame(animatemodel)
this is like a loop, basically it makes the model rotates every time by creating frames. -
animeatemodel()
calls the function.
Now you can click on run again!
Amazing, huh?
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:
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.
I'll start making the red square in the background:
new Zdog.Box({
addTo: model,
width: 100,
height: 100,
color: '#ec3750',
stroke: 20,
translate: { z: -18 },
})
- As seen before, the
addTo
property puts the made shape inside of the main Zdog Illustration. - Used the width and height properties to make a perfect square, i didn't give it a depth because it was not needed.
- 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.
- As mentioned before, the stroke property helps the shape to look a little rounded.
- 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:
That looks perfect! Now I will create the letter h, so I am gonna need 3 more boxes:
new Zdog.Box({
addTo: model,
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
new Zdog.Box({
addTo: model,
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.
new Zdog.Box({
addTo: model,
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.
Now, i will just animate it
function animation() {
model.rotate.y += 0.01
model.updateRenderGraph()
requestAnimationFrame(animation)
}
animation()
Here's the final result:
Hack It
Congratulations! You just learned the basics of Zdog, feel free to check the resources below to improve your knowledge...
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:
- Live digital clock made using Zdog
- Amethyst from Steven Universe made using Zdog
- Generic coin made using Zdog