block by HarryStevens e159afb21b227ed42e250013c385115c

Rotating Cube

Full Screen

A demostration of the Getting Started guide from the Three.js documentation. The wireframe around the cube is from an answer to a StackOverflow question.

index.html

<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge">
		<meta name="viewport" content="width=device-width, initial-scale=1">		
		<style>
			body {
				margin: 0; 
			}
			canvas {
				width: 100%;
				height: 100%;
			}
			#controls {
				position: absolute;
				padding: 10px;
				color: #fff;
				font-family: "Helvetica Neue", sans-serif;
				background: rgba(255, 255, 255, .1);
			}
			#controls .input-wrapper {
				display: inline-block;
				text-align: center;
			}
		</style>
	</head>
	<body>
		<div id="controls">
			<div class="input-wrapper">
				<div>Vertical rotation</div>
				<input id="x" type="range" value="0" min="0" max="1000">
			</div>
			<div class="input-wrapper">
				<div>Horizontal rotation</div>
				<input id="y" type="range" value="1000" min="0" max="1000">
			</div>
		</div>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/88/three.min.js"></script>
		<script>
			var scene = new THREE.Scene();

			// There are a few different cameras in three.js. For now, let's use a PerspectiveCamera.

			// The first attribute is the field of view. 
			// FOV is the extent of the scene that is seen on the display at any given moment.
			// The value is in degrees.

			// The second one is the aspect ratio.
			// You almost always want to use the width of the element divided by the height,
			// or you'll get the same result as when you play old movies on a widescreen TV -
			// the image looks squished.

			// The next two attributes are the near and far clipping plane.
			// What that means, is that objects further away from the camera than the value of far
			// or closer than near won't be rendered.
			// You don't have to worry about this now, but you may want to use other values in your apps
			// to get better performance.
			var camera = new THREE.PerspectiveCamera(75, window.innerWidth  / window.innerHeight, 0.1, 1000);

			// Next up is the renderer. This is where the magic happens.
			// In addition to the WebGLRenderer we use here, three.js comes with a few others,
			// often used as fallbacks for users with older browsers
			// or for those who don't have WebGL support for some reason.

			// In addition to creating the renderer instance,
			// we also need to set the size at which we want it to render our app.
			// It's a good idea to use the width and height of the area we want to fill with our app -
			// in this case, the width and height of the browser window. For performance intensive apps,
			// you can also give setSize smaller values, like window.innerWidth/2 and window.innerHeight/2,
			// which will make the app render at half size.

			// If you wish to keep the size of your app but render it at a lower resolution,
			// you can do so by calling setSize with false as updateStyle (the third argument).
			// For example, setSize(window.innerWidth/2, window.innerHeight/2, false) will render your app
			// at half resolution, given that your <canvas> has 100% width and height.
			var renderer = new THREE.WebGLRenderer();
			renderer.setSize(window.innerWidth, window.innerHeight);

			// Last but not least, we add the renderer element to our HTML document.
			// This is a <canvas> element the renderer uses to display the scene to us.
			document.body.appendChild(renderer.domElement);

			// To create a cube, we need a BoxGeometry.
			// This is an object that contains all the points (vertices) and fill (faces) of the cube.
			// We'll explore this more in the future.
			var geometry = new THREE.BoxGeometry(2, 2, 2);

			// In addition to the geometry, we need a material to color it.
			// Three.js comes with several materials, but we'll stick to the MeshBasicMaterial for now.
			// All materials take an object of properties which will be applied to them.
			// To keep things very simple, we only supply a color attribute of 0x00ff00, which is green.
			// This works the same way that colors work in CSS or Photoshop (hex colors).
			var material = new THREE.MeshBasicMaterial({ color: "steelblue" });

			// The third thing we need is a Mesh.
			// A mesh is an object that takes a geometry, and applies a material to it,
			// which we then can insert to our scene, and move freely around.
			var cube = new THREE.Mesh(geometry, material);

			// By default, when we call scene.add(), the thing we add will be added to the coordinates (0,0,0).
			// This would cause both the camera and the cube to be inside each other.
			// To avoid this, we simply move the camera out a bit.
			scene.add(cube);
			camera.position.z = 5;

			// From https://stackoverflow.com/questions/20153705/three-js-wireframe-material-all-polygons-vs-just-edges/
			// If you want to render a wireframe of a given geometry, you can now use this pattern:
			// WireframeGeometry will render all edges. EdgesGeometry will render the hard edges only.
			var geo = new THREE.EdgesGeometry(geometry); // or WireframeGeometry(geometry)
			var mat = new THREE.LineBasicMaterial({ color: "white", linewidth: 1 });
			var wireframe = new THREE.LineSegments(geo, mat);
			scene.add(wireframe);

			// This will create a loop that causes the renderer to draw the scene 60 times per second.

			// This will be run every frame (60 times per second),
			// and give the cube (and wireframe) a nice rotation animation.
			// Basically, anything you want to move or change while the app is running 
			// has to go through the animate loop.
			// You can of course call other functions from there,
			// so that you don't end up with a animate function that's hundreds of lines.
			function animate() {
				// If you're new to writing games in the browser,
				// you might say "why don't we just create a setInterval?"
				// The thing is - we could, but requestAnimationFrame has a number of advantages.
				// Perhaps the most important one is that it pauses 
				// hen the user navigates to another browser tab,
				// hence not wasting their precious processing power and battery life.
				requestAnimationFrame(animate);

				var x = Math.sqrt(document.getElementById("x").value) / 1000;
				var y = Math.sqrt(document.getElementById("y").value) / 1000;

				cube.rotation.x += x;
				cube.rotation.y += y;

				wireframe.rotation.x += x;
				wireframe.rotation.y += y;

				renderer.render(scene, camera);
			}
			animate();			

			window.onmousemove = () => {
				var	mouse_x = event.clientX,
				    mouse_y = event.clientY,
						controls_bounds = document.getElementById("controls").getBoundingClientRect();
				
				if (mouse_x > controls_bounds.width || mouse_y > controls_bounds.height){
					document.getElementById("x").value = mouse_y / window.innerHeight * 1000;
					document.getElementById("y").value = mouse_x / window.innerWidth * 1000;	
				}				
			}
		</script>
	</body>
</html>