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.
forked from HarryStevens's block: Rotating Cube
license: gpl-3.0 |
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.
forked from HarryStevens's block: Rotating Cube
<!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> |
�PNG | |