Files
shoot-miniprograms/src/components/ScorePanel.vue

123 lines
2.7 KiB
Vue
Raw Normal View History

2025-05-10 16:57:36 +08:00
<script setup>
2025-08-25 13:47:32 +08:00
import { ref, watch, onMounted, onBeforeUnmount } from "vue";
2025-05-10 16:57:36 +08:00
const props = defineProps({
rowCount: {
type: Number,
default: 0,
},
total: {
type: Number,
default: 0,
},
scores: {
type: Array,
default: () => [],
},
2025-06-16 00:44:28 +08:00
fontSize: {
type: Number,
default: 25,
},
2025-06-25 22:02:10 +08:00
completeEffect: {
type: Boolean,
default: true,
},
2025-05-10 16:57:36 +08:00
});
const items = ref(new Array(props.total).fill(9));
2025-06-25 18:41:30 +08:00
const width = ref(92);
const itemWidth = ref(0);
const bgImages = [
"../static/complete-light1.png",
"../static/complete-light2.png",
];
const bgIndex = ref(0);
2025-06-15 15:53:57 +08:00
watch(
() => props.total,
(newValue) => {
items.value = new Array(newValue).fill(9);
}
);
2025-06-25 18:41:30 +08:00
const timer = ref(null);
onMounted(() => {
timer.value = setInterval(() => {
bgIndex.value = bgIndex.value === 0 ? 1 : 0;
2025-06-28 12:03:33 +08:00
}, 200);
2025-06-25 18:41:30 +08:00
});
2025-08-25 13:47:32 +08:00
onBeforeUnmount(() => {
2025-06-25 18:41:30 +08:00
if (timer.value) {
clearInterval(timer.value);
}
});
2025-05-10 16:57:36 +08:00
</script>
<template>
<view class="container">
2025-06-25 18:41:30 +08:00
<image
2025-06-25 22:02:10 +08:00
v-if="total > 0 && scores.length === total && completeEffect"
2025-06-25 18:41:30 +08:00
:src="bgImages[bgIndex]"
class="complete-light"
:style="{
width: `calc(${(100 / (rowCount + 2)) * rowCount}vw + ${
(100 / (total * 2)) * (rowCount * 2 + (total === 12 ? 8 : 24))
}px)`,
height: `calc(${(100 / (rowCount + 2)) * (total / rowCount)}vw + ${
(100 / (total * 2)) *
((total / rowCount) * 2 + (total === 12 ? 7 : 24))
}px)`,
top: `${total === 12 ? -2 : -3}vw`,
}"
/>
2025-05-10 16:57:36 +08:00
<view
v-for="(_, index) in items"
:key="index"
class="score-item"
2025-06-16 00:44:28 +08:00
:style="{
width: 100 / (rowCount + 2) + 'vw',
height: 100 / (rowCount + 2) + 'vw',
2025-06-16 22:43:39 +08:00
lineHeight: 100 / (rowCount + 2) + 'vw',
2025-06-16 00:44:28 +08:00
fontSize: fontSize + 'px',
2025-06-25 18:41:30 +08:00
margin: 100 / (total * 2) + 'px',
2025-06-16 00:44:28 +08:00
}"
2025-05-10 16:57:36 +08:00
>
2025-06-24 13:18:03 +08:00
<image src="../static/score-bg.png" mode="widthFix" />
2025-08-27 18:41:42 +08:00
<text
:style="{ fontWeight: scores[index] !== undefined ? 'bold' : 'normal' }"
>{{ scores[index] !== undefined ? scores[index] : "-" }}</text
>
2025-05-10 16:57:36 +08:00
</view>
</view>
</template>
<style scoped>
.container {
2025-06-25 18:41:30 +08:00
width: 92vw;
2025-05-10 16:57:36 +08:00
display: flex;
flex-wrap: wrap;
2025-06-16 00:44:28 +08:00
justify-content: center;
2025-06-28 12:03:33 +08:00
margin: 0 4vw;
2025-06-25 18:41:30 +08:00
position: relative;
padding: 1vw 0;
2025-05-10 16:57:36 +08:00
}
.score-item {
2025-06-24 13:18:03 +08:00
/* background-image: url("../static/score-bg.png");
2025-05-10 16:57:36 +08:00
background-size: cover;
background-repeat: no-repeat;
2025-06-24 13:18:03 +08:00
background-position: center; */
2025-05-10 16:57:36 +08:00
color: #fed847;
display: flex;
justify-content: center;
align-items: center;
2025-06-24 13:18:03 +08:00
position: relative;
}
.score-item > image {
position: absolute;
width: 100%;
top: 5%;
}
.score-item > text {
position: relative;
2025-07-15 14:02:09 +08:00
margin-top: 2px;
2025-05-10 16:57:36 +08:00
}
2025-06-25 18:41:30 +08:00
.complete-light {
position: absolute;
}
2025-05-10 16:57:36 +08:00
</style>