photo-sphere-viewer實作VR全景圖以及Vue3+Egg線上聊天
- photo-sphere-viewer
-
- 安裝
- 建立容器
- 引入
- 初始化全景圖
- addMarker添加标記
- Marker配置項
- 常用事件
- Vue3+Egg線上聊天
-
- Vue
-
- 安裝
- main.js引入
- utils/socket (直接拷貝就行)
- 頁面中使用
- Egg
-
- 安裝
- 配置
- 使用
photo-sphere-viewer
安裝
//
npm install photo-sphere-viewer --save;
建立容器
<div id="viewer">
</div>
引入
import { Viewer } from "photo-sphere-viewer";
import "photo-sphere-viewer/dist/photo-sphere-viewer.css";
import { MarkersPlugin } from "photo-sphere-viewer/dist/plugins/markers";
import "photo-sphere-viewer/dist/plugins/markers.css";
初始化全景圖
let viewer = new Viewer({
container: document.querySelector('#viewer'), //容器
panorama: panoramaImg, //全景圖圖檔路徑
size: {
width: '100%',
height: '100%',
},//容器大小
loadingTxt: "加載中...", //加載時顯示
defaultZoomLvl: 30, //初始縮放 介于0-100之間
navbar: [
'autorotate',
'zoom',
'caption',
'fullscreen',
], //底部按鈕包括自動播放 全屏 改變縮放大小等
plugins: [
[MarkersPlugin, {
markers: [ //标記點配置 根據具體情況配置(可以直接配置,也可以後面調用addMarker添加)
id, //唯一id 可以通過new Date().getTime()目前時間戳使id唯一
html: `
<div class="marker-tooltip-container">
</div>
<img style="width:20px;height:20px;" class="sign-point" src="http://127.0.0.1:8088/src/assets/img/signmarker.png "></img>
`, //這是自己設定的樣式類似于v-html
longitude: data.longitude,//經度
latitude: data.latitude,//緯度
anchor: 'center center',
tooltip: {
content: `
<div>
<p style="font-weight: 700;
font-size: 20px;">
${signForm.title}
</p>
<p style="font-weight: 300;
font-size: 14px;">
${signForm.description}
</p>
</div>
`,//這裡類似于上面的html
position: 'center top'
},
visible: true, // 标注初始顯示與否
type: 'sign',//自己設定我這裡設定了 sign和jump倆種
target: 跳轉房間的圖檔, //如果要切換場景的話可以配置
sceneName: id, //需要跳轉的場景id
description: signForm.description, //添加描述的話可以配置
],
}],
],
});
addMarker添加标記
//
let markersPlugin = viewer.getPlugin(MarkersPlugin);//通過getPlugin擷取markerPlugin;
const config = { //具體配置參照上面markers裡的資料}
markersPlugin.addMarker(config) //通過addMarker方法添加标記
Marker配置項
id (required)
type: string
标記的唯一辨別符。
x & y or latitude & longitude (required)
type: integer or double
标記在紋理坐标(像素)或球坐标(弧度)中的位置。
width & height (required for images, recommended for html)
type: integer
标記的大小。
scale
type: double[] | { zoom: double[], longitude: [] }
default: no scalling
根據縮放級别和/或經度偏移配置标記的比例。這旨在在使用者縮放和移動時為标記的大小提供自然的感覺。
anchor
type: string
default: ‘center center’
定義标記朝向其定義位置的放置位置。任何 CSS 位置都是有效的,例如bottom center或 20% 80%。
visible
type: boolean
default: true
标記的初始可見性。
tooltip
type: string | {content: string, position: string}
default: {content: null, position: ‘top center’}
tooltip内容和位置。
data
type: any
要附加到标記的任何自定義資料。
target
type: string
可以設定跳轉後的全景圖
常用事件
Viewer事件
viewer.once('ready', () => { //全景圖準備完成後觸發
viewer.on('click', (e, data) => { //全景圖點選事件
// console.log('click', e, data); //可以擷取到點選的坐标資訊
//可以在這裡面調用上面添加标記的事件
});
});
标注常用方法
1.添加标注 addMarker(properties)
2.清除所有标注 clearMarkers()
3.删除标記removeMarker(id) | removeMarkers(ids)
4.标記點選事件select-marker(marker, data)
markersPlugin.on('select-marker', (e, marker, data) => {
console.log('marker', marker); //點選的标點
viewer.setPanorama(currentSpace.panoramaImg).then(() => { //通過setPanorama()設定顯示的全景圖實作場景切換參數為圖檔位址 });})
具體編輯跳轉或标記業務需要自己根據實際情況
更多配置檢視
連結: [link](https://blog.csdn.net/weixin_42752574/article/details/122243459)
Vue3+Egg線上聊天
Vue
安裝
npm i vue-socket.io --Save
main.js引入
import VueSocketIO from 'vue-socket.io';
import {registerSockets,destroySockets} from '@/utils/socket'//具體代碼在後面
const socket = new VueSocketIO({
// debug: false,
connection: 'http://localhost:7001',//後端位址
autoConnect: false, //禁止自動連接配接socket,由于不需要一直連socket服務,是以這裡設定關閉
options: {
transports: ['websocket', 'polling']
}
})
// // 便于在任意位置擷取到 socket 對象 //因為vue3不能通過this拿到 需要配置
app.config.globalProperties.$socket = socket;
// 監聽事件
app.config.globalProperties.$addSockets = registerSockets;
// 移除事件
app.config.globalProperties.$removeSockets = destroySockets;
utils/socket (直接拷貝就行)
export const registerSockets = (sockets, proxy) => {
sockets &&
Object.keys(sockets).forEach((t) => {
"subscribe" !== t &&
"unsubscribe" !== t &&
proxy.$socket.emitter.addListener(t, sockets[t], proxy);
});
};
export const destroySockets = (sockets, proxy) => {
sockets &&
Object.keys(sockets).forEach((t) => {
proxy.$socket.emitter.removeListener(t, proxy);
});
};
頁面中使用
App.js
import { getCurrentInstance } from 'vue'
const { proxy } = getCurrentInstance()
console.log(proxy.$socket);
proxy.$socket.io.on("connect", () => {
console.log("已連接配接",); // 監聽 socket 連接配接事件
proxy.$socket.io.emit("addid", { //可以自定義方法 我這裡連接配接上後觸發這個事件用來儲存使用者id和其對應的連接配接id
uid: store.userinfo.id,
username: store.userinfo.username,
})
})
具體發送消息頁面
import { getCurrentInstance } from 'vue'
const { proxy } = getCurrentInstance()
const sockets = {
res(data) { //背景傳回資料
console.log(data);
},
online(data) { //可以根據背景添加各種事件 前提是名字和路由一樣
console.log(data);
},
};
const sendMessage = ()=>{
proxy.$socket.io.emit("server", { //發送内容 資料自己決定傳什麼
message: '發送了一條消息',
});
}
onMounted(async () => { //在onMounted中挂載事件 不挂載的話sockets裡的事件好像都監聽不到
proxy.$addSockets(sockets, proxy);
})
onBeforeUnmount(() => { //登出事件
proxy.$removeSockets(sockets, proxy);
});
Egg
安裝
npm i egg-socket.io --Save
配置
config.default.js
config.io = {
init: {},
namespace: {
'/': {
connectionMiddleware: ['connection'],
packetMiddleware: ['packet'],
},
},
};
plugin.js
io: {
enable: true,
package: 'egg-socket.io'
},
使用
app目錄下建立
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL2ETZygjZ3IWO3QGOyUWMhRDO4QjYxAjZiFGMhNDMmRzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
default.js
async ping() {
const { app, socket, logger, helper } = this.ctx;
const id = socket.id; //拿到連接配接的id
const senddata = this.ctx.args[0]; //拿到前台發送的資訊
var receiverres = await app.redis.get(receiverid); //拿到redis中想發送的人的連接配接id redis通過egg-redis安裝 好像也需要下redis
var senderres = await app.redis.get(senderid);
//to中的參數是接收人的連接配接時的id
this.ctx.app.io.of('/').to(receiverres).emit('res', senddata);
this.ctx.app.io.of('/').to(senderres).emit('res', senddata); //前端在res方法裡可以接收到
// 斷開連接配接
// this.ctx.socket.disconnect();
}
async addid() {
const { app, socket, logger, helper } = this.ctx;
const id = socket.id;
const nsp = app.io.of('/');
nsp.adapter.clients([room], (err, clients) => {
console.log('clients', clients); //可以輸出所有連接配接的id
});
const senddata = this.ctx.args[0];//前端傳來的資料
await app.redis.set(senddata.uid, id) //存入連接配接id key是使用者id value是連接配接id
this.ctx.app.io.of('/').to(room).emit('online', this.ctx.socket.id + "上線了");
}
connection.js
const room = 'default_room';
module.exports = (app) => {
return async (ctx, next) => {
console.log('已連接配接');
console.log(ctx.socket.id);
// console.log(ctx);
// ctx.app.io
// .of('/')
// .to(room)
// .emit('online', { msg: 'welcome', id: ctx.socket.id });
ctx.socket.join(room); //類似于添加到聊天室
await next();
console.log(ctx.socket.id,'斷開連接配接!');
};
};
packet.js
module.exports = (app) => {
return async (ctx, next) => {
//這裡沒做什麼操作 隻是簡單輸出一下
// console.log('packetctx',ctx.socket);
console.log('packet:', ctx.packet);
await next();
};
};
router.js 中需要設定對應路由