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 | |