Here are all the things you need to get started with Three.JS.
First create your html page.
You will need:
An element to attach the scene to. I'm using the body tags for this.
The Three.JS library included. Could use the node module if your app contains a transpiler.
The JavaScript for creating a scene.
<!DOCTYPE html> <html> <head> <meta charset=utf-8> <title>Web Viewer</title> <link type="text/css" rel="stylesheet" href="main.css"> </head> <body> <script src="public/three.min.js"></script> <script src="index.js"></script> </body> </html>
*Bonus: If you want css to fix the margins so that you don't have any scrolling nonsense going on, you can add a main.css
file like I have in the HTML above and add:
body { margin: 0; overflow: hidden; }
The way I'm including the javascript is by including it after the body
tag was created and the three.js
library was imported.
In index.js
in the same location as index.html
, there are around 6 things needed to create a basic scene in Three.JS:
// 1. Create the scene var scene = new THREE.Scene() // 2. Add a camera view var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ) camera.position.z = 10 // 3. Add a renderer to generate the camera's picture var renderer = new THREE.WebGLRenderer() renderer.setSize( window.innerWidth, window.innerHeight ) // 4. Attach what we're rendering to the web page document.body.appendChild( renderer.domElement ) // 5. Lighting + Objects var geometry = new THREE.BoxGeometry(2, 2, 2) var material = new THREE.MeshLambertMaterial({color: 0xfd59d7}) var cube = new THREE.Mesh(geometry, material) scene.add(cube) var light = new THREE.PointLight(0xFFFF00) light.position.set(10, 0, 25) scene.add(light) // 6. Run the renderer var animate = function () { requestAnimationFrame( animate ); cube.rotation.x += .1; cube.rotation.y += .1; camera.updateProjectionMatrix(); renderer.render(scene, camera); }; animate();
The regular way to create a background is by setting this.scene.background
to one of the three THREE classes: Color
, Texture
, or CubeTexture
. For a surrounding background (e.g. panorama/cubemap) we want CubeTexture.
Let's start from the basics just to make sure we can get the background to change, and then increase the complexity from there.
To add a color as a background, we can do:
scene.background = new THREE.Color( 0xf0f0f0 )
There are a bunch of operations you can use to create a color with this class.
Lay a background that always is on the back of the canvas.
I copied the textures pack that is in the Three.JS repo here to assets/textures
.
var texture = new THREE.TextureLoader().load( "assets/textures/water.jpg" ); texture.wrapS = THREE.RepeatWrapping; texture.wrapT = THREE.RepeatWrapping; texture.repeat.set( 4, 4 ); this.scene.background = texture;
Note: The middle three lines are extras essentially saying we want to repeat in the horizontal plane wrapS
, the vertical plane wrapT
and also repeat 4 time by 4 times. Otherwise, only keeping the first and last line stretches the image to the canvas.
If you try to move the scene around once you have controls built in (why not build them in now? Skip to Controls), you'll see that the background stays static. Kinda sucks, but I guess there may be a use for this.
This is what we want for panoramas.
We can use a CubeTextureLoader to select the path of where all of our images are, and then load them as an array of images:
var texture = new THREE.CubeTextureLoader() .setPath( 'assets/textures/cube/Bridge2/' ) .load( [ 'posx.jpg', 'negx.jpg', 'posy.jpg', 'negy.jpg', 'posz.jpg', 'negz.jpg' ] ); this.scene.background = texture;
This part is going to take some effort. There is an example here that does this.
I don't really like how they accomplish this with creating a 1x1x1 cube in the scene painted with the sides of the image, so I've externalized the steps to creating this scene here:
Be able to grab and drag the scene around. These don't seem to be built in, but some of the examples in the Three.JS repo has some things we can extract out of it.
Copy out the file from examples/js/controls/OrthographicTrackballControls.js
to a place that makes sense to you in your repo. I placed it in assets/js/controls
.
Open your html page and add a reference to that script:
<script src="../assets/js/controls/OrbitControls.js"></script>
Note: Be sure this is before your main Three.JS logic so you can use it immediately.
this
reference is because I'm actually creating a Visualizer instance and doing all of this inside the Visualizer class.this.controls = new THREE.OrbitControls( this.camera, this.renderer.domElement ); this.controls.enableZoom = false; this.controls.enablePan = false; this.controls.enableDamping = true;
Feel free to remove the last three lines if you don't want those settings on.
We can make a lot of different kinds of objects with different kinds of materials. I'm going to skip a bunch and go straight to sprites as this is what I'm dealing with right now.
We'll just place a regular sprite off-center in the scene:
const spriteMap = new THREE.TextureLoader().load( "../assets/textures/sprite2.png" ); const spriteMaterial = new THREE.SpriteMaterial( { map: spriteMap, color: 0xffffff } ); const sprite = new THREE.Sprite( spriteMaterial ); sprite.position.z = 10 this.scene.add( sprite );