封装一个基于ThreeJS渲染基础模型的类,非常简单,可拖动可缩放

工作需求要求threeJS渲染一个模型以供可视化大屏展示,抛出模型精度不谈,只说业务实现

1.Three.JS的引入

ThreeJS官网地址:Three.js – JavaScript 3D Library

查看文档

中文切换及安装创建步骤

如果是自己研究学习用的,在官网安装完后,直接在-创建一个场景-里面直接copy代码玩就行了

如果是业务需求相关,希望快速构建一个简单的模型模块看下一页

2.封装模型模块

第一步先引入模块相关的threeJS模块

import * as THREE from 'three';

// gltf文件装载器

import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

// 视图旋转控件

import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';

第二步构建一个class类并初始化constructor内的参数

class ThreeModel {
    constructor(GLTF, Dom) {
        this.glft = GLTF; // 模型文件
        this.Dom = Dom; // dom容器
        this.scene = new THREE.Scene(); // 实例化场景
        this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 20000); // 实例化相机
        this.renderer = new THREE.WebGLRenderer(); // 实例化渲染器
        this.loader = new GLTFLoader(); // 实例化gltf装载器
        this.CameraPosition = {
            x: 0,
            y: 2600,
            z: 0
        }
    }
}

constructor内的参数分别为GLTF(引用的gltf格式模型文件)、Dom(挂载的dom元素)

我使用的vue2框架,调用该模块时须传入以下

import { ThreeModel } from "../three.js"

...

mounted() {
    const model_one = new ThreeModel('Texture/scene.gltf', this.$refs.box);
    model_one.init()
  }

接下来是类里面的初始化函数

    init() {
        this.renderer.setSize(window.innerWidth, window.innerHeight);
        this.Dom.appendChild(this.renderer.domElement);
        this.loader.load(
            this.glft,
            (gltf) => {
                const model = gltf.scene;
                // 创建一个Object3D对象
                const modelContainer = new THREE.Object3D();
                // 将模型的网格添加到Object3D对象中
                modelContainer.add(model);
                // 添加Object3D对象到场景中
                this.scene.add(modelContainer);
            },
            undefined,
            (err) => {
                console.log('报错', err)
            }
        )
        this.initControls();
        this.initLight();
        this.initCamera();
        const animate = () => {
            requestAnimationFrame(animate);
            // 在此处更新场景的其他内容
            this.renderer.render(this.scene, this.camera);
        }
        animate();

    }

初始化控制三维场景缩放和旋转的函数

    initControls() { //使用OrbitControls控制三维场景缩放和旋转等功能
        this.controls = new OrbitControls(this.camera, this.renderer.domElement);
        //动态阻尼系数 即鼠标拖拽旋转的灵敏度
        this.controls.dampingFactor = 0.25;
        // this.controls.target.set(0, 900, 0)
        // //上下旋转范围
        this.controls.minPolarAngle = 0;
        this.controls.maxPolarAngle = 1.5;
        this.controls.autoRotate = true;
        //惯性滑动,滑动大小默认0.25
        this.controls.dampingFactor = 0.25;
        //滚轮是否可控制zoom,zoom速度默认1
        //缩放倍数
        this.controls.zoomSpeed = 1.0;
        //最大最小相机移动距离(景深相机)
        this.controls.minDistance = 1;
        this.controls.maxDistance = Infinity;
        //水平方向视角限制
        this.minAzimuthAngle = -Math.PI * 2;
        this.maxAzimuthAngle = Math.PI * 2;
        this.controls.enabledPan = true;
        this.keyPanSpeed = 7.0;
    }

初始化光照函数

    initLight() { // 初始化光照
        let ambientLight = new THREE.AmbientLight(0x404040);
        this.scene.add(ambientLight);
        //定义灯,并设置位置
        this.light = new THREE.DirectionalLight(0x333333);
        this.light.position.set(60, 30, 40);
        this.light2 = new THREE.DirectionalLight(0xdddddd);
        this.light2.position.set(-20, 20, -20);
        this.scene.add(this.light);
        this.scene.add(this.light2);
    }

初始化相机函数

initCamera() {//初始化相机
        this.scene.scale.set(0.1, 0.1, 0.1)
        this.camera.position.set(0, this.CameraPosition.y, 0); // 设置相机位置,根据需求调整坐标
        this.camera.lookAt(1, 1, 5); // 设置相机观察的目标位置
    }

以下是完整代码

import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
// 视图旋转控件
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
// 拖拽控件
// import { DragControls } from 'three/examples/jsm/controls/DragControls';
class ThreeModel {
    constructor(GLTF, Dom) {
        this.glft = GLTF; // 模型文件
        this.Dom = Dom; // dom容器
        this.scene = new THREE.Scene(); // 实例化场景
        this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 20000); // 实例化相机
        this.renderer = new THREE.WebGLRenderer(); // 实例化渲染器
        this.loader = new GLTFLoader(); // 实例化gltf装载器
        this.CameraPosition = {
            x: 0,
            y: 2600,
            z: 0
        }
    }
    init() {
        this.renderer.setSize(window.innerWidth, window.innerHeight);
        this.Dom.appendChild(this.renderer.domElement);
        this.loader.load(
            this.glft,
            (gltf) => {
                const model = gltf.scene;
                // 创建一个Object3D对象
                const modelContainer = new THREE.Object3D();
                // 将模型的网格添加到Object3D对象中
                modelContainer.add(model);
                // 添加Object3D对象到场景中
                this.scene.add(modelContainer);
            },
            undefined,
            (err) => {
                console.log('报错', err)
            }
        )
        this.initControls();
        this.initLight();
        this.initCamera();
        const animate = () => {
            requestAnimationFrame(animate);
            // 在此处更新场景的其他内容
            this.renderer.render(this.scene, this.camera);
        }
        animate();

    }
    initControls() { //使用OrbitControls控制三维场景缩放和旋转等功能
        this.controls = new OrbitControls(this.camera, this.renderer.domElement);
        //动态阻尼系数 即鼠标拖拽旋转的灵敏度
        this.controls.dampingFactor = 0.25;
        // this.controls.target.set(0, 900, 0)
        // //上下旋转范围
        this.controls.minPolarAngle = 0;
        this.controls.maxPolarAngle = 1.5;
        this.controls.autoRotate = true;
        //惯性滑动,滑动大小默认0.25
        this.controls.dampingFactor = 0.25;
        //滚轮是否可控制zoom,zoom速度默认1
        //缩放倍数
        this.controls.zoomSpeed = 1.0;
        //最大最小相机移动距离(景深相机)
        this.controls.minDistance = 1;
        this.controls.maxDistance = Infinity;
        //水平方向视角限制
        this.minAzimuthAngle = -Math.PI * 2;
        this.maxAzimuthAngle = Math.PI * 2;
        this.controls.enabledPan = true;
        this.keyPanSpeed = 7.0;
    }
    initLight() { // 初始化光照
        let ambientLight = new THREE.AmbientLight(0x404040);
        this.scene.add(ambientLight);
        //定义灯,并设置位置
        this.light = new THREE.DirectionalLight(0x333333);
        this.light.position.set(60, 30, 40);
        this.light2 = new THREE.DirectionalLight(0xdddddd);
        this.light2.position.set(-20, 20, -20);
        this.scene.add(this.light);
        this.scene.add(this.light2);
    }
    initCamera() {//初始化相机
        this.scene.scale.set(0.1, 0.1, 0.1)
        this.camera.position.set(0, this.CameraPosition.y, 0); // 设置相机位置,根据需求调整坐标
        this.camera.lookAt(1, 1, 5); // 设置相机观察的目标位置
    }
}
export { ThreeModel }

3.注意事项和说明

说明:

1.第三方模型文件要按照threeJS支持的格式要求

如图:

2.模型市场

推荐Explore 3D Models - Sketchfab

注意事项:

我使用的是vue项目,一定要将模型文件存放在public文件夹下,否则找不到或报引用错误

本人接触threeJS不多,该模块仅限于基础功能的使用,适用性较低,如果有懂的大佬希望评论或私信交流,如有错误请指出

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/179363.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JVM垃圾回收相关算法

目录 一、前言 二、标记阶段:引用计数算法 三、标记阶段:可达性分析算法 (一)基本思路 (二)GC Roots对象 四、对象的finalization机制 五、MAT与JProfiler的GC Roots溯源 六、清除阶段:…

C#,数值计算——插值和外推,多项式插值与外推插值(Poly_interp)的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// 多项式插值与外推插值 /// Polynomial Interpolation and /// Extrapolation interpolation routines for one dimension /// </summary> public class Poly…

IDEA中 java: 警告: 源发行版 11 需要目标发行版 11 如何解决

步骤1找到项目结构&#xff0c;下面有两种方式 步骤2找到 模块中对应的项目&#xff0c;修改对应的源的语言级别和依赖的模块SDK(M) 步骤3&#xff0c;启动一下&#xff0c;看有无问题&#xff0c; 步骤4&#xff0c;去文件-->设置-->构建、执行、部署-->编译器-->…

海康Visionmaster-模块索引:MFC 模块索引异常解决 办法

现象&#xff1a;文件编码格式为 UTF-8 不带签名编码格式&#xff0c;模块索引会出现 模块无法找到异常 更改文件类型为 UTF-8 带签名格式或 vs 默认 GBK2312 编码格式

替换的DLL用户电脑报错加载失败

编译后混淆加签名的dll 远程下载下来有个选项&#xff1a; 在某用户电脑上出现加载失败的报错 右键dll 属性里勾选解除锁定后 加载运行正常 跟用户电脑安全策略有关系 有的会出现 大部分不会

C# Winform使用log4net记录日志

写在前面 Log4Net是从Java的log4j移植过来的&#xff0c;功能也与log4j类似&#xff0c;可以把日志信息输出到文件、数据库、控制台、Windows 事件日志、远程系统日志服务等不同的介质或目标。 Log4Net配置选项丰富灵活&#xff0c;并且可在运行时动态更新配置并应用&#xf…

dolphinscheduler有任务一直在运行(问题)目前对数据库解决

dolphinscheduler有任务一直在运行&#xff08;问题&#xff09;目前对数据库解决 危害&#xff1a; 这么多的任务没有结束&#xff0c;会涉及很多问题的&#xff0c;系统的数据盘会不断入职日志&#xff0c;数据量很大&#xff0c; 其实对于dolphinscheduler的性能是下降的&a…

git merge 和 git rebase

一、是什么 在使用 git 进行版本管理的项目中&#xff0c;当完成一个特性的开发并将其合并到 master 分支时&#xff0c;会有两种方式&#xff1a; git merge git rebasegit rebase 与 git merge都有相同的作用&#xff0c;都是将一个分支的提交合并到另一分支上&#xff0c;…

看图说话:对脏读、不可重复度、幻读进行总结

1、脏读 「事务B」将 id 为 1 的用户 name 修改为“小卡”&#xff0c;事务未提交。「事务A」查询 id 为 1 的用户数据&#xff0c;此时 name 已为“小卡”。 2、不可重复度 「事务A」第一次读取 id 为 1 的用户&#xff0c;name 是 “卡卡”。「事务B」将 id 为 1 的用户 nam…

Mac M1 安装Docker打包arm64的python项目的镜像包

1、首先安装Docker&#xff0c;到官网下载&#xff0c;选择apple chip版 Docker中文网 官网 2、双击下载的dmg文件&#xff0c;在弹出框中之间拖拽到右边 3、打开docker&#xff0c;修改国内镜像源&#xff0c;位置在配置-DockerEngine "registry-mirrors": ["…

Veritas NBU 5240机头右上角硬盘灯常灭居然是正常的?

在某次给客户硬件设备巡检的过程中&#xff0c;发现NBU机头右上角的那块硬盘指示灯没亮&#xff0c;当时第一反应就是硬盘坏了&#xff0c;之后赶紧去后台查硬盘的状态信息&#xff0c;发现都是正常的&#xff0c;没有任何报错现象和日志&#xff1b;然后就在想硬盘是好的&…

Python VisPy库:高性能科学可视化

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;我是涛哥&#xff0c;今天为大家分享 Python VisPy库&#xff1a;高性能科学可视化&#xff0c;文章2800字&#xff0c;阅读大约10分钟&#xff0c;大家enjoy~~ VisPy是一个用于高性能科学可视化的Python库&…

python实现调和反距离空间插值法AIDW

1 简介 AIDW 主要是针对 IDW 的缺点进行了改进&#xff0c;考虑了样本点与预测点的位置&#xff0c;即方向和距离&#xff0c;具体见下图&#xff1a; 2 改进 IDW 公式&#xff1a; 从IDW算法可看出&#xff0c;插值点的估算值仅与插值样本距插值点的远近相关&#xff0c;并未…

Python基础【一】--入门知识[2023.11.22]

1 标识符 标识符是编程时使用的名字&#xff0c;用于给变量、函数、语句块等命名。 Python 中标识符由字母、数字、下划线组成&#xff0c;不能以数字开头&#xff0c;区分大小写。 2 关键字 上面表中是 Python 中的关键字&#xff08;保留字&#xff09;&#xff0c;我们在自定…

android11 申请所有文件访问权限

Android 11 引入了强制执行分区存储的限制&#xff0c;导致应用默认不能访问外部文件。 针对以前涉及较多文件的操作&#xff0c;可采用申请所有文件访问权限的方式来解决这一问题&#xff0c;实现方式如下。 &#xff08;虽然这样做安全性低&#xff0c;官方并不推荐这样&…

【Rxjava详解】(二) 操作符的妙用

文章目录 接口变化操作符mapflatmapdebouncethrottleFirst()takeconcat RxJava 是一个基于 观察者模式的异步编程库&#xff0c;它提供了丰富的操作符来处理和转换数据流。 操作符是 RxJava 的核心组成部分&#xff0c;它们提供了一种灵活、可组合的方式来处理数据流&#xf…

PHP如何持续监听Redis的消息订阅并推送到前端?

PHP如何持续监听Redis的消息订阅并推送到前端&#xff1f; 概述: 在许多Web应用程序中&#xff0c;实时推送消息是很常见的需求。当我们需要向前端实时发送消息时&#xff0c;往往会使用轮询或长轮询的方式去获取最新数据。但这种方式对服务器资源的消耗较大&#xff0c;同时响…

IP地址定位技术发展与未来趋势

随着互联网的快速发展&#xff0c;人们对网络的需求和依赖程度越来越高。在海量的网络数据传输中&#xff0c;IP地址定位技术作为网络安全与信息追踪的重要手段&#xff0c;其精准度一直备受关注。近年来&#xff0c;随着技术的不断进步&#xff0c;IP地址定位的精准度得到了显…

idea编译问题导致接口调用不通

问题背景&#xff1a; 1.idea版本2021&#xff0c;springboot&#xff0c;父子maven项目&#xff0c;创建了一个新的model。启动之后&#xff0c;调试controller接口&#xff0c;接口一直报404。 问题分析&#xff1a; 1.查看编译后的文件&#xff0c;发现java代码一直没编译…