This commit is contained in:
Your Name
2026-05-28 10:50:21 +08:00
parent 4f066b560e
commit 33f8f669ad
10 changed files with 7835 additions and 1925 deletions
@@ -8,7 +8,7 @@
/>
<view v-if="title" class="celebrate-card" :class="{ pop: cardPop }">
<view class="celebrate-card-glow" />
<TongjiIcon name="sparkles" size="lg" color="#0891B2" />
<TongjiIcon name="sparkles" size="lg" color="#204E2B" />
<text class="celebrate-card-title">{{ title }}</text>
<text v-if="subtitle" class="celebrate-card-sub">{{ subtitle }}</text>
</view>
@@ -28,7 +28,7 @@ const props = defineProps({
const particles = ref([])
const cardPop = ref(false)
const COLORS = ['#0891B2', '#22D3EE', '#059669', '#FBBF24', '#F472B6', '#A78BFA']
const COLORS = ['#204E2B', '#386641', '#AFE2B3', '#FBBF24', '#727970', '#DC2626']
function buildParticles() {
const list = []
@@ -129,7 +129,7 @@ watch(
margin-top: 16rpx;
font-size: 36rpx;
font-weight: 800;
color: #164e63;
color: #1b1c1a;
}
.celebrate-card-sub {
position: relative;
@@ -47,12 +47,12 @@ const treeEmoji = computed(() => (TREE_LEVELS[clampedLevel.value] || TREE_LEVELS
function buildTreeSvg(level) {
const pot = `
<ellipse cx="24" cy="50" rx="15" ry="3" fill="#0ea5a4" opacity="0.12"/>
<ellipse cx="24" cy="50" rx="15" ry="3" fill="#204e2b" opacity="0.12"/>
<path d="M11 46h26c1.2 0 2 1 2 2.2v3.8c0 1-.8 1.8-1.8 1.8H10.8c-1 0-1.8-.8-1.8-1.8v-3.8c0-1.2.8-2.2 2-2.2z" fill="#E7E5E4"/>
<path d="M12.5 46h23c.8 0 1.5.7 1.5 1.5v2.2c0 .6-.5 1.1-1.1 1.1H12.1c-.6 0-1.1-.5-1.1-1.1v-2.2c0-.8.7-1.5 1.5-1.5z" fill="#D6D3D1"/>
<ellipse cx="24" cy="46.5" rx="9" ry="1.6" fill="#A8A29E" opacity="0.35"/>
`
const soil = `<ellipse cx="24" cy="44.5" rx="8" ry="2.2" fill="#0d9488" opacity="0.18"/>`
const soil = `<ellipse cx="24" cy="44.5" rx="8" ry="2.2" fill="#386641" opacity="0.18"/>`
if (level <= 0) {
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 56" fill="none">
@@ -69,7 +69,7 @@ function buildTreeSvg(level) {
const leaf = (cx, cy, r, fill, opacity = 1) =>
`<circle cx="${cx}" cy="${cy}" r="${r}" fill="${fill}" opacity="${opacity}"/>
<circle cx="${cx - r * 0.25}" cy="${cy - r * 0.2}" r="${r * 0.35}" fill="#ecfdf5" opacity="0.55"/>`
<circle cx="${cx - r * 0.25}" cy="${cy - r * 0.2}" r="${r * 0.35}" fill="#eef6ef" opacity="0.55"/>`
const bloom =
level >= 7
@@ -82,13 +82,13 @@ function buildTreeSvg(level) {
level >= 9
? leaf(12, 22, 6, '#34d399', 0.9) +
leaf(36, 22, 6, '#34d399', 0.9) +
leaf(24, 10, 7, '#10b981', 0.95) +
leaf(24, 10, 7, '#386641', 0.95) +
bloom
: bloom
let canopy = ''
if (level === 1) {
canopy = leaf(24, 38, 4, '#6ee7b7') + `<path d="M24 38v-5" stroke="#14b8a6" stroke-width="1.2" stroke-linecap="round"/>`
canopy = leaf(24, 38, 4, '#afe2b3') + `<path d="M24 38v-5" stroke="#386641" stroke-width="1.2" stroke-linecap="round"/>`
} else if (level === 2) {
canopy = leaf(24, 32, 5.5, '#34d399') + leaf(20, 34, 3.5, '#6ee7b7', 0.9)
} else if (level <= 4) {
@@ -101,10 +101,10 @@ function buildTreeSvg(level) {
leaf(24, 24, 9, '#22c55e') +
leaf(14, 26, 7, '#4ade80', 0.92) +
leaf(34, 26, 7, '#4ade80', 0.92) +
leaf(24, 16, 6, '#10b981', 0.88)
leaf(24, 16, 6, '#386641', 0.88)
} else {
canopy =
leaf(24, 20, 10, '#059669') +
leaf(24, 20, 10, '#204e2b') +
leaf(13, 24, 8, '#34d399', 0.95) +
leaf(35, 24, 8, '#34d399', 0.95) +
crown
@@ -132,14 +132,14 @@ const treeImageSrc = computed(() => svgToDataUrl(buildTreeSvg(clampedLevel.value
position: absolute;
inset: 6%;
border-radius: 50%;
background: radial-gradient(circle, rgba(14, 165, 164, 0.22) 0%, transparent 68%);
background: radial-gradient(circle, rgba(32, 78, 43, 0.22) 0%, transparent 68%);
pointer-events: none;
}
.lv-0 .stg-glow { background: radial-gradient(circle, rgba(148, 163, 184, 0.25) 0%, transparent 70%); }
.tier-4 .stg-glow,
.tier-5 .stg-glow,
.is-max .stg-glow {
background: radial-gradient(circle, rgba(251, 191, 36, 0.3) 0%, rgba(14, 165, 164, 0.15) 55%, transparent 72%);
background: radial-gradient(circle, rgba(251, 191, 36, 0.3) 0%, rgba(32, 78, 43, 0.15) 55%, transparent 72%);
}
.stg-aura {
position: absolute;
@@ -24,7 +24,7 @@ import { svgToDataUrl } from '../utils/svgDataUrl.js'
const props = defineProps({
name: { type: String, required: true },
size: { type: String, default: 'md' },
color: { type: String, default: '#0891B2' }
color: { type: String, default: '#204E2B' }
})
const useFallback = ref(false)
@@ -86,8 +86,8 @@ const ICON_FALLBACK = {
}
const strokeColor = computed(() => {
const c = String(props.color || '#0891B2').trim()
return /^#[0-9A-Fa-f]{3,8}$/.test(c) ? c : '#0891B2'
const c = String(props.color || '#204E2B').trim()
return /^#[0-9A-Fa-f]{3,8}$/.test(c) ? c : '#204E2B'
})
const iconSrc = computed(() => {