vue项目如何使用three.js实现vr360度全景图片预览
作者:Thurmanwang
这篇文章主要介绍了vue项目如何使用three.js实现vr360度全景图片预览,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
使用three.js实现vr360度全景图片预览
当前demo使用的three.js为0.115.0版本
项目中安装three
npm install three
安装完成再组件如下导入
import * as THREE from 'three'
html文件中写入如下代码图片预览容器
代码如下:
<div ref="container" id="container"></div>
script脚本中如下代码
data() { return { sceneUrl: '', // 需要预览的图片绝对路径 camera: null, scene: null, renderer: null, isUserInteracting: false, onPointerDownPointerX: 0, onPointerDownPointerY: 0, lon: 0, onPointerDownLon: 0, lat: 0, onPointerDownLat: 0, phi: 0, theta: 0, target: new THREE.Vector3() } }, mounted() { this.init() }, methods: { init() { let textureLoader = new THREE.TextureLoader(); textureLoader.load(this.sceneUrl, (texture) => { texture.mapping = THREE.UVMapping; this.initImg(texture); this.render(); }); }, initImg(texture) { let container, mesh; // 容器宽度、高度 let containerWidth = this.$refs.container.offsetWidth; let containerHeight = this.$refs.container.offsetHeight; container = document.getElementById('container'); this.renderer = new THREE.WebGLRenderer({ antialias: true }); this.renderer.setPixelRatio(window.devicePixelRatio); // this.renderer.setSize(window.innerWidth, window.innerHeight); this.renderer.setSize(containerWidth, containerHeight); let childs = container.childNodes; if (container.childNodes.length > 0) { container.removeChild(childs[0]); container.appendChild(this.renderer.domElement); } else { container.appendChild(this.renderer.domElement); } this.scene = new THREE.Scene(); this.camera = new THREE.PerspectiveCamera(60, containerWidth / containerHeight , 1, 1000); mesh = new THREE.Mesh(new THREE.SphereBufferGeometry(500, 32, 16), new THREE.MeshBasicMaterial({ map: texture })); mesh.geometry.scale(-1, 1, 1); this.scene.add(mesh); container.addEventListener('mousedown', this.onDocumentMouseDown, false); container.addEventListener('mousemove', this.onDocumentMouseMove, false); container.addEventListener('mouseup', this.onDocumentMouseUp, false); container.addEventListener('mousewheel', this.onDocumentMouseWheel, false); container.addEventListener('touchstart', this.onDocumentTouchStart, false); container.addEventListener('touchmove', this.onDocumentTouchMove, false); }, onDocumentMouseDown(event) { event.preventDefault(); this.isUserInteracting = true; this.onPointerDownPointerX = event.clientX; this.onPointerDownPointerY = event.clientY; this.onPointerDownLon = this.lon; this.onPointerDownLat = this.lat; }, onDocumentMouseMove(event) { if (this.isUserInteracting) { this.lon = (this.onPointerDownPointerX - event.clientX) * 0.1 + this.onPointerDownLon; this.lat = (event.clientY - this.onPointerDownPointerY) * 0.1 + this.onPointerDownLat; this.render(); } }, onDocumentMouseUp(event) { this.isUserInteracting = false; this.render(); }, onDocumentMouseWheel(event) { this.camera.fov -= event.wheelDeltaY * 0.05; this.camera.updateProjectionMatrix(); event = event || window.event; if (event.stopPropagation) { // 这是取消冒泡 event.stopPropagation(); } else { event.cancelBubble = true; }; if (event.preventDefault) { // 这是取消默认行为 event.preventDefault(); } else { event.returnValue = false; }; this.render(); }, onDocumentTouchStart(event) { if (event.touches.length == 1) { event.preventDefault(); this.onPointerDownPointerX = event.touches[0].pageX; this.onPointerDownPointerY = event.touches[0].pageY; this.onPointerDownLon = this.lon; this.onPointerDownLat = this.lat; } }, onDocumentTouchMove(event) { if (event.touches.length == 1) { event.preventDefault(); this.lon = (this.onPointerDownPointerX - event.touches[0].pageX) * 0.1 + this.onPointerDownLon; this.lat = (event.touches[0].pageY - this.onPointerDownPointerY) * 0.1 + this.onPointerDownLat; this.render(); } }, render() { this.lon += 0.15; this.lat = Math.max(-85, Math.min(85, this.lat)); this.phi = THREE.Math.degToRad(90 - this.lat); this.theta = THREE.Math.degToRad(this.lon); this.camera.position.x = 100 * Math.sin(this.phi) * Math.cos(this.theta); this.camera.position.y = 100 * Math.cos(this.phi); this.camera.position.z = 100 * Math.sin(this.phi) * Math.sin(this.theta); this.camera.lookAt(this.scene.position); this.renderer.render(this.scene, this.camera); } }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。