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

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

【load_file读文件】

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

JavaScript object(2)

这样的话&#xff0c;就变成只读了。...

Acwing 排序

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

分布式环境下验证码登录的技术实现

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

数据结构-5.9.树的存储结构

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

【Linux】解锁线程基本概念和线程控制,步入多线程学习的大门

目录 1、线程初识 1.1线程的概念 1.2.关于线程和进程的进一步理解 1.3.线程的设计理念 1.4.进程vs线程&#xff08;图解&#xff09; 1.5地址空间的第四谈 2.线程的控制&#xff1a; 2.1.关于线程控制的前置知识 2.2创建线程的系统调用&#xff1a; 这个几号手册具体…...

uniapp学习(005-2 详解Part.2)

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

深度学习的关键概念和术语

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

navicate可视化数据库操作-cnblog

1 连接数据库 点击链接&#xff0c;自定义名称&#xff0c;输入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 量子机器学习及其应用 目录 &#x1f300; 量子机器学习的基础概念&#x1f4a1; 量子计算的原理与经典计算的区别&#x1f511; 量子算法在机器学习中的应用潜力⚛️ 量子计算与经典机器学习算法的结合&#x1f680; 案例展示&#xff1a;量子算法提升机器学习效率&a…...

echarts显示隐藏柱状图柱子的背景色

showBackground: true, //控制是否显示背景色backgroundStyle: {// color: rgba(180, 180, 180, 0.4) //背景色的颜色color: red} 关键代码是 showBackground: true, //控制是否显示背景色 设置为false或者直接而不写就是不显示背景色&#xff0c;默认是不显示背景色 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 一个文件从其他服务器到本机&#xff0c;怎么跳过ssh登录验证呢&#xff1f; 要在使用SCP时跳过密码登录&#xff0c;你可以设置SSH密钥认证。首…...

音视频入门基础:FLV专题(15)——Video Tag简介

一、引言 根据《video_file_format_spec_v10_1.pdf》第75页&#xff0c;如果某个Tag的Tag header中的TagType值为9&#xff0c;表示该Tag为Video Tag&#xff1a; 这时StreamID之后紧接着的就是VideoTagHeader&#xff0c;也就是说这时Tag header之后的就是VideoTagHeader&…...

尚硅谷rabbitmq2024 第15-18节 springboot整合与可靠性答疑

在spring boot项目中&#xff0c;只引入了一个amqp的starter&#xff0c;为什么在写listener的时候能看到rabbitmq相关的类&#xff0c;比如RabbitListener( public void processMessage(String dataString, Message message, channel channel){ 这里的Message就是rabbitmq下面…...

ctfshow-web 萌新题

给她 pyload: 1.dirsearch扫描&#xff0c;发现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开发者大赛中&#xff0c;涌现出一批技术突出、创意卓越的作品。为了让这些优秀项目被更多人看到&#xff0c;我们特意开设了优秀作品报道专栏&#xff0c;旨在展示其独特之处和开发者的精彩故事。 无论您是技术专家还是爱好者&#xff0c;希望能带给…...

Tmux常用操作--云GPU版

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

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

计算机基础知识解析:从应用到架构的全面拆解

目录 前言 1、 计算机的应用领域&#xff1a;无处不在的数字助手 2、 计算机的进化史&#xff1a;从算盘到量子计算 3、计算机的分类&#xff1a;不止 “台式机和笔记本” 4、计算机的组件&#xff1a;硬件与软件的协同 4.1 硬件&#xff1a;五大核心部件 4.2 软件&#…...

Git常用命令完全指南:从入门到精通

Git常用命令完全指南&#xff1a;从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制

目录 节点的功能承载层&#xff08;GATT/Adv&#xff09;局限性&#xff1a; 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能&#xff0c;如 Configuration …...

Ubuntu系统复制(U盘-电脑硬盘)

所需环境 电脑自带硬盘&#xff1a;1块 (1T) U盘1&#xff1a;Ubuntu系统引导盘&#xff08;用于“U盘2”复制到“电脑自带硬盘”&#xff09; U盘2&#xff1a;Ubuntu系统盘&#xff08;1T&#xff0c;用于被复制&#xff09; &#xff01;&#xff01;&#xff01;建议“电脑…...