feat:更新代码
This commit is contained in:
59
src/utils/scroll-to.js
Normal file
59
src/utils/scroll-to.js
Normal file
@@ -0,0 +1,59 @@
|
||||
const easeInOutQuad = (t, b, c, d) => {
|
||||
t /= d / 2;
|
||||
if (t < 1) {
|
||||
return (c / 2) * t * t + b;
|
||||
}
|
||||
t--;
|
||||
return (-c / 2) * (t * (t - 2) - 1) + b;
|
||||
};
|
||||
|
||||
const requestAnimFrame = (function () {
|
||||
return (
|
||||
window.requestAnimationFrame ||
|
||||
(window).webkitRequestAnimationFrame ||
|
||||
(window).mozRequestAnimationFrame ||
|
||||
function (callback) {
|
||||
window.setTimeout(callback, 1000 / 60);
|
||||
}
|
||||
);
|
||||
})();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number} amount
|
||||
*/
|
||||
const move = (amount) => {
|
||||
document.documentElement.scrollTop = amount;
|
||||
(document.body.parentNode).scrollTop = amount;
|
||||
document.body.scrollTop = amount;
|
||||
};
|
||||
|
||||
const position = () => {
|
||||
return document.documentElement.scrollTop || (document.body.parentNode).scrollTop || document.body.scrollTop;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {number} to
|
||||
* @param {number} duration
|
||||
* @param {Function} callback
|
||||
*/
|
||||
export const scrollTo = (to, duration, callback) => {
|
||||
const start = position();
|
||||
const change = to - start;
|
||||
const increment = 20;
|
||||
let currentTime = 0;
|
||||
duration = typeof duration === 'undefined' ? 500 : duration;
|
||||
const animateScroll = function () {
|
||||
currentTime += increment;
|
||||
const val = easeInOutQuad(currentTime, start, change, duration);
|
||||
move(val);
|
||||
if (currentTime < duration) {
|
||||
requestAnimFrame(animateScroll);
|
||||
} else {
|
||||
if (callback && typeof callback === 'function') {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
};
|
||||
animateScroll();
|
||||
};
|
||||
@@ -1,99 +0,0 @@
|
||||
import { mqttClient } from "./mqtt";
|
||||
import { getWhiteboardShapes, getWhiteboardHistory } from "@/views/custom/api";
|
||||
import { useMeterStore } from '@/stores/modules/meter';
|
||||
import { encode, decode } from '@msgpack/msgpack'
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { emitter } from "@/utils/bus.js";
|
||||
const meterStore = useMeterStore();
|
||||
meterStore.initUdid();
|
||||
|
||||
let isRemote = false;
|
||||
let canvasInstance = null;
|
||||
|
||||
// 获取本地缓存 userData
|
||||
function getLocalUserData() {
|
||||
const dataStr = sessionStorage.getItem('userData');
|
||||
if (!dataStr) return null;
|
||||
try {
|
||||
return JSON.parse(dataStr);
|
||||
} catch (e) {
|
||||
console.error("解析 userData 失败:", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export const WhiteboardSync = {
|
||||
async init(canvas, roomUid) {
|
||||
if (!canvas || !roomUid) return;
|
||||
canvasInstance = canvas;
|
||||
|
||||
const localUser = getLocalUserData();
|
||||
const localUid = localUser?.uid;
|
||||
try {
|
||||
// 先连接 MQTT
|
||||
await mqttClient.connect(meterStore.getSudid());
|
||||
// 获取历史数据
|
||||
const res = await getWhiteboardHistory({ after_timestamp: 0 }, roomUid);
|
||||
if (res.meta.code === 200 && res.data.shapes.length > 0) {
|
||||
canvasInstance.addShape(res.data.shapes);
|
||||
}else if(res.meta.code === 401){
|
||||
emitter.emit('whiteboardFailed',true);
|
||||
}
|
||||
|
||||
// 订阅当前房间
|
||||
const topic = `xSynergy/ROOM/${roomUid}/whiteboard/#`;
|
||||
mqttClient.subscribe(topic, async (shapeData) => {
|
||||
const shapeDataNew = JSON.parse(shapeData.toString())
|
||||
// const shapeDataNew = decode(message);
|
||||
try {
|
||||
isRemote = true;
|
||||
// 如果 shape 来自本地用户,则跳过
|
||||
if (shapeDataNew.user_uid === localUid) return;
|
||||
const res = await getWhiteboardHistory({ after_timestamp: shapeDataNew.created_at }, roomUid);
|
||||
if (res.meta.code === 200) {
|
||||
canvasInstance.addShape(res.data.shapes);
|
||||
} else {
|
||||
ElMessage.error("获取历史数据失败");
|
||||
console.error("获取历史数据失败");
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("处理MQTT数据失败:", e);
|
||||
} finally {
|
||||
isRemote = false;
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
console.log("初始化多人同步失败:", err)
|
||||
// console.error("❌ 连接或订阅失败:", err);
|
||||
}
|
||||
|
||||
// 监听画布事件:新增图形
|
||||
canvas.on('drawingEnd', async (shape) => {
|
||||
// 如果来自远程,或不是需要同步的类型,跳过
|
||||
if (isRemote || !['pencil', 'line', 'rectangle', 'circle', 'eraser'].includes(shape.type)) return;
|
||||
|
||||
// 如果是本地用户自己的 shape,则不调用接口
|
||||
if (shape.user_uid && shape.user_uid === localUid) return;
|
||||
|
||||
shape.room_uid = roomUid;
|
||||
try {
|
||||
await getWhiteboardShapes(shape, roomUid);
|
||||
} catch (err) {
|
||||
ElMessage.error("提交形状失败");
|
||||
console.error("提交形状失败:", err);
|
||||
}
|
||||
});
|
||||
|
||||
// 监听画布事件:清空
|
||||
canvas.on('clear', async () => {
|
||||
if (!isRemote) {
|
||||
try {
|
||||
// TODO: 调用接口,后端再发 MQTT
|
||||
// await clearWhiteboard(roomUid);
|
||||
} catch (err) {
|
||||
console.error("提交清空失败:", err);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
@@ -1,103 +0,0 @@
|
||||
import { mqttClient } from "./mqtt";
|
||||
import { getWhiteboardShapes, getWhiteboardHistory } from "@/views/custom/api";
|
||||
import { useMeterStore } from '@/stores/modules/meter';
|
||||
import { encode, decode } from '@msgpack/msgpack'
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
const meterStore = useMeterStore();
|
||||
meterStore.initUdid();
|
||||
|
||||
let isRemote = false;
|
||||
let canvasInstance = null;
|
||||
|
||||
// 获取本地缓存 userData
|
||||
function getLocalUserData() {
|
||||
const dataStr = sessionStorage.getItem('userData');
|
||||
if (!dataStr) return null;
|
||||
try {
|
||||
return JSON.parse(dataStr);
|
||||
} catch (e) {
|
||||
console.error("解析 userData 失败:", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export const WhiteboardSync = {
|
||||
async init(canvas, roomUid) {
|
||||
if (!canvas || !roomUid) return;
|
||||
console.log('初始化多人同步:', roomUid);
|
||||
canvasInstance = canvas;
|
||||
|
||||
const localUser = getLocalUserData();
|
||||
const localUid = localUser?.uid;
|
||||
try {
|
||||
// 先连接 MQTT
|
||||
await mqttClient.connect(meterStore.getSudid());
|
||||
console.log("✅ MQTT 已连接");
|
||||
|
||||
// 获取历史数据
|
||||
const res = await getWhiteboardHistory({ after_timestamp: 0 }, roomUid);
|
||||
if (res.meta.code === 200 && res.data.shapes.length > 0) {
|
||||
canvasInstance.addShape(res.data.shapes);
|
||||
}
|
||||
|
||||
// 订阅当前房间
|
||||
const topic = `xSynergy/ROOM/${roomUid}/whiteboard/#`;
|
||||
mqttClient.subscribe(topic, async (shapeData) => {
|
||||
const shapeDataNew = JSON.parse(shapeData.toString())
|
||||
// const shapeDataNew = decode(message);
|
||||
// console.log(shapeDataNew, '格式解码')
|
||||
try {
|
||||
isRemote = true;
|
||||
// 如果 shape 来自本地用户,则跳过
|
||||
if (shapeDataNew.user_uid === localUid) return;
|
||||
const res = await getWhiteboardHistory({ after_timestamp: shapeDataNew.created_at }, roomUid);
|
||||
if (res.meta.code === 200) {
|
||||
canvasInstance.addShape(res.data.shapes);
|
||||
} else {
|
||||
ElMessage.error("获取历史数据失败");
|
||||
console.error("获取历史数据失败");
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("处理MQTT数据失败:", e);
|
||||
} finally {
|
||||
isRemote = false;
|
||||
}
|
||||
});
|
||||
|
||||
console.log("✅ 已订阅:", topic);
|
||||
} catch (err) {
|
||||
console.log("初始化多人同步失败:", err)
|
||||
// console.error("❌ 连接或订阅失败:", err);
|
||||
}
|
||||
|
||||
// 监听画布事件:新增图形
|
||||
canvas.on('drawingEnd', async (shape) => {
|
||||
// 如果来自远程,或不是需要同步的类型,跳过
|
||||
if (isRemote || !['pencil', 'line', 'rectangle', 'circle', 'eraser'].includes(shape.type)) return;
|
||||
|
||||
// 如果是本地用户自己的 shape,则不调用接口
|
||||
if (shape.user_uid && shape.user_uid === localUid) return;
|
||||
|
||||
shape.room_uid = roomUid;
|
||||
try {
|
||||
await getWhiteboardShapes(shape, roomUid);
|
||||
} catch (err) {
|
||||
ElMessage.error("提交形状失败");
|
||||
console.error("提交形状失败:", err);
|
||||
}
|
||||
});
|
||||
|
||||
// 监听画布事件:清空
|
||||
canvas.on('clear', async () => {
|
||||
if (!isRemote) {
|
||||
try {
|
||||
// TODO: 调用接口,后端再发 MQTT
|
||||
// await clearWhiteboard(roomUid);
|
||||
} catch (err) {
|
||||
console.error("提交清空失败:", err);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user