vue項(xiàng)目如何使用three.js實(shí)現(xiàn)vr360度全景圖片預(yù)覽
更新時(shí)間:2024年03月24日 10:14:56 作者:Thurmanwang
這篇文章主要介紹了vue項(xiàng)目如何使用three.js實(shí)現(xiàn)vr360度全景圖片預(yù)覽,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
使用three.js實(shí)現(xiàn)vr360度全景圖片預(yù)覽
當(dāng)前demo使用的three.js為0.115.0版本
項(xiàng)目中安裝three
npm install three
安裝完成再組件如下導(dǎo)入
import * as THREE from 'three'
html文件中寫入如下代碼圖片預(yù)覽容器
代碼如下:
<div ref="container" id="container"></div>
script腳本中如下代碼
data() { return { sceneUrl: '', // 需要預(yù)覽的圖片絕對(duì)路徑 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) { // 這是取消默認(rèn)行為 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); } }
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue2集成Lodop插件實(shí)現(xiàn)在線打印功能
這篇文章主要為大家詳細(xì)介紹了Vue2如何集成Lodop插件實(shí)現(xiàn)在線打印功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-03-03vue2.0 根據(jù)狀態(tài)值進(jìn)行樣式的改變展示方法
下面小編就為大家分享一篇vue2.0 根據(jù)狀態(tài)值進(jìn)行樣式的改變展示方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-03-03vue.js中關(guān)于點(diǎn)擊事件方法的使用(click)
這篇文章主要介紹了vue.js中關(guān)于點(diǎn)擊事件方法的使用(click),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08Vue實(shí)現(xiàn)自定義組件改變組件背景色(示例代碼)
要實(shí)現(xiàn) Vue 自定義組件改變組件背景色,你可以通過 props 將背景色作為組件的一個(gè)屬性傳遞給組件,在組件內(nèi)部監(jiān)聽這個(gè)屬性的變化,并將其應(yīng)用到組件的樣式中,下面通過示例代碼介紹Vue如何實(shí)現(xiàn)自定義組件改變組件背景色,感興趣的朋友一起看看吧2024-03-03vue2模擬vue-element-admin手寫角色權(quán)限的實(shí)現(xiàn)
本文主要介紹了vue2模擬vue-element-admin手寫角色權(quán)限的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07Vue進(jìn)階之利用transition標(biāo)簽實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)動(dòng)畫
這篇文章主要為大家詳細(xì)介紹了Vue如何利用transition標(biāo)簽實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)動(dòng)畫,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起一下2023-08-08