"use strict"; // 參考 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode //////////////////////////////////////////////////////////////////////////////// // 時鐘作業:正確地旋轉指針 //////////////////////////////////////////////////////////////////////////////// var camera, scene, renderer; var cameraControls, effectController; var clock = new THREE.Clock(); var gridX = false; var gridY = false; var gridZ = false; var axes = true; var ground = true; function fillScene() { scene = new THREE.Scene(); scene.fog = new THREE.Fog( 0x808080, 2000, 4000 ); // 光源 var ambientLight = new THREE.AmbientLight( 0x222222 ); var light = new THREE.DirectionalLight( 0xFFFFFF, 1.0 ); light.position.set( 200, 400, 500 ); var light2 = new THREE.DirectionalLight( 0xFFFFFF, 1.0 ); light2.position.set( -500, 250, -200 ); scene.add(ambientLight); scene.add(light); scene.add(light2); var faceMaterial = new THREE.MeshLambertMaterial( { color: 0xFFECA9 } ); var markMaterial = new THREE.MeshLambertMaterial( { color: 0x89581F } ); var mark12Material = new THREE.MeshLambertMaterial( { color: 0xE6880E } ); var minuteHandMaterial = new THREE.MeshLambertMaterial( { color: 0x226894 } ); var hourHandMaterial = new THREE.MeshLambertMaterial( { color: 0xE02BFB } ); // 時鐘 var clock = new THREE.Mesh( new THREE.CylinderGeometry( 75, 75, 10, 32 ), faceMaterial ); clock.position.y = 5; scene.add( clock ); // 標記 var cube = new THREE.Mesh( new THREE.CubeGeometry( 20, 4, 15 ), mark12Material ); cube.position.x = 60; cube.position.y = 9; scene.add( cube ); cube = new THREE.Mesh( new THREE.CubeGeometry( 10, 4, 10 ), markMaterial ); cube.position.x = -60; cube.position.y = 9; scene.add( cube ); cube = new THREE.Mesh( new THREE.CubeGeometry( 10, 4, 10 ), markMaterial ); cube.position.z = 60; cube.position.y = 9; scene.add( cube ); cube = new THREE.Mesh( new THREE.CubeGeometry( 10, 4, 10 ), markMaterial ); cube.position.z = -60; cube.position.y = 9; scene.add( cube ); // 你的程式寫在這裡: // 時鐘指針的大小與方向是對的 // 你只要找出施加座標變換的正確順序 cube = new THREE.Mesh( new THREE.CubeGeometry( 70, 4, 4 ), minuteHandMaterial ); cube.position.y = 14; cube.position.x = 70/2 - 10; cube.rotation.y = -60 * Math.PI/180; scene.add( cube ); var sphere = new THREE.Mesh( new THREE.SphereGeometry( 0.5, 32, 16 ), hourHandMaterial ); sphere.position.y = 18; // 將一個時鐘指針移到另一個之上 sphere.position.x = 50/2 - 10; sphere.rotation.y = 30 * Math.PI/180; sphere.scale.x = 50; sphere.scale.y = 4; sphere.scale.z = 4; scene.add( sphere ); } function init() { var canvasWidth = window.innerWidth; var canvasHeight = window.innerHeight; var canvasRatio = canvasWidth / canvasHeight; // RENDERER renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.gammaInput = true; renderer.gammaOutput = true; renderer.setSize(canvasWidth, canvasHeight); renderer.setClearColorHex( 0xAAAAAA, 1.0 ); // 攝影機 camera = new THREE.PerspectiveCamera( 30, canvasRatio, 1, 10000 ); camera.position.set( -420, 400, 100 ); // 控制 cameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement); cameraControls.target.set(0,0,0); fillScene(); } function drawHelpers() { if (ground) { Coordinates.drawGround({size:10000}); } if (gridX) { Coordinates.drawGrid({size:10000,scale:0.01}); } if (gridY) { Coordinates.drawGrid({size:10000,scale:0.01, orientation:"y"}); } if (gridZ) { Coordinates.drawGrid({size:10000,scale:0.01, orientation:"z"}); } if (axes) { Coordinates.drawAllAxes({axisLength:200,axisRadius:1,axisTess:50}); } } function addToDOM() { var container = document.getElementById('container'); var canvas = container.getElementsByTagName('canvas'); if (canvas.length>0) { container.removeChild(canvas[0]); } container.appendChild( renderer.domElement ); } function animate() { window.requestAnimationFrame(animate); render(); } function render() { var delta = clock.getDelta(); cameraControls.update(delta); if ( effectController.newGridX !== gridX || effectController.newGridY !== gridY || effectController.newGridZ !== gridZ || effectController.newGround !== ground || effectController.newAxes !== axes) { gridX = effectController.newGridX; gridY = effectController.newGridY; gridZ = effectController.newGridZ; ground = effectController.newGround; axes = effectController.newAxes; fillScene(); drawHelpers(); } renderer.render(scene, camera); } function setupGui() { effectController = { newGridX: gridX, newGridY: gridY, newGridZ: gridZ, newGround: ground, newAxes: axes }; var gui = new dat.GUI(); gui.add( effectController, "newGridX").name("顯示 XZ 格線"); gui.add( effectController, "newGridY" ).name("顯示 YZ 格線"); gui.add( effectController, "newGridZ" ).name("顯示 XY 格線"); gui.add( effectController, "newGround" ).name("顯示地面"); gui.add( effectController, "newAxes" ).name("顯示軸線"); } document.addEventListener("DOMContentLoaded", function () { try { init(); setupGui(); drawHelpers(); addToDOM(); animate(); } catch(e) { var errorReport = "你的程式遇到不可復原的錯誤,無法繪製 Canvas。錯誤是:<br/><br/>"; $('#container').append(errorReport+e); } })