Files
xSynergy-manage/src/views/custom/tabulaRase/index.vue

145 lines
3.6 KiB
Vue

<template>
<div class="wrapper-content">
<div>
<!-- 未加入时显示按钮 -->
<div v-if="!hasJoined" class="login-button-container">
<el-button type="primary" size="large" link @click="joinWhiteboard">
正在进入互动画板
</el-button>
</div>
<!-- 已加入时显示白板 -->
<div v-else class="whiteboard-wrapper">
<ToolBox v-if="canvas" class="toolbox" :canvas="canvas" />
<canvas id="whiteboard" class="whiteboard-canvas"></canvas>
</div>
</div>
</div>
</template>
<script setup>
import { ref, nextTick, onUnmounted, onMounted } from "vue";
import { ElLoading, ElMessage } from "element-plus";
import { v4 as uuidv4 } from "uuid";
import { useRoute } from "vue-router";
import { mqttClient } from "@/utils/mqtt";
import { WhiteboardSync } from "@/utils/whiteboardSync";
import ToolBox from "@/components/ToolBox/index.vue";
import Canvas from "@/core/index.js";
import { getInfo } from "@/api/login";
const props = defineProps({
roomId: {
type: String,
default: '',
},
userId: {
type: String,
default: '',
},
})
const hasJoined = ref(false); // 是否加入白板
const canvas = ref(null);
const route = useRoute();
/** 进入白板 */
async function joinWhiteboard() {
const loading = ElLoading.service({
lock: true,
text: "正在进入互动画板...",
background: "rgba(0, 0, 0, 0.4)",
});
try {
const clientId = `whiteboard-${uuidv4()}`;
await mqttClient.connect(clientId);
// console.log("✅ 已连接 MQTT:", clientId);
hasJoined.value = true;
// 等待 DOM 更新后再初始化画布
await nextTick();
initWhiteboard();
ElMessage.success("已进入互动画板 🎉");
} catch (err) {
console.error("❌ 连接失败:", err);
ElMessage.error("连接白板失败,请重试");
} finally {
loading.close();
}
}
/** 初始化白板 */
function initWhiteboard() {
const el = document.getElementById("whiteboard");
if (!el) {
console.error("⚠️ 找不到 canvas 元素");
return;
}
// 初始化画布
canvas.value = new Canvas("whiteboard");
// 获取房间号
const roomUid = route.query.room_uid || props.roomId || "default-room";
// 初始化多人同步
WhiteboardSync.init(canvas.value, roomUid);
}
onMounted(async () => {
joinWhiteboard()
});
onUnmounted(() => {
if (canvas.value) canvas.value.destroy();
});
</script>
<style scoped>
/* 外层容器全屏居中 */
.wrapper-content {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background: #fff;
position: relative; /* 关键:为绝对定位子元素提供参照 */
}
/* 登录按钮容器居中 */
.login-button-container {
display: flex;
justify-content: center;
align-items: center;
}
/* 白板容器 */
.whiteboard-wrapper {
position: relative;
width: 72vw;
height: 69vh;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
}
/* 画布占满白板容器 */
.whiteboard-canvas {
width: 100%;
height: 100%;
display: block;
}
/* 工具栏固定在 wrapper-content 内 */
.toolbox {
position: absolute;
top: 50%;
left: 40px; /* 距离左侧的间距 */
transform: translateY(-50%);
z-index: 1000;
}
</style>