You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

292 lines
6.8 KiB

7 days ago
<template>
<view v-if="show" class="hm-mask">
<view class="hm">
<!-- 追击动画区 -->
<view class="hm-stage" v-if="phase !== 'result'">
<view class="hm-radar">
<view class="hm-radar-sweep"></view>
<view class="hm-radar-ring r1"></view>
<view class="hm-radar-ring r2"></view>
<view class="hm-rocket" :class="phase">GO</view>
<image class="hm-target-avatar" :src="target.avatar || defaultAvatar" mode="aspectFill"></image>
</view>
<view class="hm-phase-text">{{phaseText}}</view>
<view class="hm-dots">
<text class="hm-dot"></text>
<text class="hm-dot"></text>
<text class="hm-dot"></text>
</view>
</view>
<!-- 结果区 -->
<view class="hm-result" v-else>
<view class="hm-result-emoji">{{resultBadge}}</view>
<view class="hm-result-title" :class="result.result">{{resultTitle}}</view>
<view class="hm-result-msg">{{result.message}}</view>
<view class="hm-result-gain" v-if="result.result === 'success'">
<text class="hm-gain-num">+{{result.totalGain}}</text>
<text class="hm-gain-unit">星球券</text>
</view>
<view class="hm-result-remain">今日剩余追捕 {{result.remainHunt}} </view>
<view class="hm-result-btn" @tap="onClose">{{result.result === 'success' ? '收入囊中' : '知道了'}}</view>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
show: { type: Boolean, default: false },
phase: { type: String, default: 'searching' },
result: { type: Object, default: null },
target: { type: Object, default: () => ({}) }
},
data() {
return {
defaultAvatar: 'https://jewel-shop.oss-cn-beijing.aliyuncs.com/41cfb56caff4419b94b69d0f2303b602.png'
}
},
computed: {
phaseText() {
const map = {
searching: '雷达搜索目标飞船...',
locking: '已锁定目标坐标...',
chasing: '星际追击中...'
}
return map[this.phase] || '追击中...'
},
resultBadge() {
if (!this.result) return 'GO'
if (this.result.result === 'success') return 'GET'
if (this.result.result === 'shield') return 'SAFE'
return 'MISS'
},
resultTitle() {
if (!this.result) return ''
if (this.result.result === 'success') return '追捕成功'
if (this.result.result === 'shield') return '目标已防护'
return '追捕扑空'
}
},
methods: {
onClose() {
this.$emit('close')
}
}
}
</script>
<style lang="scss" scoped>
.hm-mask {
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background: rgba(18,52,47,0.28);
backdrop-filter: blur(8px);
z-index: 80;
display: flex;
align-items: center;
justify-content: center;
}
.hm {
width: 580rpx;
padding: 56rpx 40rpx 40rpx;
border-radius: 46rpx;
background: linear-gradient(155deg, rgba(255,255,255,0.94), rgba(244,255,249,0.78));
border: 2rpx solid rgba(255,255,255,0.92);
box-shadow: 0 34rpx 80rpx rgba(53,214,166,0.22);
}
.hm-stage {
display: flex;
flex-direction: column;
align-items: center;
}
.hm-radar {
position: relative;
width: 340rpx;
height: 340rpx;
border-radius: 50%;
background: radial-gradient(circle, rgba(53,214,166,0.14), rgba(79,183,255,0.06) 52%, transparent 70%);
display: flex;
align-items: center;
justify-content: center;
}
.hm-radar-ring {
position: absolute;
border-radius: 50%;
border: 2rpx solid rgba(53,214,166,0.26);
}
.hm-radar-ring.r1 { width: 240rpx; height: 240rpx; }
.hm-radar-ring.r2 { width: 340rpx; height: 340rpx; }
.hm-radar-sweep {
position: absolute;
width: 154rpx;
height: 5rpx;
top: 50%;
left: 50%;
transform-origin: left center;
background: linear-gradient(90deg, rgba(53,214,166,0.68), rgba(53,214,166,0));
border-radius: 999rpx;
animation: sweep 1.6s linear infinite;
}
@keyframes sweep {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.hm-target-avatar {
width: 96rpx;
height: 96rpx;
border-radius: 50%;
border: 5rpx solid rgba(255,255,255,0.94);
opacity: 0.95;
box-shadow: 0 14rpx 30rpx rgba(255,122,89,0.18);
}
.hm-rocket {
position: absolute;
width: 58rpx;
height: 58rpx;
line-height: 58rpx;
text-align: center;
border-radius: 50%;
background: linear-gradient(135deg, #FF7A59, #FFB84D);
color: #FFFFFF;
font-size: 20rpx;
font-weight: 900;
left: 20rpx;
top: 130rpx;
box-shadow: 0 12rpx 26rpx rgba(255,122,89,0.24);
}
.hm-rocket.searching { animation: orbit 2.5s linear infinite; }
.hm-rocket.locking { animation: orbit 1.4s linear infinite; }
.hm-rocket.chasing { animation: orbit 0.7s linear infinite; }
@keyframes orbit {
0% { transform: rotate(0deg) translateX(150rpx) rotate(0deg); }
100% { transform: rotate(360deg) translateX(150rpx) rotate(-360deg); }
}
.hm-phase-text {
margin-top: 30rpx;
color: #12342F;
font-size: 28rpx;
font-weight: 800;
letter-spacing: 1rpx;
}
.hm-dots {
margin-top: 16rpx;
display: flex;
}
.hm-dot {
width: 12rpx;
height: 12rpx;
border-radius: 50%;
background: #35D6A6;
margin: 0 6rpx;
animation: blink 1.2s ease infinite;
}
.hm-dot:nth-child(2) { animation-delay: 0.2s; }
.hm-dot:nth-child(3) { animation-delay: 0.4s; }
@keyframes blink {
0%, 100% { opacity: 0.3; }
50% { opacity: 1; }
}
.hm-result {
display: flex;
flex-direction: column;
align-items: center;
}
.hm-result-emoji {
width: 160rpx;
height: 160rpx;
line-height: 160rpx;
text-align: center;
border-radius: 50%;
background: linear-gradient(145deg, #E5FFF1, #EAF8FF);
color: #22B889;
font-size: 30rpx;
font-weight: 900;
letter-spacing: 2rpx;
animation: pop 0.5s ease;
box-shadow: inset 0 0 0 2rpx rgba(255,255,255,0.92), 0 18rpx 42rpx rgba(53,214,166,0.14);
}
@keyframes pop {
0% { transform: scale(0.3); opacity: 0; }
70% { transform: scale(1.2); }
100% { transform: scale(1); opacity: 1; }
}
.hm-result-title {
margin-top: 16rpx;
font-size: 40rpx;
font-weight: 800;
color: #12342F;
}
.hm-result-title.success { color: #22B889; }
.hm-result-title.shield { color: #4FB7FF; }
.hm-result-title.fail { color: #7E9691; }
.hm-result-msg {
margin-top: 14rpx;
color: #42635E;
font-size: 26rpx;
text-align: center;
padding: 0 20rpx;
}
.hm-result-gain {
margin-top: 24rpx;
display: flex;
align-items: baseline;
}
.hm-gain-num {
color: #22B889;
font-size: 64rpx;
font-weight: 800;
}
.hm-gain-unit {
color: #42635E;
font-size: 26rpx;
margin-left: 8rpx;
}
.hm-result-remain {
margin-top: 16rpx;
color: #7E9691;
font-size: 22rpx;
}
.hm-result-btn {
margin-top: 36rpx;
width: 100%;
height: 84rpx;
line-height: 84rpx;
text-align: center;
border-radius: 42rpx;
background: linear-gradient(135deg, #35D6A6, #4FB7FF);
color: #FFFFFF;
font-size: 30rpx;
font-weight: 800;
box-shadow: 0 18rpx 36rpx rgba(53,214,166,0.22);
}
</style>