查看場景切換效果javascript
用6個面組成的立方體做爲場景圖,發現會出現變形的現象,css3DRenderer 不會變形,可是不方便增長文字,最後採用scene的背景做爲場景,背景是用cubeTextureLoader()加載的。css
完整代碼html
<button id="btn1" class="btn btn-primary" style="margin-bottom:20px;">切換場景1</button> <button id="btn2" class="btn btn-warning" style="margin-bottom:20px;">切換場景2</button> <canvas id="canvas" width="64" height="64" style="display:none;"></canvas> <div class="canvasWrap" id="canvasWrap" style="margin-bottom:15px;"></div>
<script src="../plugins/jQuery/jQuery-2.1.4.min.js"></script> <script src="../bootstrap/js/bootstrap.js"></script> <script src="../dist/js/three.js"></script> <script src="../dist/js/OrbitControls.js"></script>
<script> var width, height; var renderer; function initRender() { width = document.getElementById('canvasWrap').clientWidth; height = document.getElementById('canvasWrap').clientHeight; renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(width, height); document.getElementById('canvasWrap').appendChild(renderer.domElement); } var camera; function initCamera() { camera = new THREE.PerspectiveCamera(75, width / height, 1, 1000); console.log(camera) camera.position.set(0, 0, 300); } var scene; function initScene() { scene = new THREE.Scene(); //scene.background = new THREE.TextureLoader().load( '../textures/2294472375_24a3b8ef46_o.jpg' ) //scene不會跟着旋轉 scene.background = new THREE.CubeTextureLoader() .setPath('../dist/textures/cube/Bridge2/').load( [ 'posx.jpg', 'negx.jpg', 'posy.jpg', 'negy.jpg', 'posz.jpg', 'negz.jpg' ] ); console.log(scene) } var light; function initLight() { //scene.add(new THREE.AmbientLight(0x404040)); scene.add(new THREE.AmbientLight(0xffffff)); light = new THREE.DirectionalLight(0xffffff); //light.position.set(1,1,1); light.position.set(0, 0, 50); scene.add(light); } var text = "first text"; function showText() { const canvas = document.getElementById("canvas"); const ctx = canvas.getContext("2d"); ctx.canvas.width = 256; const x = 0; const y = 32; ctx.fillStyle = "red"; ctx.font = "30px arial"; ctx.textAlign = "left"; ctx.textBaseline = "middle"; ctx.fillText(text, x, y) } var sprite function showSprite() { showText() const canvasTexture = new THREE.CanvasTexture( document.querySelector("#canvas") ) //canvasTexture.needsUpdate = true; //注意這句不能少 const spritMaterial = new THREE.SpriteMaterial({ map: canvasTexture }) sprite = new THREE.Sprite(spritMaterial) sprite.position.set(-380, 100, 0); //精靈的默認大小很小估計是[1,1,1] sprite.scale.set(0.64 * 256, 0.64 * 64, 1); scene.add(sprite) } function initModel() { var texture1 = new THREE.TextureLoader().load('../dist/textures/cube/Bridge2/posx.jpg') var texture2 = new THREE.TextureLoader().load('../dist/textures/cube/Bridge2/negx.jpg') var texture3 = new THREE.TextureLoader().load('../dist/textures/cube/Bridge2/posy.jpg') var texture4 = new THREE.TextureLoader().load('../dist/textures/cube/Bridge2/negy.jpg') var texture5 = new THREE.TextureLoader().load('../dist/textures/cube/Bridge2/posz.jpg') var texture6 = new THREE.TextureLoader().load('../dist/textures/cube/Bridge2/negz.jpg') var materialArr = [ //紋理對象賦值給6個材質對象 new THREE.MeshBasicMaterial({ map: texture1, side: THREE.DoubleSide }), new THREE.MeshBasicMaterial({ map: texture2, side: THREE.DoubleSide }), new THREE.MeshBasicMaterial({ map: texture3, side: THREE.DoubleSide }), new THREE.MeshBasicMaterial({ map: texture4, side: THREE.DoubleSide }), new THREE.MeshBasicMaterial({ map: texture5, side: THREE.DoubleSide }), new THREE.MeshBasicMaterial({ map: texture6, side: THREE.DoubleSide }) ]; var boxGeometry = new THREE.BoxGeometry(200, 200, 200, 100, 100, 100); //boxGeometry.scale( -1, 1, 1 ); var cube = new THREE.Mesh(boxGeometry, materialArr); // var cube = new THREE.Mesh(new THREE.SphereGeometry(50, 180, 120), material) //new THREE.SphereGeometry(3, 18, 12) scene.add(cube); } //用戶交互插件 鼠標左鍵按住旋轉,右鍵按住平移,滾輪縮放 var controls; function initControls() { controls = new THREE.OrbitControls(camera, renderer.domElement); // 若是使用animate方法時,將此函數刪除 //controls.addEventListener( 'change', render ); // 使動畫循環使用時阻尼或自轉 意思是否有慣性 controls.enableDamping = true; //動態阻尼係數 就是鼠標拖拽旋轉靈敏度 //controls.dampingFactor = 0.25; //是否能夠縮放 controls.enableZoom = true; //是否自動旋轉 controls.autoRotate = false; //設置相機距離原點的最遠距離 //controls.minDistance = 50; //設置相機距離原點的最遠距離 //controls.maxDistance =200; //是否開啓右鍵拖拽 controls.enablePan = true; } function render() { renderer.render(scene, camera); } //窗口變更觸發的函數 function onWindowResize() { width = document.getElementById('canvasWrap').clientWidth; height = document.getElementById('canvasWrap').clientHeight; camera.aspect = width / height; camera.updateProjectionMatrix(); render(); renderer.setSize(width, height); } function animate() { //更新控制器 controls.update(); render(); requestAnimationFrame(animate); } function draw() { initRender(); initScene(); initCamera(); //initLight() showSprite(); initModel(); initControls(); animate(); window.onresize = onWindowResize; } var btn = document.getElementById("btn1"); btn.onclick = function() { console.log(scene) //scene.background = new THREE.Color( 0xff0000 ) scene.background = new THREE.CubeTextureLoader() .setPath('../dist/textures/cube/Park2/').load( [ 'posx.jpg', 'negx.jpg', 'posy.jpg', 'negy.jpg', 'posz.jpg', 'negz.jpg' ] ); } var btn = document.getElementById("btn2"); btn.onclick = function() { console.log(scene) //scene.background = new THREE.Color( 0xff0000 ) scene.background = new THREE.CubeTextureLoader() .setPath('../dist/textures/cube/Bridge2/').load( [ 'posx.jpg', 'negx.jpg', 'posy.jpg', 'negy.jpg', 'posz.jpg', 'negz.jpg' ] ); } //MeshFaceMaterial 不加燈光會不顯示,MeshBasicMaterial能夠不用光線,MeshPhongMaterial必定要有光線,不然不顯示 </script>
若是點擊文字的時候彈出對話框,須要用到Raycaster ,特別注意有多個精靈sprite的話,最好建一個組,把全部的精靈放進去java
var group = new THREE.Group(); function showSprite1(){ scene.add(group); showText() const canvasTexture = new THREE.CanvasTexture( document.querySelector("#canvas") ) const spritMaterial = new THREE.SpriteMaterial({ map:canvasTexture }) sprite = new THREE.Sprite(spritMaterial) sprite.position.set(-380,100,0); //精靈的默認大小很小估計是[1,1,1] sprite.scale.set(0.64*256,0.64*64,1); sprite.name = "the first sprite"; group.add(sprite) }
關於事件交互的具體用法請見我另外一篇博客css3