Three.js在vue中的使用(二)-加载、控制

在 Vue 中使用 Three.js 加载模型、控制视角、添加点击事件是构建 3D 场景的常见需求。下面是一个完整的示例,演示如何在 Vue 单文件组件中实现以下功能:

  • 使用 GLTFLoader 加载 .glb/.gltf 模型
  • 添加 OrbitControls 控制视角(旋转、缩放、平移)
  • 给模型添加点击事件

使用的技术栈

  • Vue 3 + Composition API(或 Vue 2)
  • Three.js 核心库
  • three/examples/js/loaders/GLTFLoader
  • three/examples/js/controls/OrbitControls

📦 安装依赖(如未安装)

npm install three
npm install three-gltf-loader  # 或直接引入 GLTFLoader

示例代码:Vue 单文件组件

<template><div class="model-viewer-container" ref="viewerContainer"></div>
</template><script setup>
import { ref, onMounted } from 'vue'
import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'const viewerContainer = ref(null)let scene, camera, renderer, controls, modelfunction init() {// 创建场景scene = new THREE.Scene()scene.background = new THREE.Color(0xeeeeee)// 创建相机const width = viewerContainer.value.clientWidthconst height = viewerContainer.value.clientHeightcamera = new THREE.PerspectiveCamera(45, width / height, 0.1, 1000)camera.position.set(0, 2, 5)// 创建渲染器renderer = new THREE.WebGLRenderer({ antialias: true })renderer.setSize(width, height)renderer.setPixelRatio(window.devicePixelRatio)viewerContainer.value.appendChild(renderer.domElement)// 添加光源const ambientLight = new THREE.AmbientLight(0xffffff, 0.6)scene.add(ambientLight)const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8)directionalLight.position.set(5, 10, 7.5)scene.add(directionalLight)// 添加控制器controls = new OrbitControls(camera, renderer.domElement)controls.enableDamping = true// 加载模型const loader = new GLTFLoader()loader.load('/models/test.glb', // 替换为你的模型路径(gltf) => {model = gltf.scenescene.add(model)// 添加点击事件监听window.addEventListener('click', onClick)},undefined,(error) => {console.error('An error occurred while loading the model:', error)})// 渲染循环function animate() {requestAnimationFrame(animate)controls.update()renderer.render(scene, camera)}animate()
}// 点击事件处理函数
function onClick(event) {if (!model) return// 计算鼠标归一化坐标const mouse = new THREE.Vector2()mouse.x = (event.clientX / window.innerWidth) * 2 - 1mouse.y = -(event.clientY / window.innerHeight) * 2 + 1// 创建射线const raycaster = new THREE.Raycaster()raycaster.setFromCamera(mouse, camera)// 获取模型中的所有可交互对象const intersects = raycaster.intersectObject(model, true)if (intersects.length > 0) {console.log('点击了模型!', intersects[0].object)alert('你点击了模型上的一个部件')}
}// 响应窗口变化
window.addEventListener('resize', () => {if (!camera || !renderer) returncamera.aspect = viewerContainer.value.clientWidth / viewerContainer.value.clientHeightcamera.updateProjectionMatrix()renderer.setSize(viewerContainer.value.clientWidth, viewerContainer.value.clientHeight)
})onMounted(() => {init()
})
</script><style scoped>
.model-viewer-container {width: 100%;height: 100vh;
}
</style>

文件结构建议

your-project/
├── public/
│   └── models/
│       └── test.glb   <-- 放置你的模型文件
├── src/
│   └── components/
│       └── ModelViewer.vue

注意:模型放在 public/models/ 目录下,通过 /models/test.glb 路径访问。


🔧 功能说明

功能实现方式
加载模型使用 GLTFLoader 加载 .glb 或 .gltf 模型
控制视角使用 OrbitControls 实现自由旋转、缩放、平移
点击事件使用 Raycaster 进行射线检测,判断是否点击到模型
响应式布局监听 resize 事件并更新相机和渲染器尺寸

扩展建议

需求推荐做法
多个模型加载使用 Promise.all() 异步加载多个模型
模型动画播放使用 AnimationMixer 和 Clock 控制动画
加载进度条使用 LoadingManager 显示加载百分比
自定义材质遍历模型子对象并修改材质颜色、透明度等属性
高亮选中部分修改点击对象的材质颜色或使用 OutlinePass 后期高亮

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

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

相关文章

软件架构之旅(6):浅析ATAM 在软件技术架构评估中的应用

文章目录 一、引言1.1 研究背景1.2 研究目的与意义 二、ATAM 的理论基础2.1 ATAM 的定义与核心思想2.2 ATAM 涉及的质量属性2.3 ATAM 与其他架构评估方法的关系 三、ATAM 的评估流程3.1 准备阶段3.2 场景和需求收集阶段3.3 架构描述阶段3.4 评估阶段3.5 结果报告阶段 四、ATAM …

vue-chat 开源即时聊天系统web本地运行方法

官方文档 https://gitcode.com/gh_mirrors/vuechat7/vue-chat.git npm install 可能需要用 npm 下载两个包 "viewerjs": "^1.9.0", "vue-hot-reload-api": "^2.3.4", src\constant\index.js 改下面两行 export const LOGIN_API …

Rust与C/C++互操作实战指南

目录 1.前言2.动态库调用2.1 动态加载2.2 静态加载3.代码调用4.静态库调用1.前言 本文原文为:Rust与C/C++互操作实战指南 由于rust诞生时间太短,目前生态不够完善,因此大量的功能库都需要依赖于C、C++语言的历史积累。 而本文将要介绍的便是如何实现rust与c乃至c++之间实…

ppt设计美化公司_杰青_长江学者_优青_青年长江学者_万人计划青年拔尖人才答辩ppt模板

WordinPPT / 持续为双一流高校、科研院所、企业等提供PPT制作系统服务。 / 近期PPT美化案例 - 院士增选、科学技术奖、杰青、长江学者特聘教授、校企联聘长江、重点研发、优青、青长、青拔.. 杰青&#xff08;杰出青年科学基金&#xff09; 支持已取得突出成果的45岁以下学…

修复笔记:SkyReels-V2 项目中的 torch.load 警告

#工作记录 一、问题描述 在运行项目时&#xff0c;出现以下警告&#xff1a; FutureWarning: You are using torch.load with weights_onlyFalse (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pic…

GNOME扩展:Bing壁纸

难点 网络请求(Soup) 下载文件(Soup) 读写设置(Gio.Settings) 源码 import GLib from "gi://GLib"; import Gio from gi://Gio; import St from gi://St; import Soup from gi://Soup;import { Extension } from resource:///org/gnome/shell/extensions/extens…

计算机视觉综合实训室解决方案

一、引言 在当今科技飞速发展的时代&#xff0c;计算机视觉作为人工智能领域的核心技术之一&#xff0c;正以前所未有的速度改变着我们的生活和工作方式。从智能手机中的人脸识别解锁&#xff0c;到自动驾驶汽车对道路和障碍物的精准识别&#xff1b;从安防监控系统中的智能视…

C++23 std::tuple与其他元组式对象的兼容 (P2165R4)

文章目录 引言C23 std::tuple概述std::tuple的定义和基本用法std::tuple的特性std::tuple的应用场景 其他元组式对象的特点Python元组的特点Python元组与C std::tuple的对比 P2165R4提案的具体内容提案背景提案主要内容提案的影响 兼容性示例代码总结 引言 在C编程的世界里&am…

Go语言:协程调度器GPM模型深度解析

一、GPM模型概述 Go语言的并发模型是其最强大的特性之一,而这一切的核心就是GPM调度模型。让我们用一个生活中的例子来理解: 想象你经营着一家快递公司: G(Goroutine):就像一个个待配送的包裹P(Processor):就像是你公司的配送站,负责组织配送工作M(Machine):就像…

NVIDIA显卡演进历程及其关键参数对比

一、早期架构阶段&#xff08;1995-1999&#xff09; 技术特点&#xff1a;聚焦图形渲染性能提升&#xff0c;逐步引入硬件加速功能。 NV1&#xff08;1995&#xff09; 工艺制程&#xff1a;500nm核心频率&#xff1a;12MHz显存频率&#xff1a;75MHz创新点&#xff1a;首款集…

c++ 之 cout

1.进制转换 1. 1 进制转换 默认十进制&#xff1a;cout 默认输出十进制。十六进制&#xff1a;使用 hex 操纵符。八进制&#xff1a;使用 oct 操纵符。恢复十进制&#xff1a;使用 dec 操纵符。 #include <iostream> using namespace std;int main() {int num 30;cou…

动态规划算法精解(Java实现):从入门到精通

一、动态规划概述 动态规划&#xff08;Dynamic Programming&#xff0c;DP&#xff09;是一种解决复杂问题的高效算法&#xff0c;通过将问题分解为相互重叠的子问题&#xff0c;并存储子问题的解来避免重复计算。它在众多领域如计算机科学、运筹学、经济学等都有广泛应用&am…

【JLINK调试器】适配【大华HC32F4A0芯片】的完整解决方案

JLINK调试器适配 大华HC32F4A0芯片的完整解决方案 文章目录 JLINK调试器适配 大华HC32F4A0芯片的完整解决方案一、问题背景1.1 HC32F4A0芯片特性1.2 为何需要J-Link支持1.3 未适配的影响 二、解决方案2.1 问题复现2.2 手动配置2.3 结果验证 三、常见问题四、固件烧入 一、问题背…

AVOutputFormat 再分析

AVOutputFormat 结构体 /*** addtogroup lavf_encoding* {*/ typedef struct AVOutputFormat {const char *name;/*** Descriptive name for the format, meant to be more human-readable* than name. You should use the NULL_IF_CONFIG_SMALL() macro* to define it.*/const…

4.29-4.30 Maven+单元测试

单元测试&#xff1a; BeforeAll在所有的单元测试方法运行之前&#xff0c;运行一次。 AfterAll在所有单元测试方法运行之后&#xff0c;运行一次。 BeforeEach在每个单元测试方法运行之前&#xff0c;都会运行一次 AfterEach在每个单元测试方法运行之后&#xff0c;都会运行…

具身系列——Q-Learning算法实现CartPole游戏(强化学习)

完整代码参考&#xff1a; rl/qlearning_cartpole.py 陈先生/ailib - Gitee.com 部分训练得分&#xff1a; Episode 0 Reward: 19.0 Avg Reward: 19.00 Time: 0.00s Episode 1 Reward: 17.0 Avg Reward: 18.98 Time: 0.00s Episode 2 Reward: 10.0 Avg Reward: 18.89 Time:…

2.2 矩阵

考点一&#xff1a;方阵的幂 1. 计算方法 (1) ​找规律法​ ​适用场景​&#xff1a;低阶矩阵或具有周期性规律的矩阵。​示例​&#xff1a; 计算 A ( 0 1 1 0 ) n A \begin{pmatrix} 0 & 1 \\ 1 & 0 \end{pmatrix}^n A(01​10​)n&#xff1a; 当 n n n 为奇…

一个完整的神经网络训练流程详解(附 PyTorch 示例)

&#x1f9e0; 一个完整的神经网络训练流程详解&#xff08;附 PyTorch 示例&#xff09; &#x1f4cc; 第一部分&#xff1a;神经网络训练流程概览&#xff08;总&#xff09; 在深度学习中&#xff0c;构建和训练一个神经网络模型并不是简单的“输入数据、得到结果”这么简…

从入门到登峰-嵌入式Tracker定位算法全景之旅 Part 0 |Tracker 设备定位概览与系统架构

Part 0 |Tracker 设备定位概览与系统架构 在开始算法与代码之前,本章将从“高空视角”全面剖析一个嵌入式 Tracker 定位系统的整体架构:背景、目标与规划、关键约束、开发环境配置、硬件清单与资源预算、逻辑框图示意、通信链路与协议栈、软件架构与任务划分,以及低功耗管…

【自然语言处理与大模型】大模型意图识别实操

本文先介绍一下大模型意图识别是什么&#xff1f;如何实现&#xff1f;然后通过一个具体的实战案例&#xff0c;详细演示如何运用大模型完成意图识别任务。最后&#xff0c;对大模型在该任务中所发挥的核心作用进行总结归纳。 一、意图识别的定义与核心任务 意图识别是自然语言…