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

news2024/11/17 13:56:50

工作需求要求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不多,该模块仅限于基础功能的使用,适用性较低,如果有懂的大佬希望评论或私信交流,如有错误请指出

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Docker部署单机nginx

一、拉取镜像运行容器 docker run -d --name nginx-server -v /opt/nginx-server:/home/work/tools/nginx/dist/html:ro nginx-d 后台运行 –name 为这个容器命名 -v 挂载,目录映射 /opt/nginx-server:/home/work/tools/nginx/dist/html 容器内地址:本地…

SA实战 ·《SpringCloud Alibaba实战》第14章-服务网关加餐:SpringCloud Gateway核心技术

大家好,我是冰河~~ 一不小心《SpringCloud Alibaba实战》专栏都更新到第14章了,再不上车就跟不上了,小伙伴们快跟上啊! 在《SpringCloud Alibaba实战》专栏前面的文章中,我们实现了用户微服务、商品微服务和订单微服务之间的远程调用,并且实现了服务调用的负载均衡。也基…

抖音汽车租赁小程序技术指南:开发高效便捷的租赁系统

为了更好地满足用户需求,抖音汽车租赁小程序成为一个备受关注的技术解决方案。本文将深入探讨开发高效便捷的汽车租赁系统所需的技术要点,为开发者提供一份实用的技术指南。 小程序架构选择 在搭建抖音汽车租赁小程序时,选择合适的小程序架构…

使用 Pinia 的五个技巧

在这篇文章中,想与大家分享使用 Pinia 的五大技巧。 以下是简要总结: 不要创建无用的 getter在 Option Stores 中使用组合式函数(composables)对于复杂的组合式函数,使用 Setup Stores使用 Setup Stores 注入全局变量…

Python入门教程之条件语句与运算符优先级详解

文章目录 Python 条件语句Python运算符优先级关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、面试资料六、Python兼职渠道 Python 条件语句 …

vscode-insiders Remote-SSH XHR failed无法访问远程服务器

问题概述: destFolder/home/apple/.vscode-server-insiders > destFolder2/vscode-cli-05cd2640ec8a106a4ee99cb38e6ee34fbec04f11.tar.gz > 194f252f7426:trigger_server_download_end > Waiting for client to transfer server archive... > W…

VM——畸变校正、标定板标定

1、需求:精密测量时,使用远心镜头时依然会有畸变,最好使用标定板进行畸变校正和像素当量计算 2、方法:使用VM的“畸变校正”、“标定板标定”模块 2.1 标定板制作 step1: 使用海康的标定板生成工具,可以制作海康I型…

设计模式——行为型模式(二)

6.8 迭代器模式 6.8.1 概述 定义:提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。 6.8.2 结构 迭代器模式主要包含以下角色: 抽象聚合(Aggregate)角色:定义存储、添加、删除聚合元素以及创建迭代器对象的接口。具体聚合(ConcreteAggreg…

python+pytest接口自动化:token关联登录这样做,阿里p8都直呼牛逼!!!

在PC端登录公司的后台管理系统或在手机上登录某个APP时,经常会发现登录成功后,返回参数中会包含token,它的值为一段较长的字符串,而后续去请求的请求头中都需要带上这个token作为参数,否则就提示需要先登录。 这其实就…

python+pytest接口自动化:cookie绕过登录(保持登录状态)这样做,测试组长都直呼牛逼!!!

在编写接口自动化测试用例或其他脚本的过程中,经常会遇到需要绕过用户名/密码或验证码登录,去请求接口的情况,一是因为有时验证码会比较复杂,比如有些图形验证码,难以通过接口的方式去处理;再者&#xff0c…

【高级程序设计】django与网页设计

django安装与配置 使用pip进行Django的安装: pip install djangoconda install django验证django安装成功 import django django.__version__ ## django.get_version()新建一个名称为blog的django项目(project), D:\>cd web-project D:\web-project>django-admi…

Nginx结合cpolar实现内网穿透多个Windows Web站点端口

文章目录 1. 下载windows版Nginx2. 配置Nginx3. 测试局域网访问4. cpolar内网穿透5. 测试公网访问6. 配置固定二级子域名7. 测试访问公网固定二级子域名 1. 下载windows版Nginx 进入官方网站(http://nginx.org/en/download.html)下载windows版的nginx 下载好后解压进入nginx目…

Pycharm 教育版下载

1 访问主站-->Developer Tools-->PyCharm JetBrains: Essential tools for software developers and teams 2 页面往下划找到 PyCharm for Education-->CHECK IT OUT! PyCharm: the Python IDE for Professional Developers by JetBrains 3 点击 Download free Lea…

TIDB基础

TIDB整个逻辑架构跟MYSQL类似,如下: TIDB集群:相当于MYSQL的数据库服务器,区别是MYSQL数据库服务器为单进程的,TIDB集群为分布式多进程的。 数据库:同MYSQL数据库,数据库属于集群,…

类初始化,类加载,类加载器

类初始化,类加载,类加载器 1. 类加载1.1. 类的加载1.2. 类的链接1.2.1. 验证1.2.2. 准备1.2.3. 解析 2. 类加载器2.1. 类加载器分为四种:前三种为虚拟机自带的加载器。2.2. 类加载有三种方式:2.3. **JVM类加载机制**2.4. 双亲委派…

财报解读:电商GMV增长30%后,快手将坚守本地生活?

快手逐渐讲好了其高质量成长的故事。 根据财报,快手三季度业绩超出预期,其中,营收279.5亿元,同比增长20.8%;调整后净利润31.7亿元,同比扭亏为盈。 而联系市场环境来看,三季度广告、电商市场较…

小猪优版的前世今生:从籍籍无名到行业瞩目,再到骤变的风暴中心

1. 前世:籍籍无名到行业新星的崛起 小猪优版在初创时期,并不被大众所知。然而,它凭借对短视频行业的深度洞察,以及独特的商业模式,开始在这个领域崭露头角。它提供了一个平台,不仅助力内容创作者更好地展现…

2. OpenHarmony源码下载

OpenHarmony源码下载(windows, ubuntu) 现在的 OpenHarmony 4.0 源码已经有了,在 https://gitee.com/openharmony 地址中,描述了源码获取的方式。下来先写下 windows 的获取方式,再写 ubuntu 的获取方式。 获取源码前,还需要的准…

超详细的pytest玩转HTML报告:修改、汉化和优化

前言 Pytest框架可以使用两种测试报告,其中一种就是使用pytest-html插件生成的测试报告,但是报告中有一些信息没有什么用途或者显示的不太好看,还有一些我们想要在报告中展示的信息却没有,最近又有人问我pytest-html生成的报告&a…

【giszz笔记】产品设计标准流程【合集】【1.79 万字】

Tips:原笔记共8篇,本文是合集,字数较多,可收藏或关注。 目录 一、普通产品打造的流程 二、更标准一点的产品打造过程(十一步) (一)制定工作计划 (二)用户…