feat: 结算页结局演出(彩带+动态标题+鼓励语+场景 emoji)
This commit is contained in:
@@ -1,18 +1,31 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<!-- 彩带(通关/完美时) -->
|
||||
<view v-if="result && stars > 0" class="confetti">
|
||||
<view
|
||||
v-for="(p, i) in pieces"
|
||||
:key="i"
|
||||
class="confetti-piece"
|
||||
:style="{ left: p.left + '%', background: p.color, animationDelay: p.delay + 's', animationDuration: p.duration + 's', transform: 'rotate(' + p.rotate + 'deg)' }"
|
||||
></view>
|
||||
</view>
|
||||
|
||||
<view v-if="result" class="result">
|
||||
<view class="result-title">闯关完成</view>
|
||||
<view class="result-emoji">{{ sceneEmoji }}</view>
|
||||
<view class="result-title" :class="{ great: stars >= 3, ok: stars > 0 && stars < 3, again: stars === 0 }">{{ title }}</view>
|
||||
|
||||
<view class="stars-area">
|
||||
<view
|
||||
v-for="i in 3"
|
||||
:key="i"
|
||||
class="big-star"
|
||||
:class="{ on: i <= result.final.stars, pop: i <= result.final.stars }"
|
||||
:class="{ on: i <= stars, pop: i <= stars }"
|
||||
:style="{ animationDelay: i * 0.35 + 's' }"
|
||||
>★</view>
|
||||
</view>
|
||||
|
||||
<view v-if="encourage" class="encourage">💪 {{ encourage }}</view>
|
||||
|
||||
<view class="card panel">
|
||||
<view class="panel-row">
|
||||
<text class="label">关卡</text>
|
||||
@@ -44,17 +57,41 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { sceneVisual } from '../../utils/visual.js'
|
||||
import { playSound } from '../../utils/sound.js'
|
||||
|
||||
const RESULT_KEY = '36wisdom_result'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return { result: null }
|
||||
return { result: null, pieces: [] }
|
||||
},
|
||||
onLoad() {
|
||||
const saved = uni.getStorageSync(RESULT_KEY)
|
||||
this.result = saved || null
|
||||
if (!saved) {
|
||||
uni.reLaunch({ url: '/pages/map/map' })
|
||||
return
|
||||
}
|
||||
this.pieces = this.makePieces(30)
|
||||
playSound(this.result.final.stars > 0 ? 'finish' : 'bad')
|
||||
},
|
||||
computed: {
|
||||
stars() {
|
||||
return this.result.final.stars
|
||||
},
|
||||
title() {
|
||||
if (this.stars >= 3) return '完美通关!'
|
||||
if (this.stars > 0) return '通关啦!'
|
||||
return '再试一次!'
|
||||
},
|
||||
sceneEmoji() {
|
||||
return sceneVisual(this.result.scene_name).emoji
|
||||
},
|
||||
encourage() {
|
||||
if (this.stars === 0) return '你已经很棒了,再试一次会更好!'
|
||||
if (this.stars < 3) return '还差一点点,补完分支就能完美!'
|
||||
return ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -63,6 +100,20 @@ export default {
|
||||
},
|
||||
backMap() {
|
||||
uni.reLaunch({ url: '/pages/map/map' })
|
||||
},
|
||||
makePieces(n) {
|
||||
const colors = ['#ff6b35', '#ffb347', '#4ecdc4', '#6c8cff', '#a58cff', '#ff6b9a']
|
||||
const list = []
|
||||
for (let i = 0; i < n; i++) {
|
||||
list.push({
|
||||
left: Math.random() * 100,
|
||||
delay: Math.random() * 1.5,
|
||||
duration: 2 + Math.random() * 2,
|
||||
color: colors[i % colors.length],
|
||||
rotate: Math.random() * 360
|
||||
})
|
||||
}
|
||||
return list
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -176,4 +227,13 @@ export default {
|
||||
background: #f5ece0;
|
||||
color: #7a6248;
|
||||
}
|
||||
.result-emoji { font-size: 96rpx; margin-bottom: 8rpx; animation: t-pop 0.6s ease; }
|
||||
.result-title.great { color: #ffb347; }
|
||||
.result-title.ok { color: #ff6b35; }
|
||||
.result-title.again { color: #6c8cff; }
|
||||
.encourage { font-size: 30rpx; color: #7a6248; background: #fff0e5; border-radius: 30rpx; padding: 16rpx 32rpx; margin-bottom: 32rpx; display: inline-block; }
|
||||
@keyframes t-pop { 0% { opacity: 0; transform: scale(0.5); } 70% { transform: scale(1.1); } 100% { opacity: 1; transform: scale(1); } }
|
||||
.confetti { position: fixed; inset: 0; pointer-events: none; overflow: hidden; z-index: 5; }
|
||||
.confetti-piece { position: absolute; top: -40rpx; width: 16rpx; height: 28rpx; border-radius: 4rpx; opacity: 0; animation: confetti-fall linear forwards; }
|
||||
@keyframes confetti-fall { 0% { opacity: 1; transform: translateY(0) rotate(0); } 100% { opacity: 0.7; transform: translateY(110vh) rotate(720deg); } }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user