VUE---VR全景360度图片预览【完整代码】
最近遇到一个需求,要实现VR全景360度进行图片预览,话不多说,上代码:
第一步:安装three.js
npm install three
第二步:引入
import * as THREE from 'three'
完整代码:
<template> <div class="hello"> <div ref="container" id="container"></div> </div> </template> <script> import * as THREE from 'three' export default { name: 'HelloWorld', data () { return { sceneUrl: 'https://pics1.baidu.com/feed/55e736d12f2eb9387ce1aa96df61283ce4dd6fd7.jpeg', // 需要预览的图片绝对路径 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); } } } </script> <style type="text/css"> #container{width: 100%; height: 1000px; background: #eee;} </style>
打完收工!