vue中加载three.js全景图
代码如下:
<template> <div class="VRScene"> <div id="container"></div> </div> </template> <script> import * as THREE from "three"; import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js"; export default { name: 'VRScene', data() { return {}; }, props:{ imgUrl:{ type:String, default:'/static/sushe_low.jpg' } }, watch:{ imgUrl(){ let texture = new THREE.TextureLoader().load(imgUrl); this.material.map = new THREE.MeshBasicMaterial({ map: texture }); } }, mounted() { this.camera this.scene this.renderer this.isUserInteracting = false this.onMouseDownMouseX = 0 this.onMouseDownMouseY = 0 this.lon = 0 this.onMouseDownLon = 0 this.lat = 0 this.onMouseDownLat = 0 this.phi = 0 this.theta = 0 this.init() this.animate() }, methods: { init() { var container, mesh; container = document.getElementById('container'); this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1100); this.camera.target = new THREE.Vector3(0, 0, 0); this.scene = new THREE.Scene(); var geometry = new THREE.SphereBufferGeometry(500, 60, 40); // invert the geometry on the x-axis so that all of the faces point inward geometry.scale(-1, 1, 1); let texture = new THREE.TextureLoader().load('/static/sushe_low.jpg'); this.material = new THREE.MeshBasicMaterial({ map: texture }); this.material.needsUpdate = true mesh = new THREE.Mesh(geometry, this.material); this.scene.add(mesh); this.renderer = new THREE.WebGLRenderer(); this.renderer.setPixelRatio(window.devicePixelRatio); this.renderer.setSize(window.innerWidth, window.innerHeight); container.appendChild(this.renderer.domElement); document.addEventListener('mousedown', this.onPointerStart, false); document.addEventListener('mousemove', this.onPointerMove, false); document.addEventListener('mouseup', this.onPointerUp, false); document.addEventListener('wheel', this.onDocumentMouseWheel, false); document.addEventListener('touchstart', this.onPointerStart, false); document.addEventListener('touchmove', this.onPointerMove, false); document.addEventListener('touchend', this.onPointerUp, false); document.addEventListener( 'dragover', function ( event ) { event.preventDefault(); event.dataTransfer.dropEffect = 'copy'; }, false ); document.addEventListener( 'dragenter', function () { document.body.style.opacity = 0.5; }, false ); document.addEventListener( 'dragleave', function () { document.body.style.opacity = 1; }, false ); document.addEventListener( 'drop', function ( event ) { event.preventDefault(); var reader = new FileReader(); reader.addEventListener( 'load', function ( event ) { material.map.image.src = event.target.result; material.map.needsUpdate = true; }, false ); reader.readAsDataURL( event.dataTransfer.files[ 0 ] ); document.body.style.opacity = 1; }, false ); window.addEventListener('resize', this.onWindowResize, false); }, onWindowResize() { this.camera.aspect = window.innerWidth / window.innerHeight; this.camera.updateProjectionMatrix(); this.renderer.setSize(window.innerWidth, window.innerHeight); }, onPointerStart(event) { this.isUserInteracting = true; var clientX = event.clientX || event.touches[0].clientX; var clientY = event.clientY || event.touches[0].clientY; this.onMouseDownMouseX = clientX; this.onMouseDownMouseY = clientY; this.onMouseDownLon = this.lon; this.onMouseDownLat = this.lat; }, onPointerMove(event) { if (this.isUserInteracting === true) { var clientX = event.clientX || event.touches[0].clientX; var clientY = event.clientY || event.touches[0].clientY; this.lon = (this.onMouseDownMouseX - clientX) * 0.1 + this.onMouseDownLon; this.lat = (clientY - this.onMouseDownMouseY) * 0.1 + this.onMouseDownLat; } }, onPointerUp() { this.isUserInteracting = false; }, onDocumentMouseWheel(event) { var fov = this.camera.fov + event.deltaY * 0.05; this.camera.fov = THREE.MathUtils.clamp(fov, 10, 75); this.camera.updateProjectionMatrix(); }, animate() { requestAnimationFrame(this.animate); this.update(); }, update() { if (this.isUserInteracting === false) { this.lon += 0.1; } this.lat = Math.max(-85, Math.min(85, this.lat)); this.phi = THREE.MathUtils.degToRad(90 - this.lat); this.theta = THREE.MathUtils.degToRad(this.lon); this.camera.target.x = 500 * Math.sin(this.phi) * Math.cos(this.theta); this.camera.target.y = 500 * Math.cos(this.phi); this.camera.target.z = 500 * Math.sin(this.phi) * Math.sin(this.theta); this.camera.lookAt(this.camera.target); this.renderer.render(this.scene, this.camera); } }, beforeDestroy() {} }; </script> <style lang="less" scoped> .VRScene { div { 100%; height: 100%; margin-top: 200px; } } </style>
如有疑惑,请加群讨论:854184700