172 lines
3.7 KiB
Vue
172 lines
3.7 KiB
Vue
<script setup>
|
||
import { computed } from "vue";
|
||
|
||
const MAX_VISIBLE_SCORE_CARDS = 60;
|
||
|
||
const props = defineProps({
|
||
arrows: {
|
||
type: Array,
|
||
default: () => [],
|
||
},
|
||
total: {
|
||
type: Number,
|
||
default: 0,
|
||
},
|
||
trainingType: {
|
||
type: String,
|
||
default: "",
|
||
},
|
||
recordMode: {
|
||
type: Boolean,
|
||
default: false,
|
||
},
|
||
});
|
||
|
||
const getDisplayText = (arrow = {}) => {
|
||
if (!arrow) return "";
|
||
if (!arrow.ring) return props.trainingType === "stability" ? "-" : "0";
|
||
return arrow.ringX ? "X" : String(arrow.ring);
|
||
};
|
||
|
||
const isFailed = (arrow = {}) => {
|
||
if (!arrow) return false;
|
||
if (
|
||
props.recordMode &&
|
||
props.trainingType !== "precision" &&
|
||
props.trainingType !== "rhythm" &&
|
||
props.trainingType !== "stability"
|
||
) {
|
||
return false;
|
||
}
|
||
return arrow.ok !== true;
|
||
};
|
||
|
||
const hiddenScoreCount = computed(() =>
|
||
props.recordMode
|
||
? 0
|
||
: Math.max(props.arrows.length - MAX_VISIBLE_SCORE_CARDS, 0)
|
||
);
|
||
|
||
const displayArrows = computed(() => {
|
||
const list = props.recordMode
|
||
? [...props.arrows]
|
||
: props.arrows.slice(-MAX_VISIBLE_SCORE_CARDS);
|
||
// total 是达标箭数,不是实际射箭上限;训练中始终预留下一箭空框。
|
||
if (!props.recordMode) list.push(null);
|
||
return list;
|
||
});
|
||
</script>
|
||
|
||
<template>
|
||
<view v-if="displayArrows.length" class="score-panel">
|
||
<text v-if="hiddenScoreCount" class="score-window-tip">
|
||
已省略前 {{ hiddenScoreCount }} 支,仅显示最近
|
||
{{ MAX_VISIBLE_SCORE_CARDS }} 支
|
||
</text>
|
||
<view class="score-grid">
|
||
<view
|
||
v-for="(arrow, index) in displayArrows"
|
||
:key="index"
|
||
class="score-card"
|
||
>
|
||
<image
|
||
class="score-card-bg"
|
||
:src="
|
||
isFailed(arrow)
|
||
? 'https://static.shelingxingqiu.com/shootmini/static/training-difficulty-design/block-gray.png'
|
||
: 'https://static.shelingxingqiu.com/shootmini/static/training-difficulty-design/block-gold.png'
|
||
"
|
||
/>
|
||
<image
|
||
v-if="trainingType === 'precision' && arrow"
|
||
class="score-result-icon"
|
||
:src="
|
||
arrow.ok === true
|
||
? 'https://static.shelingxingqiu.com/shootmini/static/training-difficulty-design/gou.png'
|
||
: 'https://static.shelingxingqiu.com/shootmini/static/training-difficulty-design/cha.png'
|
||
"
|
||
mode="aspectFit"
|
||
/>
|
||
<text
|
||
v-else
|
||
class="score-value"
|
||
:class="{ 'score-value--low': isFailed(arrow) }"
|
||
>
|
||
{{ getDisplayText(arrow) }}
|
||
</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<style scoped lang="scss">
|
||
.score-panel {
|
||
width: 100%;
|
||
padding: 30rpx 40rpx 0 40rpx;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.score-grid {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.score-window-tip {
|
||
display: block;
|
||
margin-bottom: 18rpx;
|
||
color: rgba(255, 255, 255, 0.6);
|
||
font-size: 22rpx;
|
||
line-height: 1.4;
|
||
}
|
||
|
||
.score-card {
|
||
position: relative;
|
||
width: 100rpx;
|
||
height: 56rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
overflow: hidden;
|
||
margin-right: 14rpx;
|
||
margin-bottom: 14rpx;
|
||
}
|
||
|
||
.score-card:nth-child(6n) {
|
||
margin-right: 0;
|
||
}
|
||
|
||
.score-card-bg {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100rpx;
|
||
height: 56rpx;
|
||
}
|
||
|
||
.score-result-icon {
|
||
position: relative;
|
||
z-index: 1;
|
||
width: 30rpx;
|
||
height: 30rpx;
|
||
}
|
||
|
||
.score-value {
|
||
position: relative;
|
||
z-index: 1;
|
||
min-width: 28rpx;
|
||
text-align: center;
|
||
font-size: 34rpx;
|
||
line-height: 1;
|
||
font-weight: 700;
|
||
font-style: italic;
|
||
color: #f6e3b2;
|
||
text-shadow: 0 2rpx 0 rgba(36, 36, 48, 0.5);
|
||
margin-left: -10rpx;
|
||
}
|
||
|
||
.score-value--low {
|
||
color: #cfcfcf;
|
||
text-shadow: 0 2rpx 0 rgba(0, 0, 0, 0.5);
|
||
}
|
||
</style>
|