当前位置: 首页 > news >正文

若依/vue2引入threejs展示glb/gltf模型,以及画布截图功能

需求背景:前端对glb/gltf模型进行线上管理,支持上传本地模型,每次上传后展示模型,在提交给后端的时候带上该模型的截图,具体效果不便展示,相关代码如下:

1.安装依赖

// "three": "^0.162.0",

npm install three

2.引入依赖,初始化画布并渲染模型

<divref="modelDisplay"class="model-display"id="model-display"
></div>
// 1.引入
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { RoomEnvironment } from "three/examples/jsm/environments/RoomEnvironment";
import { MeshoptDecoder } from "three/examples/jsm/libs/meshopt_decoder.module";var scene;
var camera;
var renderer;
var control;// 2.初始化
methods:{//初始化initCanvas(item) {const _this = this;const domDiv = document.getElementById("model-display");// 场景,相机scene = new THREE.Scene();this.initCamera(domDiv);// 渲染器// 参数 antialias: true 为开启抗锯齿renderer = new THREE.WebGLRenderer({ antialias: true });renderer.setSize(domDiv.offsetWidth, domDiv.offsetHeight);renderer.setClearColor(0x000000, 0);domDiv.appendChild(renderer.domElement);// 材质const environment = new RoomEnvironment();const pmremGenerator = new THREE.PMREMGenerator(renderer);scene.environment = pmremGenerator.fromScene(environment).texture;this.initControl();// 坐标系//   const axesHelper = new THREE.AxesHelper(14);//   scene.add(axesHelper);function animate() {requestAnimationFrame(animate);renderer.render(scene, camera);}animate();},initCamera(domDiv) {camera = new THREE.PerspectiveCamera(45,domDiv.offsetWidth / domDiv.offsetHeight,1,2200);camera.position.set(-70, 50, 50);//设置相机默认看向哪里   三个 0  代表 默认看向原点camera.lookAt(0, 0, 0);},initControl() {// 控制器control = new OrbitControls(camera, renderer.domElement);},// 当选择的模型发生变化时,调用loader方法loader() {const _this = this;const loader = new GLTFLoader();loader.load(process.env.VUE_APP_BASE_API + this.form.modelPath,(gltf) => {scene.add(_this.editModel(gltf.scene));renderer.render(scene, camera);});},// 调整模型缩放editModel(_scene) {const boxHelper = new THREE.BoxHelper(_scene);boxHelper.geometry.computeBoundingBox();const box = boxHelper.geometry.boundingBox;const maxDiameter = Math.max(box.max.x - box.min.x,box.max.y - box.min.y,box.max.z - box.min.z);const scale = camera.position.z / maxDiameter;_scene.scale.set(scale, scale, scale); // 调整模型缩放_scene.position.set(0, 0, 0);return _scene;},// 关闭后清除画布,保证下次打开的时候是空白画布disposeScene(scene) {while (scene.children.length > 0) {let obj = scene.children[0];scene.remove(obj);if (obj.geometry) {obj.geometry.dispose();}if (obj.material) {if (Array.isArray(obj.material)) {obj.material.forEach((material) => {material.dispose();});} else {obj.material.dispose();}}}renderer.clear();},
}

3.截图

// 截屏方法screenPic() {return new Promise((resolve, reject) => {let canvas = renderer.domElement;renderer.render(scene, camera);const imgUrl = canvas.toDataURL("image/png", 1.0);resolve(this.base64ToFile(imgUrl, this.form.modelName.split(".")[0]));});},// base64编码图片转file格式base64ToFile(base64, fileName) {if (typeof base64 != "string") {return;}var arr = base64.split(",");var type = arr[0].match(/:(.*?);/)[1];var fileExt = type.split("/")[1];var bstr = atob(arr[1]);var n = bstr.length;var u8arr = new Uint8Array(n);while (n--) {u8arr[n] = bstr.charCodeAt(n);}return new File([u8arr], `${fileName}.` + fileExt, {type: type,});},


http://www.mrgr.cn/news/7802.html

相关文章:

  • 如何选择需求跟踪管理软件?8款优质推荐
  • 数据结构-栈与队列-数组和链表的推广运用-第六天
  • 云计算实训33——高并发负载均衡项目(eleme)
  • ​14:00面试,14:06就出来了,问的问题有点变态。。。
  • Pytorch cat()与stack()函数详解
  • 嵌入式学习(网络通信UDP\TCP)
  • iOS工程:获取手机相册权限,iOS原生系统弹窗, Privacy隐私政策选择,如何添加系统弹出并修改描述文字
  • 如何在 Ubuntu 系统中安装PyCharm集成开发环境?
  • 当前A股平均市盈率
  • 回调函数的使用
  • 如何使用ssm实现公司项目管理系统设计与实现
  • (第三期)书生大模型实战营——OpenXLab部署InternLM2实践——上传模型
  • Vue.js实战教程:如何一步步构建HSK在线学习平台
  • API 的多版本管理,如何在 Apifox 中操作?
  • 【日常记录-Linux】dnf工具
  • React 使用ref属性调用子组件方法(也可以适用于父子传参)
  • FastAPI+React18开发通用后台管理系统用户功能实战
  • staticHeader(静态标头)
  • BUG——GT911上电后中断一直触发
  • 数据集笔记: FourSquare - NYC and Tokyo Check-ins