photo-sphere-viewer实现VR全景图以及Vue3+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目录下新建
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 中需要设置对应路由