Discover three.js is now open source!
Word Count:1168, reading time: ~6minutes

The Structure of a three.js App

Before we can build a three.js app, we need to create a web page. We briefly discussed how we’re going to do that in the introduction ( Ch 0.5 and Ch 0.6), but let’s take a deeper look now. As we mentioned in the last chapter, our goal here is to create the most basic, simple, unexciting webpage possible, without making any assumptions about what a real-world web application that uses three.js might look like. By doing this, we ensure the code we write can be adapted to work anywhere without too much effort.

We’ll create this basic web page out of just two files: index.html, and styles/main.css. That’s it. Open up the editor by pressing the button now and take a look at both of these files now.

If anything from this chapter is unfamiliar to you, refer to the HTML and CSS Reference where we take a deeper look at the construction of a simple web page.

index.html

index.html is the root file of our app. It’s the only file we open directly in the browser, and all CSS and JavaScript files are loaded via references from this file.

index.html: the root of our web page
    <!DOCTYPE html>
<html>

<head>
  <title>Discoverthreejs.com - The Structure of a three.js App</title>

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta charset="UTF-8" />

  <link rel="icon" href="https://discoverthreejs.com/favicon.ico" type="image/x-icon">

  <link href="./styles/main.css" rel="stylesheet" type="text/css">

  <script type="module" src="./src/main.js"></script>
</head>

<body>
  <h1>Discoverthreejs.com - Nothing to see here yet :)</h1>

  <div id="scene-container">
    <!-- Our <canvas> will be inserted here -->
  </div>
</body>

</html>

  

styles/main.css

Within the <head> section of index.html, one of the <link> elements references the styles/main.css file:

index.html: Referencing main.css
      <link href="./styles/main.css" rel="stylesheet" type="text/css">

  

… which contains some simple styles for controlling the appearance of our page:

styles/main.css
    body {
  /* remove margins and scroll bars */
  margin: 0;
  overflow: hidden;

  /* style text */
  text-align: center;
  font-size: 12px;
  font-family: Sans-Serif;

  /* color text */
  color: #444;
}

h1 {
  /* position the heading */
  position: absolute;
  width: 100%;

  /* make sure that the heading is drawn on top */
  z-index: 1;
}

#scene-container {
  /* tell our scene container to take up the full page */
  position: absolute;
  width: 100%;
  height: 100%;

  /*
    Set the container's background color to the same as the scene's
    background to prevent flashing on load
  */
  background-color: skyblue;
}


  

We’ll take a closer look at the styles for the #scene-container in a moment, while the rest of this file is explained in more detail in the appendices.

src/main.js: the JavaScript Entry Point

Back in index.html, just below the styles <link> is a <script> tag referencing the src/main.js file:

index.html: Referencing main.js
      <script type="module" src="./src/main.js"></script>

  

… which is currently empty:

src/main.js: coming soon!
    // just waiting for your beautiful creations!


  

main.js is the entry point for our JavaScript application, and we’ll fill it up in the next chapter. The type="module" attribute tells the browser we’re writing JavaScript modules. If this is new to you, head over to the JavaScript Modules Reference, which has everything you need to know about JavaScript modules to follow the code in this book.

There’s another advantage to the module attribute: the browser will automatically defer running this file until the HTML has been parsed. This will prevent errors caused by trying to access an HTML element before the browser has read that far (browsers read HTML from top to bottom).

Adding a three.js Scene to the Page

The next point of interest in index.html is the scene container element:

index.html: The scene container
    <body>
  <h1>Discoverthreejs.com - Nothing to see here yet :)</h1>

  <div id="scene-container">
    <!-- Our <canvas> will be inserted here -->
  </div>
</body>

  

All three.js scenes are rendered inside a <canvas> element. Once we have set up our app, three.js will create a canvas for us, and then we’ll insert it inside the scene container:

index.html: once our app is running we’ll insert the three.js canvas into the scene container
    

<div id="scene-container">
  <canvas></canvas>
</div>

  

We can then control the position and size of our scene by styling the scene container element. If you turn your attention back to main.css, you’ll see that we have already created some styles for this element. By setting the position, width, and height, we’re telling the browser this element should take up the full window:

main.css: styling the scene container
    #scene-container {
  /* tell our scene container to take up the full page */
  position: absolute;
  width: 100%;
  height: 100%;

  /*
    Set the container's background color to the same as the scene's
    background to prevent flashing on load
  */
  background-color: skyblue;
}

  

Finally, we have set the background color to sky blue since that’s the background color we’ll give most of our three.js scenes in this section. Our scene will take a few milliseconds to get ready, while the browser parses JavaScript, loads 3D models, and builds the scene, and while all that is going on the scene container will be visible. By making the container the same color as the scene we ensure that the transition is as smooth as possible.

Other Folders

Turn your attention to the file tree in the editor. There are two folders we haven’t looked at so far: assets/, and vendor/.

The vendor/ Folder

The vendor/ folder is where we put JavaScript files that other people have written. For most of the examples in this book, that means files from the three.js library, downloaded from the three.js GitHub repo. In this book, we’ll use just three files from the library:

  • vendor/three/build/three.module.js: the main three.js file.
  • vendor/three/examples/jsm/controls/OrbitControls.js: a camera control plugin that we’ll introduce in Ch 1.9.
  • vendor/three/examples/jsm/loaders/GLTFLoader.js: a loader for 3D models that we’ll introduce in Ch 1.13.

The vendor/three folder mirrors the structure of the GitHub repo, but for clarity, we’ll include only the files needed in each chapter. To import these files within main.js, we’ll use NPM style imports:

src/main.js: importing three.js files, NPM style
    
import {
Camera,
Group,
Scene,
} from 'three';

import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

  

If you prefer to work locally, you can download the files from the editor as a zip archive using the button. Within the zip file, any three.js imports will be converted to CDN imports from skypack.dev:

src/main.js: importing three.js files, CDN style
    


import { Camera, Group, Scene } from "https://cdn.skypack.dev/[email protected]";

import { OrbitControls } from "https://cdn.skypack.dev/[email protected]/examples/jsm/controls/OrbitControls.js?module";
import { GLTFLoader } from "https://cdn.skypack.dev/[email protected]/examples/jsm/loaders/GLTFLoader.js?module";



  

Refer back to the intro for more details.

The assets Folder

Finally, there’s the assets/ folder. Anything used in our app that is not HTML, CSS, or JavaScript goes in here: textures, 3D models, fonts, sounds, and so on. Currently, there’s one test texture that we’ll use in the chapter on Texture, and one model of a flamingo that we’ll use in the chapter on Loading Models chapter on Loading Models.

 

With that out of the way, it’s time to get down to business! In the next chapter, we’ll create our first simple three.js application.

Import Style
Selected Texture