通信模块配置软件
This commit is contained in:
2806
src/render/components/SatelliteSystem/EarthView.vue
Normal file
2806
src/render/components/SatelliteSystem/EarthView.vue
Normal file
File diff suppressed because it is too large
Load Diff
23
src/render/components/SatelliteSystem/FlagView.vue
Normal file
23
src/render/components/SatelliteSystem/FlagView.vue
Normal file
@@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<div v-show="!!src">
|
||||
<img :src="src" @dblclick="close">
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
import { useStore } from 'vuex';
|
||||
|
||||
const store = useStore()
|
||||
const src = computed(() => './image/flag/' + store.getters["satelliteSystem/name"] + '.png')
|
||||
|
||||
const close = () => {
|
||||
window.ipcRenderer.send('CLOSE')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
img {
|
||||
width: 10rem;
|
||||
}
|
||||
</style>
|
||||
327
src/render/components/SatelliteSystem/Quiz.vue
Normal file
327
src/render/components/SatelliteSystem/Quiz.vue
Normal file
@@ -0,0 +1,327 @@
|
||||
<template>
|
||||
<button id="step21" @click="showit" class="quiz"> 知识问答 </button>
|
||||
<div
|
||||
id="step22"
|
||||
v-if="show"
|
||||
class="text-center p-10"
|
||||
style="
|
||||
color: #ffffff;
|
||||
background-color: rgb(0 0 0 / 0.6);
|
||||
border-radius: 2rem;
|
||||
box-shadow: 0 0px 1rem 0px rgb(165 243 252 / 1);
|
||||
position: fixed;
|
||||
top: 10vh;
|
||||
left: 20vw;
|
||||
width: 60vw;
|
||||
height: 80vh;
|
||||
font-size: 2rem;
|
||||
"
|
||||
>
|
||||
<div
|
||||
@click="close"
|
||||
class="bg-gray-600 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
style="width: 2rem; height: 2rem; border-top-right-radius: 1rem; border-bottom-left-radius: 1rem;"
|
||||
>
|
||||
<el-icon style="width: 2rem; height: 2rem;">
|
||||
<CloseBold color="#ffffff" />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div style="font-weight: bold; color: #ffffff; font-size: 2rem; text-align: left;"> 题目:{{ topic.stem }} </div>
|
||||
<el-radio-group v-model="radio">
|
||||
<div class="w-full">
|
||||
<el-radio id="topicA" value="a" class="align-left" style="margin-right: 0px; margin-bottom: 2rem;color: #ffffff;">
|
||||
<div @click="radio = 'a'" :style="!checked ? radio == 'a' ? 'font-size: 2rem; background: radial-gradient(circle, rgba(60, 133, 211, 0.9), rgba(60, 133, 211, 0.1));' : 'font-size: 2rem;' : topic.answer == 'A' ? 'font-size: 2rem; background: radial-gradient(circle, rgba(65, 184, 131, 0.9), rgba(65, 184, 131, 0.1));' : 'font-size: 2rem; background: radial-gradient(circle, rgba(204, 62, 62, 0.9), rgba(204, 62, 62, 0.1));'">
|
||||
<label>A:{{ topic.A }}</label>
|
||||
<label style="color: rgba(0, 0, 0, 0)">{{ labelA }}</label>
|
||||
</div>
|
||||
</el-radio>
|
||||
</div>
|
||||
<div class="w-full">
|
||||
<el-radio id="topicB" value="b" class="align-left" style="margin-right: 0px; margin-bottom: 2rem; color: #ffffff;">
|
||||
<div @click="radio = 'b'" :style="!checked ? radio == 'b' ? 'font-size: 2rem; background: radial-gradient(circle, rgba(60, 133, 211, 0.9), rgba(60, 133, 211, 0.1));' : 'font-size: 2rem;' : topic.answer == 'B' ? 'font-size: 2rem; background: radial-gradient(circle, rgba(65, 184, 131, 0.9), rgba(65, 184, 131, 0.1));' : 'font-size: 2rem; background: radial-gradient(circle, rgba(204, 62, 62, 0.9), rgba(204, 62, 62, 0.1));'">
|
||||
<label>B:{{ topic.B }}</label>
|
||||
<label style="color: rgba(0, 0, 0, 0)">{{ labelB }}</label>
|
||||
</div>
|
||||
</el-radio>
|
||||
</div>
|
||||
<div class="w-full">
|
||||
<el-radio id="topicC" value="c" class="align-left" style="margin-right: 0px; margin-bottom: 2rem; color: #ffffff;">
|
||||
<div @click="radio = 'c'" :style="!checked ? radio == 'c' ? 'font-size: 2rem; background: radial-gradient(circle, rgba(60, 133, 211, 0.9), rgba(60, 133, 211, 0.1));' : 'font-size: 2rem;' : topic.answer == 'C' ? 'font-size: 2rem; background: radial-gradient(circle, rgba(65, 184, 131, 0.9), rgba(65, 184, 131, 0.1));' : 'font-size: 2rem; background: radial-gradient(circle, rgba(204, 62, 62, 0.9), rgba(204, 62, 62, 0.1));'">
|
||||
<label>C:{{ topic.C }}</label>
|
||||
<label style="color: rgba(0, 0, 0, 0)">{{ labelC }}</label>
|
||||
</div>
|
||||
</el-radio>
|
||||
</div>
|
||||
</el-radio-group>
|
||||
<br />
|
||||
<button type="text" :disabled="radio == ''" style="font-size: 2rem; background: radial-gradient(circle, rgba(60, 133, 211, 0.9), rgba(60, 133, 211, 0.1));" @click="showAnswer"> 揭晓答案 </button>
|
||||
<br />
|
||||
<el-text v-show="checked" style="font-weight: bold; color: #ffffff; font-size: 2rem; background: radial-gradient(circle, rgba(65, 184, 131, 0.9), rgba(65, 184, 131, 0.1));">
|
||||
正确答案:{{ topic.answer }}
|
||||
</el-text>
|
||||
<br />
|
||||
<el-text v-show="checked" :style="radio.toUpperCase() == topic.answer ? 'font-weight: bold; color: #ffffff; font-size: 2rem; background: radial-gradient(circle, rgba(223, 93, 126, 0.9), rgba(223, 93, 126, 0.1));' : 'font-weight: bold; color: #ffffff; font-size: 2rem; background: radial-gradient(circle, rgba(217, 203, 48, 0.9), rgba(217, 203, 48, 0.1));'">
|
||||
{{ radio.toUpperCase() == topic.answer ? "恭喜您,答对了!" : "答错了,请再接再厉!" }}
|
||||
</el-text>
|
||||
<br />
|
||||
<button v-show="checked" type="text" style="font-size: 2rem; background: radial-gradient(circle, rgba(60, 133, 211, 0.9), rgba(60, 133, 211, 0.1));" @click="nextTopic"> 下一题 </button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch, onMounted } from "vue";
|
||||
import { useStore } from "vuex";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
|
||||
const store = useStore();
|
||||
const satellites = store.state;
|
||||
|
||||
const show = ref(false);
|
||||
const showFrist = ref(true);
|
||||
const topic = reactive({
|
||||
stem: "",
|
||||
A: "",
|
||||
B: "",
|
||||
C: "",
|
||||
answer: "",
|
||||
});
|
||||
const radio = ref("");
|
||||
const checked = ref(false);
|
||||
const labelA = ref("");
|
||||
const labelB = ref("");
|
||||
const labelC = ref("");
|
||||
|
||||
const getRandomDate = () => {
|
||||
// 将日期转换为时间戳
|
||||
const startDate = new Date("1997-01-01").getTime();
|
||||
const endDate = new Date(new Date().toISOString().split('T')[0]).getTime();
|
||||
// 生成一个随机时间戳
|
||||
const randomTime = Math.random() * (endDate - startDate) + startDate;
|
||||
// 将时间戳转换回日期对象
|
||||
const randomDate = new Date(randomTime);
|
||||
// 格式化日期为YYYY-MM-DD
|
||||
const year = randomDate.getFullYear();
|
||||
const month = String(randomDate.getMonth() + 1).padStart(2, '0'); // 月份从0开始,需要加1
|
||||
const day = String(randomDate.getDate()).padStart(2, '0');
|
||||
return `${year}-${month}-${day}`;
|
||||
};
|
||||
|
||||
const adder = (num) => {
|
||||
let placeholder = "";
|
||||
for (let index = 0; index < num; index++) {
|
||||
placeholder = placeholder + "0";
|
||||
}
|
||||
return placeholder;
|
||||
};
|
||||
|
||||
const makeTopic = () => {
|
||||
const satelliteSystem = {
|
||||
beidou: "中国北斗卫星导航",
|
||||
"gps-ops": "美国全球定位",
|
||||
"glo-ops": "俄罗斯格洛纳斯卫星导航",
|
||||
galileo: "欧盟研制伽利略卫星导航",
|
||||
};
|
||||
let x = Math.floor(Math.random() * satellites.satelliteSystem.satellites.length),
|
||||
y = satellites.satelliteSystem.satellites[x].description.split("<p>")[2].slice(4, -4),
|
||||
z = satelliteSystem[satellites.satelliteSystem.name],
|
||||
topicId,
|
||||
topics = [
|
||||
{
|
||||
topic: `NORAD ID 是指由北美防空司令部(North American Aerospace Defense Command,缩写为 NORAD) 为地球轨道上的所有人造物体分配的唯一识别编号,用于全球范围内的追踪、监测和管理。请问,PRN为${y}的${z}系统卫星的NORAD ID是多少?`,
|
||||
makeAnswer: () => {
|
||||
const correctAnswer = satellites.satelliteSystem.satellites[x].description.split("<p>")[1].slice(9, -4);
|
||||
const uniqueNumbers = [];
|
||||
while (uniqueNumbers.length < 3) {
|
||||
let num = Math.floor(Math.random() * 90000) + 10000;
|
||||
if (!uniqueNumbers.includes(num) && num !== correctAnswer) {
|
||||
uniqueNumbers.push(num);
|
||||
}
|
||||
}
|
||||
topic.A = uniqueNumbers[0];
|
||||
topic.B = uniqueNumbers[1];
|
||||
topic.C = uniqueNumbers[2];
|
||||
const answerId = ["A", "B", "C"];
|
||||
const answer = answerId[Math.floor(Math.random() * 3)];
|
||||
topic.answer = answer;
|
||||
topic[answer] = correctAnswer;
|
||||
},
|
||||
},
|
||||
{
|
||||
topic: `PRN为${y}的${z}系统卫星的发射日期是:`,
|
||||
// 发射日期:2018-03-29 /1997
|
||||
makeAnswer: () => {
|
||||
const correctAnswer = satellites.satelliteSystem.satellites[x].description.split("<p>")[4].slice(5, -4);
|
||||
const uniqueNumbers = [];
|
||||
while (uniqueNumbers.length < 3) {
|
||||
let num = getRandomDate();
|
||||
if (!uniqueNumbers.includes(num) && num !== correctAnswer) {
|
||||
uniqueNumbers.push(num);
|
||||
}
|
||||
}
|
||||
topic.A = uniqueNumbers[0];
|
||||
topic.B = uniqueNumbers[1];
|
||||
topic.C = uniqueNumbers[2];
|
||||
const answerId = ["A", "B", "C"];
|
||||
const answer = answerId[Math.floor(Math.random() * 3)];
|
||||
topic.answer = answer;
|
||||
topic[answer] = correctAnswer;
|
||||
},
|
||||
},
|
||||
{
|
||||
topic: `PRN为${y}的${z}系统卫星的运行周期是:`,
|
||||
makeAnswer: () => {
|
||||
const correctAnswer = satellites.satelliteSystem.satellites[x].description.split("<p>")[5].slice(9, -4);
|
||||
const uniqueNumbers = [];
|
||||
while (uniqueNumbers.length < 3) {
|
||||
let num = ((Math.random() * 1350) + 90).toFixed(2);
|
||||
if (!uniqueNumbers.includes(num) && num !== correctAnswer) {
|
||||
uniqueNumbers.push(num);
|
||||
}
|
||||
}
|
||||
topic.A = uniqueNumbers[0];
|
||||
topic.B = uniqueNumbers[1];
|
||||
topic.C = uniqueNumbers[2];
|
||||
const answerId = ["A", "B", "C"];
|
||||
const answer = answerId[Math.floor(Math.random() * 3)];
|
||||
topic.answer = answer;
|
||||
topic[answer] = correctAnswer;
|
||||
},
|
||||
},
|
||||
{
|
||||
topic: `PRN为${y}的${z}系统卫星的轨道面倾角是多少度:`,
|
||||
makeAnswer: () => {
|
||||
const correctAnswer = satellites.satelliteSystem.satellites[x].description.split("<p>")[6].slice(9, -4);
|
||||
const uniqueNumbers = [];
|
||||
while (uniqueNumbers.length < 3) {
|
||||
let num = ((Math.random() * 90)).toFixed(2);
|
||||
if (!uniqueNumbers.includes(num) && num !== correctAnswer) {
|
||||
uniqueNumbers.push(num);
|
||||
}
|
||||
}
|
||||
topic.A = uniqueNumbers[0];
|
||||
topic.B = uniqueNumbers[1];
|
||||
topic.C = uniqueNumbers[2];
|
||||
const answerId = ["A", "B", "C"];
|
||||
const answer = answerId[Math.floor(Math.random() * 3)];
|
||||
topic.answer = answer;
|
||||
topic[answer] = correctAnswer;
|
||||
},
|
||||
},
|
||||
{
|
||||
topic: `PRN为${y}的${z}系统卫星的远地点高度是多少公里:`,
|
||||
makeAnswer: () => {
|
||||
const correctAnswer = satellites.satelliteSystem.satellites[x].description.split("<p>")[7].slice(10, -4);
|
||||
const uniqueNumbers = [];
|
||||
while (uniqueNumbers.length < 3) {
|
||||
let num = Math.floor(Math.random() * 34586) + 1200;
|
||||
if (!uniqueNumbers.includes(num) && num !== correctAnswer) {
|
||||
uniqueNumbers.push(num);
|
||||
}
|
||||
}
|
||||
topic.A = uniqueNumbers[0];
|
||||
topic.B = uniqueNumbers[1];
|
||||
topic.C = uniqueNumbers[2];
|
||||
const answerId = ["A", "B", "C"];
|
||||
const answer = answerId[Math.floor(Math.random() * 3)];
|
||||
topic.answer = answer;
|
||||
topic[answer] = correctAnswer;
|
||||
},
|
||||
},
|
||||
{
|
||||
topic: `PRN为${y}的${z}系统卫星的近地点高度是多少公里:`,
|
||||
makeAnswer: () => {
|
||||
const correctAnswer = satellites.satelliteSystem.satellites[x].description.split("<p>")[8].slice(10, -4);
|
||||
const uniqueNumbers = [];
|
||||
while (uniqueNumbers.length < 3) {
|
||||
let num = Math.floor(Math.random() * 34586) + 1200;
|
||||
if (!uniqueNumbers.includes(num) && num !== correctAnswer) {
|
||||
uniqueNumbers.push(num);
|
||||
}
|
||||
}
|
||||
topic.A = uniqueNumbers[0];
|
||||
topic.B = uniqueNumbers[1];
|
||||
topic.C = uniqueNumbers[2];
|
||||
const answerId = ["A", "B", "C"];
|
||||
const answer = answerId[Math.floor(Math.random() * 3)];
|
||||
topic.answer = answer;
|
||||
topic[answer] = correctAnswer;
|
||||
},
|
||||
},
|
||||
];
|
||||
topicId = Math.floor(Math.random() * topics.length);
|
||||
topic.stem = topics[topicId].topic;
|
||||
topics[topicId].makeAnswer();
|
||||
topic.A = String(topic.A);
|
||||
topic.B = String(topic.B);
|
||||
topic.C = String(topic.C);
|
||||
labelA.value = ""
|
||||
labelB.value = ""
|
||||
labelC.value = ""
|
||||
if (topic.A.length > topic.B.length && topic.A.length > topic.C.length) {
|
||||
labelB.value = adder(topic.A.length - topic.B.length);
|
||||
labelC.value = adder(topic.A.length - topic.C.length);
|
||||
} else if (topic.B.length > topic.A.length && topic.B.length > topic.C.length) {
|
||||
labelA.value = adder(topic.B.length - topic.A.length);
|
||||
labelC.value = adder(topic.B.length - topic.C.length);
|
||||
} else if (topic.C.length > topic.A.length && topic.C.length > topic.B.length) {
|
||||
labelA.value = adder(topic.C.length - topic.A.length);
|
||||
labelB.value = adder(topic.C.length - topic.B.length);
|
||||
} else if (topic.A.length < topic.B.length && topic.B.length == topic.C.length) {
|
||||
labelA.value = adder(topic.B.length - topic.A.length);
|
||||
} else if (topic.B.length < topic.A.length && topic.A.length == topic.C.length) {
|
||||
labelB.value = adder(topic.A.length - topic.B.length);
|
||||
} else if (topic.C.length < topic.A.length && topic.A.length == topic.B.length) {
|
||||
labelC.value = adder(topic.A.length - topic.C.length);
|
||||
}
|
||||
};
|
||||
|
||||
const showit = () => {
|
||||
if (showFrist.value) {
|
||||
showFrist.value = false;
|
||||
makeTopic();
|
||||
}
|
||||
show.value = true;
|
||||
};
|
||||
|
||||
const showAnswer = () => {
|
||||
checked.value = true;
|
||||
};
|
||||
|
||||
const nextTopic = () => {
|
||||
makeTopic();
|
||||
checked.value = false;
|
||||
radio.value = '';
|
||||
};
|
||||
|
||||
const close = () => {
|
||||
show.value = false;
|
||||
checked.value = false;
|
||||
radio.value = '';
|
||||
};
|
||||
|
||||
defineExpose({ show });
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.quiz {
|
||||
font-size: 1rem;
|
||||
color: rgba(255, 255, 255, 0);
|
||||
background-color: #ffffff;
|
||||
width: 1rem;
|
||||
height: 2rem;
|
||||
line-height: 2rem;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 0px 1rem 0px rgb(165 243 252 / 1);
|
||||
position: fixed;
|
||||
bottom: 20rem;
|
||||
right: 0;
|
||||
border-top-left-radius: 1rem;
|
||||
border-bottom-left-radius: 1rem;
|
||||
}
|
||||
|
||||
.quiz:hover {
|
||||
width: 6rem;
|
||||
color: #000000;
|
||||
background-color: rgb(165 243 252 / 1);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<div id="step20">
|
||||
<select class="cesium-button" v-model="selected">
|
||||
<option v-for="(value, key) in option_dic" :key="key" :value="key">
|
||||
{{ value }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch, onMounted } from "vue";
|
||||
import { useStore } from "vuex";
|
||||
|
||||
const store = useStore();
|
||||
const selected = ref("");
|
||||
const firstLoad = ref(true);
|
||||
|
||||
const emit = defineEmits(["handleSatelliteSystemSelect", "handleElementsFly"]);
|
||||
|
||||
defineExpose({ selected });
|
||||
|
||||
watch(selected, (value) => {
|
||||
if (value !== "custom") {
|
||||
store.dispatch("satelliteSystem/setName", { name: value });
|
||||
}
|
||||
window.allowUpdate = true;
|
||||
emit("handleSatelliteSystemSelect", value);
|
||||
if (!firstLoad.value) {
|
||||
let viewName = window.document.getElementsByClassName("cesium-toolbar-button")[1]
|
||||
.classList[2];
|
||||
if (viewName == "cesium-sceneModePicker-button2D") {
|
||||
window.document.getElementsByClassName("cesium-toolbar-button")[4].click();
|
||||
setTimeout(() => {
|
||||
window.document.getElementsByClassName("cesium-toolbar-button")[3].click();
|
||||
emit("handleElementsFly");
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
onMounted(
|
||||
() => (
|
||||
(selected.value = Object.keys(option_dic)[0]),
|
||||
setTimeout(() => {
|
||||
firstLoad.value = false;
|
||||
}, 0)
|
||||
)
|
||||
);
|
||||
|
||||
const option_dic = {
|
||||
beidou: "中国北斗卫星导航系统",
|
||||
"gps-ops": "美国全球定位系统",
|
||||
"glo-ops": "俄罗斯格洛纳斯卫星导航系统",
|
||||
galileo: "欧盟研制伽利略卫星导航系统",
|
||||
custom: "自定义卫星导航系统",
|
||||
};
|
||||
</script>
|
||||
2607
src/render/components/SatelliteSystem/SatelliteSystemView.vue
Normal file
2607
src/render/components/SatelliteSystem/SatelliteSystemView.vue
Normal file
File diff suppressed because it is too large
Load Diff
183
src/render/components/SatelliteSystem/SatelliteTableView.vue
Normal file
183
src/render/components/SatelliteSystem/SatelliteTableView.vue
Normal file
@@ -0,0 +1,183 @@
|
||||
<template>
|
||||
<div>
|
||||
<div id="satellite-table-container" class="text-white absolute bottom-0 text-center">
|
||||
<SvgButton id="step9" @click="show = !show" />
|
||||
<table ref="satelliteTable" v-show="show" class="text-center">
|
||||
<thead class="text-2xl">
|
||||
<th
|
||||
class="py-3 bg-blue-900 border border-gray-900"
|
||||
v-for="(label, index) in ['序号', '卫星名称', '显示/隐藏', '跟踪']"
|
||||
:key="label"
|
||||
:style="{ width: index == 1 ? '37.5vw' : '12.5vw' }"
|
||||
>
|
||||
<div style="display: flex; justify-content: center; align-items: center;">
|
||||
<div style="margin-right: 0.5rem;">
|
||||
{{ label }}
|
||||
</div>
|
||||
<input
|
||||
id="step10"
|
||||
v-if="label == '显示/隐藏'"
|
||||
:indeterminate="someShow"
|
||||
:checked="allShow"
|
||||
type="checkbox"
|
||||
class="w-6 h-6 cursor-pointer"
|
||||
@change="allOnShowStateCheckboxChanged"
|
||||
/>
|
||||
</div>
|
||||
</th>
|
||||
</thead>
|
||||
<tbody class="text-lg odd:bg-gray-50">
|
||||
<tr v-for="({ id, show }, index) in satellites" :key="id">
|
||||
<td class="border border-gray-900"> {{ index + 1 }} </td>
|
||||
<td id="satelliteId" class="border border-gray-900">{{ id }}</td>
|
||||
<td class="border border-gray-900">
|
||||
<div style="display: flex; justify-content: center; align-items: center;">
|
||||
<input
|
||||
id="step11"
|
||||
:checked="ashow"
|
||||
type="checkbox"
|
||||
class="w-6 h-6 cursor-pointer"
|
||||
@change="onShowStateCheckboxChanged(id)"
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
<td class="border border-gray-900">
|
||||
<button id="step12" @click="onTrackButtonClicked(id)">
|
||||
<TrackSvg />
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="text-white bg-blue-900"> {{ softwareName }} </div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, watch, onMounted } from "vue";
|
||||
import { useStore } from "vuex";
|
||||
|
||||
import SvgButton from "../SvgButton.vue";
|
||||
import TrackSvg from "../TrackSvg.vue";
|
||||
|
||||
const show = ref(false);
|
||||
const ashow = ref(true);
|
||||
const someShow = ref(false);
|
||||
const allShow = ref(true);
|
||||
const showarr = ref({});
|
||||
const softwareName = ref("卫星科普互动展示系统V1.0");
|
||||
|
||||
const store = useStore();
|
||||
const satellites = computed(() => store.getters["satelliteSystem/satellites"]);
|
||||
|
||||
const onTrackButtonClicked = (id) => {
|
||||
store.dispatch("satelliteSystem/track", id);
|
||||
};
|
||||
|
||||
const onShowStateCheckboxChanged = (id) => {
|
||||
window.allowUpdate = true;
|
||||
window.toallowUpdate = true;
|
||||
someShow.value = true;
|
||||
showarr.value[id] = !showarr.value[id];
|
||||
store.dispatch("satelliteSystem/toggleShow", id);
|
||||
let ashowsum = 0;
|
||||
satellites.value.forEach((item, index) => {
|
||||
if (showarr.value[item.id] == true) {
|
||||
ashowsum = ashowsum + 1;
|
||||
}
|
||||
});
|
||||
if (ashowsum == 0) {
|
||||
someShow.value = false;
|
||||
} else if (ashowsum == satellites.value.length) {
|
||||
someShow.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const allOnShowStateCheckboxChanged = () => {
|
||||
if (allShow.value) {
|
||||
allShow.value = false;
|
||||
ashow.value = false;
|
||||
} else {
|
||||
allShow.value = true;
|
||||
ashow.value = true;
|
||||
}
|
||||
satellites.value.forEach((element) => {
|
||||
if (showarr.value[element.id] !== ashow.value) {
|
||||
onShowStateCheckboxChanged(element.id);
|
||||
}
|
||||
onShowStateCheckboxChanged(element.id);
|
||||
});
|
||||
someShow.value = false;
|
||||
};
|
||||
|
||||
|
||||
// 表格数据更新时,滚动条回到最顶部
|
||||
const satelliteTable = ref(null);
|
||||
|
||||
watch(satellites, () => {
|
||||
ashow.value = true;
|
||||
someShow.value = false;
|
||||
allShow.value = true;
|
||||
showarr.value = {};
|
||||
satellites.value.forEach((item) => {
|
||||
showarr.value[item.id] = false;
|
||||
});
|
||||
satelliteTable.value.scrollTop = 0;
|
||||
});
|
||||
|
||||
const changeName = (newName) => {
|
||||
if (newName !== undefined) {
|
||||
softwareName.value = newName;
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({ show, onTrackButtonClicked });
|
||||
|
||||
onMounted(() => {
|
||||
if ("ipcRenderer" in window) {
|
||||
ipcRenderer.receive("softwareName", changeName);
|
||||
ipcRenderer.send("APP_MOUNTED");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
#satellite-table-container {
|
||||
left: 12.5vw;
|
||||
right: 12.5vw;
|
||||
}
|
||||
|
||||
table {
|
||||
display: block;
|
||||
height: 18rem;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
tr:nth-child(odd) {
|
||||
background-color: rgb(17, 24, 39);
|
||||
}
|
||||
|
||||
tr:nth-child(even) {
|
||||
background-color: rgb(31, 41, 55);
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0.25rem 0;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 0.6rem;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
-webkit-box-shadow: inset 0 0 6px rgb(0 0 0 / 30%);
|
||||
background-color: #4fbee2;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
-webkit-box-shadow: inset 0 0 6px rgb(0 0 0 / 30%);
|
||||
background-color: #111827;
|
||||
}
|
||||
</style>
|
||||
222
src/render/components/SatelliteSystem/ShowModel.vue
Normal file
222
src/render/components/SatelliteSystem/ShowModel.vue
Normal file
@@ -0,0 +1,222 @@
|
||||
<template>
|
||||
<div id="step15" class="bg-white" style="width: 30vw; height: 44vh; z-index: 99;">
|
||||
<div
|
||||
class="text-3xl absolute bottom-2 right-2 cursor-pointer flex justify-center items-center"
|
||||
style="width: 2rem; height: 6rem"
|
||||
>
|
||||
<div
|
||||
class="bg-gray-600"
|
||||
style="
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
border-top-left-radius: 50%;
|
||||
border-top-right-radius: 50%;
|
||||
"
|
||||
>
|
||||
<div
|
||||
id="step16"
|
||||
class="bg-gray-600 hover:bg-red-600"
|
||||
style="width: 2rem; height: 2rem; border-radius: 50%"
|
||||
>
|
||||
<el-icon @click="plus">
|
||||
<Plus color="#ffffff" />
|
||||
</el-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-gray-600" style="width: 2rem; height: 2rem">
|
||||
<div
|
||||
id="step17"
|
||||
class="hover:bg-red-600"
|
||||
style="width: 2rem; height: 2rem; border-radius: 50%"
|
||||
>
|
||||
<el-icon @click="refresh">
|
||||
<RefreshRight color="#ffffff" />
|
||||
</el-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="bg-gray-600"
|
||||
style="
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
border-bottom-left-radius: 50%;
|
||||
border-bottom-right-radius: 50%;
|
||||
"
|
||||
>
|
||||
<div
|
||||
id="step18"
|
||||
class="bg-gray-600 hover:bg-red-600"
|
||||
style="width: 2rem; height: 2rem; border-radius: 50%;"
|
||||
>
|
||||
<el-icon @click="minus">
|
||||
<Minus color="#ffffff" />
|
||||
</el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@click="closeModel"
|
||||
class="bg-gray-600 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
style="width: 2rem; height: 2rem"
|
||||
>
|
||||
<el-icon style="width: 2rem; height: 2rem">
|
||||
<CloseBold color="#ffffff" />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div
|
||||
id="threeCanvas"
|
||||
ref="canvasContainer"
|
||||
style="width: 30vw; height: 44vh; z-index: 99; margin: 0; overflow: hidden;"
|
||||
></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import { CloseBold, Plus, RefreshRight, Minus } from "@element-plus/icons-vue";
|
||||
|
||||
import * as THREE from "three";
|
||||
|
||||
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
|
||||
// import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
|
||||
|
||||
import sky from "../../assets/sky.jpg";
|
||||
|
||||
const canvasContainer = ref(null);
|
||||
const model = ref(null);
|
||||
let scene, camera, renderer, clonedModel, controls;
|
||||
|
||||
// 初始化场景
|
||||
const initScene = () => {
|
||||
const threeCanvas = document.getElementById("threeCanvas");
|
||||
// 创建场景
|
||||
scene = new THREE.Scene();
|
||||
scene.background = new THREE.Color(0x666666);
|
||||
|
||||
// 创建相机(透视相机)
|
||||
camera = new THREE.PerspectiveCamera(75, threeCanvas.clientWidth / threeCanvas.clientHeight, 0.1, 1000);
|
||||
camera.position.z = 5;
|
||||
|
||||
// 创建渲染器
|
||||
renderer = new THREE.WebGLRenderer({ antialias: true });
|
||||
renderer.setSize(threeCanvas.clientWidth, threeCanvas.clientHeight);
|
||||
|
||||
// 挂载到 DOM
|
||||
canvasContainer.value.appendChild(renderer.domElement);
|
||||
|
||||
//创建鼠标控制器
|
||||
controls = new OrbitControls(camera, renderer.domElement);
|
||||
|
||||
// 添加灯光
|
||||
const light = new THREE.DirectionalLight(0xffffff, 1);
|
||||
light.position.set(1, 1, 1);
|
||||
scene.add(light);
|
||||
const light1 = new THREE.DirectionalLight(0xffffff, 1);
|
||||
light1.position.set(-1, 1, 1);
|
||||
scene.add(light1);
|
||||
const light2 = new THREE.DirectionalLight(0xffffff, 1);
|
||||
light2.position.set(1, -1, 1);
|
||||
scene.add(light2);
|
||||
const light3 = new THREE.DirectionalLight(0xffffff, 1);
|
||||
light3.position.set(1, 1, -1);
|
||||
scene.add(light3);
|
||||
const light4 = new THREE.DirectionalLight(0xffffff, 1);
|
||||
light4.position.set(-1, -1, 1);
|
||||
scene.add(light4);
|
||||
const light5 = new THREE.DirectionalLight(0xffffff, 1);
|
||||
light5.position.set(1, -1, -1);
|
||||
scene.add(light5);
|
||||
const light6 = new THREE.DirectionalLight(0xffffff, 1);
|
||||
light6.position.set(-1, 1, -1);
|
||||
scene.add(light6);
|
||||
const light7 = new THREE.DirectionalLight(0xffffff, 1);
|
||||
light7.position.set(-1, -1, -1);
|
||||
scene.add(light7);
|
||||
|
||||
// 创建半球体几何体
|
||||
const skyGeometry = new THREE.SphereGeometry(66, 66, 66); // 半径、宽度分段、高度分段
|
||||
|
||||
// 加载天空纹理
|
||||
const skyTextureLoader = new THREE.TextureLoader();
|
||||
const skyTexture = skyTextureLoader.load(sky);
|
||||
|
||||
// 创建材质,并应用天空纹理
|
||||
const skyMaterial = new THREE.MeshBasicMaterial({
|
||||
map: skyTexture,
|
||||
side: THREE.BackSide,
|
||||
}); // 使用背面显示纹理
|
||||
|
||||
// 创建天空穹顶网格
|
||||
const skyDome = new THREE.Mesh(skyGeometry, skyMaterial);
|
||||
|
||||
// 将天空穹顶添加到场景中
|
||||
scene.add(skyDome);
|
||||
};
|
||||
|
||||
const loadModel = () => {
|
||||
setTimeout(() => {
|
||||
if (clonedModel !== undefined) {
|
||||
scene.remove(clonedModel);
|
||||
}
|
||||
clonedModel = model.value.model.clone();
|
||||
scene.add(clonedModel);
|
||||
}, 0);
|
||||
};
|
||||
|
||||
// 动画循环
|
||||
const animate = () => {
|
||||
requestAnimationFrame(animate);
|
||||
controls.update();
|
||||
renderer.render(scene, camera);
|
||||
};
|
||||
|
||||
// 初始球体半径
|
||||
// r1 = Math.sqrt(x * x + y * y + z * z)
|
||||
// 相机移动后的球体半径为 r2 ,假设相机向球心移动距离为 1 单位长度
|
||||
// r1 - r2 = 1
|
||||
// 调整相机移动距离 d 以获取相机移动后的球体半径 r2
|
||||
// r2 = r1 - d
|
||||
// 坐标值与球体半径比例是固定的,初始坐标值为 x1,相机移动后的坐标值为 x2
|
||||
// x1 / r1 = x2 / r2
|
||||
// x2 = x1 / r1 * r2
|
||||
|
||||
const plus = () => {
|
||||
const moveValue = 1;
|
||||
const r1 = Math.sqrt(camera.position.x * camera.position.x + camera.position.y * camera.position.y + camera.position.z * camera.position.z);
|
||||
const r2 = r1 - moveValue;
|
||||
const x = (camera.position.x / r1) * r2;
|
||||
const y = (camera.position.y / r1) * r2;
|
||||
const z = (camera.position.z / r1) * r2;
|
||||
camera.position.set(x, y, z);
|
||||
};
|
||||
|
||||
const refresh = () => {
|
||||
camera.position.set(0, 0, 5);
|
||||
};
|
||||
|
||||
const minus = () => {
|
||||
const moveValue = 1;
|
||||
const r1 = Math.sqrt(camera.position.x * camera.position.x + camera.position.y * camera.position.y + camera.position.z * camera.position.z);
|
||||
const r2 = r1 + moveValue;
|
||||
const x = (camera.position.x / r1) * r2;
|
||||
const y = (camera.position.y / r1) * r2;
|
||||
const z = (camera.position.z / r1) * r2;
|
||||
camera.position.set(x, y, z);
|
||||
};
|
||||
|
||||
defineExpose({ model, loadModel });
|
||||
|
||||
onMounted(() => {
|
||||
initScene();
|
||||
loadModel();
|
||||
animate();
|
||||
});
|
||||
|
||||
const emit = defineEmits(["showModel"]);
|
||||
|
||||
const closeModel = () => {
|
||||
emit("showModel", false, "", "");
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
387
src/render/components/SatelliteSystem/Tour.vue
Normal file
387
src/render/components/SatelliteSystem/Tour.vue
Normal file
@@ -0,0 +1,387 @@
|
||||
<template>
|
||||
<el-dropdown class="text-center felx justify-end items-center">
|
||||
<button class="tour">
|
||||
系统导航
|
||||
<el-icon
|
||||
style="width: 1rem; height: 1rem; font-size: 1rem"
|
||||
class="el-icon--right"
|
||||
><arrow-down
|
||||
/></el-icon>
|
||||
</button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item
|
||||
v-for="(step, index) in tourSteps"
|
||||
@click="tour(index)"
|
||||
>
|
||||
<el-link
|
||||
style="width: 8rem; height: 1.8rem; font-weight: bold; font-size: 1rem;"
|
||||
:underline="false"
|
||||
type="primary"
|
||||
>
|
||||
{{ step.tourName }}
|
||||
</el-link>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<el-tour v-for="step in tourSteps" v-model="step.tourOpen">
|
||||
<template #default>
|
||||
<el-tour-step
|
||||
v-for="(stepData, index) in step.tourData"
|
||||
:target="stepData.target"
|
||||
:prev-button-props="{
|
||||
children: '上一步',
|
||||
onClick: stepData.handlePrevClick,
|
||||
}"
|
||||
:next-button-props="{
|
||||
children: index == step.tourData.length - 1 ? '完成' : '下一步',
|
||||
onClick: stepData.handleNextClick,
|
||||
}"
|
||||
>
|
||||
<template #header>
|
||||
<div style="color: blueviolet">{{ stepData.title }}</div>
|
||||
</template>
|
||||
<template #default>
|
||||
<div style="color: blueviolet">{{ stepData.content }}</div>
|
||||
</template>
|
||||
</el-tour-step>
|
||||
</template>
|
||||
<template #indicators="{ current, total }">
|
||||
<span>{{ current + 1 }} / {{ total }}</span>
|
||||
</template>
|
||||
</el-tour>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { ArrowDown } from "@element-plus/icons-vue";
|
||||
|
||||
const emit = defineEmits(["handleNext"]);
|
||||
|
||||
const tourSteps = ref([
|
||||
{
|
||||
tourName: "罗盘导航",
|
||||
tourOpen: false,
|
||||
tourData: [
|
||||
{
|
||||
target: "#step1",
|
||||
title: "罗盘外部的作用",
|
||||
content: "用于视图的方向(北、南、东、西)控制",
|
||||
handlePrevClick: () => {
|
||||
// console.log("prevEvent");
|
||||
},
|
||||
handleNextClick: () => {
|
||||
// console.log("nextEvent");
|
||||
},
|
||||
},
|
||||
{
|
||||
target: "#step2",
|
||||
title: "罗盘内部的作用",
|
||||
content: "用于视图的旋转控制",
|
||||
handlePrevClick: () => {
|
||||
// console.log("prevEvent");
|
||||
},
|
||||
handleNextClick: () => {
|
||||
// console.log("nextEvent");
|
||||
},
|
||||
},
|
||||
{
|
||||
target: "#step3",
|
||||
title: "放大按钮的作用",
|
||||
content: "用于放大视图",
|
||||
handlePrevClick: () => {
|
||||
// console.log("prevEvent");
|
||||
},
|
||||
handleNextClick: () => {
|
||||
// console.log("nextEvent");
|
||||
},
|
||||
},
|
||||
{
|
||||
target: "#step4",
|
||||
title: "复位按钮的作用",
|
||||
content: "用于定位和复位视图",
|
||||
handlePrevClick: () => {
|
||||
// console.log("prevEvent");
|
||||
},
|
||||
handleNextClick: () => {
|
||||
// console.log("nextEvent");
|
||||
},
|
||||
},
|
||||
{
|
||||
target: "#step5",
|
||||
title: "缩小按钮的作用",
|
||||
content: "用于缩小视图",
|
||||
handlePrevClick: () => {
|
||||
// console.log("prevEvent");
|
||||
},
|
||||
handleNextClick: () => {
|
||||
// console.log("nextEvent");
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
tourName: "动画控制导航",
|
||||
tourOpen: false,
|
||||
tourData: [
|
||||
{
|
||||
target: "#animation_pathPointer",
|
||||
title: "速度调节指针的作用",
|
||||
content: "用于控制动画速度",
|
||||
handlePrevClick: () => {
|
||||
// console.log("prevEvent");
|
||||
},
|
||||
handleNextClick: () => {
|
||||
// console.log("nextEvent");
|
||||
},
|
||||
},
|
||||
{
|
||||
target: "#step6",
|
||||
title: "反转按钮的作用",
|
||||
content: "用于反转动画",
|
||||
handlePrevClick: () => {
|
||||
// console.log("prevEvent");
|
||||
},
|
||||
handleNextClick: () => {
|
||||
// console.log("nextEvent");
|
||||
},
|
||||
},
|
||||
{
|
||||
target: "#step7",
|
||||
title: "暂停按钮的作用",
|
||||
content: "用于暂停动画",
|
||||
handlePrevClick: () => {
|
||||
// console.log("prevEvent");
|
||||
},
|
||||
handleNextClick: () => {
|
||||
// console.log("nextEvent");
|
||||
},
|
||||
},
|
||||
{
|
||||
target: "#step8",
|
||||
title: "播放按钮的作用",
|
||||
content: "用于播放动画",
|
||||
handlePrevClick: () => {
|
||||
// console.log("prevEvent");
|
||||
},
|
||||
handleNextClick: () => {
|
||||
// console.log("nextEvent");
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
tourName: "卫星列表导航",
|
||||
tourOpen: false,
|
||||
tourData: [
|
||||
{
|
||||
target: "#step9",
|
||||
title: "卫星列表开关展示/隐藏按钮的作用",
|
||||
content: "用于展示或隐藏卫星列表",
|
||||
handlePrevClick: () => {
|
||||
// console.log("prevEvent");
|
||||
},
|
||||
handleNextClick: () => {
|
||||
// console.log("nextEvent");
|
||||
},
|
||||
},
|
||||
{
|
||||
target: "#step10",
|
||||
title: "显示/隐藏所有卫星勾选框的作用",
|
||||
content: "用于显示/隐藏所有卫星的运行轨迹和卫星模型",
|
||||
handlePrevClick: () => {
|
||||
// console.log("prevEvent");
|
||||
},
|
||||
handleNextClick: () => {
|
||||
// console.log("nextEvent");
|
||||
},
|
||||
},
|
||||
{
|
||||
target: "#step11",
|
||||
title: "显示/隐藏选中卫星勾选框的作用",
|
||||
content: "用于显示/隐藏选中卫星的运行轨迹和卫星模型",
|
||||
handlePrevClick: () => {
|
||||
// console.log("prevEvent");
|
||||
},
|
||||
handleNextClick: () => {
|
||||
// console.log("nextEvent");
|
||||
// 触发查看卫星的事件
|
||||
emit("handleNext", "#step12");
|
||||
},
|
||||
},
|
||||
{
|
||||
target: "#step12",
|
||||
title: "查看卫星详情按钮的作用",
|
||||
content: "用于查看卫星的详细信息并跟踪该卫星的视角",
|
||||
handlePrevClick: () => {
|
||||
// console.log("prevEvent");
|
||||
},
|
||||
handleNextClick: () => {
|
||||
// console.log("nextEvent");
|
||||
},
|
||||
},
|
||||
{
|
||||
target: "#step13",
|
||||
title: "卫星详情信息",
|
||||
content: "卫星的详细信息",
|
||||
handlePrevClick: () => {
|
||||
// console.log("prevEvent");
|
||||
},
|
||||
handleNextClick: () => {
|
||||
// console.log("nextEvent");
|
||||
},
|
||||
},
|
||||
{
|
||||
target: "#step14",
|
||||
title: "跟踪/解除卫星视角按钮的作用",
|
||||
content: "用于跟踪或解除跟随卫星运动的视角,并在左侧窗口中展示卫星的模型",
|
||||
handlePrevClick: () => {
|
||||
// console.log("prevEvent");
|
||||
},
|
||||
handleNextClick: () => {
|
||||
// console.log("nextEvent");
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
tourName: "卫星模型展示导航",
|
||||
tourOpen: false,
|
||||
tourData: [
|
||||
{
|
||||
target: "#step15",
|
||||
title: "卫星模型展示区域的作用",
|
||||
content: "用于展示更为精细的卫星模型",
|
||||
handlePrevClick: () => {
|
||||
// console.log("prevEvent");
|
||||
},
|
||||
handleNextClick: () => {
|
||||
// console.log("nextEvent");
|
||||
},
|
||||
},
|
||||
{
|
||||
target: "#step16",
|
||||
title: "放大按钮的作用",
|
||||
content: "用于放大视图",
|
||||
handlePrevClick: () => {
|
||||
// console.log("prevEvent");
|
||||
},
|
||||
handleNextClick: () => {
|
||||
// console.log("nextEvent");
|
||||
},
|
||||
},
|
||||
{
|
||||
target: "#step17",
|
||||
title: "复位按钮的作用",
|
||||
content: "用于复位视图",
|
||||
handlePrevClick: () => {
|
||||
// console.log("prevEvent");
|
||||
},
|
||||
handleNextClick: () => {
|
||||
// console.log("nextEvent");
|
||||
},
|
||||
},
|
||||
{
|
||||
target: "#step18",
|
||||
title: "缩小按钮的作用",
|
||||
content: "用于缩小视图",
|
||||
handlePrevClick: () => {
|
||||
// console.log("prevEvent");
|
||||
},
|
||||
handleNextClick: () => {
|
||||
// console.log("nextEvent");
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
tourName: "视图与卫星系统切换",
|
||||
tourOpen: false,
|
||||
tourData: [
|
||||
{
|
||||
target: "#step19",
|
||||
title: "视图切换按钮的作用",
|
||||
content: "用于切换地球的3D,2D和哥伦布视图",
|
||||
handlePrevClick: () => {
|
||||
// console.log("prevEvent");
|
||||
},
|
||||
handleNextClick: () => {
|
||||
// console.log("nextEvent");
|
||||
},
|
||||
},
|
||||
{
|
||||
target: "#step20",
|
||||
title: "卫星系统切换按钮的作用",
|
||||
content: "用于切换不同的卫星系统,包括北斗和其他国际卫星系统",
|
||||
handlePrevClick: () => {
|
||||
// console.log("prevEvent");
|
||||
},
|
||||
handleNextClick: () => {
|
||||
// console.log("nextEvent");
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
tourName: "知识问答导航",
|
||||
tourOpen: false,
|
||||
tourData: [
|
||||
{
|
||||
target: "#step21",
|
||||
title: "趣味问答按钮的作用",
|
||||
content: "用于显示趣味问答区域",
|
||||
handlePrevClick: () => {
|
||||
// console.log("prevEvent");
|
||||
},
|
||||
handleNextClick: () => {
|
||||
// console.log("nextEvent");
|
||||
emit("handleNext", "#step22");
|
||||
},
|
||||
},
|
||||
{
|
||||
target: "#step22",
|
||||
title: "趣味问答区域的作用",
|
||||
content: "用于展示与卫星相关的趣味问答和相关知识",
|
||||
handlePrevClick: () => {
|
||||
// console.log("prevEvent");
|
||||
},
|
||||
handleNextClick: () => {
|
||||
// console.log("nextEvent");
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
const tour = (index) => {
|
||||
emit("handleNext", tourSteps.value[index].tourData[0].target);
|
||||
setTimeout(() => {
|
||||
tourSteps.value[index].tourOpen = true;
|
||||
}, 0);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.tour {
|
||||
font-size: 1rem;
|
||||
color: rgba(255, 255, 255, 0);
|
||||
background-color: #ffffff;
|
||||
width: 1rem;
|
||||
height: 2rem;
|
||||
line-height: 2rem;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 0px 1rem 0px rgb(165 243 252 / 1);
|
||||
position: fixed;
|
||||
bottom: 16rem;
|
||||
right: 0;
|
||||
border-top-left-radius: 1rem;
|
||||
border-bottom-left-radius: 1rem;
|
||||
}
|
||||
|
||||
.tour:hover {
|
||||
width: 10rem;
|
||||
color: #000000;
|
||||
background-color: rgb(165 243 252 / 1);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user