vue2+three.js+blender(实现3d 模型引入并可点击效果)

news2025/3/10 5:25:59

2023.9.13今天我学习了如何把3d建模里面的模型引入到vue中,并可以实现拖动,点击的效果:

首先安装:

npm install three

相关代码如下:

<!--3d基础版,实现单个3d图形-->
<template>
  <div>
    <div id="content"/>
  </div>
</template>
<script>
import * as THREE from 'three'
import {GLTFLoader} from 'three/examples/jsm/loaders/GLTFLoader';
import {OrbitControls} from "three/examples/jsm/controls/OrbitControls"; //鼠标控制器

export default {
  data() {
    return {
      scene: null,//场景
      camera: null,//照相机
      renderer: null,//渲染器
      raycaster: null,
      mesh: null,//物体
      mouse: null,
      onCLick: null,
      childList: null,
      light: null,//灯光
      cuModel: "", //当前选中模型
      mouseControls: null, //轨道控制
      pointLight: null, //点光源
      ambientLight: null, //环境光
      num: 0,//点击次数
    }
  },
  mounted() {
    this.init()
    window.addEventListener("click", this.onClick, false);
  },

  methods: {
    init() {
      // 创建场景
      this.createScene()
      // 创建照相机
      this.createCamera()
      // 创建渲染器
      this.createRenderer()
      // 创建灯光
      this.createLight()
      // 创建控制器
      this.createOrbitControls();
      // 创建物体
      this.createMesh()
      // 触发
      this.render()
    },
    // 创建场景
    createScene() {
      this.scene = new THREE.Scene()
    },
    // 创建照相机
    createCamera() {
      this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000)
      this.camera.position.set(200, 200, 200)
      this.camera.lookAt(this.scene.position)
    },
    // 创建渲染器
    createRenderer() {
      this.renderer = new THREE.WebGLRenderer()
      this.renderer.setSize(window.innerWidth, window.innerHeight)
      this.renderer.setClearColor(new THREE.Color(0xffffff))
      document.getElementById('content').appendChild(this.renderer.domElement)
    },
    // 创建灯光
    createLight() {
      this.light = new THREE.DirectionalLight({
        color: 'red'
      })
      this.light.position.set(100, 100, 100)
      this.scene.add(this.light)
    },
    // 创建物体
    createMesh() {
      let lm = new Promise((resolve, reject) => {
        let loader = new GLTFLoader();
        loader.load('model/bear.glb', (gltf) => {
          resolve(gltf);
        })
      })
      lm.then((res) => {
        res.scene.position.set(
            -100, 0, 0
        )
        res.scene.scale.set(20, 20, 20)
        res.scene.userData = {id: 1, name: 'bear'}
        this.scene.add(res.scene)
        this.render()
      })
    },
    //触发
    render() {
      this.renderer.render(this.scene, this.camera)
    },
    //创建轨道控制
    createOrbitControls() {
      //没有缩放阻尼
      this.mouseControls = new OrbitControls(
          this.camera,
          this.renderer.domElement
      ); //创建控件对象
      this.mouseControls.addEventListener('change', () => {
        this.renderer.render(this.scene, this.camera)
      })
    },
    onClick(event) {
      this.raycaster = new THREE.Raycaster();
      this.mouse = new THREE.Vector2();
      this.mouse.x = (event.clientX / window.innerWidth) * 2 - 1
      this.mouse.y = -(event.clientY / window.innerHeight) * 2 + 1
      this.raycaster.setFromCamera(this.mouse, this.camera);
      const intersects = this.raycaster.intersectObjects(this.scene.children, true);
      if (intersects.length > 0) {
        const clickedObject = intersects[0].object;
        if (clickedObject.name === clickedObject.name) {
          switch (this.num) {
            case 0:
              clickedObject.material.color.set(0xff0000)
              this.num++;
              break;
            case 1:
              clickedObject.material.color.set(0x00ff00)
              this.num++;
              break;
            case 2:
              clickedObject.material.color.set(0xFFFF00)
              this.num++;
              break;
            default:
              clickedObject.material.color.set(0x0000FF)
              this.num -= 3
          }
          this.render()
        }
      }
    }
  }
}
</script>

 如果没有图片可以去

Three.js--》建模软件如何加载外部3D模型?_threejs加载3d模型_亦世凡华、的博客-CSDN博客

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

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

相关文章

【服务器】ASUS ESC4000-E11 安装系统

ASUS ESC4000-E11说明书 没找到 ASUS ESC4000-E11的说明书&#xff0c;下面是ESC4000A-E11的说明书&#xff1a; https://manualzz.com/doc/65032674/asus-esc4000a-e11-servers-and-workstation-user-manual 下载地址&#xff1a; https://www.manualslib.com/manual/231379…

【PTA】PAT(甲级)2022年冬季考试自测

个人学习记录&#xff0c;代码难免不尽人意。 这次考试&#xff0c;e&#xff0c;第一题我看好多人都没理解题意做错了&#xff0c;还有第四题真的是比较意外&#xff0c;之前做的题都是给序列建树&#xff0c;但是这次让判断是否可以生成树&#xff0c;之前从来没有遇到过这类…

leecode 每日一题 2596. 检查骑士巡视方案

2596. 检查骑士巡视方案 骑士在一张 n x n 的棋盘上巡视。在 有效 的巡视方案中&#xff0c;骑士会从棋盘的 左上角 出发&#xff0c;并且访问棋盘上的每个格子 恰好一次 。 给你一个 n x n 的整数矩阵 grid &#xff0c;由范围 [0, n * n - 1] 内的不同整数组成&#xff0c;其…

pyechart练习(一):画图小练习

1、使用Map制作全球人口分布图 import math import osimport matplotlib.pyplot as plt from pyecharts.charts import Map from pyecharts import options as opts# 只有部分国家的人口数据 POPULATION [["China", 1420062022], ["India", 1368737513],…

【C++】拷贝构造函数调用时机 ② ( 对象值作为函数参数 | 对象值作为函数返回值 )

文章目录 一、拷贝构造函数概念二、对象值作为函数参数1、拷贝构造函数调用情况说明2、代码示例 - 对象值作为函数参数 三、对象值作为函数返回值1、拷贝构造函数调用情况说明2、代码示例 - 对象值作为函数返回值 博客总结 : " 拷贝构造函数 " 又称为 " 赋值构…

MySQL之分布式事务

写在前面 当数据库进行了分库分表 之后为了保证数据的一致性。不可变的就需要引入跨数据的事务解决方案&#xff0c;这种解决方案我们叫做分布式事务。本文就一起来看下分布式事务相关的内容。 在8.0 版本上学习。 1&#xff1a;实战 为了能够更好的理解理论知识&#xff0c;…

基于SSM的中小型企业财务管理系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

C++项目实战——基于多设计模式下的同步异步日志系统-②-前置知识补充-不定参函数

文章目录 专栏导读不定参函数C风格不定参函数不定参宏函数 专栏导读 &#x1f338;作者简介&#xff1a;花想云 &#xff0c;在读本科生一枚&#xff0c;C/C领域新星创作者&#xff0c;新星计划导师&#xff0c;阿里云专家博主&#xff0c;CSDN内容合伙人…致力于 C/C、Linux 学…

数据分析三剑客之Matplotlib

0.Matplotlib绘图和可视化 1.简介 我的前面两篇文章介绍了 Nimpy &#xff0c;Pandas 。今天来介绍一下Matplotlib。 简单来说&#xff0c;Matplotlib 是 Python 的一个绘图库。它包含了大量的工具&#xff0c;你可以使用这些工具创建各种图形&#xff0c;包括简单的散点图&…

Java多线程并发面试题

文章目录 Java并发基础并行和并发有什么区别&#xff1f;说说什么是进程和线程&#xff1f;Java线程创建方式&#xff1f;Runnable和Callable接口的区别&#xff1f;为什么调用start()方法时会执行run()方法&#xff0c;不直接调用run()方法&#xff1f;sleep()和wait()的区别&…

预约陪诊就诊小程序源码多城市开发版

陪诊小程序多城市版开发 小程序支持多城市开通&#xff0c;支持创建陪诊团队以及提成奖励设置&#xff0c;可以定义多种服务类型&#xff0c;订单流程简单明了&#xff0c;支持陪诊师手机端订单处理&#xff0c;家政类目可以轻松过审。 小程序市场前景&#xff1a; 人口老龄化…

强大:dynamsoft-barcode-reader-dotnet-9.6.30 Crack

dynamsoft-barcode-reader-dotnet 具有灵活 API 的强大条码扫描器 SDK 无论它是扭曲的、黑暗的、遥远的、模糊的、批量的还是移动的&#xff0c;我们都可以扫描它。速度快 条码扫描速度每分钟500 业界最快的扫描解码&#xff0c;可应用于不同场景&#xff1a; 多个条形码/二维…

【VS2022】调试

F9 创建或取消断点 ctrlF9 禁用断点 F5 开始调试&#xff08;到断点处停下来&#xff09; F10 逐过程&#xff08;不进入函数&#xff09; F11 逐语句 F5、F10、F11都可以直接进入调试 【调试】->【窗口】->【监视】&#xff0c;输入变量就可以观察到变量的值。 …

C语言数组和指针笔试题(二)(一定要看)

目录 字符数组二例题1例题2例题3例题4例题5例题6例题7总结 字符数组三例题1例题2例题3例题4例题5例题6例题7 字符数组二 char arr[] {a,b,c,d,e,f} 1:printf("%d\n", strlen(arr)); 2:printf("%d\n", strlen(arr0)); 3:printf("%d\n", strlen(…

Python小项目之Tkinter应用】随机点名/抽奖工具大优化:新增查看历史记录窗口!语音播报功能!修复预览文件按钮等之前版本的bug!

文章目录 前言一、实现思路二、关键代码查看历史记录按钮语音播报按钮三、完整代码总结前言 老生常谈,先看效果:(订阅专栏可获取完整代码) 初始状态下,我们为除了【设置】外的按钮添加弹窗,提示用户在使用工具之前要先【设置】。在设置界面,我们主要修改了【预览文件】…

每日一题 2596. 检查骑士巡视方案

难度&#xff1a;中等 很简单&#xff0c;从第 0 步开始模拟即可&#xff0c;唯一sb的就是测试用例中如果&#xff08;0&#xff0c;0&#xff09;处不为0的话就直接false&#xff0c;而不是去找0在哪 我的代码&#xff1a; class Solution:def checkValidGrid(self, grid: L…

2000-2021年上市公司全要素生产率数据OP法(含原始数据+计算代码+结果)

2000-2021年上市公司全要素生产率数据OP法&#xff08;含原始数据计算代码结果&#xff09; 1、时间&#xff1a;2000-2021年 2、指标&#xff1a;股票代码、年份、证券代码、固定资产净额、营业总收入、营业收入、营业成本、销售费用、管理费用、财务费用、支付给职工以及为…

防火墙 (五十四)

目录 前言 一、防火墙作用 二、防火墙分类 三、防火墙性能 四、硬件防火墙 五、软件防火墙 5.1 iptables 六、iptables应用 前言 本文就简单的介绍了防火墙的基础内容和一些简单案例的操作。 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、防火墙…

jmeter线程组 bzm - Concurrency Thread Group 阶梯式压测

简介 bzm - Concurrency Thread Group 不是JMeter的官方插件&#xff0c;而是一种由Blazemeter提供的高级线程组插件&#xff0c;它提供了更灵活的并发性能测试设置。它可以在不同的时间内并发执行不同数量的线程&#xff0c;模拟不同的负载场景。 插件下载地址&#xff08;jme…

信创办公–基于WPS的EXCEL最佳实践系列 (通过函数实现灵活限制)

信创办公–基于WPS的EXCEL最佳实践系列 &#xff08;通过函数实现灵活限制&#xff09; 目录 应用背景操作步骤1、sum函数的应用2、and函数的应用3、日期相关函数的应用4、eomonth函数的应用 应用背景 在Excel表格中&#xff0c;我们经常遇到需要大量计算或需要特殊处理的数据…