Intro to Three.js + Interactive Text Example/Tutorial
Tags: javascript, threejs, tutorial, webdev
Published: 2019-03-18 16:22:47

---
title: Intro to Three.js + Interactive Text Example/Tutorial
published: true
description: An intro tutorial to the Three.js library and a walkthrough of a interactive example
tags: JavaScript, Three.js, Tutorial, Web Development
---
#What is Three.js?
From the [Wikipedia article](https://en.wikipedia.org/wiki/Three.js):
*"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?
1. Displaying 3D content
2. Multi-Media Projects
3. Music Visualization
4. Data Visualization
5. Video Games
6. For fun (it's fun!!!)

#Why should you use Three.js?
1. There are several similar libraries also based off of WebGL.
    + GLGE
    + sceneJS
    + PhiloGL
2. It's a large library that is well documented.
3. It has DOZENS of example projects and proof-of-concepts to get inspiration and reference from
4. 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.
5. Active community with 14,000 questions (and growing) questions on Stack Overflow
    + [Documentation](https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene)
    + [Examples](https://threejs.org/examples/)
    + [Forum](https://discourse.threejs.org/)
    + [Slack](https://threejs-slack.herokuapp.com/)
    + [IRC](http://webchat.freenode.net/?channels=three.js)
    + [Stack Overflow](https://stackoverflow.com/questions/tagged/three.js)
6. Its is available via the MIT license
    + To quote the [Wikipedia article](https://en.wikipedia.org/wiki/MIT_License) 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

#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!
{% jsfiddle https://jsfiddle.net/Emurtzle/02dbuvxf/ % result,js,html%}

##Line 1
```javascript
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
```javascript
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
```javascript
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 the `material` to the `geometry` 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
```javascript
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!

{% jsfiddle https://jsfiddle.net/Emurtzle/9a4fmr8b % result,js,html%}