update:优化个人训练
This commit is contained in:
@@ -17,6 +17,7 @@ const trainingModeRouteMap = {
|
||||
rhythm: "rhythm",
|
||||
strength: "power",
|
||||
};
|
||||
const unavailableTrainingIds = new Set(["rhythm", "strength"]);
|
||||
// 训练项目卡片右侧主图标。
|
||||
const trainingModeIconMap = {
|
||||
base_bow:
|
||||
@@ -79,7 +80,7 @@ const trainingData = ref(createDefaultTrainingData());
|
||||
const recommendedTrainingId = ref("");
|
||||
const visibleTrainingItems = computed(() =>
|
||||
Array.isArray(trainingData.value.training_items)
|
||||
? trainingData.value.training_items.filter((item) => item.id !== "strength")
|
||||
? trainingData.value.training_items
|
||||
: []
|
||||
);
|
||||
const pageMounted = ref(false);
|
||||
@@ -91,8 +92,17 @@ const radarFigureWidthRpx = 448;
|
||||
const radarFigureHeightRpx = Math.round(
|
||||
(radarFigureWidthRpx * radarImageHeight) / radarImageWidth
|
||||
);
|
||||
const radarCanvasWidth = Math.round(uni.upx2px(radarFigureWidthRpx));
|
||||
const radarCanvasHeight = Math.round(uni.upx2px(radarFigureHeightRpx));
|
||||
const radarCanvasPixelRatio = Math.max(
|
||||
1,
|
||||
Number(uni.getDeviceInfo().pixelRatio) || 1
|
||||
);
|
||||
const radarTargetWidth = uni.upx2px(radarFigureWidthRpx);
|
||||
const radarTargetHeight = uni.upx2px(radarFigureHeightRpx);
|
||||
// 画布按设备像素比直接绘制,并让显示尺寸与物理像素严格对应,避免图片二次缩放。
|
||||
const radarCanvasWidth = Math.round(radarTargetWidth * radarCanvasPixelRatio);
|
||||
const radarCanvasHeight = Math.round(radarTargetHeight * radarCanvasPixelRatio);
|
||||
const radarDisplayWidth = radarCanvasWidth / radarCanvasPixelRatio;
|
||||
const radarDisplayHeight = radarCanvasHeight / radarCanvasPixelRatio;
|
||||
const radarScaleX = radarCanvasWidth / radarImageWidth;
|
||||
const radarScaleY = radarCanvasHeight / radarImageHeight;
|
||||
const radarScale = Math.min(radarScaleX, radarScaleY);
|
||||
@@ -103,9 +113,10 @@ const radarPointRadius = Math.max(2.5, 3.5 * radarScale);
|
||||
const radarOuterRadiusX = 110.7089 * radarScaleX;
|
||||
const radarOuterRadiusY = 110.7089 * radarScaleY;
|
||||
const radarFigureStyle = {
|
||||
width: `${radarFigureWidthRpx}rpx`,
|
||||
height: `${radarFigureHeightRpx}rpx`,
|
||||
width: `${radarDisplayWidth}px`,
|
||||
height: `${radarDisplayHeight}px`,
|
||||
};
|
||||
let radarRenderGeneration = 0;
|
||||
|
||||
const formatValue = (value, digits = 1) => {
|
||||
const numberValue = Number(value);
|
||||
@@ -116,7 +127,7 @@ const formatValue = (value, digits = 1) => {
|
||||
const getLevelText = (item) => {
|
||||
if (!item) return "";
|
||||
const level = Number(item.current_level) || 0;
|
||||
return item.is_locked ? `Coming! LV${level}` : `当前进度 LV${level} >`;
|
||||
return `当前进度 LV${level} >`;
|
||||
};
|
||||
|
||||
// 卡路里字段按需求做 K / W 缩写展示。
|
||||
@@ -156,6 +167,7 @@ const updateRecommendedTraining = () => {
|
||||
const trainingId = radarDimensionTrainingIdMap[item?.name];
|
||||
const rawScore = item?.score;
|
||||
if (
|
||||
unavailableTrainingIds.has(trainingId) ||
|
||||
!visibleTrainingIds.includes(trainingId) ||
|
||||
rawScore === undefined ||
|
||||
rawScore === null ||
|
||||
@@ -176,9 +188,10 @@ const updateRecommendedTraining = () => {
|
||||
const lowestCandidates = candidates.filter(
|
||||
(item) => item.score === lowestScore
|
||||
);
|
||||
const selectedIndex = Math.floor(Math.random() * lowestCandidates.length);
|
||||
const selectedIndex = Math.floor(Math.random() * lowestCandidates.length); //暂时先不随机,默认使用第一个
|
||||
console.log(candidates, selectedIndex, lowestCandidates)
|
||||
recommendedTrainingId.value =
|
||||
lowestCandidates[selectedIndex]?.trainingId || "";
|
||||
lowestCandidates[0]?.trainingId || "";
|
||||
};
|
||||
|
||||
const getRadarPoint = (centerX, centerY, radiusX, radiusY, angle) => ({
|
||||
@@ -251,11 +264,14 @@ const drawRadar = () => {
|
||||
ctx.draw();
|
||||
};
|
||||
|
||||
// 小程序 canvas 首次渲染时机不稳定,延后一帧再绘制更稳。
|
||||
// 小程序 Canvas 首次渲染时机不稳定,延后一帧再绘制更稳。
|
||||
const refreshRadar = async () => {
|
||||
const generation = ++radarRenderGeneration;
|
||||
await nextTick();
|
||||
setTimeout(() => {
|
||||
drawRadar();
|
||||
if (generation === radarRenderGeneration) {
|
||||
drawRadar();
|
||||
}
|
||||
}, 30);
|
||||
};
|
||||
|
||||
@@ -303,17 +319,17 @@ const openTrainingRecord = () => {
|
||||
};
|
||||
|
||||
const openTrainingItem = (item = {}) => {
|
||||
const mode = getTrainingMode(item);
|
||||
if (!mode) return;
|
||||
|
||||
if (item.is_locked) {
|
||||
if (unavailableTrainingIds.has(item.id)) {
|
||||
uni.showToast({
|
||||
title: `${item.name || "训练"} 暂未开放`,
|
||||
title: "功能开发中...",
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const mode = getTrainingMode(item);
|
||||
if (!mode) return;
|
||||
|
||||
uni.navigateTo({
|
||||
url: `/pages/training/difficulty?mode=${mode}`,
|
||||
});
|
||||
@@ -344,7 +360,12 @@ onShow(async () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Container :showBackToGame="true" :bgType="7" bgColor="#050b19">
|
||||
<Container
|
||||
:showBackToGame="true"
|
||||
:bgType="7"
|
||||
bgColor="#050b19"
|
||||
:usePageScroll="true"
|
||||
>
|
||||
<view class="training-home">
|
||||
<view class="week-grid">
|
||||
<view
|
||||
@@ -818,10 +839,9 @@ onShow(async () => {
|
||||
}
|
||||
|
||||
.radar-figure {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
position: relative;
|
||||
top: 54rpx;
|
||||
transform: translateX(-50%);
|
||||
margin: 0 auto;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user