动态效果

复制代码

 


<script setup lang="ts"> import useMqttStore from '@/stores/modules/mqtt'; import imganimation1 from '@/assets/images/fly_test_01.png'; import imganimation2 from '@/assets/images/fly_test_02.png'; import imganimation3 from '@/assets/images/fly_test_03.png'; import imgstatic1 from '@/assets/images/fly_test_static_01.png'; import imgstatic2 from '@/assets/images/fly_test_static_02.png'; import imgstatic3 from '@/assets/images/fly_test_static_03.png'; defineOptions({ name: 'FlySelfTest', }); const mqttStore = useMqttStore(); const styleObj = reactive({ width: '40rem', top: '20%', left: '40%', }); const title = ref('飞行自检'); const flySelfTestRef = ref(); const isSuccess = ref(false); // 获取当前飞机的实时信息 const uavData = computed(() => { return mqttStore.CURRENT_INFO?.uav; }); const interval = ref(null) as any; const allStatus = ref({ status1: 'pedding', status2: 'pedding', status3: 'pedding', status4: 'pedding', status5: 'pedding', status6: 'pedding', status7: 'pedding', status8: 'pedding', status9: 'pedding', }) as any; const tests = ref([ { category: '飞行器状态检测', items: [ { name: '健康信息检测', statusKey: 'status1' }, { name: '电池电量检测', statusKey: 'status2' }, { name: '搜星状态检测', statusKey: 'status3' }, ], success: false, imgUrl: imganimation1, imgUrlStatic: imgstatic1, }, { category: '飞行安全设置项检测', items: [ { name: 'RTK检测', statusKey: 'status4' }, { name: '安全高度检测', statusKey: 'status5' }, { name: '返航设置检测', statusKey: 'status6' }, ], success: false, imgUrl: imganimation2, imgUrlStatic: imgstatic2, }, { category: '起飞环境检测', items: [ { name: '雨量检测', statusKey: 'status7' }, { name: '风速检测', statusKey: 'status8' }, { name: '网络检测', statusKey: 'status9' }, ], success: false, imgUrl: imganimation3, imgUrlStatic: imgstatic3, }, ]); // 检查所有类别的状态,若每个类别内的项都为 'success',则更新该类别的 success 状态 function checkCategorySuccess() { tests.value.forEach((test) => { // 检查当前类别下的所有项的状态 const allItemsSuccess = test.items.every(item => allStatus.value[item.statusKey] === 'success'); test.success = allItemsSuccess; }); } function changeStyle() { if (isSuccess.value) { styleObj.width = '20rem'; styleObj.top = '20%'; styleObj.left = '45%'; return; } styleObj.width = '40rem'; styleObj.top = '20%'; styleObj.left = '40%'; } function initData() { isSuccess.value = false; title.value = '飞行自检'; changeStyle(); for (const key in allStatus.value) { allStatus.value[key] = 'pedding'; } checkCategorySuccess(); } function openDialog() { initData(); flySelfTestRef.value.open(); startTesting(); } function startTesting() { const statusKeys = Object.keys(allStatus.value); let index = 0; interval.value = setInterval(() => { // if (interval.value) { // clearInterval(interval.value); // } if (index === statusKeys.length - 1 && (uavData.value?.modeCode === undefined || uavData.value?.modeCode === 0)) { return; } if (index < statusKeys.length) { const key = statusKeys[index]; allStatus.value[key] = 'success'; index++; checkCategorySuccess(); } else { clearInterval(interval.value); const key = statusKeys[index]; allStatus.value[key] = 'success'; title.value = ''; isSuccess.value = true; changeStyle(); checkCategorySuccess(); setTimeout(() => { flySelfTestRef.value?.close(); }, 2000); } }, 6 * 1000); watch(() => uavData.value, (newVal) => { if (newVal?.modeCode === 1) { title.value = ''; // 所有状态都为成功 for (const key in allStatus.value) { allStatus.value[key] = 'success'; } clearInterval(interval.value); checkCategorySuccess(); setTimeout(() => { changeStyle(); isSuccess.value = true; }, 100); setTimeout(() => { flySelfTestRef.value?.close(); }, 2000); } }, { immediate: true, deep: true }); } function closeDialog(bool?: boolean) { initData(); clearInterval(interval.value); if (!bool) { flySelfTestRef.value?.close(); } } // onMounted(() => { // setTimeout(() => { // uavData.value.modeCode = 1; // }, 8000); // }) defineExpose({ openDialog, closeDialog, }); </script> <template> <Dialog ref="flySelfTestRef" :footer="false" :title="title" :dialog-style="{ width: styleObj.width, top: styleObj.top, left: styleObj.left }" :is-close="true" @close="closeDialog(true)" > <div class="w-full f-full"> <div v-if="!isSuccess" class="flex items-center justify-between pl-10 pr-10"> <div v-for="test in tests" :key="test.category" class="flex flex-col gap-[0.5rem] justify-center items-center"> <div class="img"> <img v-if="!test.success" :src="test.imgUrl" alt=""> <img v-else :src="test.imgUrlStatic" alt=""> <div v-if="!test.success" class="loading-bg" /> <div class="inner-bg" /> </div> <div class="inline-flex flex-col gap-[0.5rem]"> <div class="title"> <span>{{ test.category }}</span> </div> <div v-for="item in test.items" :key="item.name" class="flex items-center gap-[0.4rem]"> <div v-if="allStatus[item.statusKey] === 'pedding'" class="loading" /> <div v-else class="flex items-center"> <PubSvgIcon name="fly_test_succ" size="1rem" /> </div> <span class="content">{{ item.name }}</span> </div> </div> </div> </div> <div v-else class="flex items-center"> <PubSvgIcon name="fly_test_success" size="1.5rem" class="mr-2" /> <span style="font-size: 1rem;">一切正常,准备起飞</span> </div> </div> </Dialog> </template> <style lang="less" scoped> .success-img { width: 18px; height: 18px; margin-right: 3px; background: url(@/assets/images/fly_test_success.png) no-repeat; background-size: 100% 100%; } .title { font-size: 16px; font-weight: 500; color: #f7f7f7; } .content { font-size: 15px; font-weight: 400; color: #ffffffb3; } .img { position: relative; display: flex; align-items: center; justify-content: center; width: 133px; height: 121px; img { position: absolute; top: 50%; left: 50%; width: 88px; height: 88px; transform: translate(-50%, -50%); } .loading-bg { z-index: 1; width: 88px; height: 88px; background: url(@/assets/images/fly_test_outer.png) no-repeat; background-size: 100% 100%; animation: spin 3s linear infinite; } .inner-bg { position: absolute; top: 50%; left: 50%; width: 100%; height: 100%; background: url(@/assets/images/fly_test_inner.png) no-repeat; background-size: 100% 100%; transform: translate(-50%, -50%); } } .loading { width: 16px; height: 16px; background: url(@/assets/images/fly_test_loading.png) no-repeat; background-size: 100% 100%; animation: spin 2s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } </style>
复制代码

 

posted @   abcByme  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示