vue3+three 開發(fā)3D汽車展示在掘金看到一篇three.js開發(fā)汽車展示廳的教程,就動(dòng)手用vue3實(shí)現(xiàn)一個(gè),模型
在掘金看到一篇three.js開發(fā)汽車展示廳的教程,就動(dòng)手用vue3實(shí)現(xiàn)一個(gè),模型在sketchFab上找的特斯拉模型,ui操作用vue 實(shí)現(xiàn),three的基本概念在掘金也很多,就不多說了。廢話少說
先上效果
再上代碼
<template> <div class="maskLoading" v-if="isLoading"> <div class="loading"> <div :style="{width : loadingWidth +'%' }"></div> </div> <div style="padding-left: 10px;">{{parseInt(loadingWidth)}}%</div> </div> <div class="mask"> <p>x : {{x}} y:{{y}} z :{{z}}</p> <button @click="isAutoFun">轉(zhuǎn)動(dòng)車</button> <button @click="stop">停止</button> <div class="flex"> <div @click="setCarColor(index)" v-for="(item,index) in colorAry" :style="{backgroundColor : item}"></div> </div> </div> </template> <script setup> import {onMounted, reactive, ref, toRefs} from 'vue' import { Color, DirectionalLight, DirectionalLightHelper, HemisphereLight, HemisphereLightHelper, Mesh, MeshPhongMaterial, PerspectiveCamera, PlaneGeometry, Scene, WebGLRenderer } from 'three' import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js' import {GLTFLoader} from 'three/examples/jsm/loaders/GLTFLoader' const colorAry = [ "rgb(216, 27, 67)", "rgb(142, 36, 170)", "rgb(81, 45, 168)", "rgb(48, 63, 159)", "rgb(30, 136, 229)", "rgb(0, 137, 123)", "rgb(67, 160, 71)", "rgb(251, 192, 45)", "rgb(245, 124, 0)", "rgb(230, 74, 25)", "rgb(233, 30, 78)", "rgb(156, 39, 176)", "rgb(94, 53, 177)", "rgb(57, 73, 171)", "rgb(33, 150, 243)", "rgb(0, 150, 136)", "rgb(76, 175, 80)", "rgb(253, 216, 53)", "rgb(251, 140, 0)", "rgb(244, 81, 30)", "rgb(236, 64, 100)", "rgb(171, 71, 188)", "rgb(103, 58, 183)", "rgb(92, 107, 192)", "rgb(66, 165, 245)", "rgb(38, 166, 154)", "rgb(129, 199, 132)", "rgb(255, 235, 59)", "rgb(255, 167, 38)", "rgb(255, 87, 34)", "rgb(240, 98, 125)", "rgb(186, 104, 200)", "rgb(126, 87, 194)", "rgb(121, 134, 203)", "rgb(100, 181, 246)", "rgb(128, 203, 196)", "rgb(165, 214, 167)", "rgb(255, 241, 118)", "rgb(255, 183, 77)", "rgb(255, 138, 101)", "rgb(244, 143, 160)", "rgb(206, 147, 216)", "rgb(149, 117, 205)", "rgb(159, 168, 218)", "rgb(144, 202, 249)", "rgb(178, 223, 219)", "rgb(200, 230, 201)", "rgb(255, 245, 157)", "rgb(255, 204, 128)", "rgb(255, 171, 145)", "rgb(255, 255, 255)", "rgb(224, 224, 224)", "rgb(182, 182, 182)", "rgb(153, 153, 153)", "rgb(137, 137, 137)", "rgb(90, 90, 90)", "rgb(55, 55, 55)", "rgb(35, 35, 35)", "rgb(22, 22, 22)", "rgb(0, 0, 0)"] //const lightColor = new Color(colorAry[Math.floor(Math.random() * colorAry.length)]) const loader = new GLTFLoader() const defaultMap = { x: 510, y: 128, z: 0, } const map = reactive(defaultMap) const {x, y, z} = toRefs(map) let scene, camera, renderer, controls, floor, dhelper, hHelper, directionalLight, hemisphereLight let isLoading = ref(true) let loadingWidth = ref(0) const setFloor = () => { let floorGeometry = new PlaneGeometry(5000, 5000, 1, 1.1) let floorMaterial = new MeshPhongMaterial({ color: 0x77F28F, // wireframe: true }) floor = new Mesh(floorGeometry, floorMaterial) floor.rotation.x = -0.5 * Math.PI floor.position.y = -2.1 scene.add(floor) } const setLight = () => { directionalLight = new DirectionalLight(0xffffff, 0.5) directionalLight.position.set(-4, 8, 4) dhelper = new DirectionalLightHelper(directionalLight, 5, 0xff0000) hemisphereLight = new HemisphereLight(0xffffff, 0xffffff, 0.4) hemisphereLight.position.set(0, 8, 0) hHelper = new HemisphereLightHelper(hemisphereLight, 5) scene.add(directionalLight) scene.add(hemisphereLight) } const setCamera = () => { const {x, y, z} = defaultMap scene = new Scene() camera = new PerspectiveCamera(60, innerWidth / innerHeight, 1, 1000) camera.position.set(x, y, z) renderer = new WebGLRenderer() renderer.setSize(innerWidth, innerHeight) document.body.appendChild(renderer.domElement) } const setControls = () => { controls = new OrbitControls(camera, renderer.domElement) controls.maxPolarAngle = 0.9 * Math.PI / 2 controls.enableZoom = true controls.addEventListener('change', render) } const init = async () => { const gltf = await loadFile('src/assets/3d/tesla_2018_model_3/scene.gltf') setCamera() setLight() //setFloor() setControls() scene.add(gltf.scene) loop() } const loop = () => { requestAnimationFrame(loop) renderer.render(scene, camera) controls.update() } const isAutoFun = () => { controls.autoRotate = true } const stop = () => { controls.autoRotate = false } const render = () => { map.x = Number.parseInt(camera.position.x) map.y = Number.parseInt(camera.position.y) map.z = Number.parseInt(camera.position.z) } const setCarColor = (index) => { const currentColor = new Color(colorAry[index]) scene.traverse(child => { if (child.isMesh) { console.log(child.name) if (child.name.includes('door_')) { child.material.color.set(currentColor) } } }) } const loadFile = (url) => { return new Promise(((resolve, reject) => { loader.load(url, (gltf) => { resolve(gltf) }, ({loaded,total}) => { let load = Math.abs(loaded /total * 100) loadingWidth.value = load if (load >= 100) { setTimeout(() => { isLoading.value = false }, 1000) } console.log((loaded / total * 100) + '% loaded') }, (err) => { reject(err) } ) })) } const onResizeFun = (ev)=>{ setCamera() } onMounted(() => { init() window.addEventListener('resize',onResizeFun) }) </script> <style> body { margin: 0; } .maskLoading { background: #000; position: fixed; display: flex; justify-content: center; align-items: center; top: 0; left: 0; bottom: 0; right: 0; z-index: 1111111; color: #fff; } .maskLoading .loading { width: 400px; height: 20px; border: 1px solid #fff; background: #000; overflow: hidden; border-radius: 10px; } .maskLoading .loading div { background: #fff; height: 20px; width: 0; transition-duration: 500ms; transition-timing-function: ease-in; } canvas { width: 100%; height: 100%; margin: auto; } .mask { color: #fff; position: absolute; top: 0; left: 0; width: 100%; } .flex { display: flex; flex-wrap: wrap; padding: 20px; } .flex div { width: 10px; height: 10px; margin: 5px; cursor: pointer; } </style>
相關(guān)知識(shí)
創(chuàng)維汽車
汽車黑科技研究:車載健康的五個(gè)發(fā)展階段
關(guān)注車內(nèi)健康,倡導(dǎo)健康出行 中國汽車健康指數(shù)引領(lǐng)汽車行業(yè)加速發(fā)展
交通運(yùn)輸部辦公廳關(guān)于開展汽車維修電子健康檔案系統(tǒng)建設(shè)工作的通知
3M攜手途虎養(yǎng)車發(fā)布全新汽車養(yǎng)護(hù)產(chǎn)品:single
長城汽車攜全新藍(lán)山閃耀廣州車展 詮釋智能化實(shí)力
[湖北]汽車維修電子健康檔案建設(shè)即將在我省全面展開
小班游戲課教案《開汽車》
孕婦開車時(shí)該不該系汽車安全帶 孕婦開車系法
電動(dòng)汽車無線充電電磁安全性的最新研究進(jìn)展
網(wǎng)址: vue3+three 開發(fā)3D汽車展示在掘金看到一篇three.js開發(fā)汽車展示廳的教程,就動(dòng)手用vue3實(shí)現(xiàn)一個(gè),模型 http://m.u1s5d6.cn/newsview536840.html
推薦資訊
- 1發(fā)朋友圈對(duì)老公徹底失望的心情 12775
- 2BMI體重指數(shù)計(jì)算公式是什么 11235
- 3補(bǔ)腎吃什么 補(bǔ)腎最佳食物推薦 11199
- 4性生活姿勢(shì)有哪些 盤點(diǎn)夫妻性 10425
- 5BMI正常值范圍一般是多少? 10137
- 6在線基礎(chǔ)代謝率(BMR)計(jì)算 9652
- 7一邊做飯一邊躁狂怎么辦 9138
- 8從出汗看健康 出汗透露你的健 9063
- 9早上怎么喝水最健康? 8613
- 10五大原因危害女性健康 如何保 7826