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