|
@@ -0,0 +1,203 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <!-- 智能台灯 -->
|
|
|
|
|
+ <div class="desk-lamp-container">
|
|
|
|
|
+ <!-- 标题框 -->
|
|
|
|
|
+ <div class="title-box">
|
|
|
|
|
+ <div class="box-icon" @click="goBack">
|
|
|
|
|
+ <el-icon class="left-icon"><ArrowLeftBold /></el-icon>
|
|
|
|
|
+ 智能台灯
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <img src="@/assets/images/desklamp.png" alt="智能台灯" class="full-screen-image" />
|
|
|
|
|
+ <!-- 使用动态样式设置灯光遮罩 -->
|
|
|
|
|
+ <div v-if="isLightOn" :style="{ '--lamp-color': lampColor,'--lamp-opacity': lampBrightness / 100 }" class="lamp-light-mask"></div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 右下角按钮组 -->
|
|
|
|
|
+ <div class="button-group">
|
|
|
|
|
+ <el-button class="control-button run-button" @click="toggleLight">运行</el-button>
|
|
|
|
|
+ <el-button class="control-button code-button" @click="handleViewCode">查看代码</el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 显示当前灯光信息 -->
|
|
|
|
|
+ <div v-if="isLightOn" class="lamp-info">
|
|
|
|
|
+ <p>颜色: {{ lampColor }}</p>
|
|
|
|
|
+ <p>亮度: {{ lampBrightness }}%</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script setup>
|
|
|
|
|
+import { ref, computed, onMounted } from 'vue'
|
|
|
|
|
+import { useRouter } from 'vue-router'
|
|
|
|
|
+import { ArrowLeftBold } from '@element-plus/icons-vue'
|
|
|
|
|
+
|
|
|
|
|
+const router = useRouter()
|
|
|
|
|
+const isLightOn = ref(false)
|
|
|
|
|
+const lampColor = ref('#fff') // 默认白色
|
|
|
|
|
+const lampBrightness = ref(50) // 默认亮度50%
|
|
|
|
|
+
|
|
|
|
|
+// 返回虚拟实验室列表
|
|
|
|
|
+const goBack = () => {
|
|
|
|
|
+ router.push('/virtual-laboratory')
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 处理查看代码的逻辑
|
|
|
|
|
+const handleViewCode = () => {
|
|
|
|
|
+ // 传递完整的灯光状态到Blockly页面
|
|
|
|
|
+ router.push({
|
|
|
|
|
+ path: '/blockly',
|
|
|
|
|
+ query: {
|
|
|
|
|
+ isLightOn: isLightOn.value,
|
|
|
|
|
+ lampColor: lampColor.value,
|
|
|
|
|
+ lampBrightness: lampBrightness.value
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 切换灯光状态
|
|
|
|
|
+const toggleLight = () => {
|
|
|
|
|
+ isLightOn.value = true;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 从路由参数中获取状态(Blockly页面返回时)
|
|
|
|
|
+onMounted(() => {
|
|
|
|
|
+ const query = router.currentRoute.value.query
|
|
|
|
|
+ if (query.isLightOn !== undefined) {
|
|
|
|
|
+ isLightOn.value = query.isLightOn === 'true'
|
|
|
|
|
+ }
|
|
|
|
|
+ if (query.lampColor) {
|
|
|
|
|
+ lampColor.value = query.lampColor
|
|
|
|
|
+ }
|
|
|
|
|
+ if (query.lampBrightness) {
|
|
|
|
|
+ lampBrightness.value = parseInt(query.lampBrightness)
|
|
|
|
|
+ }
|
|
|
|
|
+})
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped lang="scss">
|
|
|
|
|
+@use "sass:math";
|
|
|
|
|
+
|
|
|
|
|
+@function rpx($px) {
|
|
|
|
|
+ @return math.div($px, 750) * 100vw;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.desk-lamp-container {
|
|
|
|
|
+ position: fixed;
|
|
|
|
|
+ top: 0;
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+ right: 0;
|
|
|
|
|
+ bottom: 0;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.full-screen-image {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ object-fit: cover;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 台灯灯光样式 - 使用动态颜色 */
|
|
|
|
|
+.lamp-light-mask {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ width: rpx(100);
|
|
|
|
|
+ height: rpx(350);
|
|
|
|
|
+ margin-top: rpx(20);
|
|
|
|
|
+ margin-left: rpx(250);
|
|
|
|
|
+ background: radial-gradient(circle, var(--lamp-color) 0%, var(--lamp-color) 50%, rgba(255, 255, 255, 0) 70%);
|
|
|
|
|
+ filter: blur(50px);
|
|
|
|
|
+ transform: rotate(25deg);
|
|
|
|
|
+ transform-origin: top center;
|
|
|
|
|
+ opacity: var(--lamp-opacity, 0.6);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 灯光信息显示 */
|
|
|
|
|
+.lamp-info {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ bottom: 100px;
|
|
|
|
|
+ right: 30px;
|
|
|
|
|
+ background-color: rgba(255, 255, 255, 0.2);
|
|
|
|
|
+ padding: 10px 20px;
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+ backdrop-filter: blur(10px);
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ z-index: 1000;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 标题框样式 */
|
|
|
|
|
+.title-box {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ top: 20px;
|
|
|
|
|
+ left: 20px;
|
|
|
|
|
+ z-index: 1000;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.box-icon {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 10px;
|
|
|
|
|
+ padding: 10px 20px;
|
|
|
|
|
+ background-color: rgba(255, 255, 255, 0.2);
|
|
|
|
|
+ border-radius: 30px;
|
|
|
|
|
+ backdrop-filter: blur(10px);
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ transition: all 0.3s ease;
|
|
|
|
|
+ font-size: 16px;
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.box-icon:hover {
|
|
|
|
|
+ background-color: rgba(255, 255, 255, 0.3);
|
|
|
|
|
+ transform: translateX(-3px);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.left-icon {
|
|
|
|
|
+ font-size: 18px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 右下角按钮组样式 */
|
|
|
|
|
+.button-group {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ bottom: 30px;
|
|
|
|
|
+ right: 30px;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ gap: 15px;
|
|
|
|
|
+ z-index: 1000;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.control-button {
|
|
|
|
|
+ padding: 12px 24px;
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+ font-size: 16px;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+ transition: all 0.3s ease;
|
|
|
|
|
+ backdrop-filter: blur(5px);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.run-button {
|
|
|
|
|
+ background-color: rgba(64, 169, 255, 0.8);
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ border: none;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.run-button:hover {
|
|
|
|
|
+ background-color: rgba(64, 169, 255, 1);
|
|
|
|
|
+ transform: translateY(-2px);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.code-button {
|
|
|
|
|
+ background-color: rgba(132, 94, 255, 0.8);
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ border: none;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.code-button:hover {
|
|
|
|
|
+ background-color: rgba(132, 94, 255, 1);
|
|
|
|
|
+ transform: translateY(-2px);
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|