Files
----/前端源码/uni-app/components/screens/AuspiciousLoading.vue

321 lines
6.8 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="aus-load">
<view class="aus-load-bg"></view>
<view class="aus-compass-wrapper">
<view class="aus-compass">
<view class="compass-glow"></view>
<view class="compass-svg-wrap">
<!-- 外圈虚线圆 -->
<view class="circle-outer"></view>
<view class="circle-main"></view>
<!-- 天干地支 -->
<view
v-for="(char, i) in runes"
:key="'rune-' + i"
class="rune-char"
:class="{ active: i === activeCharIndex }"
:style="getRuneStyle(i)"
>
{{ char }}
</view>
<!-- 八卦符号 - 旋转圈 -->
<view class="bagua-circle" :style="{ transform: 'rotate(' + baGuaRotation + 'deg)' }">
<view
v-for="(gua, i) in baGua"
:key="'gua-' + i"
class="bagua-char"
:style="getBaGuaStyle(i)"
>
{{ gua }}
</view>
</view>
<!-- 中心罗盘指针 -->
<view class="compass-pointer" :style="{ transform: 'rotate(' + pointerRotation + 'deg)' }">
<view class="pointer-bar"></view>
<view class="pointer-dot"></view>
</view>
</view>
</view>
<!-- 加载文本 -->
<view class="loading-text">
<view class="loading-title">择吉推演中</view>
<view class="loading-subtitle">结合八字 · 排盘择吉 · 避讳冲煞</view>
<view class="loading-tip">分析时间预计1-2分钟可点击返回按钮退出并在我的方案中查看结果</view>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from "vue";
const runes = [
"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸",
"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"
];
const baGua = ["☰", "☱", "☲", "☳", "☴", "☵", "☶", "☷"];
const activeCharIndex = ref(-1);
const baGuaRotation = ref(0);
const pointerRotation = ref(0);
let runeInterval: number | null = null;
let baGuaInterval: number | null = null;
let pointerInterval: number | null = null;
const getRuneStyle = (index: number) => {
const angle = (index * 360) / runes.length;
const radius = 240;
const angleRad = (angle - 90) * (Math.PI / 180);
const x = 300 + radius * Math.cos(angleRad);
const y = 300 + radius * Math.sin(angleRad);
return {
left: x + "rpx",
top: y + "rpx",
transform: `translate(-50%, -50%) rotate(${angle}deg)`
};
};
const getBaGuaStyle = (index: number) => {
const angle = (index * 360) / 8;
const radius = 145;
const angleRad = (angle - 90) * (Math.PI / 180);
const x = 180 + radius * Math.cos(angleRad);
const y = 180 + radius * Math.sin(angleRad);
return {
left: x + "rpx",
top: y + "rpx",
transform: `translate(-50%, -50%) rotate(${angle}deg)`
};
};
onMounted(() => {
let count = 0;
runeInterval = setInterval(() => {
activeCharIndex.value = count % runes.length;
count++;
}, 100);
baGuaInterval = setInterval(() => {
baGuaRotation.value += 0.25;
}, 30);
let pointerCount = 0;
pointerInterval = setInterval(() => {
pointerCount += 1;
pointerRotation.value = pointerCount * 1.2;
}, 10);
});
onUnmounted(() => {
if (runeInterval) clearInterval(runeInterval);
if (baGuaInterval) clearInterval(baGuaInterval);
if (pointerInterval) clearInterval(pointerInterval);
});
</script>
<style scoped>
.aus-load {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background: #1a1a1a;
position: relative;
overflow: hidden;
font-family: SimSun, "Songti SC", "Songti TC", "Noto Serif SC", STSong, serif;
}
.aus-load-bg {
position: absolute;
inset: 0;
background: url("https://www.transparenttextures.com/patterns/rice-paper.png");
opacity: 0.08;
pointer-events: none;
}
.aus-compass-wrapper {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 96rpx;
}
.aus-compass {
position: relative;
width: 100%;
height: 60vh;
display: flex;
align-items: center;
justify-content: center;
min-width: 512rpx;
min-height: 512rpx;
}
.compass-glow {
position: absolute;
inset: 0;
border-radius: 50%;
background-color: #d4af37;
filter: blur(60rpx);
opacity: 0.2;
animation: pulse 4s ease-in-out infinite;
max-width: 80vw;
max-height: 80vw;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
@keyframes pulse {
0%, 100% {
opacity: 0.15;
transform: translate(-50%, -50%) scale(0.95);
}
50% {
opacity: 0.35;
transform: translate(-50%, -50%) scale(1.05);
}
}
.compass-svg-wrap {
position: relative;
width: 80vw;
height: 80vw;
max-width: 600rpx;
max-height: 600rpx;
}
.circle-outer {
position: absolute;
left: 10rpx;
top: 10rpx;
width: 580rpx;
height: 580rpx;
border-radius: 50%;
border: 1rpx dashed #d4af37;
opacity: 0.3;
}
.circle-main {
position: absolute;
left: 20rpx;
top: 20rpx;
width: 560rpx;
height: 560rpx;
border-radius: 50%;
border: 2rpx solid #d4af37;
opacity: 0.4;
}
.rune-char {
position: absolute;
font-size: 24rpx;
color: #888;
font-family: SimSun, serif;
transition: all 0.2s;
}
.rune-char.active {
color: #d4af37;
font-weight: bold;
text-shadow: 0 0 10rpx #d4af37;
}
.bagua-circle {
position: absolute;
left: 120rpx;
top: 120rpx;
width: 360rpx;
height: 360rpx;
border-radius: 50%;
border: 2rpx solid rgba(212, 175, 55, 0.15);
transition: transform 0.3s linear;
}
.bagua-char {
position: absolute;
font-size: 48rpx;
color: #d4af37;
opacity: 0.7;
font-family: SimSun, serif;
}
.compass-pointer {
position: absolute;
left: 300rpx;
top: 300rpx;
width: 0;
height: 0;
transition: transform 0.05s linear;
}
.pointer-bar {
position: absolute;
left: 50%;
top: -160rpx;
width: 4rpx;
height: 160rpx;
background-color: #8b2323;
transform: translateX(-50%);
}
.pointer-dot {
position: absolute;
left: 50%;
top: 50%;
width: 12rpx;
height: 12rpx;
border-radius: 50%;
background-color: #d4af37;
transform: translate(-50%, -50%);
}
.loading-text {
display: flex;
flex-direction: column;
align-items: center;
gap: 24rpx;
animation: fade 2.5s ease-in-out infinite;
}
@keyframes fade {
0%, 100% { opacity: 0.3; }
50% { opacity: 1; }
}
.loading-title {
color: #d4af37;
letter-spacing: 0.4em;
font-size: 40rpx;
font-weight: bold;
text-shadow: 0 0 20rpx rgba(212, 175, 55, 0.5);
}
.loading-subtitle {
color: #888;
letter-spacing: 0.2em;
font-size: 24rpx;
}
.loading-tip {
margin-top: 16rpx;
padding: 0 48rpx;
color: rgba(226, 226, 226, 0.72);
letter-spacing: 0.06em;
font-size: 22rpx;
line-height: 1.6;
text-align: center;
}
</style>