实战篇:(四)Vue2 + Three.js 创建可交互的360度全景视图,可控制旋转、缩放完整代码
Vue2 + Three.js 创建可交互的360度全景视图,可控制旋转、缩放
引言
在现代网页开发中,三维图形技术已经成为提升用户体验的重要工具。本文将展示如何使用 Three.js 创建一个简单的可交互360度全景视图。通过这一项目,你将能够学习到基本的场景设置、相机控制以及用户交互的实现方式。
效果展示
环境准备
首先,你需要在项目中引入 Three.js。可以通过 npm 安装:
npm install three
确保你的项目结构中有一个名为 images
的文件夹,并放入一张全景图像(如 001.jpg
),以便后续使用。
代码示例
下面是实现可交互360度全景视图的 Vue.js 组件代码:
<template><div class="c-width c-height" id="containerVr"></div>
</template><script>
import * as THREE from 'three';
import PANO0001 from './images/001.jpg';export default {name: 'containerVr',data() {return {scene: null,camera: null,renderer: null,};},mounted() {this.init();},methods: {init(img) {img = img ? img : PANO0001;const containerVr = document.getElementById('containerVr');containerVr.innerHTML = '';// 初始化用户交互变量let isUserInteracting = false,onPointerDownMouseX = 0, onPointerDownMouseY = 0,lon = 0, onPointerDownLon = 0,lat = 0, onPointerDownLat = 0,phi = 0, theta = 0;// 创建相机对象const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1100);// 创建场景对象const scene = new THREE.Scene();// 创建球体几何体,表示全景图的表面const geometry = new THREE.SphereGeometry(500, 60, 40);geometry.scale(-1, 1, 1);// 加载并设置全景图纹理const texture = new THREE.TextureLoader().load(img);texture.colorSpace = THREE.SRGBColorSpace;const material = new THREE.MeshBasicMaterial({ map: texture });// 创建网格对象,将几何体和材质结合const mesh = new THREE.Mesh(geometry, material);scene.add(mesh);// 创建渲染器并设置参数const renderer = new THREE.WebGLRenderer();renderer.setSize(window.innerWidth, window.innerHeight);renderer.setPixelRatio(window.devicePixelRatio);// 将渲染器的DOM元素添加到容器中containerVr.appendChild(renderer.domElement);containerVr.style.touchAction = 'none';// 添加事件监听器以处理用户交互containerVr.addEventListener('pointerdown', onPointerDown);document.addEventListener('wheel', onDocumentMouseWheel);// 窗口大小调整事件window.addEventListener('resize', onWindowResize);function onWindowResize() {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize(window.innerWidth, window.innerHeight);}// Pointer Down事件处理function onPointerDown(event) {if (event.isPrimary === false) return;isUserInteracting = true;onPointerDownMouseX = event.clientX;onPointerDownMouseY = event.clientY;onPointerDownLon = lon;onPointerDownLat = lat;document.addEventListener('pointermove', onPointerMove);document.addEventListener('pointerup', onPointerUp);}// Pointer Move事件处理function onPointerMove(event) {if (event.isPrimary === false) return;lon = (onPointerDownMouseX - event.clientX) * 0.1 + onPointerDownLon; lat = (event.clientY - onPointerDownMouseY) * 0.1 + onPointerDownLat;}// Pointer Up事件处理function onPointerUp() {if (event.isPrimary === false) return;isUserInteracting = false;document.removeEventListener('pointermove', onPointerMove);document.removeEventListener('pointerup', onPointerUp);}// 滚轮事件处理function onDocumentMouseWheel(event) {if (event.toElement.getAttribute('data-engine') && event.toElement.getAttribute('data-engine').indexOf('three.js') > -1) {const fov = camera.fov + event.deltaY * 0.05; camera.fov = THREE.MathUtils.clamp(fov, 10, 75); camera.updateProjectionMatrix(); }}// 动画循环function animate() {requestAnimationFrame(animate);update();}// 更新函数,处理相机位置和渲染function update() {if (isUserInteracting === false) {lon += 0.02; }lat = Math.max(-85, Math.min(85, lat));phi = THREE.MathUtils.degToRad(90 - lat);theta = THREE.MathUtils.degToRad(lon);const x = 500 * Math.sin(phi) * Math.cos(theta);const y = 500 * Math.cos(phi);const z = 500 * Math.sin(phi) * Math.sin(theta);camera.lookAt(x, y, z); renderer.render(scene, camera); }animate(); },// 设置图像的方法setImg(url) {let loader = new THREE.TextureLoader(); let texture = loader.load(url); let material = new THREE.MeshBasicMaterial({map: texture, side: THREE.DoubleSide });return material; },}
}
</script><style scoped>
#containerVr {width: 100% !important; flex: 1 !important;
}
#containerVr >>> canvas {max-width: 100%; max-height: 100%;
}
</style>
代码解析
- 组件结构:该组件使用 Vue.js 的
<template>
、<script>
和<style>
标签组织代码。 - 初始化方法:在
mounted
钩子中调用init
方法,初始化 Three.js 的场景、相机和渲染器。 - 用户交互:实现了鼠标按下、移动和滚动事件,用户可以通过拖动鼠标来旋转视图。
- 自适应窗口:通过监听窗口大小变化事件,动态更新相机和渲染器的尺寸。
总结
通过本文,你可以学习如何使用 Three.js 创建一个基础的360度全景视图。这种技术可以广泛应用于虚拟现实、在线展示以及游戏开发等多个领域。希望这篇文章对你理解 Three.js 和创建互动场景有所帮助。
进一步学习
- Three.js 官方文档
- Three.js 示例
- Vue.js 官方文档
通过这种方式,读者不仅可以理解代码的具体实现,还能了解到如何在实际项目中应用这些技术。希望这个结构能帮助你更好地撰写博客!如果你有其他想法或需要进一步的帮助,请告诉我。
相关文章:

实战篇:(四)Vue2 + Three.js 创建可交互的360度全景视图,可控制旋转、缩放完整代码
Vue2 Three.js 创建可交互的360度全景视图,可控制旋转、缩放 引言 在现代网页开发中,三维图形技术已经成为提升用户体验的重要工具。本文将展示如何使用 Three.js 创建一个简单的可交互360度全景视图。通过这一项目,你将能够学习到基本的场…...

【load_file读文件】
一、文件操作基础 show 先试试 show variables;发现显示了三百多行的系统变量: 这是数据库的目录: mysql有多种编码方式,有数据库编码、连接时的编码、还有客户端的编码: 这里还有一个日志路径,这个日志是需要手动打开的&#…...

JavaScript object(2)
这样的话,就变成只读了。...

Acwing 排序
1.快速排序 主要思想:基于分治思想。通过选择一个基准元素,将数组分为两部分,左边部分元素都小于等于基准,右边部分元素都大于等于基准。然后对这两部分分别递归地进行排序。 分区逻辑:双指针算法 左指针i从左往右找…...

分布式环境下验证码登录的技术实现
分布式环境下验证码登录的技术实现 在分布式系统中,实现验证码登录是一个复杂但至关重要的任务。它不仅能防止暴力破解和自动化攻击,还能提高系统的安全性和用户体验。本文将详细介绍在分布式环境下如何实现验证码登录,涵盖验证码的生成、存…...

数据结构-5.9.树的存储结构
一.树的逻辑结构: 二.双亲表示法(顺序存储): 1.树中除了根结点外每一颗树中的任意一个结点都只有一个父结点(双亲结点); 2.结点包括结点数据和指针; 3.上述图片中右边的顺序存储解析:比如A结点左边的0,就…...

【Linux】解锁线程基本概念和线程控制,步入多线程学习的大门
目录 1、线程初识 1.1线程的概念 1.2.关于线程和进程的进一步理解 1.3.线程的设计理念 1.4.进程vs线程(图解) 1.5地址空间的第四谈 2.线程的控制: 2.1.关于线程控制的前置知识 2.2创建线程的系统调用: 这个几号手册具体…...

uniapp学习(005-2 详解Part.2)
零基础入门uniapp Vue3组合式API版本到咸虾米壁纸项目实战,开发打包微信小程序、抖音小程序、H5、安卓APP客户端等 总时长 23:40:00 共116P 此文章包含第41p-第p47的内容 文章目录 mainifest.json文件配置获取微信小程序appid注册微信小程序微信小程序控制台图形界…...

深度学习的关键概念和术语
特征 特征是图像上可进行视觉辨识的区域。特征通常代表对应用相关的内容(缺陷、对象、对象的特定部分)。 特征尺寸 仅用于聚焦模式下的绿色分类、红色、蓝色定位和蓝色读取工具。 您认为对分析图像内容最重要的图像特征的主观大小。该特征尺寸确定用于…...

navicate可视化数据库操作-cnblog
1 连接数据库 点击链接,自定义名称,输入root密码 2 准备按照图例创建数据库demo 3 新建数据库...

kubernetes中的微服务
目录 一 什么是微服务 二 微服务的类型 三 ipvs模式 3.1 ipvs模式配置方式 四 微服务类型详解 4.1 clusterip 4.2 ClusterIP中的特殊模式headless 4.3 nodeport 4.4 loadbalancer 4.5 metalLB 4.6 externalname 五 Ingress-nginx 5.1 ingress-nginx功能 5.2 部署…...

Python 量子机器学习及其应用
Python 量子机器学习及其应用 目录 🌀 量子机器学习的基础概念💡 量子计算的原理与经典计算的区别🔑 量子算法在机器学习中的应用潜力⚛️ 量子计算与经典机器学习算法的结合🚀 案例展示:量子算法提升机器学习效率&a…...

echarts显示隐藏柱状图柱子的背景色
showBackground: true, //控制是否显示背景色backgroundStyle: {// color: rgba(180, 180, 180, 0.4) //背景色的颜色color: red} 关键代码是 showBackground: true, //控制是否显示背景色 设置为false或者直接而不写就是不显示背景色,默认是不显示背景色 true的时…...

QT文件操作【记事本】
mainwindow.h核心函数 QFileDialog::getOpenFileName()QFileDialog::getSaveFileName() #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include<QFileDialog> #include<QMessageBox> #include<QDebug> #include<QFile> #…...

Linux 定时备份系统日志
Linux 定时备份系统日志 SSH跨机免密登录复制备份到另一台虚机上开启定时任务 SSH跨机免密登录 定时备份首先要实现免登入 一、scp 一个文件从其他服务器到本机,怎么跳过ssh登录验证呢? 要在使用SCP时跳过密码登录,你可以设置SSH密钥认证。首…...

音视频入门基础:FLV专题(15)——Video Tag简介
一、引言 根据《video_file_format_spec_v10_1.pdf》第75页,如果某个Tag的Tag header中的TagType值为9,表示该Tag为Video Tag: 这时StreamID之后紧接着的就是VideoTagHeader,也就是说这时Tag header之后的就是VideoTagHeader&…...

尚硅谷rabbitmq2024 第15-18节 springboot整合与可靠性答疑
在spring boot项目中,只引入了一个amqp的starter,为什么在写listener的时候能看到rabbitmq相关的类,比如RabbitListener( public void processMessage(String dataString, Message message, channel channel){ 这里的Message就是rabbitmq下面…...

ctfshow-web 萌新题
给她 pyload: 1.dirsearch扫描,发现git 2. GitHack工具得到.git文件 <?php $passsprintf("and pass%s",addslashes($_GET[pass])); $sqlsprintf("select * from user where name%s $pass",addslashes($_GET[name])); ?>addslashes函…...

基于RPA+AI的网页自动填写机器人 | OPENAIGC开发者大赛高校组优秀作品
在第二届拯救者杯OPENAIGC开发者大赛中,涌现出一批技术突出、创意卓越的作品。为了让这些优秀项目被更多人看到,我们特意开设了优秀作品报道专栏,旨在展示其独特之处和开发者的精彩故事。 无论您是技术专家还是爱好者,希望能带给…...

Tmux常用操作--云GPU版
Tmux是什么,作用? Tmux是一个终端复用器(terminal multiplexer),属于常用的开发工具。 作用 使用Tmux创建守护进程,可以使得关闭PyCharm或者其他终端的情况下,远程服务器(云GPU&a…...

股市入门常见术语介绍
鉴于最近行情讨论火热,我也想借此平台,结合我大学时期身边同学老师的投资经历,写一篇交易入门术语简介。内容不多但是足以达到科普之用。 希望大家能谨慎对待投资,始终保持谦虚学习的态度。不要迷失在瞬息万变的金融市场&…...

专栏十九:单细胞大数据时代使用scvi和scanpy整合数据
慢更ing,主要是记录自己在分析中的一些困惑 一、基础知识和解惑 放在最前面,是因为scvi整合不像harmony,傻瓜式操作,很多地方还是要注意一下的。 1.如何正确的寻找HVGs 一般我们使用的函数就是scanpy.pp.highly_variable_genes,里面的参数较为复杂。 Q:输入数据的格…...

C语言编程必备知识
C语言是编程领域中基础且广泛使用的语言之一,掌握C语言编程需要一些核心知识,涵盖基本语法、内存管理、数据结构等方面。以下是C语言编程中的一些必备知识点: 1. **基础语法** - **变量声明**:所有变量都需要在使用前声明&…...

k8s 1.28 集群部署
文章目录 环境配置安装docker安装cri-dockerd(Docker与Kubernetes通信的中间程序): 部署kubernetes 环境配置 关闭Selinux #永久 sed -i s/enforcing/disabled/ /etc/selinux/config #临时 setenforce 0 关闭Swap #临时 swapoff-a #永久 sed -ri s/.*swap.*/#&a…...

python入门教程
Python 是一种非常流行的编程语言,因其简单易学的语法和广泛的应用领域(如数据分析、人工智能、Web 开发等)而备受欢迎。以下是一个入门级 Python 教程,适合初学者快速掌握 Python 的基础知识。 1. 安装 Python 你可以从 Python…...

bat(批处理脚本学习)
输出banner echo off echo () echo JL echo ^|^| echo LJ echo _,--"""""""---. echo , …...

【JAVA毕业设计】基于Vue和SpringBoot的渔具租赁系统
本文项目编号 T 005 ,文末自助获取源码 \color{red}{T005,文末自助获取源码} T005,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 渔…...

Maven和Gradle的对比
Maven和Gradle都是Java项目构建工具,它们在帮助开发者管理项目依赖、编译、打包等方面发挥着重要作用。 Maven和Gradle的区别 1、语法与配置文件 Maven使用XML作为配置文件(如pom.xml)的语言,XML结构清晰但相对冗长。Gradle则使…...

Windows安装Ollama环境
在Windows环境下,可以安装Ollama,然后在其上面下载相应的大语言模式,下面是目前支持的LLM及相应的命令等信息: Model Parameters Size Download Llama 38B4.7GBollama run llama3Llama 370B40GBollama run llama3:70bPhi-33.8B2.3GBollama run phi3Mistral7B4.1GBollama ru…...

Java入门:11.抽象类,接口,instanceof,类关系,克隆
1 JDK中的包 JDK JRE 开发工具集(javac.exe) JRE JVM java类库 JVM java 虚拟机 jdk中自带了许多的包(类) , 常用的有 java.lang 该包中的类,不需要引用,可以直接使用。 例如࿱…...