update:代码备份
This commit is contained in:
116
src/pages/training/components/BowData.vue
Normal file
116
src/pages/training/components/BowData.vue
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
<script setup>
|
||||||
|
import AppBackground from "@/components/AppBackground.vue";
|
||||||
|
import Avatar from "@/components/Avatar.vue";
|
||||||
|
import BowTarget from "@./BowTarget.vue";
|
||||||
|
import ScorePanel from "./ScorePanel.vue";
|
||||||
|
import useStore from "@/store";
|
||||||
|
import { storeToRefs } from "pinia";
|
||||||
|
const store = useStore();
|
||||||
|
const { user } = storeToRefs(store);
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
show: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
onClose: {
|
||||||
|
type: Function,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
|
arrows: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
total: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="container" :style="{ display: show ? 'flex' : 'none' }">
|
||||||
|
<AppBackground :type="1" />
|
||||||
|
<view class="header">
|
||||||
|
<view>
|
||||||
|
<Avatar :src="user.avatar" :rankLvl="user.rankLvl" :size="45" />
|
||||||
|
<view>
|
||||||
|
<text>{{ user.nickName }}</text>
|
||||||
|
<text>{{ user.lvlName }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view @click="onClose">
|
||||||
|
<image src="../static/close-white.png" mode="widthFix" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view :style="{ width: '100%', marginBottom: '20px' }">
|
||||||
|
<BowTarget :scores="arrows" />
|
||||||
|
</view>
|
||||||
|
<view class="desc">
|
||||||
|
<text>{{ arrows.length }}</text>
|
||||||
|
<text>支箭,共</text>
|
||||||
|
<text>{{ arrows.reduce((a, b) => a + (b.ring || 0), 0) }}</text>
|
||||||
|
<text>环</text>
|
||||||
|
</view>
|
||||||
|
<ScorePanel
|
||||||
|
:completeEffect="false"
|
||||||
|
:rowCount="total === 12 ? 6 : 9"
|
||||||
|
:total="total"
|
||||||
|
:arrows="arrows"
|
||||||
|
:margin="total === 12 ? 4 : 1"
|
||||||
|
:fontSize="total === 12 ? 25 : 22"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
background-color: #232323;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
width: calc(100% - 20px);
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
.header > view:first-child {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
.header > view:first-child > view:last-child {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
margin-left: 10px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.header > view:first-child > view:last-child > text:last-child {
|
||||||
|
font-size: 10px;
|
||||||
|
background-color: #5f51ff;
|
||||||
|
padding: 2px 5px;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
.header > view:last-child > image {
|
||||||
|
width: 40px;
|
||||||
|
}
|
||||||
|
.desc {
|
||||||
|
color: #fff;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
.desc > text:nth-child(2),
|
||||||
|
.desc > text:nth-child(4) {
|
||||||
|
color: #fed847;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import {
|
import {
|
||||||
computed,
|
computed,
|
||||||
getCurrentInstance,
|
|
||||||
nextTick,
|
|
||||||
onBeforeUnmount,
|
onBeforeUnmount,
|
||||||
onMounted,
|
onMounted,
|
||||||
ref,
|
ref,
|
||||||
@@ -17,7 +15,6 @@ import useStore from "@/store";
|
|||||||
import { storeToRefs } from "pinia";
|
import { storeToRefs } from "pinia";
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
const { user, device } = storeToRefs(store);
|
const { user, device } = storeToRefs(store);
|
||||||
const instance = getCurrentInstance();
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
currentRound: {
|
currentRound: {
|
||||||
@@ -278,122 +275,6 @@ const showHighlightCanvas = computed(() => {
|
|||||||
return props.totalRound > 0 && currentHighlightAreas.value.length > 0;
|
return props.totalRound > 0 && currentHighlightAreas.value.length > 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
const targetImageNaturalSize = ref({
|
|
||||||
width: 0,
|
|
||||||
height: 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
const targetLayerRect = ref({
|
|
||||||
left: 0,
|
|
||||||
top: 0,
|
|
||||||
width: 0,
|
|
||||||
height: 0,
|
|
||||||
ready: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const targetHighlightLayerStyle = computed(() => ({
|
|
||||||
left: `${targetLayerRect.value.left}px`,
|
|
||||||
top: `${targetLayerRect.value.top}px`,
|
|
||||||
width: `${targetLayerRect.value.width}px`,
|
|
||||||
height: `${targetLayerRect.value.height}px`,
|
|
||||||
}));
|
|
||||||
|
|
||||||
const getRectNumber = (value, fallback = 0) => {
|
|
||||||
const numberValue = Number(value);
|
|
||||||
return Number.isFinite(numberValue) ? numberValue : fallback;
|
|
||||||
};
|
|
||||||
|
|
||||||
const getImageContentRect = (imageRect) => {
|
|
||||||
const naturalWidth = getRectNumber(targetImageNaturalSize.value.width);
|
|
||||||
const naturalHeight = getRectNumber(targetImageNaturalSize.value.height);
|
|
||||||
const imageWidth = getRectNumber(imageRect?.width);
|
|
||||||
const imageHeight = getRectNumber(imageRect?.height);
|
|
||||||
|
|
||||||
if (naturalWidth <= 0 || naturalHeight <= 0 || imageWidth <= 0 || imageHeight <= 0) {
|
|
||||||
return imageRect;
|
|
||||||
}
|
|
||||||
|
|
||||||
const naturalRatio = naturalWidth / naturalHeight;
|
|
||||||
const boxRatio = imageWidth / imageHeight;
|
|
||||||
|
|
||||||
if (naturalRatio > boxRatio) {
|
|
||||||
const contentHeight = imageWidth / naturalRatio;
|
|
||||||
return {
|
|
||||||
left: imageRect.left,
|
|
||||||
top: imageRect.top + (imageHeight - contentHeight) / 2,
|
|
||||||
width: imageWidth,
|
|
||||||
height: contentHeight,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const contentWidth = imageHeight * naturalRatio;
|
|
||||||
return {
|
|
||||||
left: imageRect.left + (imageWidth - contentWidth) / 2,
|
|
||||||
top: imageRect.top,
|
|
||||||
width: contentWidth,
|
|
||||||
height: imageHeight,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const updateTargetLayerRect = async () => {
|
|
||||||
await nextTick();
|
|
||||||
|
|
||||||
const query = uni.createSelectorQuery().in(instance?.proxy);
|
|
||||||
query.select(".target").boundingClientRect();
|
|
||||||
query.select(".target-image").boundingClientRect();
|
|
||||||
query.exec((rects = []) => {
|
|
||||||
const stageRect = rects[0];
|
|
||||||
const imageRect = rects[1];
|
|
||||||
|
|
||||||
if (!stageRect || !imageRect || !imageRect.width || !imageRect.height) {
|
|
||||||
targetLayerRect.value = {
|
|
||||||
...targetLayerRect.value,
|
|
||||||
ready: false,
|
|
||||||
};
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const contentRect = getImageContentRect(imageRect);
|
|
||||||
const width = Math.round(getRectNumber(contentRect?.width));
|
|
||||||
const height = Math.round(getRectNumber(contentRect?.height));
|
|
||||||
|
|
||||||
targetLayerRect.value = {
|
|
||||||
left: getRectNumber(contentRect?.left) - getRectNumber(stageRect.left),
|
|
||||||
top: getRectNumber(contentRect?.top) - getRectNumber(stageRect.top),
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
ready: width > 0 && height > 0,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const onTargetImageLoad = (event) => {
|
|
||||||
const width = getRectNumber(event?.detail?.width);
|
|
||||||
const height = getRectNumber(event?.detail?.height);
|
|
||||||
|
|
||||||
if (width > 0 && height > 0) {
|
|
||||||
targetImageNaturalSize.value = {
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
updateTargetLayerRect();
|
|
||||||
};
|
|
||||||
|
|
||||||
const onWindowResize = () => {
|
|
||||||
updateTargetLayerRect();
|
|
||||||
};
|
|
||||||
|
|
||||||
watch(
|
|
||||||
showHighlightCanvas,
|
|
||||||
(newVal) => {
|
|
||||||
if (newVal) {
|
|
||||||
updateTargetLayerRect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
async function onReceiveMessage(message) {
|
async function onReceiveMessage(message) {
|
||||||
if (Array.isArray(message)) return;
|
if (Array.isArray(message)) return;
|
||||||
if (message.type === MESSAGETYPESV2.ShootResult && message.shootData) {
|
if (message.type === MESSAGETYPESV2.ShootResult && message.shootData) {
|
||||||
@@ -418,10 +299,6 @@ async function onReceiveMessage(message) {
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
uni.$on("socket-inbox", onReceiveMessage);
|
uni.$on("socket-inbox", onReceiveMessage);
|
||||||
setTimeout(updateTargetLayerRect, 30);
|
|
||||||
if (uni.onWindowResize) {
|
|
||||||
uni.onWindowResize(onWindowResize);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
@@ -434,9 +311,6 @@ onBeforeUnmount(() => {
|
|||||||
dirTimer.value = null;
|
dirTimer.value = null;
|
||||||
}
|
}
|
||||||
uni.$off("socket-inbox", onReceiveMessage);
|
uni.$off("socket-inbox", onReceiveMessage);
|
||||||
if (uni.offWindowResize) {
|
|
||||||
uni.offWindowResize(onWindowResize);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -454,14 +328,10 @@ onBeforeUnmount(() => {
|
|||||||
class="target-image"
|
class="target-image"
|
||||||
src="../../../static/bow-target.png"
|
src="../../../static/bow-target.png"
|
||||||
mode="aspectFit"
|
mode="aspectFit"
|
||||||
@load="onTargetImageLoad"
|
|
||||||
/>
|
/>
|
||||||
<TargetCanvas
|
<TargetCanvas
|
||||||
v-if="showHighlightCanvas && targetLayerRect.ready"
|
v-if="showHighlightCanvas"
|
||||||
class="target-highlight-layer"
|
class="target-highlight-layer"
|
||||||
:style="targetHighlightLayerStyle"
|
|
||||||
:canvasWidth="targetLayerRect.width"
|
|
||||||
:canvasHeight="targetLayerRect.height"
|
|
||||||
:coordinateRadius="coordinateRadius"
|
:coordinateRadius="coordinateRadius"
|
||||||
:showCrosshair="false"
|
:showCrosshair="false"
|
||||||
:showQuadrantLabels="false"
|
:showQuadrantLabels="false"
|
||||||
@@ -573,6 +443,10 @@ onBeforeUnmount(() => {
|
|||||||
}
|
}
|
||||||
.target-highlight-layer {
|
.target-highlight-layer {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, computed } from "vue";
|
import { ref, onMounted, computed } from "vue";
|
||||||
import ScreenHint from "@/components/ScreenHint.vue";
|
import ScreenHint from "./ScreenHint.vue";
|
||||||
import BowData from "@/components/BowData.vue";
|
import BowData from "./BowData.vue";
|
||||||
import UserUpgrade from "@/components/UserUpgrade.vue";
|
import UserUpgrade from "@/components/UserUpgrade.vue";
|
||||||
import { directionAdjusts } from "@/constants";
|
import { directionAdjusts } from "@/constants";
|
||||||
import useStore from "@/store";
|
import useStore from "@/store";
|
||||||
|
|||||||
89
src/pages/training/components/ScreenHint.vue
Normal file
89
src/pages/training/components/ScreenHint.vue
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
<script setup>
|
||||||
|
import IconButton from "./IconButton.vue";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
show: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
onClose: {
|
||||||
|
type: Function,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
default: "normal",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const getContentHeight = () => {
|
||||||
|
if (props.mode === "tall") return "50vw";
|
||||||
|
if (props.mode === "square") return "74vw";
|
||||||
|
return "36vw";
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="container" :style="{ display: show ? 'flex' : 'none' }">
|
||||||
|
<view class="scale-in" :style="{ height: getContentHeight() }">
|
||||||
|
<image
|
||||||
|
v-if="mode === 'normal'"
|
||||||
|
src="../static/screen-hint-bg.png"
|
||||||
|
mode="widthFix"
|
||||||
|
/>
|
||||||
|
<image
|
||||||
|
v-if="mode === 'tall'"
|
||||||
|
src="../static/coach-comment.png"
|
||||||
|
mode="widthFix"
|
||||||
|
/>
|
||||||
|
<image
|
||||||
|
v-if="mode === 'square'"
|
||||||
|
src="../static/prompt-bg-square.png"
|
||||||
|
mode="widthFix"
|
||||||
|
/>
|
||||||
|
<image
|
||||||
|
v-if="mode === 'small'"
|
||||||
|
src="../static/finish-frame.png"
|
||||||
|
mode="widthFix"
|
||||||
|
/>
|
||||||
|
<slot />
|
||||||
|
</view>
|
||||||
|
<IconButton
|
||||||
|
v-if="!!onClose"
|
||||||
|
src="../static/close-gold-outline.png"
|
||||||
|
:width="30"
|
||||||
|
:onClick="onClose"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.8);
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
.container > view:first-child {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
width: 70vw;
|
||||||
|
color: #fff;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
.container > view:first-child > image {
|
||||||
|
position: absolute;
|
||||||
|
width: 80vw;
|
||||||
|
left: -7%;
|
||||||
|
bottom: -18vw;
|
||||||
|
z-index: -1;
|
||||||
|
transform: translateY(-75px);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -29,6 +29,13 @@ const { user } = storeToRefs(store);
|
|||||||
|
|
||||||
const sound = ref(true);
|
const sound = ref(true);
|
||||||
const start = ref(false);
|
const start = ref(false);
|
||||||
|
const pageStages = Object.freeze({
|
||||||
|
DISTANCE: "distance",
|
||||||
|
SHOOTING: "shooting",
|
||||||
|
RESULT: "result",
|
||||||
|
LOADING: "loading",
|
||||||
|
});
|
||||||
|
const pageStage = ref(pageStages.DISTANCE);
|
||||||
const scores = ref([]);
|
const scores = ref([]);
|
||||||
const defaultTotal = 12;
|
const defaultTotal = 12;
|
||||||
const defaultShootTime = 120;
|
const defaultShootTime = 120;
|
||||||
@@ -53,6 +60,13 @@ const env = computed(() => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const isDistanceStage = computed(() => pageStage.value === pageStages.DISTANCE);
|
||||||
|
const isShootingStage = computed(() => pageStage.value === pageStages.SHOOTING);
|
||||||
|
const hasPractiseResult = computed(() => !!practiseResult.value?.details);
|
||||||
|
const showResult = computed(
|
||||||
|
() => pageStage.value === pageStages.RESULT && hasPractiseResult.value
|
||||||
|
);
|
||||||
|
|
||||||
const defaultHighlightAreas = [{ quadrant: 1, rings: [7] }];
|
const defaultHighlightAreas = [{ quadrant: 1, rings: [7] }];
|
||||||
|
|
||||||
// 临时高亮测试数据:第 N 项对应第 N 箭,每箭展示一个不同区域。
|
// 临时高亮测试数据:第 N 项对应第 N 箭,每箭展示一个不同区域。
|
||||||
@@ -123,6 +137,7 @@ const runHighlightTest = () => {
|
|||||||
clearHighlightTestTimer();
|
clearHighlightTestTimer();
|
||||||
useHighlightTest.value = true;
|
useHighlightTest.value = true;
|
||||||
practiseResult.value = {};
|
practiseResult.value = {};
|
||||||
|
pageStage.value = pageStages.SHOOTING;
|
||||||
start.value = true;
|
start.value = true;
|
||||||
|
|
||||||
let arrowIndex = 1;
|
let arrowIndex = 1;
|
||||||
@@ -162,21 +177,44 @@ onLoad((options = {}) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const onReady = async () => {
|
const onReady = async () => {
|
||||||
|
pageStage.value = pageStages.LOADING;
|
||||||
clearHighlightTestTimer();
|
clearHighlightTestTimer();
|
||||||
useHighlightTest.value = false;
|
useHighlightTest.value = false;
|
||||||
await startPractiseAPI();
|
try {
|
||||||
scores.value = [];
|
await startPractiseAPI();
|
||||||
start.value = true;
|
practiseResult.value = {};
|
||||||
audioManager.play("练习开始");
|
scores.value = [];
|
||||||
|
start.value = true;
|
||||||
|
pageStage.value = pageStages.SHOOTING;
|
||||||
|
audioManager.play("练习开始");
|
||||||
|
} catch (error) {
|
||||||
|
start.value = false;
|
||||||
|
pageStage.value = pageStages.DISTANCE;
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onOver = async () => {
|
const onOver = async () => {
|
||||||
practiseResult.value = await getPractiseAPI(practiseId.value);
|
if (!isShootingStage.value) return;
|
||||||
|
|
||||||
|
clearHighlightTestTimer();
|
||||||
|
pageStage.value = pageStages.LOADING;
|
||||||
start.value = false;
|
start.value = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
practiseResult.value = (await getPractiseAPI(practiseId.value)) || {};
|
||||||
|
pageStage.value = hasPractiseResult.value
|
||||||
|
? pageStages.RESULT
|
||||||
|
: pageStages.DISTANCE;
|
||||||
|
} catch (error) {
|
||||||
|
start.value = true;
|
||||||
|
pageStage.value = pageStages.SHOOTING;
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
async function onReceiveMessage(msg) {
|
async function onReceiveMessage(msg) {
|
||||||
if (msg.type === MESSAGETYPESV2.ShootResult) {
|
if (msg.type === MESSAGETYPESV2.ShootResult && isShootingStage.value) {
|
||||||
scores.value = msg.details;
|
scores.value = msg.details;
|
||||||
} else if (msg.type === MESSAGETYPESV2.BattleEnd) {
|
} else if (msg.type === MESSAGETYPESV2.BattleEnd) {
|
||||||
// setTimeout(onOver, 1500);
|
// setTimeout(onOver, 1500);
|
||||||
@@ -184,18 +222,25 @@ async function onReceiveMessage(msg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onComplete() {
|
function onComplete() {
|
||||||
|
pageStage.value = pageStages.LOADING;
|
||||||
|
start.value = false;
|
||||||
uni.$emit(trainingDifficultyRefreshEvent);
|
uni.$emit(trainingDifficultyRefreshEvent);
|
||||||
uni.navigateBack();
|
uni.navigateBack();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onRetry() {
|
async function onRetry() {
|
||||||
|
pageStage.value = pageStages.LOADING;
|
||||||
clearHighlightTestTimer();
|
clearHighlightTestTimer();
|
||||||
useHighlightTest.value = false;
|
useHighlightTest.value = false;
|
||||||
practiseId.value = "";
|
practiseId.value = "";
|
||||||
practiseResult.value = {};
|
practiseResult.value = {};
|
||||||
start.value = false;
|
start.value = false;
|
||||||
scores.value = [];
|
scores.value = [];
|
||||||
await createPractice();
|
try {
|
||||||
|
await createPractice();
|
||||||
|
} finally {
|
||||||
|
pageStage.value = pageStages.DISTANCE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const onClickShare = debounce(async () => {
|
const onClickShare = debounce(async () => {
|
||||||
@@ -241,83 +286,92 @@ onBeforeUnmount(() => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Container
|
<Container
|
||||||
:bgType="!start && !practiseResult.id?9:10"
|
:bgType="isDistanceStage ? 9 : 10"
|
||||||
:showBottom="!start && !scores.length"
|
:showBottom="isDistanceStage"
|
||||||
headerClass="training-practise-header"
|
:scroll="!isShootingStage"
|
||||||
>
|
>
|
||||||
<view>
|
<view class="practise-content">
|
||||||
<TestDistance v-if="!start && !practiseResult.id" />
|
<TestDistance v-if="isDistanceStage" />
|
||||||
<block v-else>
|
<view v-else-if="isShootingStage" class="shooting-layout">
|
||||||
<ShootProgress
|
<view class="shooting-fixed">
|
||||||
:start="start"
|
<ShootProgress
|
||||||
:onStop="onOver"
|
:start="start"
|
||||||
/>
|
:onStop="onOver"
|
||||||
<view class="user-row">
|
/>
|
||||||
<!-- <Avatar :src="user.avatar" :size="35" /> -->
|
<view class="user-row">
|
||||||
<BubbleTip v-if="showGuide" type="normal2">
|
<!-- <Avatar :src="user.avatar" :size="35" /> -->
|
||||||
<text>还有两场,坚持</text>
|
<BubbleTip v-if="showGuide" type="normal2">
|
||||||
<text>就是胜利!💪</text>
|
<text>还有两场,坚持</text>
|
||||||
</BubbleTip>
|
<text>就是胜利!💪</text>
|
||||||
<!-- <BowPower /> -->
|
</BubbleTip>
|
||||||
</view>
|
<!-- <BowPower /> -->
|
||||||
<BowTarget
|
</view>
|
||||||
:totalRound="start ? total / 4 : 0"
|
<BowTarget
|
||||||
:currentRound="scores.length % 3"
|
:totalRound="start ? total / 4 : 0"
|
||||||
:scores="scores"
|
:currentRound="scores.length % 3"
|
||||||
:showCrosshair="false"
|
:scores="scores"
|
||||||
:highlightAreas="targetHighlightAreas"
|
:showCrosshair="false"
|
||||||
/>
|
:highlightAreas="targetHighlightAreas"
|
||||||
<view v-if="env !== 'release'" class="highlight-test-actions">
|
/>
|
||||||
<button
|
<view v-if="env !== 'release'" class="highlight-test-actions">
|
||||||
class="highlight-test-btn"
|
<button
|
||||||
hover-class="none"
|
class="highlight-test-btn"
|
||||||
@click="runHighlightTest"
|
hover-class="none"
|
||||||
>
|
@click="runHighlightTest"
|
||||||
高亮测试
|
>
|
||||||
</button>
|
高亮测试
|
||||||
<button
|
</button>
|
||||||
class="highlight-test-btn"
|
<button
|
||||||
hover-class="none"
|
class="highlight-test-btn"
|
||||||
@click="resetHighlightTest"
|
hover-class="none"
|
||||||
>
|
@click="resetHighlightTest"
|
||||||
重置高亮
|
>
|
||||||
</button>
|
重置高亮
|
||||||
</view>
|
</button>
|
||||||
<view class="sound-text-box">
|
</view>
|
||||||
<button class="sound-btn" hover-class="none" @click="updateSound">
|
<view class="sound-text-box">
|
||||||
<image
|
<button class="sound-btn" hover-class="none" @click="updateSound">
|
||||||
class="sound-icon"
|
<image
|
||||||
:src="`/static/sound${sound ? '' : '-off'}-yellow.png`"
|
class="sound-icon"
|
||||||
mode="aspectFit"
|
:src="`/static/sound${sound ? '' : '-off'}-yellow.png`"
|
||||||
/>
|
mode="aspectFit"
|
||||||
</button>
|
/>
|
||||||
<view class="bat-text-big-box">
|
</button>
|
||||||
<image
|
<view class="bat-text-big-box">
|
||||||
class="dao-icon"
|
<image
|
||||||
src="../../static/training-difficulty-design/dao-icon.png"
|
class="dao-icon"
|
||||||
mode="widthFix"
|
src="../../static/training-difficulty-design/dao-icon.png"
|
||||||
/>
|
mode="widthFix"
|
||||||
<view class="bat-text-box">
|
/>
|
||||||
<view class="bat-text-small-box">
|
<view class="bat-text-box">
|
||||||
<view class="text-round-box">
|
<view class="bat-text-small-box">
|
||||||
<view class="text1">每箭命中9环之上</view>
|
<view class="text-round-box">
|
||||||
<view class="text2">剩余<text class="text2-yellow">3</text>箭</view>
|
<view class="text1">每箭命中9环之上</view>
|
||||||
|
<view class="text2">剩余<text class="text2-yellow">3</text>箭</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<ScorePanel2 :arrows="scores" :total="total" />
|
<scroll-view
|
||||||
<ScoreResult
|
class="score-scroll"
|
||||||
v-if="practiseResult.details"
|
scroll-y
|
||||||
:rowCount="6"
|
:enhanced="true"
|
||||||
:total="total"
|
:show-scrollbar="false"
|
||||||
:onClose="onComplete"
|
>
|
||||||
:onRetry="onRetry"
|
<ScorePanel2 :arrows="scores" :total="total" />
|
||||||
:result="practiseResult"
|
</scroll-view>
|
||||||
/>
|
</view>
|
||||||
<canvas class="share-canvas" id="shareCanvas" type="2d"></canvas>
|
<ScoreResult
|
||||||
</block>
|
v-else-if="showResult"
|
||||||
|
:rowCount="6"
|
||||||
|
:total="total"
|
||||||
|
:onClose="onComplete"
|
||||||
|
:onRetry="onRetry"
|
||||||
|
:result="practiseResult"
|
||||||
|
/>
|
||||||
|
<canvas class="share-canvas" id="shareCanvas" type="2d"></canvas>
|
||||||
</view>
|
</view>
|
||||||
<template #bottom>
|
<template #bottom>
|
||||||
<view class="btn-box">
|
<view class="btn-box">
|
||||||
@@ -333,6 +387,30 @@ onBeforeUnmount(() => {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
.practise-content {
|
||||||
|
height: 100%;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shooting-layout {
|
||||||
|
height: 100%;
|
||||||
|
min-height: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shooting-fixed {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.score-scroll {
|
||||||
|
flex: 1;
|
||||||
|
height: 0;
|
||||||
|
min-height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
.btn-box{
|
.btn-box{
|
||||||
width: 488rpx;
|
width: 488rpx;
|
||||||
height: 234rpx;
|
height: 234rpx;
|
||||||
@@ -360,11 +438,6 @@ onBeforeUnmount(() => {
|
|||||||
bottom: -36rpx;
|
bottom: -36rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.training-practise-header .back-btn) {
|
|
||||||
position: relative;
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.highlight-test-actions {
|
.highlight-test-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|||||||
Reference in New Issue
Block a user