upload project source code
This commit is contained in:
487
前端源码/uni-app/components/MysticFantasyBg.vue
Normal file
487
前端源码/uni-app/components/MysticFantasyBg.vue
Normal file
@@ -0,0 +1,487 @@
|
||||
<template>
|
||||
<view class="mfgb" aria-hidden="true">
|
||||
<view class="mfgb__base" />
|
||||
<!-- 暗纹:万字锦地(极低透明度) -->
|
||||
<view class="mfgb__wanzi" />
|
||||
<view class="mfgb__ink" />
|
||||
<view
|
||||
v-for="c in clouds"
|
||||
:key="c.id"
|
||||
class="mfgb__cloud"
|
||||
:style="getCloudStyle(c)"
|
||||
/>
|
||||
|
||||
<!-- 八卦 + 太极:先天卦序,极慢旋转 -->
|
||||
<view class="mfgb__bagua-wrap">
|
||||
<svg
|
||||
class="mfgb__bagua-svg mfgb__bagua-spin"
|
||||
viewBox="-100 -100 200 200"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<defs>
|
||||
<linearGradient id="mfgb-gold-stroke" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" style="stop-color: rgba(212, 175, 55, 0.55)" />
|
||||
<stop offset="100%" style="stop-color: rgba(212, 175, 55, 0.2)" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<circle
|
||||
cx="0"
|
||||
cy="0"
|
||||
r="90"
|
||||
fill="none"
|
||||
stroke="url(#mfgb-gold-stroke)"
|
||||
stroke-width="0.6"
|
||||
opacity="0.35"
|
||||
/>
|
||||
<circle
|
||||
cx="0"
|
||||
cy="0"
|
||||
r="78"
|
||||
fill="none"
|
||||
stroke="rgba(212, 175, 55, 0.12)"
|
||||
stroke-width="0.4"
|
||||
stroke-dasharray="4 6"
|
||||
opacity="0.5"
|
||||
/>
|
||||
<g
|
||||
v-for="(trig, ti) in baguaTrigrams"
|
||||
:key="'bg-' + ti"
|
||||
:transform="'rotate(' + (ti * 45 - 90) + ') translate(0 -72)'"
|
||||
>
|
||||
<g v-for="(solid, li) in trig" :key="'ln-' + ti + '-' + li">
|
||||
<line
|
||||
v-if="solid"
|
||||
x1="-11"
|
||||
:y1="8 - li * 8"
|
||||
x2="11"
|
||||
:y2="8 - li * 8"
|
||||
stroke="rgba(212, 175, 55, 0.42)"
|
||||
stroke-width="2.4"
|
||||
stroke-linecap="round"
|
||||
/>
|
||||
<g v-else>
|
||||
<line
|
||||
x1="-11"
|
||||
:y1="8 - li * 8"
|
||||
x2="-3.5"
|
||||
:y2="8 - li * 8"
|
||||
stroke="rgba(212, 175, 55, 0.42)"
|
||||
stroke-width="2.4"
|
||||
stroke-linecap="round"
|
||||
/>
|
||||
<line
|
||||
x1="3.5"
|
||||
:y1="8 - li * 8"
|
||||
x2="11"
|
||||
:y2="8 - li * 8"
|
||||
stroke="rgba(212, 175, 55, 0.42)"
|
||||
stroke-width="2.4"
|
||||
stroke-linecap="round"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<!-- 太极简形:阴阳鱼 -->
|
||||
<circle cx="0" cy="0" r="20" fill="none" stroke="rgba(212, 175, 55, 0.28)" stroke-width="0.8" />
|
||||
<path
|
||||
d="M0-20 A20 20 0 0 1 0 20 A10 10 0 0 1 0 0 A10 10 0 0 0 0-20 Z"
|
||||
fill="rgba(212, 175, 55, 0.08)"
|
||||
/>
|
||||
<path
|
||||
d="M0 20 A20 20 0 0 1 0-20 A10 10 0 0 1 0 0 A10 10 0 0 0 0 20 Z"
|
||||
fill="rgba(15, 23, 42, 0.45)"
|
||||
/>
|
||||
<circle cx="0" cy="-10" r="3.2" fill="rgba(15, 23, 42, 0.75)" />
|
||||
<circle cx="0" cy="10" r="3.2" fill="rgba(212, 175, 55, 0.4)" />
|
||||
</svg>
|
||||
</view>
|
||||
|
||||
<!-- 四角卷云纹 -->
|
||||
<view
|
||||
v-for="corner in cornerKeys"
|
||||
:key="corner"
|
||||
class="mfgb__corner"
|
||||
:class="'mfgb__corner--' + corner"
|
||||
>
|
||||
<svg class="mfgb__corner-svg" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
class="mfgb__corner-path"
|
||||
d="M6 58 C6 14 14 6 58 6 M10 54 C10 22 22 10 54 10 M16 48 C18 28 28 18 48 16"
|
||||
fill="none"
|
||||
stroke="rgba(212, 175, 55, 0.22)"
|
||||
stroke-width="1.2"
|
||||
stroke-linecap="round"
|
||||
/>
|
||||
<path
|
||||
class="mfgb__corner-path"
|
||||
d="M52 12 Q40 12 36 20 Q32 28 38 36"
|
||||
fill="none"
|
||||
stroke="rgba(212, 175, 55, 0.16)"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
/>
|
||||
</svg>
|
||||
</view>
|
||||
|
||||
<view
|
||||
class="mfgb__sigil mfgb__sigil--outer"
|
||||
:class="sigilModifier"
|
||||
/>
|
||||
<view
|
||||
class="mfgb__sigil mfgb__sigil--inner"
|
||||
:class="sigilModifier"
|
||||
/>
|
||||
<view v-for="s in stars" :key="s.id" class="mfgb__star" :style="getStarStyle(s)" />
|
||||
<view class="mfgb__glow" />
|
||||
<view class="mfgb__mist" />
|
||||
<view class="mfgb__vignette" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
export type MysticRoundPhase = 'ready' | 'loading' | 'result';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
/** 测名页:测算中加快阵法转速;登录页可省略(默认 ready) */
|
||||
roundPhase?: MysticRoundPhase;
|
||||
}>(),
|
||||
{ roundPhase: 'ready' },
|
||||
);
|
||||
|
||||
const sigilModifier = computed(() => {
|
||||
if (props.roundPhase === 'loading') return 'mfgb__sigil--phase-loading';
|
||||
if (props.roundPhase === 'result') return 'mfgb__sigil--phase-result';
|
||||
return '';
|
||||
});
|
||||
|
||||
/** 先天八卦卦序(自下而上爻):乾 兑 离 震 巽 坎 艮 坤 */
|
||||
const baguaTrigrams: boolean[][] = [
|
||||
[true, true, true],
|
||||
[true, true, false],
|
||||
[true, false, true],
|
||||
[true, false, false],
|
||||
[false, true, true],
|
||||
[false, true, false],
|
||||
[false, false, true],
|
||||
[false, false, false],
|
||||
];
|
||||
|
||||
const cornerKeys = ['tl', 'tr', 'bl', 'br'] as const;
|
||||
|
||||
const stars = Array.from({ length: 36 }, (_, i) => ({
|
||||
id: `mfgb-st-${i}`,
|
||||
top: Math.random() * 100,
|
||||
left: Math.random() * 100,
|
||||
size: Math.random() * 2.2 + 0.8,
|
||||
opacity: Math.random() * 0.35 + 0.12,
|
||||
duration: Math.random() * 4 + 3,
|
||||
delay: Math.random() * 4,
|
||||
}));
|
||||
|
||||
const clouds = Array.from({ length: 7 }, (_, i) => ({
|
||||
id: `mfgb-cl-${i}`,
|
||||
top: Math.random() * 70 - 10,
|
||||
left: Math.random() * 90 - 5,
|
||||
w: 180 + Math.random() * 220,
|
||||
h: 60 + Math.random() * 80,
|
||||
opacity: 0.08 + Math.random() * 0.12,
|
||||
duration: 28 + Math.random() * 18,
|
||||
delay: Math.random() * -40,
|
||||
}));
|
||||
|
||||
const getStarStyle = (s: (typeof stars)[number]) => ({
|
||||
top: `${s.top}%`,
|
||||
left: `${s.left}%`,
|
||||
width: `${s.size}px`,
|
||||
height: `${s.size}px`,
|
||||
opacity: s.opacity,
|
||||
animationDuration: `${s.duration}s`,
|
||||
animationDelay: `${s.delay}s`,
|
||||
});
|
||||
|
||||
const getCloudStyle = (c: (typeof clouds)[number]) => ({
|
||||
top: `${c.top}%`,
|
||||
left: `${c.left}%`,
|
||||
width: `${c.w}px`,
|
||||
height: `${c.h}px`,
|
||||
opacity: c.opacity,
|
||||
animationDuration: `${c.duration}s`,
|
||||
animationDelay: `${c.delay}s`,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.mfgb {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
pointer-events: none;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mfgb__base {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background:
|
||||
radial-gradient(ellipse 120% 80% at 50% -20%, rgba(212, 175, 55, 0.14), transparent 52%),
|
||||
radial-gradient(ellipse 90% 60% at 80% 20%, rgba(88, 28, 135, 0.18), transparent 45%),
|
||||
radial-gradient(ellipse 70% 50% at 10% 30%, rgba(127, 29, 29, 0.12), transparent 50%),
|
||||
linear-gradient(165deg, #070a12 0%, #12102a 38%, #0a1628 72%, #05080f 100%);
|
||||
}
|
||||
|
||||
/* 万字锦地暗纹 */
|
||||
.mfgb__wanzi {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
opacity: 0.04;
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='48' viewBox='0 0 48 48'%3E%3Cpath fill='none' stroke='%23d4af37' stroke-width='0.6' d='M24 4v40M4 24h40M12 12l24 24M36 12L12 36'/%3E%3C/svg%3E");
|
||||
background-size: 48px 48px;
|
||||
}
|
||||
|
||||
.mfgb__ink {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: -5%;
|
||||
height: 42%;
|
||||
opacity: 0.35;
|
||||
background:
|
||||
radial-gradient(ellipse 100% 55% at 20% 100%, rgba(15, 23, 42, 0.95), transparent 70%),
|
||||
radial-gradient(ellipse 90% 50% at 55% 100%, rgba(30, 41, 59, 0.85), transparent 68%),
|
||||
radial-gradient(ellipse 80% 45% at 85% 100%, rgba(15, 23, 42, 0.9), transparent 65%);
|
||||
filter: blur(1px);
|
||||
mask-image: linear-gradient(to top, black 0%, black 55%, transparent 100%);
|
||||
}
|
||||
|
||||
.mfgb__cloud {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
background: radial-gradient(ellipse at center, rgba(212, 175, 55, 0.2) 0%, rgba(212, 175, 55, 0.06) 45%, transparent 70%);
|
||||
filter: blur(18px);
|
||||
animation: mfgb-cloud-drift linear infinite;
|
||||
}
|
||||
|
||||
@keyframes mfgb-cloud-drift {
|
||||
0% {
|
||||
transform: translate(0, 0) scale(1);
|
||||
}
|
||||
50% {
|
||||
transform: translate(-2%, 1.5%) scale(1.03);
|
||||
}
|
||||
100% {
|
||||
transform: translate(0, 0) scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* 八卦层:置于祥云之下、阵环之上,略透明 */
|
||||
.mfgb__bagua-wrap {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 52%;
|
||||
width: min(92vw, 680px);
|
||||
height: min(92vw, 680px);
|
||||
transform: translate(-50%, -50%);
|
||||
opacity: 0.38;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.mfgb__bagua-svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.mfgb__bagua-spin {
|
||||
animation: mfgb-bagua-spin 200s linear infinite;
|
||||
transform-origin: center center;
|
||||
}
|
||||
|
||||
@keyframes mfgb-bagua-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.mfgb__corner {
|
||||
position: absolute;
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
z-index: 1;
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.mfgb__corner-svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mfgb__corner--tl {
|
||||
top: calc(12px + env(safe-area-inset-top, 0px));
|
||||
left: 12px;
|
||||
}
|
||||
|
||||
.mfgb__corner--tr {
|
||||
top: calc(12px + env(safe-area-inset-top, 0px));
|
||||
right: 12px;
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
|
||||
.mfgb__corner--bl {
|
||||
bottom: calc(12px + env(safe-area-inset-bottom, 0px));
|
||||
left: 12px;
|
||||
transform: scaleY(-1);
|
||||
}
|
||||
|
||||
.mfgb__corner--br {
|
||||
bottom: calc(12px + env(safe-area-inset-bottom, 0px));
|
||||
right: 12px;
|
||||
transform: scale(-1);
|
||||
}
|
||||
|
||||
.mfgb__sigil {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 54%;
|
||||
border-radius: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
border: 1px dashed rgba(212, 175, 55, 0.28);
|
||||
box-shadow:
|
||||
0 0 40px rgba(212, 175, 55, 0.08),
|
||||
inset 0 0 30px rgba(212, 175, 55, 0.04);
|
||||
opacity: 0.65;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.mfgb__sigil--outer {
|
||||
width: min(72vw, 560px);
|
||||
height: min(72vw, 560px);
|
||||
animation: mfgb-sigil-cw 48s linear infinite;
|
||||
}
|
||||
|
||||
.mfgb__sigil--inner {
|
||||
width: min(52vw, 400px);
|
||||
height: min(52vw, 400px);
|
||||
border-style: dotted;
|
||||
border-color: rgba(212, 175, 55, 0.2);
|
||||
animation: mfgb-sigil-ccw 32s linear infinite;
|
||||
}
|
||||
|
||||
.mfgb__sigil--outer.mfgb__sigil--phase-loading {
|
||||
animation-duration: 2.8s;
|
||||
border-color: rgba(212, 175, 55, 0.55);
|
||||
opacity: 0.85;
|
||||
box-shadow:
|
||||
0 0 56px rgba(212, 175, 55, 0.15),
|
||||
inset 0 0 36px rgba(212, 175, 55, 0.08);
|
||||
}
|
||||
|
||||
.mfgb__sigil--inner.mfgb__sigil--phase-loading {
|
||||
animation-duration: 2s;
|
||||
border-color: rgba(212, 175, 55, 0.42);
|
||||
opacity: 0.88;
|
||||
}
|
||||
|
||||
.mfgb__sigil--outer.mfgb__sigil--phase-result {
|
||||
animation-duration: 5.5s;
|
||||
border-color: rgba(212, 175, 55, 0.35);
|
||||
opacity: 0.62;
|
||||
}
|
||||
|
||||
.mfgb__sigil--inner.mfgb__sigil--phase-result {
|
||||
animation-duration: 4s;
|
||||
border-color: rgba(212, 175, 55, 0.22);
|
||||
opacity: 0.58;
|
||||
}
|
||||
|
||||
@keyframes mfgb-sigil-cw {
|
||||
from {
|
||||
transform: translate(-50%, -50%) rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: translate(-50%, -50%) rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes mfgb-sigil-ccw {
|
||||
from {
|
||||
transform: translate(-50%, -50%) rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: translate(-50%, -50%) rotate(-360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.mfgb__star {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 248, 220, 0.95);
|
||||
box-shadow: 0 0 12px rgba(212, 175, 55, 0.45), 0 0 2px rgba(255, 255, 255, 0.8);
|
||||
animation: mfgb-twinkle 2.8s ease-in-out infinite;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
@keyframes mfgb-twinkle {
|
||||
0%,
|
||||
100% {
|
||||
transform: scale(0.9);
|
||||
opacity: 0.2;
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.2);
|
||||
opacity: 0.65;
|
||||
}
|
||||
}
|
||||
|
||||
.mfgb__glow {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 48%;
|
||||
width: min(90vw, 680px);
|
||||
height: min(90vw, 680px);
|
||||
transform: translate(-50%, -50%);
|
||||
background: radial-gradient(circle at 50% 35%, rgba(212, 175, 55, 0.22), rgba(139, 92, 246, 0.06) 45%, transparent 65%);
|
||||
filter: blur(36px);
|
||||
opacity: 0.9;
|
||||
animation: mfgb-glow-pulse 4.2s ease-in-out infinite;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
@keyframes mfgb-glow-pulse {
|
||||
0%,
|
||||
100% {
|
||||
transform: translate(-50%, -50%) scale(0.94);
|
||||
opacity: 0.7;
|
||||
}
|
||||
50% {
|
||||
transform: translate(-50%, -50%) scale(1.06);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.mfgb__mist {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 38%;
|
||||
background: linear-gradient(to top, rgba(2, 6, 23, 0.75), rgba(2, 6, 23, 0));
|
||||
pointer-events: none;
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
.mfgb__vignette {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: radial-gradient(ellipse 75% 65% at 50% 45%, transparent 30%, rgba(0, 0, 0, 0.45) 100%);
|
||||
pointer-events: none;
|
||||
z-index: 5;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user