Three.js進階篇之7
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <style> body {margin: 0;} body, html {overflow: hidden;} body, html, .canvasbox {width: 100%;height: 100%;} /* 座標系 */ .zuobiaoxi {position: absolute;display: table;right: 3px;top: 3px;font-size: 12px;z-index: 1;} .zuobiaoxi, .zuobiaoxi h6 {color: #fff;} .zuobiaoxi h6, .zuobiaoxi p {margin: 2px 0;} .zuobiaoxi h6 {font-size: 12px;font-weight: normal;} </style> </head> <body> <div class="canvasbox" id="canvasbox"></div> <div class="zuobiaoxi"> <h6>攝像機座標</h6> <p>X:<span id="zuobiao-x"></span></p> <p>Y:<span id="zuobiao-y"></span></p> <p>Z:<span id="zuobiao-z"></span></p> </div> <script src="https://cdn.bootcss.com/three.js/r76/three.min.js"></script> <script src="https://cdn.bootcss.com/stats.js/r16/Stats.min.js"></script> <script>/*控制攝像機的外掛*/ /** * @author qiao / https://github.com/qiao * @author mrdoob / http://mrdoob.com * @author alteredq / http://alteredqualia.com/ * @author WestLangley / http://github.com/WestLangley * @author erich666 / http://erichaines.com */ // This set of controls performs orbiting, dollying (zooming), and panning. Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default). Orbit - left mouse / touch: one finger move Zoom - middle mouse, or mousewheel / touch: two finger spread or squish Pan - right mouse, or arrow keys / touch: three finter swipe THREE.OrbitControls=function(object,domElement){this.object=object;this.domElement=(domElement!==undefined)?domElement:document;this.enabled=true;this.target=new THREE.Vector3();this.minDistance=0;this.maxDistance=Infinity;this.minZoom=0;this.maxZoom=Infinity;this.minPolarAngle=0;this.maxPolarAngle=Math.PI;this.minAzimuthAngle= -Infinity;this.maxAzimuthAngle=Infinity;this.enableDamping=false;this.dampingFactor=0.25;this.enableZoom=true;this.zoomSpeed=1.0;this.enableRotate=true;this.rotateSpeed=1.0;this.enablePan=true;this.keyPanSpeed=7.0;this.autoRotate=false;this.autoRotateSpeed=2.0;this.enableKeys=true;this.keys={LEFT:37,UP:38,RIGHT:39,BOTTOM:40};this.mouseButtons={ORBIT:THREE.MOUSE.LEFT,ZOOM:THREE.MOUSE.MIDDLE,PAN:THREE.MOUSE.RIGHT};this.target0=this.target.clone();this.position0=this.object.position.clone();this.zoom0=this.object.zoom;this.getPolarAngle=function(){return phi};this.getAzimuthalAngle=function(){return theta};this.reset=function(){scope.target.copy(scope.target0);scope.object.position.copy(scope.position0);scope.object.zoom=scope.zoom0;scope.object.updateProjectionMatrix();scope.dispatchEvent(changeEvent);scope.update();state=STATE.NONE};this.update=function(){var offset=new THREE.Vector3();var quat=new THREE.Quaternion().setFromUnitVectors(object.up,new THREE.Vector3(0,1,0));var quatInverse=quat.clone().inverse();var lastPosition=new THREE.Vector3();var lastQuaternion=new THREE.Quaternion();return function(){var position=scope.object.position;offset.copy(position).sub(scope.target);offset.applyQuaternion(quat);spherical.setFromVector3(offset);if(scope.autoRotate&&state===STATE.NONE){rotateLeft(getAutoRotationAngle())}spherical.theta+=sphericalDelta.theta;spherical.phi+=sphericalDelta.phi;spherical.theta=Math.max(scope.minAzimuthAngle,Math.min(scope.maxAzimuthAngle,spherical.theta));spherical.phi=Math.max(scope.minPolarAngle,Math.min(scope.maxPolarAngle,spherical.phi));spherical.makeSafe();spherical.radius*=scale;spherical.radius=Math.max(scope.minDistance,Math.min(scope.maxDistance,spherical.radius));scope.target.add(panOffset);offset.setFromSpherical(spherical);offset.applyQuaternion(quatInverse);position.copy(scope.target).add(offset);scope.object.lookAt(scope.target);if(scope.enableDamping===true){sphericalDelta.theta*=(1-scope.dampingFactor);sphericalDelta.phi*=(1-scope.dampingFactor)}else{sphericalDelta.set(0,0,0)}scale=1;panOffset.set(0,0,0);if(zoomChanged||lastPosition.distanceToSquared(scope.object.position)>EPS||8*(1-lastQuaternion.dot(scope.object.quaternion))>EPS){scope.dispatchEvent(changeEvent);lastPosition.copy(scope.object.position);lastQuaternion.copy(scope.object.quaternion);zoomChanged=false;return true}return false}}();this.dispose=function(){scope.domElement.removeEventListener('contextmenu',onContextMenu,false);scope.domElement.removeEventListener('mousedown',onMouseDown,false);scope.domElement.removeEventListener('mousewheel',onMouseWheel,false);scope.domElement.removeEventListener('MozMousePixelScroll',onMouseWheel,false);scope.domElement.removeEventListener('touchstart',onTouchStart,false);scope.domElement.removeEventListener('touchend',onTouchEnd,false);scope.domElement.removeEventListener('touchmove',onTouchMove,false);document.removeEventListener('mousemove',onMouseMove,false);document.removeEventListener('mouseup',onMouseUp,false);document.removeEventListener('mouseout',onMouseUp,false);window.removeEventListener('keydown',onKeyDown,false);};var scope=this;var changeEvent={type:'change'};var startEvent={type:'start'};var endEvent={type:'end'};var STATE={NONE: -1,ROTATE:0,DOLLY:1,PAN:2,TOUCH_ROTATE:3,TOUCH_DOLLY:4,TOUCH_PAN:5};var state=STATE.NONE;var EPS=0.000001;var spherical=new THREE.Spherical();var sphericalDelta=new THREE.Spherical();var scale=1;var panOffset=new THREE.Vector3();var zoomChanged=false;var rotateStart=new THREE.Vector2();var rotateEnd=new THREE.Vector2();var rotateDelta=new THREE.Vector2();var panStart=new THREE.Vector2();var panEnd=new THREE.Vector2();var panDelta=new THREE.Vector2();var dollyStart=new THREE.Vector2();var dollyEnd=new THREE.Vector2();var dollyDelta=new THREE.Vector2();function getAutoRotationAngle(){return 2*Math.PI/60/60*scope.autoRotateSpeed}function getZoomScale(){return Math.pow(0.95,scope.zoomSpeed)}function rotateLeft(angle){sphericalDelta.theta-=angle}function rotateUp(angle){sphericalDelta.phi-=angle}var panLeft=function(){var v=new THREE.Vector3();return function panLeft(distance,objectMatrix){v.setFromMatrixColumn(objectMatrix,0);v.multiplyScalar(-distance);panOffset.add(v)}}();var panUp=function(){var v=new THREE.Vector3();return function panUp(distance,objectMatrix){v.setFromMatrixColumn(objectMatrix,1);v.multiplyScalar(distance);panOffset.add(v)}}();var pan=function(){var offset=new THREE.Vector3();return function(deltaX,deltaY){var element=scope.domElement===document?scope.domElement.body:scope.domElement;if(scope.object instanceof THREE.PerspectiveCamera){var position=scope.object.position;offset.copy(position).sub(scope.target);var targetDistance=offset.length();targetDistance*=Math.tan((scope.object.fov/2)*Math.PI/180.0);panLeft(2*deltaX*targetDistance/element.clientHeight,scope.object.matrix);panUp(2*deltaY*targetDistance/element.clientHeight,scope.object.matrix)}else if(scope.object instanceof THREE.OrthographicCamera){panLeft(deltaX*(scope.object.right-scope.object.left)/scope.object.zoom/element.clientWidth,scope.object.matrix);panUp(deltaY*(scope.object.top-scope.object.bottom)/scope.object.zoom/element.clientHeight,scope.object.matrix)}else{console.warn('WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.');scope.enablePan=false}}}();function dollyIn(dollyScale){if(scope.object instanceof THREE.PerspectiveCamera){scale/=dollyScale}else if(scope.object instanceof THREE.OrthographicCamera){scope.object.zoom=Math.max(scope.minZoom,Math.min(scope.maxZoom,scope.object.zoom*dollyScale));scope.object.updateProjectionMatrix();zoomChanged=true}else{console.warn('WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.');scope.enableZoom=false}}function dollyOut(dollyScale){if(scope.object instanceof THREE.PerspectiveCamera){scale*=dollyScale}else if(scope.object instanceof THREE.OrthographicCamera){scope.object.zoom=Math.max(scope.minZoom,Math.min(scope.maxZoom,scope.object.zoom/dollyScale));scope.object.updateProjectionMatrix();zoomChanged=true}else{console.warn('WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.');scope.enableZoom=false}}function handleMouseDownRotate(event){rotateStart.set(event.clientX,event.clientY)}function handleMouseDownDolly(event){dollyStart.set(event.clientX,event.clientY)}function handleMouseDownPan(event){panStart.set(event.clientX,event.clientY)}function handleMouseMoveRotate(event){rotateEnd.set(event.clientX,event.clientY);rotateDelta.subVectors(rotateEnd,rotateStart);var element=scope.domElement===document?scope.domElement.body:scope.domElement;rotateLeft(2*Math.PI*rotateDelta.x/element.clientWidth*scope.rotateSpeed);rotateUp(2*Math.PI*rotateDelta.y/element.clientHeight*scope.rotateSpeed);rotateStart.copy(rotateEnd);scope.update()}function handleMouseMoveDolly(event){dollyEnd.set(event.clientX,event.clientY);dollyDelta.subVectors(dollyEnd,dollyStart);if(dollyDelta.y>0){dollyIn(getZoomScale())}else if(dollyDelta.y<0){dollyOut(getZoomScale())}dollyStart.copy(dollyEnd);scope.update()}function handleMouseMovePan(event){panEnd.set(event.clientX,event.clientY);panDelta.subVectors(panEnd,panStart);pan(panDelta.x,panDelta.y);panStart.copy(panEnd);scope.update()}function handleMouseUp(event){}function handleMouseWheel(event){var delta=0;if(event.wheelDelta!==undefined){delta=event.wheelDelta}else if(event.detail!==undefined){delta= -event.detail}if(delta>0){dollyOut(getZoomScale())}else if(delta<0){dollyIn(getZoomScale())}scope.update()}function handleKeyDown(event){switch(event.keyCode){case scope.keys.UP:pan(0,scope.keyPanSpeed);scope.update();break;case scope.keys.BOTTOM:pan(0,-scope.keyPanSpeed);scope.update();break;case scope.keys.LEFT:pan(scope.keyPanSpeed,0);scope.update();break;case scope.keys.RIGHT:pan(-scope.keyPanSpeed,0);scope.update();break}}function handleTouchStartRotate(event){rotateStart.set(event.touches[0].pageX,event.touches[0].pageY)}function handleTouchStartDolly(event){var dx=event.touches[0].pageX-event.touches[1].pageX;var dy=event.touches[0].pageY-event.touches[1].pageY;var distance=Math.sqrt(dx*dx+dy*dy);dollyStart.set(0,distance)}function handleTouchStartPan(event){panStart.set(event.touches[0].pageX,event.touches[0].pageY)}function handleTouchMoveRotate(event){rotateEnd.set(event.touches[0].pageX,event.touches[0].pageY);rotateDelta.subVectors(rotateEnd,rotateStart);var element=scope.domElement===document?scope.domElement.body:scope.domElement;rotateLeft(2*Math.PI*rotateDelta.x/element.clientWidth*scope.rotateSpeed);rotateUp(2*Math.PI*rotateDelta.y/element.clientHeight*scope.rotateSpeed);rotateStart.copy(rotateEnd);scope.update()}function handleTouchMoveDolly(event){var dx=event.touches[0].pageX-event.touches[1].pageX;var dy=event.touches[0].pageY-event.touches[1].pageY;var distance=Math.sqrt(dx*dx+dy*dy);dollyEnd.set(0,distance);dollyDelta.subVectors(dollyEnd,dollyStart);if(dollyDelta.y>0){dollyOut(getZoomScale())}else if(dollyDelta.y<0){dollyIn(getZoomScale())}dollyStart.copy(dollyEnd);scope.update()}function handleTouchMovePan(event){panEnd.set(event.touches[0].pageX,event.touches[0].pageY);panDelta.subVectors(panEnd,panStart);pan(panDelta.x,panDelta.y);panStart.copy(panEnd);scope.update()}function handleTouchEnd(event){}function onMouseDown(event){if(scope.enabled===false){return}event.preventDefault();if(event.button===scope.mouseButtons.ORBIT){if(scope.enableRotate===false){return}handleMouseDownRotate(event);state=STATE.ROTATE}else if(event.button===scope.mouseButtons.ZOOM){if(scope.enableZoom===false){return}handleMouseDownDolly(event);state=STATE.DOLLY}else if(event.button===scope.mouseButtons.PAN){if(scope.enablePan===false){return}handleMouseDownPan(event);state=STATE.PAN}if(state!==STATE.NONE){document.addEventListener('mousemove',onMouseMove,false);document.addEventListener('mouseup',onMouseUp,false);document.addEventListener('mouseout',onMouseUp,false);scope.dispatchEvent(startEvent)}}function onMouseMove(event){if(scope.enabled===false){return}event.preventDefault();if(state===STATE.ROTATE){if(scope.enableRotate===false){return}handleMouseMoveRotate(event)}else if(state===STATE.DOLLY){if(scope.enableZoom===false){return}handleMouseMoveDolly(event)}else if(state===STATE.PAN){if(scope.enablePan===false){return}handleMouseMovePan(event)}}function onMouseUp(event){if(scope.enabled===false){return}handleMouseUp(event);document.removeEventListener('mousemove',onMouseMove,false);document.removeEventListener('mouseup',onMouseUp,false);document.removeEventListener('mouseout',onMouseUp,false);scope.dispatchEvent(endEvent);state=STATE.NONE}function onMouseWheel(event){if(scope.enabled===false||scope.enableZoom===false||(state!==STATE.NONE&&state!==STATE.ROTATE)){return}event.preventDefault();event.stopPropagation();handleMouseWheel(event);scope.dispatchEvent(startEvent);scope.dispatchEvent(endEvent)}function onKeyDown(event){if(scope.enabled===false||scope.enableKeys===false||scope.enablePan===false){return}handleKeyDown(event)}function onTouchStart(event){if(scope.enabled===false){return}switch(event.touches.length){case 1:if(scope.enableRotate===false){return}handleTouchStartRotate(event);state=STATE.TOUCH_ROTATE;break;case 2:if(scope.enableZoom===false){return}handleTouchStartDolly(event);state=STATE.TOUCH_DOLLY;break;case 3:if(scope.enablePan===false){return}handleTouchStartPan(event);state=STATE.TOUCH_PAN;break;default:state=STATE.NONE}if(state!==STATE.NONE){scope.dispatchEvent(startEvent)}}function onTouchMove(event){if(scope.enabled===false){return}event.preventDefault();event.stopPropagation();switch(event.touches.length){case 1:if(scope.enableRotate===false){return}if(state!==STATE.TOUCH_ROTATE){return;}handleTouchMoveRotate(event);break;case 2:if(scope.enableZoom===false){return}if(state!==STATE.TOUCH_DOLLY){return;}handleTouchMoveDolly(event);break;case 3:if(scope.enablePan===false){return}if(state!==STATE.TOUCH_PAN){return;}handleTouchMovePan(event);break;default:state=STATE.NONE}}function onTouchEnd(event){if(scope.enabled===false){return}handleTouchEnd(event);scope.dispatchEvent(endEvent);state=STATE.NONE}function onContextMenu(event){event.preventDefault()}scope.domElement.addEventListener('contextmenu',onContextMenu,false);scope.domElement.addEventListener('mousedown',onMouseDown,false);scope.domElement.addEventListener('mousewheel',onMouseWheel,false);scope.domElement.addEventListener('MozMousePixelScroll',onMouseWheel,false);scope.domElement.addEventListener('touchstart',onTouchStart,false);scope.domElement.addEventListener('touchend',onTouchEnd,false);scope.domElement.addEventListener('touchmove',onTouchMove,false);window.addEventListener('keydown',onKeyDown,false);this.update()};THREE.OrbitControls.prototype=Object.create(THREE.EventDispatcher.prototype);THREE.OrbitControls.prototype.constructor=THREE.OrbitControls;Object.defineProperties(THREE.OrbitControls.prototype,{center:{get:function(){console.warn('THREE.OrbitControls: .center has been renamed to .target');return this.target}},noZoom:{get:function(){console.warn('THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.');return!this.enableZoom},set:function(value){console.warn('THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.');this.enableZoom=!value}},noRotate:{get:function(){console.warn('THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.');return!this.enableRotate},set:function(value){console.warn('THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.');this.enableRotate=!value}},noPan:{get:function(){console.warn('THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.');return!this.enablePan},set:function(value){console.warn('THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.');this.enablePan=!value}},noKeys:{get:function(){console.warn('THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.');return!this.enableKeys},set:function(value){console.warn('THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.');this.enableKeys=!value}},staticMoving:{get:function(){console.warn('THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.');return!this.constraint.enableDamping},set:function(value){console.warn('THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.');this.constraint.enableDamping=!value}},dynamicDampingFactor:{get:function(){console.warn('THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.');return this.constraint.dampingFactor},set:function(value){console.warn('THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.');this.constraint.dampingFactor=value}}}); </script> <script> (function(canvasbox, _window){ /* 基礎 */ var scene, camera, renderer, states, controls; var initCamera; // 初始化照相機 // 太陽、水、金、地、火、木、土、土星環、天、天王星環、海王星 var taiyang, shui, jin, di, huo, mu, tu, tu_huan, tian, tian_huan, hai; (function(){ // 場景 scene = new THREE.Scene(); // 照相機 initCamera = function(){ camera = new THREE.PerspectiveCamera(60, canvasbox.clientWidth / canvasbox.clientHeight, 1, 1000); } initCamera(); camera.position.set(250, 250, 250); camera.lookAt({ x: 0, y: 0, z: 0 }); // 渲染器 renderer = new THREE.WebGLRenderer(); renderer.setSize(canvasbox.clientWidth, canvasbox.clientHeight); renderer.clear(0xffffff); canvasbox.appendChild(renderer.domElement); // 監視器 states = new Stats(); document.body.appendChild(states.domElement); states.domElement.style.position = "absolute"; states.domElement.style.left = 0; states.domElement.style.top = 0; // controls = new THREE.OrbitControls(camera); })(); /* 光照 */ (function(){ var huanjing = new THREE.AmbientLight(0x8f8f8f); scene.add(huanjing); })(); /* 宇宙背景 */ (function(PIC2){ var yuzhou_geometr = new THREE.PlaneGeometry(500, 500, 1, 1); var yuzhou_material = new THREE.MeshBasicMaterial({ map: THREE.ImageUtils.loadTexture("http://www.w3cfuns.com/attachment/extend/notes/pics/201605/12/212412k1141w4h1nt1fftd.jpg"), side: THREE.DoubleSide }); var yuzhou = []; for(var i = 0; i < 6; i++){ yuzhou.push(new THREE.Mesh(yuzhou_geometr, yuzhou_material)); scene.add(yuzhou[i]); } // 正面 yuzhou[0].position.set(0, 0, 250); // 反面 yuzhou[1].position.set(0, 0, -250); // 左面 yuzhou[2].position.set(-250, 0, 0); yuzhou[2].rotation.set(0, PIC2, 0); // 右面 yuzhou[3].position.set(250, 0, 0); yuzhou[3].rotation.set(0, PIC2, 0); // 上面 yuzhou[4].position.set(0, 250, 0); yuzhou[4].rotation.set(PIC2, 0, 0); // 下面 yuzhou[5].position.set(0, -250, 0); yuzhou[5].rotation.set(PIC2, 0, 0); })(Math.PI / 2); /* 星球 */ (function(){ // 太陽 (function(){ var taiyang_geometry = new THREE.SphereGeometry(32, 100, 100); var taiyang_material = new THREE.MeshLambertMaterial({ emissive: 0xe65f05, map: THREE.ImageUtils.loadTexture("http://www.w3cfuns.com/attachment/extend/notes/pics/201605/12/212414y669k6hq6yq9yoyd.jpg"), side: THREE.DoubleSide, color: 0xffffff }); taiyang = new THREE.Mesh(taiyang_geometry, taiyang_material); scene.add(taiyang); taiyang.position.set(0, 0, 0); var taiyang_light = new THREE.PointLight(0xffffff, 1, 350); taiyang_light.position.set(0, 0, 0); scene.add(taiyang_light); })(); // 水星 (function(){ var shui_geometry = new THREE.SphereGeometry(1, 100, 100); var shui_material = new THREE.MeshLambertMaterial({ map: THREE.ImageUtils.loadTexture("http://www.w3cfuns.com/attachment/extend/notes/pics/201605/12/212414pff85jucjf2fc5aj.jpg"), side: THREE.DoubleSide, }); shui = new THREE.Mesh(shui_geometry, shui_material); scene.add(shui); shui.position.set(0, 0, 35); })(); // 金星 (function(){ var jin_geometry = new THREE.SphereGeometry(2, 100, 100); var jin_material = new THREE.MeshLambertMaterial({ map: THREE.ImageUtils.loadTexture("http://www.w3cfuns.com/attachment/extend/notes/pics/201605/12/212413v1pqsfp17046np69.jpg"), side: THREE.DoubleSide, }); jin = new THREE.Mesh(jin_geometry, jin_material); scene.add(jin); jin.position.set(0, 0, 42); })(); // 地球 (function(){ var di_geometry = new THREE.SphereGeometry(4, 100, 100); var di_material = new THREE.MeshLambertMaterial({ map: THREE.ImageUtils.loadTexture("http://www.w3cfuns.com/attachment/extend/notes/pics/201605/12/212412na5paf7hzrp710pg.jpg"), side: THREE.DoubleSide, }); di = new THREE.Mesh(di_geometry, di_material); scene.add(di); di.position.set(0, 0, 55); })(); // 火星 (function(){ var huo_geometry = new THREE.SphereGeometry(5, 100, 100); var huo_material = new THREE.MeshLambertMaterial({ map: THREE.ImageUtils.loadTexture("http://www.w3cfuns.com/attachment/extend/notes/pics/201605/12/212412p6qt9qgqzo1t96nd.jpg"), side: THREE.DoubleSide, }); huo = new THREE.Mesh(huo_geometry, huo_material); scene.add(huo); huo.position.set(0, 0, 70); })(); // 木星 (function(){ var mu_geometry = new THREE.SphereGeometry(17, 100, 100); var mu_material = new THREE.MeshLambertMaterial({ map: THREE.ImageUtils.loadTexture("http://www.w3cfuns.com/attachment/extend/notes/pics/201605/12/212413y6svmlc52tv288mp.jpg"), side: THREE.DoubleSide, }); mu = new THREE.Mesh(mu_geometry, mu_material); scene.add(mu); mu.position.set(0, 0, 100); mu.rotation.set(0, 20, 0); })(); // 土星 (function(){ var tu_geometry = new THREE.SphereGeometry(11, 100, 100); var tu_material = new THREE.MeshLambertMaterial({ map: THREE.ImageUtils.loadTexture("http://www.w3cfuns.com/attachment/extend/notes/pics/201605/12/212416s4xwrvkw0ar6wutu.jpg"), side: THREE.DoubleSide, }); tu = new THREE.Mesh(tu_geometry, tu_material); scene.add(tu); tu.position.set(0, 0, 140); tu.rotation.set(0.5, 0, 0); // 土星環 var tu_huan_geometry = new THREE.CylinderGeometry(14, 22, 0, 100, 100, true); var tu_huan_material = new THREE.MeshLambertMaterial({ map: THREE.ImageUtils.loadTexture("http://www.w3cfuns.com/attachment/extend/notes/pics/201605/12/212416ikv311fsy7vif3km.jpg"), side: THREE.DoubleSide, }); tu_huan = new THREE.Mesh(tu_huan_geometry, tu_huan_material); scene.add(tu_huan); tu_huan.position.set(0, 0, 140); tu_huan.rotation.set(0.5, 0, 0); })(); // 天王星 (function(){ var tian_geometry = new THREE.SphereGeometry(9, 100, 100); var tian_material = new THREE.MeshLambertMaterial({ map: THREE.ImageUtils.loadTexture("http://www.w3cfuns.com/attachment/extend/notes/pics/201605/12/212414q44z3zeaaenqerbh.jpg"), side: THREE.DoubleSide, }); tian = new THREE.Mesh(tian_geometry, tian_material); scene.add(tian); tian.position.set(0, 0, 170); tian.rotation.set(0, 0, 0.3); // 天王星環 var tian_huan_geometry = new THREE.CylinderGeometry(10, 12, 0, 100, 100, true); var tian_huan_material = new THREE.MeshLambertMaterial({ map: THREE.ImageUtils.loadTexture("http://www.w3cfuns.com/attachment/extend/notes/pics/201605/12/212415e2vkzfvkyjijb386.jpg"), side: THREE.DoubleSide, }); tian_huan = new THREE.Mesh(tian_huan_geometry, tian_huan_material); scene.add(tian_huan); tian_huan.position.set(0, 0, 170); tian_huan.rotation.set(0, 0, 0.3); })(); // 海王星 (function(){ var hai_geometry = new THREE.SphereGeometry(6, 100, 100); var hai_material = new THREE.MeshLambertMaterial({ map: THREE.ImageUtils.loadTexture("http://www.w3cfuns.com/attachment/extend/notes/pics/201605/12/212412utl29a6tzaucac6l.jpg"), side: THREE.DoubleSide, }); hai = new THREE.Mesh(hai_geometry, hai_material); scene.add(hai); hai.position.set(0, 0, 192); })(); })(); /*座標系 // 畫線x (function(){ var geometry = new THREE.Geometry(); var material = new THREE.LineBasicMaterial( { vertexColors: true } ); var color = new THREE.Color( 0xffffff ); // 線的材質可以由2點的顏色決定 var p1 = new THREE.Vector3(200, 0, 0); var p2 = new THREE.Vector3(0, 0, 0); geometry.vertices.push(p1); geometry.vertices.push(p2); geometry.colors.push(color, color); var line = new THREE.Line( geometry, material, THREE.LinePieces ); scene.add(line); })(); // 畫線y (function(){ var geometry = new THREE.Geometry(); var material = new THREE.LineBasicMaterial( { vertexColors: true } ); var color = new THREE.Color( 0x7cfc00 ); // 線的材質可以由2點的顏色決定 var p1 = new THREE.Vector3(0, 200, 0); var p2 = new THREE.Vector3(0, 0, 0); geometry.vertices.push(p1); geometry.vertices.push(p2); geometry.colors.push(color, color); var line = new THREE.Line( geometry, material, THREE.LinePieces ); scene.add(line); })(); // 畫線z (function(){ var geometry = new THREE.Geometry(); var material = new THREE.LineBasicMaterial( { vertexColors: true } ); var color = new THREE.Color( 0x00ffff ); // 線的材質可以由2點的顏色決定 var p1 = new THREE.Vector3(0, 0, 200); var p2 = new THREE.Vector3(0, 0, 0); geometry.vertices.push(p1); geometry.vertices.push(p2); geometry.colors.push(color, color); var line = new THREE.Line( geometry, material, THREE.LinePieces ); scene.add(line); })(); */ /* 初始化 */ (function(){ var PI2 = 2 * Math.PI; // 弧度的最大值 var zuobiaoxi = [ // 顯示座標系的資訊 document.getElementById("zuobiao-x"), // X document.getElementById("zuobiao-y"), // Y document.getElementById("zuobiao-z") // Z ]; // 自轉 function zizhuan(){ taiyang.rotation.y = taiyang.rotation.y + 0.01 >= 2 * PI2 ? 0 : taiyang.rotation.y + 0.01; // 太陽自轉 shui.rotation.y = shui.rotation.y + 0.1 >= 2 * PI2 ? 0 : shui.rotation.y + 0.1; // 水星自轉 jin.rotation.y = jin.rotation.y + 0.05 >= 2 * PI2 ? 0 : jin.rotation.y + 0.05; // 金星自轉 di.rotation.y = di.rotation.y + 0.05 >= 2 * PI2 ? 0 : di.rotation.y + 0.05; // 地球自轉 huo.rotation.y = huo.rotation.y + 0.03 >= 2 * PI2 ? 0 : huo.rotation.y + 0.03; // 火星自轉 mu.rotation.y = mu.rotation.y + 0.003 >= 2 * PI2 ? 0 : mu.rotation.y + 0.003; // 木星自轉 tu.rotation.y = tu.rotation.y + 0.01 >= 2 * PI2 ? 0 : tu.rotation.y + 0.01; // 土星自轉 tian.rotation.y = tian.rotation.y + 0.005 >= 2 * PI2 ? 0 : tian.rotation.y + 0.005; // 天王自轉 hai.rotation.y = hai.rotation.y + 0.003 >= 2 * PI2 ? 0 : hai.rotation.y + 0.003; // 海王星自轉 } // 定義角度 var shui_deg, jin_deg, di_deg, huo_deg, mu_deg, tu_deg, tian_deg, hai_deg; shui_deg = jin_deg = di_deg = huo_deg = mu_deg = tu_deg = tian_deg = hai_deg = 0; // 公轉 function gongzhuan(){ // 水星 shui_deg = shui_deg + 0.1 >= PI2 ? 0 : shui_deg + 0.1; shui.position.set(35 * Math.sin(shui_deg), 0, 35 * Math.cos(shui_deg)); // 金星 jin_deg = jin_deg + 0.07 >= PI2 ? 0 : jin_deg + 0.07; jin.position.set(42 * Math.sin(jin_deg), 0, 42 * Math.cos(jin_deg)); // 地球 di_deg = di_deg + 0.03 >= PI2 ? 0 : di_deg + 0.03; di.position.set(55 * Math.sin(di_deg), 0, 55 * Math.cos(di_deg)); // 火星 huo_deg = huo_deg + 0.01 >= PI2 ? 0 : huo_deg + 0.01; huo.position.set(70 * Math.sin(huo_deg), 0, 70 * Math.cos(huo_deg)); // 木星 mu_deg = mu_deg + 0.002 >= PI2 ? 0 : mu_deg + 0.002; mu.position.set(100 * Math.sin(mu_deg), 0, 100 * Math.cos(mu_deg)); // 土星 tu_deg = tu_deg + 0.0009 >= PI2 ? 0 : tu_deg + 0.0009; tu.position.set(140 * Math.sin(tu_deg), 0, 140 * Math.cos(tu_deg)); tu_huan.position.set(140 * Math.sin(tu_deg), 0, 140 * Math.cos(tu_deg)); // 天王星 tian_deg = tian_deg + 0.0005 >= PI2 ? 0 : tian_deg + 0.0005; tian.position.set(170 * Math.sin(tian_deg), 0, 170 * Math.cos(tian_deg)); tian_huan.position.set(170 * Math.sin(tian_deg), 0, 170 * Math.cos(tian_deg)); // 海王星 hai_deg = hai_deg + 0.0003 >= PI2 ? 0 : hai_deg + 0.0003; hai.position.set(192 * Math.sin(hai_deg), 0, 192 * Math.cos(hai_deg)); } // 顯示資訊 function displayXYZ(){ zuobiaoxi[0].innerHTML = parseInt(camera.position.x); // 攝像機X zuobiaoxi[1].innerHTML = parseInt(camera.position.y); // 攝像機Y zuobiaoxi[2].innerHTML = parseInt(camera.position.z); // 攝像機Z } // 視窗改變事件 function windowChange(){ var x = camera.position.x, y = camera.position.y, z = camera.position.z; initCamera(); controls = new THREE.OrbitControls(camera); camera.position.set(x, y, z); camera.lookAt({ x: 0, y: 0, z: 0 }); renderer.setSize(canvasbox.clientWidth, canvasbox.clientHeight); displayXYZ(); } // 動畫 function animate(){ states.begin(); zizhuan(); gongzhuan(); renderer.clear(); renderer.render(scene, camera); states.end(); requestAnimationFrame(animate); } // 初始化 function init(){ displayXYZ(); _window.addEventListener("resize", windowChange, false); controls.addEventListener("change", displayXYZ, false); requestAnimationFrame(animate); } init(); })(); })(document.getElementById("canvasbox"), window); </script> </body> </html>
轉載地址:http://www.qdfuns.com/notes.php?mod=view&u=17100&id=fc3a521f57a552ae2d8b02fb635d3ae4
相關推薦
Three.js進階篇之7
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <style> body {margin: 0;} body, html {overflow: hidden
Three.js進階篇之2
動畫原理 在這裡,我們將動態畫面簡稱為動畫(animation)。正如動畫片的原理一樣,動畫的本質是利用了人眼的視覺暫留特性,快速地變換畫面,從而產生物體在運動的假象。而對於Three.js程式而言,動畫的實現也是通過在每秒中多次重繪畫面實現的。 為了衡量畫面切換速度
(十二)vue.js元件——進階篇之元件通訊(3)
(1)概述 所謂元件間的通訊,實際上就是指在各個元件間,進行引數或者資訊的相互傳遞。比如我們前面學的通過props給子元件傳參,實際上這就是父元件向子元件進行單向的通訊。 (2)元件間通訊的幾種方式 1.父到子的通訊 父到子的通訊使用我們前面使用的props即可
Netty進階篇之簡單版websocket發訊息(7)
序言:簡單開發前端傳送訊息,後端接收訊息並返回。 1、故事牽引 今天通過一個故事來講解netty,主要講client和ser
JS進階篇--JS陣列reduce()方法詳解及高階技巧
去除巢狀的思路: 用遞迴、reduce()、concat()來實現。 遞迴解決多層巢狀,reduce()解決每層陣列的迭代拼接,concat()來拼接陣列即拆除一層巢狀。 let sum = [0, 1, 2, 3].reduce(function(acc, val)
Java進階篇之十五 ----- JDK1.8的Lambda、Stream和日期的使用詳解(很詳細)
前言 本篇主要講述是Java中JDK1.8的一些新語法特性使用,主要是Lambda、Stream和LocalDate日期的一些使用講解。 Lambda Lambda介紹 Lambda 表示式(lambda expression)是一個匿名函式,Lambda表示式基於數學中的λ演算得名,直接對應於
Android進階篇之引導頁系列之ViewPager實現Animation動畫引導頁
小夥伴們,時隔很久,我又開始來BB了,勿噴,,今天繼續上次所說的引導頁之旅。 其實想實現一個靜態的引導頁還是很容易的,就是一個ViewPager,但是想對每一頁實現動畫效果,比如第一頁有一幾朵雲在飄啊飄!,想實現這種效果對只要瞭解過Animation動畫的人來說也不難實現。
Jenkins外掛開發進階篇之擴充套件外掛功能
之前寫過一篇文章是關於如何開發jenkins外掛,主要講述了開發jenkins外掛時需要準備的環境,如何新建一個jenkins外掛工程,以及對工程專案目錄結構的解析。本文是jenkins外掛開發的進階篇,主要講述如何擴充套件jenkins外掛的功能。如下圖所示:(1)Job任
Fragment進階篇之Fragment生命週期和回退棧
前言 上一篇blog(處女男學Android(八)---Fragment初體驗之實現Tab導航)記錄了fragment的基本概念和基本的使用方法,本篇將逐步深入記錄關於fragment的幾個重要知識點,包括:fragment的生命週期、fragm
2. web前端開發分享-css,js進階篇
一,css進階篇: 等css哪些事兒看了兩三遍之後,需要對看過的知識綜合應用,這時候需要大量的實踐經驗, 簡單的想法:把qq首頁全屏另存為jpg然後通過ps工具切圖結合css轉換成html,有無從下手的地方可以用firebug, chrome除錯工具分析網站結構樣式。如果技術熟練自信可以自己先寫,寫完
Android進階篇之引導頁系列之Splash閃屏Log
最近比較閒,所以會陸續出很多基礎型Demo和高階點的Demo,,小夥伴們肯定又要罵了,孫子又來裝B了 在android應用中,其實閃屏是一個很重要的前期 先上效果圖:就是一個頁面,沒有Logo和公司名幾乎就是一張背景,又要捱罵了 很重要?,這不廢話嗎,不重要為什麼每個應用
反射應用進階篇之自定義反射工具類在springmvc中的應用
本篇使用自定義工具類進行批量處理物件 ---將批量源物件的屬性值注入到實際需要的目標類物件(屬性名相同,型別不同)中 專案使用maven構建war工程: spring+spring MVC+Mybatis 回顧知識點: 事務:--->為什麼在使用AOP時需要使
Android進階篇之ListView、GridView以及ScrollView實現按鈕控制滾動
這次還是一樣,因為專案需要,需要對滾動檢視需要手動控制,也就是點選上下左右按鈕,能讓滾動控制元件觸發對應的操作 在android中,滾動View最基本的有三種,分別是:ListView、GridView和ScrollView 先看效果圖:1、ListView的效果圖,右下角
Data binding 入坑筆記二進階篇之雙向繫結
上一篇介紹了Data binding的基礎用法,你可能會想這也太基礎了,只支援前置資料的繫結,一旦資料變化了UI都監聽不到。不要著急,這一篇就來講到databinding的雙向繫結用法。 0.舉個例子 我們用一個輸入控制元件EditText和一個
[JS進階] HTML5 之文件操作(file)
版本 無效 tran ssl idt 無法讀取 bin erl this 版權聲明:本文為博主原創文章。未經博主同意不得
Netty進階篇之websocket傳送訊息(8)
序言:Netty進階篇之簡單版websocket發訊息(7) 大概和下面的程式碼就成相似,如果不懂,可以看一下這篇部落格
《手把手教你》系列進階篇之1-python+ selenium自動化測試 - python基礎掃盲(詳細教程)
1. 簡介 如果你從一開始就跟著巨集哥看部落格文章到這裡,基礎篇和練習篇的文章。如果你認真看過,並且手動去敲過每一篇的指令碼程式碼,那邊恭喜你,至少說你算真正會利用Python+Selenium編寫自動化指令碼了,你基本掌握了Selenium中webdriver的大部分常用的方法函式。有大佬曾經說過,自動
《手把手教你》系列進階篇之2-python+ selenium自動化測試 - python基礎掃盲(詳細教程)
1. 簡介 這篇文章主要是分享講解一下,如何封裝自己用到的方法和類。以便方便自己和別人的呼叫,這樣就可以避免重複地再造輪子。 封裝(Encapsulation)是面向物件的三大特徵之一(另外兩個是繼承和多型),它指的是將物件的狀態資訊隱藏在物件內部,不允許外部程式直接訪問物件內部資訊,而是通過該類所提
《手把手教你》系列進階篇之3-python+ selenium自動化測試 - python幾種騷操作你都知道嗎?(詳細教程)
1. 簡介 這篇文章主要是給小夥伴或者童鞋們介紹和分享 python幾種騷操:讀取配置檔案、獲取根目錄的相對路徑、獲取系統時間和格式化時間顯示、字串切割等等操作。為後邊的自動化框架打下一個結實的基礎。 2. Python讀取配置檔案內容 本文來介紹下Python中如何讀取配置檔案
Spring Cloud進階篇之Eureka原理分析
前言 之前寫了幾篇Spring Cloud的小白教程,相信看過的朋友對Spring Cloud中的一些應用有了簡單的瞭解,寫小白篇的目的就是為初學者建立一個基本概念,讓初學者在學習的道路上建立一定的基礎。 從今天開始,我會持續更新幾篇Spring Cloud的進階教程。 Eureka簡介 Eu