Intro to Three.js + Interactive Text Example/Tutorial
Emurtzle
Posted on March 18, 2019
What is Three.js?
From the Wikipedia article:
"Three.js is a lightweight cross-browser JavaScript library/API used to create and display animated 3D computer graphics on a Web browser. Three.js scripts may be used in conjunction with the HTML5 canvas element, SVG or WebGL."
Simply put, it's a way to to display 3D content in a (relatively) simple way without the need for various plugins.
It is built on top of WebGL, which is built on top of OpenGL. It essentially streamlines the use of WebGL
What is it used for?
- Displaying 3D content
- Multi-Media Projects
- Music Visualization
- Data Visualization
- Video Games
- For fun (it's fun!!!)
Why should you use Three.js?
- There are several similar libraries also based off of WebGL.
- GLGE
- sceneJS
- PhiloGL
- It's a large library that is well documented.
- It has DOZENS of example projects and proof-of-concepts to get inspiration and reference from
- It's a single JavaScript file, you don't need to load a whole bunch of weird plugins
- This increases security and compatibility between browsers while also making your code cleaner and more efficient.
- Active community with 14,000 questions (and growing) questions on Stack Overflow
- Its is available via the MIT license
- To quote the Wikipedia article again:
- “The MIT License is a permissive free software license originating at the Massachusetts Institute of Technology (MIT). As a permissive license, it puts only very limited restriction on reuse and has, therefore, an excellent license compatibility. The MIT license permits reuse within proprietary software provided that all copies of the licensed software include a copy of the MIT License terms and the copyright notice. The MIT license is also compatible with many copyleft licenses, such as the GNU General Public License (GPL); MIT licensed software can be integrated into GPL software, but not the other way around.
- Several other large programs that use the MIT license include
- Ruby on Rails
- Node.js
- JQuery
- X Window System
- To quote the Wikipedia article again:
Tutorial (Simple scene on JSFiddle)
Let's make a super simple example that creates a cube and makes it rotate. Here is the JSFiddle for it, let's go through the code line by line. There's no html or css in this fiddle, except for a script tag to import Three.js. Everything else is pure JavaScript!
Line 1
var camera, scene, renderer, geometry, material, mesh;
Let's break this down:
-
camera
is a virtual camera, what this camera sees is what is rendered. -
scene
contains everything you want rendered. The camera -> views -> the scene -
renderer
is the rendering engine, it renders what the camera sees and converts it to something the DOM can display -
geometry
is the shape of the object we are rendering -
material
is the color and/or texture of the object we are rendering -
mesh
is the actual render-able object, it needs a shape (the geometry) and a color (the material)
Line 3-4
init();
animate();
This calls two functions we define below
-
init();
initializes our 3D scene. -
animate();
starts the animation loop that rotates our cube
Line 6-24
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 500;
geometry = new THREE.CubeGeometry(200, 200, 200);
material = new THREE.MeshNormalMaterial();
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
Ok, this can be alot at once, let's go line by line. This is the majority of our file
-
scene = new THREE.Scene();
Simply creates a new scene -
camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000);
creates a new Perspective Camera there are several different types of camera but you'll probably be using perspective cameras the most. It takes four parameters- The Field of View (FoV)
- The aspect ratio,
window.innerWidth / window.innerHeight
will work for most projects - Near(float), anything closer to the camera than Near will not be rendered
- Far(float), anything further away from the camera than Far will not be rendered
-
camera.position.z = 500;
sets the position of the camera to 500 units on the z axis -
geometry = new THREE.CubeGeometry(200, 200, 200);
creates a new cube shape that is 200 units wide by 200 units tall by 200 units deep -
material = new THREE.MeshNormalMaterial();
creates a new simple material to apply to the cube. There are many different types of materials, we are using one that changes color based on the normals (direction) that a face (side of the cube) is pointing. -
mesh = new THREE.Mesh(geometry, material);
creates a new mesh, applying thematerial
to thegeometry
we defined above -
scene.add(mesh);
then adds the mesh to the scene so the camera can see it -
renderer = new THREE.WebGLRenderer();
creates a new WebGL render engine -
renderer.setSize(window.innerWidth, window.innerHeight);
sets the width and height of the rendering engine to the width and height of the window containing it -
document.body.appendChild(renderer.domElement);
the renderer takes it's render result and converts it to something the dom can use, we then append it to the body of the document(DOM)
There! That wasn't so bad was it? All we're doing is creating objects and setting up parent/child relationships. Just like we do with any ol' JavaScript driven website!
Line 26-36
function animate() {
requestAnimationFrame(animate);
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.02;
renderer.render(scene, camera);
}
This function tells the renderer to actually render the scene and it drives the animation of our cube.
-
requestAnimationFrame(animate);
This function is weird, there's not even an entry in the documentation about it. It tells Three.js to setup the code below it into a loop that runs every time the display refreshes (typically 60hz or 60 times per second) -
mesh.rotation.x += 0.01;
We increment our cubes x rotation a tiny bit, keep in mind this runs 60 times per second, large values will make the cube rotate very fast -
mesh.rotation.y += 0.02;
We increment our cubes y rotation by a tiny bit -
renderer.render(scene, camera);
We tell the render to render out the scene using our camera, we have to supply the scene and camera because you can have multiple of both in one project.
This is the main loop that drives the animation and rendering of our scene, so if you have a complex scene, this function can easily becomes many hundreds of lines, I highly recommend abstracting your animations as much as possible.
There you go! That's all there is to this project! You should now have a color changing, rotating cube
Interactive Example
Below is an more in-depth example of how to add interaction between a webpage and Three.js content. I purposely kept it simple to make sure it can run on as many machines as possible. I will not be explaining every line here, however there are comments explaining nearly every line of code there!
Posted on March 18, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.