Threejs项目实战之二:产品三维爆炸图效果展示

您所在的位置:网站首页 3d产品展示旋转图网站 Threejs项目实战之二:产品三维爆炸图效果展示

Threejs项目实战之二:产品三维爆炸图效果展示

2024-05-05 14:52| 来源: 网络整理| 查看: 265

目录最终效果1. 实现原理2. 创建项目3. 编写代码最终效果

今天我们来实现如何使用ThreeJS实现产品的三维爆炸图分解与组合的效果,先看下最终项目完成后的效果展示动画

在这里插入图片描述在这里插入图片描述1. 实现原理

要实现这种爆炸图的分解与组合效果,其实原理很简单,就是找到模型中各个组成部分对应的Mesh,然后通过修改对应Mesh的Position坐标来实现产品的分解与组合效果,为了使分解和组合效果看起来更丝滑,在修改对应Position位置的时候,设置一个动画效果,使其开起来过渡更自然,我这里使用的是GSAP动画库,这个动画库非常强大,感兴趣的小伙伴可以看我之前写的一篇关于GSAP动画库使用的博客,这里只介绍具体的使用,就不讲解各个参数的定义了。

2. 创建项目

在D盘新建vite-vue-Valve文件夹,鼠标右键点击新建的文件夹,使用vscode打开;

在vscode中使用快捷键Ctrl+Shift+~打开终端,在终端中使用vite构建工具创建项目,输入pnpm create vite bmw-app --template vue创建项目

创建成功后,在终端中输入cd bmw-app进入文件夹

输入pnpm i 安装依赖包

安装完成后,输入pnpm run div 启动项目,打开浏览器,可以看到系统默认的页面,说明项目环境搭建成功

安装ThreeJS库,在终端中输入pnpm i three安装threejs插件

安装GSAP库,在终端中输入 pnpm i gsap安装GSAP库

删除vite构建工具为我们创建的HelloWord.vue文件和style.css中的样式,删除App.vue中的样式

在components文件夹下新建ValveView.vue文件

在App.vue的Template模板中调用 ValveView.vue App.vue中代码如下

代码语言:javascript复制 import ValveView from './components/ValveView.vue';

style.css中的样式代码如下: *{ margin: 0; padding: 0; list-style: none; }

3. 编写代码

在ValveView.vue的template模板中添加一个div,id设置为scene,作为承载Threejs的容器;再增加一个div,设置class=“control”,在这个div中添加两个button,并给两个button添加点击事件,用于控制产品模型的分解与组合 template模板中代码如下:

代码语言:javascript复制 分解 组合

设置ValveView.vue中元素的样式,默认情况想,我们上面设置的id为scene的div和class为control的div是一列排列的,我们需要将control中的两个button设置为页面右上角的位置,在style代码片段中设置类名为control的样式和button的样式代码如下

代码语言:javascript复制 .control{ display: flex; position: fixed; top:50px; right: 50px; } .control button { width: 100px; height: 30px; margin: 10px; }

在script标签中引入threejs import * as THREE from 'three'

这里我们选择的产品模型是gltf格式的文件,因此,我们需要引入threejs为我们提供的GLTFLoader加载器 import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'

由于我们需要对物体进行鼠标旋转缩放控制,因此我们需要引入threejs为我们提供的OrbitControls控制器 import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'

引入GSAP库,实现产品分解、组合时的动画效果 import { gsap } from 'gsap'

引入vue的生命周期onMounted import { onMounted } from 'vue'

创建init函数,用于初始化threejs相关设置 const init = () => {}

为了便于后期代码的维护,我这里将创建threejs场景、相机、灯光、渲染器及控制器等各个部分进行了分别的封装,这样便于后期的代码维护与修改。

首先设置全局变量scene, camera, loader, renderer, controls和model let scene, camera, loader, renderer, controls, model

创建初始化场景函数,在初始化场景函数中,调用new THREE.Scene()方法初始化场景,具体代码如下

代码语言:javascript复制// 初始化场景 const initScene = () => { scene = new THREE.Scene() scene.background = new THREE.Color(0xcccccc) scene.environment = new THREE.Color(0xcccccc) }

创建初始化相机函数,在初始化相机函数中,调用 new THREE.PerspectiveCamera()方法创建相机并设置相机的位置,具体代码如下:

代码语言:javascript复制// 添加相机 const initCamera = () => { camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 1) camera.position.set(0.08, 0.08, 0.15) }

创建初始化灯光函数,在初始化灯光函数中,添加环境光、自然光、聚光灯等各种灯光效果,代码如下:

代码语言:javascript复制// 添加灯光 const initLight = () => { // 设置环境光 scene.add(new THREE.AmbientLight(0xffffff, 0.5)) // 添加球光源 const hesLight = new THREE.HemisphereLight(0xffffff, 0x444444) hesLight.intensity = 0.6 scene.add(hesLight) // 自然光 const dirLight = new THREE.DirectionalLight() dirLight.position.set(0, 0, 15) scene.add(dirLight) const dirLight2 = new THREE.DirectionalLight() dirLight2.position.set(0, 0, -15) scene.add(dirLight2) const dirLight3 = new THREE.DirectionalLight() dirLight3.position.set(15, 0, 0) scene.add(dirLight3) const dirLight4 = new THREE.DirectionalLight() dirLight4.position.set(-15, 0, 0) scene.add(dirLight4) const dirLight5 = new THREE.DirectionalLight() dirLight5.position.set(0, 15, 0) scene.add(dirLight5) const dirLight6 = new THREE.DirectionalLight() dirLight6.position.set(0, -15, 0) scene.add(dirLight6) const dirLight7 = new THREE.DirectionalLight() dirLight7.position.set(5, 15, 5) scene.add(dirLight7) const dirLight8 = new THREE.DirectionalLight() dirLight8.position.set(-5, -15, -5) scene.add(dirLight8) // 聚光灯 const sportLight = new THREE.SpotLight(0xffffff, 0.8) sportLight.angle = Math.PI / 8; //散射角度,跟水平线的夹角 sportLight.penumbra = 0.1; // 聚光锥的半影衰减百分比 sportLight.decay = 2; // 纵向:沿着光照距离的衰减量。 sportLight.distance = 10; sportLight.shadow.radius = 10; // 阴影映射宽度,阴影映射高度 sportLight.shadow.mapSize.set(512, 512); sportLight.position.set(0, 15, 0); // 光照射的方向 sportLight.target.position.set(0, 0, 0); sportLight.castShadow = true; scene.add(sportLight); }

创建加载GLTF模型函数,使用Threejs提供的new GLTFLoader()方法加载gltf模型文件,具体代码如下:

代码语言:javascript复制// 加载GLTF模型 const initModel = () => { loader = new GLTFLoader() loader.load('/model/fm.gltf', gltf => { model = gltf.scene model.position.set(0, -0.08, 0) // 添加模型到场景 scene.add(model) }) }

创建初始化渲染器函数,使用Threejs提供的new THREE.WebGLRenderer()方法创建渲染器,并设置相关参数,具体diam如下:

代码语言:javascript复制// 创建渲染器 const initRenderer = () => { renderer = new THREE.WebGLRenderer({ antialias: true }) renderer.setSize(window.innerWidth, window.innerHeight) document.getElementById('scene').appendChild(renderer.domElement) }

创建初始化控制器函数,添加控制器,使用Threejs提供的new OrbitControls()方法创建一个控制器,并设置相关参数,具体代码如下:

代码语言:javascript复制// 添加控制器 const initControl = () => { controls = new OrbitControls(camera, renderer.domElement) controls.enableDamping = true controls.dampingFactor = 0.25 controls.enableZoom = true }

创建循环渲染动画,通过调用requestAnimationFrame(animate) 循环调用该动画,并使用renderer.render(scene, camera)实时渲染场景,具体代码如下:

代码语言:javascript复制// 渲染循环 const playAnimate = () => { const animate = function () { requestAnimationFrame(animate) renderer.render(scene, camera) } animate() }

将上面创建的各个初始化函数添加到init函数中,使其在初始化时分别调用各个函数,init函数具体代码如下:

代码语言:javascript复制const init = () => { initScene() initCamera() initLight() initModel() initRenderer() initControl() playAnimate() }

在vue生命周期onMounted中调用init函数,完成页面渲染,代码如下:

代码语言:javascript复制onMounted(() => { init() })

添加分解、组合控制动画,在template模板中,我们已经给两个按钮绑定了鼠标点击事件split(),它接收一个boolean类型的参数,为true时,我们对模型进行分解操作,为false时,我们对模型进行组合操作。我这里实现模型分解与组合的方法是获取模型中的Mesh数组,通过forEach循环遍历获取需要移动位置的Mesh,修改其相关的Position来移动Mesh的位置,这里使用了gsap动画来实现动画效果,具体代码如下:

代码语言:javascript复制const split = (val) => { const myModel = model.children[0].children if(val) { myModel.forEach(item => { if(item.name === "Obj3d66-5355088-2-382") { // item.position.y = 0.03 gsap.to(item.position,{ duration:1,//动画持续时间 y:0.03,//目标位置 ease:'power2.inOut' }) } else if (item.name === "Obj3d66-5355088-2-382_1"){ // item.position.y = -0.05 gsap.to(item.position,{ duration:1,//动画持续时间 y:-0.05,//目标位置 ease:'power2.inOut' }) } }); } else { myModel.forEach(item => { if(item.name === "Obj3d66-5355088-2-382") { // item.position.y = 0.03 gsap.to(item.position,{ duration:1,//动画持续时间 y:0,//目标位置 ease:'line' }) } else if (item.name === "Obj3d66-5355088-2-382_1"){ // item.position.y = -0.05 gsap.to(item.position,{ duration:1,//动画持续时间 y:0,//目标位置 ease:'line' }) } }); } }

至此,我们就完成了产品三维爆炸图的分解与组合效果,运行程序,刷新浏览器,通过鼠标点击分解按钮和组合按钮查看动画效果,效果如下:

在这里插入图片描述在这里插入图片描述

ok,threejs项目实战的第二个项目就实现了,小伙伴们有疑问的评论区留言,喜欢的小伙伴点赞关注+收藏哦!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3