教你如何使用THREEJS實(shí)現(xiàn)一個(gè)可調(diào)節(jié)檔位、可搖頭的電風(fēng)扇
夏天到了,用Three.js
實(shí)現(xiàn)一個(gè)可以搖頭和調(diào)節(jié)檔位的電風(fēng)扇。主要使用到Blender
處理3D模型,用Vite
+Typescript
搭建項(xiàng)目框架。效果演示:
一、處理模型
1、從愛(ài)(bai)給(gei)網(wǎng)下載一個(gè)風(fēng)扇的3D模型,在Blender中打開(kāi),給模型貼上圖。
2、拆解模型。將風(fēng)扇模型拆解成按鈕、底座、扇葉、頭部四個(gè)部分,其中按鈕共五個(gè),包括四個(gè)檔位和一個(gè)搖頭的開(kāi)關(guān)。
3、導(dǎo)出模型。導(dǎo)出GLTF
格式模型。
二、場(chǎng)景搭建
1、初始化場(chǎng)景
this.scene = new THREE.Scene(); /** 攝像機(jī) */ this.camera = new THREE.PerspectiveCamera(75, this.sizes.width / this.sizes.height, 0.1, 100); this.camera.position.set(0, 0.8, 1.8); /** 燈光 */ this.lightPoint = new THREE.HemisphereLight(0xffffff, 0xffffff, 1 ); this.lightPoint.position.set(0, 500, 0); this.scene.add(this.lightPoint); /** 控制器 */ this.controls = new OrbitControls(this.camera, this.renderer.domElement); this.controls.enableKeys = false; // 禁用按鍵 this.controls.enableZoom = false; // 禁用縮放 this.controls.enablePan = false; // 禁用拖拽 this.controls.maxPolarAngle = 1.3; // 最大垂直旋轉(zhuǎn)角度 this.controls.minPolarAngle = 1.3; // 最小垂直旋轉(zhuǎn)角度 this.controls.target = new THREE.Vector3(0, 0.8, 0);
2、加載模型
import { GLTF, GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; var gltf: GLTF = await new Promise((resolve, _) => new GLTFLoader().load('./fan.glb', gltf => resolve(gltf))); this.scene.add(gltf.scene);
3、綁定風(fēng)扇按鈕
this.fan = new Fan(gltf); /** 檔位調(diào)節(jié)按鈕 */ let btns: Array<[string, Level]> = [ ['Btn_1', Level.one], ['Btn_2', Level.two], ['Btn_3', Level.three], ['Btn_4', Level.zero], ]; btns.forEach(([name, level]) => { let btn = gltf.scene.getObjectByName(name); if (btn) this.fan.btns.push(new LevelBtn(btn, level)); }); /** 搖頭按鈕 */ let btn = gltf.scene.getObjectByName("Shake"); if (btn) this.fan.btns.push(new ShakeBtn(btn));
三、功能實(shí)現(xiàn)
1、扇葉旋轉(zhuǎn)
function update() { let leaf = this.obj.scene.getObjectByName("Leaf"); let rotationY = leaf!.rotation.y + Math.PI/10 * this.speed; while(rotationY > Math.PI * 2) rotationY = rotationY - Math.PI * 2; leaf!.rotation.y = rotationY; requestAnimationFrame(() => update()); }
2、檔位調(diào)節(jié)
import { gsap } from 'gsap'; function turnLevel(btn: LevelBtn) { if(btn.state == BtnState.down) return; this.btns.filter(item => item instanceof LevelBtn).forEach(item => item.up()); btn.down(); if(btn.level !== Level.zero) this.state = State.on; this.level = btn.level; gsap.to(this, 3, { speed: this.level }); }
3、左右搖頭
let head = this.obj.scene.getObjectByName("Head"); let shake = this.obj.scene.getObjectByName("Shake"); let leaf = this.obj.scene.getObjectByName("Leaf"); let rotationZ = head!.rotation.z + Math.PI / 1000 * this.shakeDir; if(Math.abs(rotationZ) > Math.abs(this.shakeRange)) { let shakeDir = this.shakeDir; setTimeout(() => { if(shakeDir == ShakeDir.left) this.shakeDir = ShakeDir.right; else if(shakeDir == ShakeDir.right) this.shakeDir = ShakeDir.left; }, 1000) this.shakeDir = ShakeDir.wait; rotationZ = Math.abs(this.shakeRange) * Math.abs(rotationZ) / rotationZ; } head!.rotation.z = rotationZ; leaf!.rotation.z = rotationZ; shake!.rotation.z = rotationZ;
四、最后
項(xiàng)目代碼和演示地址:https://codesandbox.io/p/sandbox/threejs-mini-fans-dx6nm6
到此這篇關(guān)于使用THREEJS實(shí)現(xiàn)一個(gè)可調(diào)節(jié)檔位、可搖頭的電風(fēng)扇的文章就介紹到這了,更多相關(guān)threejs可調(diào)節(jié)檔位、可搖頭的電風(fēng)扇內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript四種調(diào)用模式和this示例介紹
JavaScript調(diào)用時(shí)除了聲明時(shí)定義的形參外,每個(gè)函數(shù)接受兩個(gè)附加參數(shù):this 和arguments,下面為大家介紹下JavaScript四種調(diào)用模式和this2014-01-01dess中一個(gè)簡(jiǎn)單的多路委托的實(shí)現(xiàn)
這個(gè)SDelegate用起來(lái)可能會(huì)比較詭異,比如很多操作都要重新賦值。Dess中,SDelegate主要用于一些特定場(chǎng)合,如DOM事件派發(fā)。2010-07-07js實(shí)現(xiàn)百度聯(lián)盟中一款不錯(cuò)的圖片切換效果完整實(shí)例
這篇文章主要介紹了js實(shí)現(xiàn)百度聯(lián)盟中一款不錯(cuò)的圖片切換效果的方法,以完整實(shí)例形式分析了javascript操作圖片切換的技巧,需要的朋友可以參考下2015-03-03javascript拖曳互換div的位置實(shí)現(xiàn)示例
一個(gè)div拖動(dòng)互換位置的demo,還有很大優(yōu)化的空間,利用dom元素的dragstart/ondragover/ondrop事件完成,感興趣的可以了解一下2021-06-06JavaScript實(shí)現(xiàn)滑動(dòng)門(mén)效果
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)滑動(dòng)門(mén)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-01-01