完善样式系统与调试链路底座

This commit is contained in:
2026-03-30 18:19:05 +08:00
parent 2c0fd4c549
commit 3b9117427e
40 changed files with 7526 additions and 389 deletions

View File

@@ -9,6 +9,8 @@ import {
import { loadRemoteMapConfig } from '../../utils/remoteMapConfig'
import { type AnimationLevel } from '../../utils/animationLevel'
import { type H5ExperienceFallbackPayload, type H5ExperienceRequest } from '../../game/experience/h5Experience'
import { type TrackColorPreset, type TrackDisplayMode, type TrackStyleProfile, type TrackTailLengthPreset } from '../../game/presentation/trackStyleConfig'
import { type GpsMarkerColorPreset, type GpsMarkerSizePreset, type GpsMarkerStyleId } from '../../game/presentation/gpsMarkerStyleConfig'
type CompassTickData = {
angle: number
long: boolean
@@ -39,6 +41,14 @@ type UserNorthReferenceMode = 'magnetic' | 'true'
type CompassTuningProfile = 'smooth' | 'balanced' | 'responsive'
type SettingLockKey =
| 'lockAnimationLevel'
| 'lockTrackMode'
| 'lockTrackTailLength'
| 'lockTrackColor'
| 'lockTrackStyle'
| 'lockGpsMarkerVisible'
| 'lockGpsMarkerStyle'
| 'lockGpsMarkerSize'
| 'lockGpsMarkerColor'
| 'lockSideButtonPlacement'
| 'lockAutoRotate'
| 'lockCompassTuning'
@@ -48,6 +58,14 @@ type SettingLockKey =
| 'lockHeartRateDevice'
type StoredUserSettings = {
animationLevel?: AnimationLevel
trackDisplayMode?: TrackDisplayMode
trackTailLength?: TrackTailLengthPreset
trackColorPreset?: TrackColorPreset
trackStyleProfile?: TrackStyleProfile
gpsMarkerVisible?: boolean
gpsMarkerStyle?: GpsMarkerStyleId
gpsMarkerSize?: GpsMarkerSizePreset
gpsMarkerColorPreset?: GpsMarkerColorPreset
autoRotateEnabled?: boolean
compassTuningProfile?: CompassTuningProfile
northReferenceMode?: UserNorthReferenceMode
@@ -55,6 +73,14 @@ type StoredUserSettings = {
showCenterScaleRuler?: boolean
centerScaleRulerAnchorMode?: CenterScaleRulerAnchorMode
lockAnimationLevel?: boolean
lockTrackMode?: boolean
lockTrackTailLength?: boolean
lockTrackColor?: boolean
lockTrackStyle?: boolean
lockGpsMarkerVisible?: boolean
lockGpsMarkerStyle?: boolean
lockGpsMarkerSize?: boolean
lockGpsMarkerColor?: boolean
lockSideButtonPlacement?: boolean
lockAutoRotate?: boolean
lockCompassTuning?: boolean
@@ -77,6 +103,7 @@ type MapPageData = MapEngineViewState & {
configSourceText: string
mockBridgeUrlDraft: string
mockHeartRateBridgeUrlDraft: string
mockDebugLogBridgeUrlDraft: string
gameInfoTitle: string
gameInfoSubtitle: string
gameInfoLocalRows: MapEngineGameInfoRow[]
@@ -101,6 +128,14 @@ type MapPageData = MapEngineViewState & {
sideButtonPlacement: SideButtonPlacement
autoRotateEnabled: boolean
lockAnimationLevel: boolean
lockTrackMode: boolean
lockTrackTailLength: boolean
lockTrackColor: boolean
lockTrackStyle: boolean
lockGpsMarkerVisible: boolean
lockGpsMarkerStyle: boolean
lockGpsMarkerSize: boolean
lockGpsMarkerColor: boolean
lockSideButtonPlacement: boolean
lockAutoRotate: boolean
lockCompassTuning: boolean
@@ -129,7 +164,7 @@ type MapPageData = MapEngineViewState & {
showRightButtonGroups: boolean
showBottomDebugButton: boolean
}
const INTERNAL_BUILD_VERSION = 'map-build-291'
const INTERNAL_BUILD_VERSION = 'map-build-293'
const USER_SETTINGS_STORAGE_KEY = 'cmr_user_settings_v1'
const CLASSIC_REMOTE_GAME_CONFIG_URL = 'https://oss-mbh5.colormaprun.com/gotomars/event/classic-sequential.json'
const SCORE_O_REMOTE_GAME_CONFIG_URL = 'https://oss-mbh5.colormaprun.com/gotomars/event/score-o.json'
@@ -138,6 +173,8 @@ let mapEngine: MapEngine | null = null
let stageCanvasAttached = false
let gameInfoPanelSyncTimer = 0
let centerScaleRulerSyncTimer = 0
let contentAudioRecorder: WechatMiniprogram.RecorderManager | null = null
let contentAudioRecording = false
let centerScaleRulerUpdateTimer = 0
let punchHintDismissTimer = 0
let panelTimerFxTimer = 0
@@ -371,6 +408,53 @@ function loadStoredUserSettings(): StoredUserSettings {
if (normalized.animationLevel === 'standard' || normalized.animationLevel === 'lite') {
settings.animationLevel = normalized.animationLevel
}
if (normalized.trackDisplayMode === 'none' || normalized.trackDisplayMode === 'full' || normalized.trackDisplayMode === 'tail') {
settings.trackDisplayMode = normalized.trackDisplayMode
}
if (normalized.trackTailLength === 'short' || normalized.trackTailLength === 'medium' || normalized.trackTailLength === 'long') {
settings.trackTailLength = normalized.trackTailLength
}
if (normalized.trackStyleProfile === 'classic' || normalized.trackStyleProfile === 'neon') {
settings.trackStyleProfile = normalized.trackStyleProfile
}
if (typeof normalized.gpsMarkerVisible === 'boolean') {
settings.gpsMarkerVisible = normalized.gpsMarkerVisible
}
if (
normalized.gpsMarkerStyle === 'dot'
|| normalized.gpsMarkerStyle === 'beacon'
|| normalized.gpsMarkerStyle === 'disc'
|| normalized.gpsMarkerStyle === 'badge'
) {
settings.gpsMarkerStyle = normalized.gpsMarkerStyle
}
if (normalized.gpsMarkerSize === 'small' || normalized.gpsMarkerSize === 'medium' || normalized.gpsMarkerSize === 'large') {
settings.gpsMarkerSize = normalized.gpsMarkerSize
}
if (
normalized.gpsMarkerColorPreset === 'mint'
|| normalized.gpsMarkerColorPreset === 'cyan'
|| normalized.gpsMarkerColorPreset === 'sky'
|| normalized.gpsMarkerColorPreset === 'blue'
|| normalized.gpsMarkerColorPreset === 'violet'
|| normalized.gpsMarkerColorPreset === 'pink'
|| normalized.gpsMarkerColorPreset === 'orange'
|| normalized.gpsMarkerColorPreset === 'yellow'
) {
settings.gpsMarkerColorPreset = normalized.gpsMarkerColorPreset
}
if (
normalized.trackColorPreset === 'mint'
|| normalized.trackColorPreset === 'cyan'
|| normalized.trackColorPreset === 'sky'
|| normalized.trackColorPreset === 'blue'
|| normalized.trackColorPreset === 'violet'
|| normalized.trackColorPreset === 'pink'
|| normalized.trackColorPreset === 'orange'
|| normalized.trackColorPreset === 'yellow'
) {
settings.trackColorPreset = normalized.trackColorPreset
}
if (normalized.northReferenceMode === 'magnetic' || normalized.northReferenceMode === 'true') {
settings.northReferenceMode = normalized.northReferenceMode
}
@@ -392,6 +476,30 @@ function loadStoredUserSettings(): StoredUserSettings {
if (typeof normalized.lockAnimationLevel === 'boolean') {
settings.lockAnimationLevel = normalized.lockAnimationLevel
}
if (typeof normalized.lockTrackMode === 'boolean') {
settings.lockTrackMode = normalized.lockTrackMode
}
if (typeof normalized.lockTrackTailLength === 'boolean') {
settings.lockTrackTailLength = normalized.lockTrackTailLength
}
if (typeof normalized.lockTrackColor === 'boolean') {
settings.lockTrackColor = normalized.lockTrackColor
}
if (typeof normalized.lockTrackStyle === 'boolean') {
settings.lockTrackStyle = normalized.lockTrackStyle
}
if (typeof normalized.lockGpsMarkerVisible === 'boolean') {
settings.lockGpsMarkerVisible = normalized.lockGpsMarkerVisible
}
if (typeof normalized.lockGpsMarkerStyle === 'boolean') {
settings.lockGpsMarkerStyle = normalized.lockGpsMarkerStyle
}
if (typeof normalized.lockGpsMarkerSize === 'boolean') {
settings.lockGpsMarkerSize = normalized.lockGpsMarkerSize
}
if (typeof normalized.lockGpsMarkerColor === 'boolean') {
settings.lockGpsMarkerColor = normalized.lockGpsMarkerColor
}
if (typeof normalized.lockSideButtonPlacement === 'boolean') {
settings.lockSideButtonPlacement = normalized.lockSideButtonPlacement
}
@@ -722,6 +830,14 @@ Page({
centerScaleRulerAnchorMode: 'screen-center',
autoRotateEnabled: false,
lockAnimationLevel: false,
lockTrackMode: false,
lockTrackTailLength: false,
lockTrackColor: false,
lockTrackStyle: false,
lockGpsMarkerVisible: false,
lockGpsMarkerStyle: false,
lockGpsMarkerSize: false,
lockGpsMarkerColor: false,
lockSideButtonPlacement: false,
lockAutoRotate: false,
lockCompassTuning: false,
@@ -763,13 +879,27 @@ Page({
heartRateSourceText: '真实心率',
mockHeartRateBridgeConnected: false,
mockHeartRateBridgeStatusText: '未连接',
mockHeartRateBridgeUrlText: 'wss://gs.gotomars.xyz/mock-gps',
mockHeartRateBridgeUrlDraft: 'wss://gs.gotomars.xyz/mock-gps',
mockHeartRateBridgeUrlText: 'wss://gs.gotomars.xyz/mock-hr',
mockHeartRateBridgeUrlDraft: 'wss://gs.gotomars.xyz/mock-hr',
mockHeartRateText: '--',
mockDebugLogBridgeConnected: false,
mockDebugLogBridgeStatusText: '已关闭 (wss://gs.gotomars.xyz/debug-log)',
mockDebugLogBridgeUrlText: 'wss://gs.gotomars.xyz/debug-log',
mockDebugLogBridgeUrlDraft: 'wss://gs.gotomars.xyz/debug-log',
heartRateScanText: '未扫描',
heartRateDiscoveredDevices: [],
panelSpeedValueText: '0',
panelTelemetryTone: 'blue',
trackDisplayMode: 'full',
trackTailLength: 'medium',
trackColorPreset: 'mint',
trackStyleProfile: 'neon',
gpsMarkerVisible: true,
gpsMarkerStyle: 'beacon',
gpsMarkerSize: 'medium',
gpsMarkerColorPreset: 'cyan',
gpsLogoStatusText: '未配置',
gpsLogoSourceText: '--',
panelHeartRateZoneNameText: '--',
panelHeartRateZoneRangeText: '',
heartRateConnected: false,
@@ -803,8 +933,14 @@ Page({
contentCardTemplate: 'story',
contentCardTitle: '',
contentCardBody: '',
contentCardActionVisible: false,
contentCardActionText: '查看详情',
contentCardActions: [],
contentQuizVisible: false,
contentQuizQuestionText: '',
contentQuizCountdownText: '',
contentQuizOptions: [],
contentQuizFeedbackVisible: false,
contentQuizFeedbackText: '',
contentQuizFeedbackTone: 'neutral',
punchButtonFxClass: '',
panelProgressFxClass: '',
panelDistanceFxClass: '',
@@ -875,6 +1011,13 @@ Page({
nextData.mockHeartRateBridgeUrlDraft = nextPatch.mockHeartRateBridgeUrlText
}
if (
typeof nextPatch.mockDebugLogBridgeUrlText === 'string'
&& this.data.mockDebugLogBridgeUrlDraft === this.data.mockDebugLogBridgeUrlText
) {
nextData.mockDebugLogBridgeUrlDraft = nextPatch.mockDebugLogBridgeUrlText
}
updateCenterScaleRulerInputCache(nextPatch)
const mergedData = {
@@ -1005,6 +1148,30 @@ Page({
if (storedUserSettings.animationLevel) {
mapEngine.handleSetAnimationLevel(storedUserSettings.animationLevel)
}
if (storedUserSettings.trackDisplayMode) {
mapEngine.handleSetTrackMode(storedUserSettings.trackDisplayMode)
}
if (storedUserSettings.trackTailLength) {
mapEngine.handleSetTrackTailLength(storedUserSettings.trackTailLength)
}
if (storedUserSettings.trackColorPreset) {
mapEngine.handleSetTrackColorPreset(storedUserSettings.trackColorPreset)
}
if (storedUserSettings.trackStyleProfile) {
mapEngine.handleSetTrackStyleProfile(storedUserSettings.trackStyleProfile)
}
if (typeof storedUserSettings.gpsMarkerVisible === 'boolean') {
mapEngine.handleSetGpsMarkerVisible(storedUserSettings.gpsMarkerVisible)
}
if (storedUserSettings.gpsMarkerStyle) {
mapEngine.handleSetGpsMarkerStyle(storedUserSettings.gpsMarkerStyle)
}
if (storedUserSettings.gpsMarkerSize) {
mapEngine.handleSetGpsMarkerSize(storedUserSettings.gpsMarkerSize)
}
if (storedUserSettings.gpsMarkerColorPreset) {
mapEngine.handleSetGpsMarkerColorPreset(storedUserSettings.gpsMarkerColorPreset)
}
const initialAutoRotateEnabled = storedUserSettings.autoRotateEnabled !== false
if (initialAutoRotateEnabled) {
mapEngine.handleSetHeadingUpMode()
@@ -1045,6 +1212,14 @@ Page({
centerScaleRulerAnchorMode: initialCenterScaleRulerAnchorMode,
autoRotateEnabled: initialAutoRotateEnabled,
lockAnimationLevel: !!storedUserSettings.lockAnimationLevel,
lockTrackMode: !!storedUserSettings.lockTrackMode,
lockTrackTailLength: !!storedUserSettings.lockTrackTailLength,
lockTrackColor: !!storedUserSettings.lockTrackColor,
lockTrackStyle: !!storedUserSettings.lockTrackStyle,
lockGpsMarkerVisible: !!storedUserSettings.lockGpsMarkerVisible,
lockGpsMarkerStyle: !!storedUserSettings.lockGpsMarkerStyle,
lockGpsMarkerSize: !!storedUserSettings.lockGpsMarkerSize,
lockGpsMarkerColor: !!storedUserSettings.lockGpsMarkerColor,
lockSideButtonPlacement: !!storedUserSettings.lockSideButtonPlacement,
lockAutoRotate: !!storedUserSettings.lockAutoRotate,
lockCompassTuning: !!storedUserSettings.lockCompassTuning,
@@ -1083,12 +1258,18 @@ Page({
heartRateSourceText: '真实心率',
mockHeartRateBridgeConnected: false,
mockHeartRateBridgeStatusText: '未连接',
mockHeartRateBridgeUrlText: 'wss://gs.gotomars.xyz/mock-gps',
mockHeartRateBridgeUrlDraft: 'wss://gs.gotomars.xyz/mock-gps',
mockHeartRateBridgeUrlText: 'wss://gs.gotomars.xyz/mock-hr',
mockHeartRateBridgeUrlDraft: 'wss://gs.gotomars.xyz/mock-hr',
mockHeartRateText: '--',
mockDebugLogBridgeConnected: false,
mockDebugLogBridgeStatusText: '已关闭 (wss://gs.gotomars.xyz/debug-log)',
mockDebugLogBridgeUrlText: 'wss://gs.gotomars.xyz/debug-log',
mockDebugLogBridgeUrlDraft: 'wss://gs.gotomars.xyz/debug-log',
panelSpeedValueText: '0',
panelSpeedFxClass: '',
panelTelemetryTone: 'blue',
gpsLogoStatusText: '未配置',
gpsLogoSourceText: '--',
panelHeartRateZoneNameText: '--',
panelHeartRateZoneRangeText: '',
heartRateConnected: false,
@@ -1123,8 +1304,14 @@ Page({
contentCardTemplate: 'story',
contentCardTitle: '',
contentCardBody: '',
contentCardActionVisible: false,
contentCardActionText: '查看详情',
contentCardActions: [],
contentQuizVisible: false,
contentQuizQuestionText: '',
contentQuizCountdownText: '',
contentQuizOptions: [],
contentQuizFeedbackVisible: false,
contentQuizFeedbackText: '',
contentQuizFeedbackTone: 'neutral',
punchButtonFxClass: '',
panelProgressFxClass: '',
panelDistanceFxClass: '',
@@ -1394,10 +1581,14 @@ Page({
if (!mapEngine) {
return
}
mapEngine.handleSetMockLocationBridgeUrl(this.data.mockBridgeUrlDraft)
mapEngine.handleSetMockHeartRateBridgeUrl(this.data.mockHeartRateBridgeUrlDraft)
mapEngine.handleSetMockDebugLogBridgeUrl(this.data.mockDebugLogBridgeUrlDraft)
mapEngine.handleConnectMockLocationBridge()
mapEngine.handleSetMockLocationMode()
mapEngine.handleSetMockHeartRateMode()
mapEngine.handleConnectMockHeartRateBridge()
mapEngine.handleConnectMockDebugLogBridge()
},
handleOpenWebViewTest() {
@@ -1448,6 +1639,30 @@ Page({
}
},
handleMockDebugLogBridgeUrlInput(event: WechatMiniprogram.Input) {
this.setData({
mockDebugLogBridgeUrlDraft: event.detail.value,
})
},
handleSaveMockDebugLogBridgeUrl() {
if (mapEngine) {
mapEngine.handleSetMockDebugLogBridgeUrl(this.data.mockDebugLogBridgeUrlDraft)
}
},
handleConnectMockDebugLogBridge() {
if (mapEngine) {
mapEngine.handleConnectMockDebugLogBridge()
}
},
handleDisconnectMockDebugLogBridge() {
if (mapEngine) {
mapEngine.handleDisconnectMockDebugLogBridge()
}
},
handleConnectMockHeartRateBridge() {
if (mapEngine) {
mapEngine.handleConnectMockHeartRateBridge()
@@ -1776,6 +1991,223 @@ Page({
})
},
handleSetTrackModeNone() {
if (this.data.lockTrackMode || !mapEngine) {
return
}
mapEngine.handleSetTrackMode('none')
persistStoredUserSettings({
...loadStoredUserSettings(),
trackDisplayMode: 'none',
})
},
handleSetTrackModeTail() {
if (this.data.lockTrackMode || !mapEngine) {
return
}
mapEngine.handleSetTrackMode('tail')
persistStoredUserSettings({
...loadStoredUserSettings(),
trackDisplayMode: 'tail',
})
},
handleSetTrackModeFull() {
if (this.data.lockTrackMode || !mapEngine) {
return
}
mapEngine.handleSetTrackMode('full')
persistStoredUserSettings({
...loadStoredUserSettings(),
trackDisplayMode: 'full',
})
},
handleSetTrackTailLengthShort() {
if (this.data.lockTrackTailLength || !mapEngine) {
return
}
mapEngine.handleSetTrackTailLength('short')
persistStoredUserSettings({
...loadStoredUserSettings(),
trackTailLength: 'short',
})
},
handleSetTrackTailLengthMedium() {
if (this.data.lockTrackTailLength || !mapEngine) {
return
}
mapEngine.handleSetTrackTailLength('medium')
persistStoredUserSettings({
...loadStoredUserSettings(),
trackTailLength: 'medium',
})
},
handleSetTrackTailLengthLong() {
if (this.data.lockTrackTailLength || !mapEngine) {
return
}
mapEngine.handleSetTrackTailLength('long')
persistStoredUserSettings({
...loadStoredUserSettings(),
trackTailLength: 'long',
})
},
handleSetTrackColorPreset(event: WechatMiniprogram.TouchEvent) {
if (this.data.lockTrackColor || !mapEngine) {
return
}
const color = event.currentTarget.dataset.color as TrackColorPreset | undefined
if (!color) {
return
}
mapEngine.handleSetTrackColorPreset(color)
persistStoredUserSettings({
...loadStoredUserSettings(),
trackColorPreset: color,
})
},
handleSetTrackStyleClassic() {
if (this.data.lockTrackStyle || !mapEngine) {
return
}
mapEngine.handleSetTrackStyleProfile('classic')
persistStoredUserSettings({
...loadStoredUserSettings(),
trackStyleProfile: 'classic',
})
},
handleSetTrackStyleNeon() {
if (this.data.lockTrackStyle || !mapEngine) {
return
}
mapEngine.handleSetTrackStyleProfile('neon')
persistStoredUserSettings({
...loadStoredUserSettings(),
trackStyleProfile: 'neon',
})
},
handleSetGpsMarkerVisibleOn() {
if (this.data.lockGpsMarkerVisible || !mapEngine) {
return
}
mapEngine.handleSetGpsMarkerVisible(true)
persistStoredUserSettings({
...loadStoredUserSettings(),
gpsMarkerVisible: true,
})
},
handleSetGpsMarkerVisibleOff() {
if (this.data.lockGpsMarkerVisible || !mapEngine) {
return
}
mapEngine.handleSetGpsMarkerVisible(false)
persistStoredUserSettings({
...loadStoredUserSettings(),
gpsMarkerVisible: false,
})
},
handleSetGpsMarkerStyleDot() {
if (this.data.lockGpsMarkerStyle || !mapEngine) {
return
}
mapEngine.handleSetGpsMarkerStyle('dot')
persistStoredUserSettings({
...loadStoredUserSettings(),
gpsMarkerStyle: 'dot',
})
},
handleSetGpsMarkerStyleBeacon() {
if (this.data.lockGpsMarkerStyle || !mapEngine) {
return
}
mapEngine.handleSetGpsMarkerStyle('beacon')
persistStoredUserSettings({
...loadStoredUserSettings(),
gpsMarkerStyle: 'beacon',
})
},
handleSetGpsMarkerStyleDisc() {
if (this.data.lockGpsMarkerStyle || !mapEngine) {
return
}
mapEngine.handleSetGpsMarkerStyle('disc')
persistStoredUserSettings({
...loadStoredUserSettings(),
gpsMarkerStyle: 'disc',
})
},
handleSetGpsMarkerStyleBadge() {
if (this.data.lockGpsMarkerStyle || !mapEngine) {
return
}
mapEngine.handleSetGpsMarkerStyle('badge')
persistStoredUserSettings({
...loadStoredUserSettings(),
gpsMarkerStyle: 'badge',
})
},
handleSetGpsMarkerSizeSmall() {
if (this.data.lockGpsMarkerSize || !mapEngine) {
return
}
mapEngine.handleSetGpsMarkerSize('small')
persistStoredUserSettings({
...loadStoredUserSettings(),
gpsMarkerSize: 'small',
})
},
handleSetGpsMarkerSizeMedium() {
if (this.data.lockGpsMarkerSize || !mapEngine) {
return
}
mapEngine.handleSetGpsMarkerSize('medium')
persistStoredUserSettings({
...loadStoredUserSettings(),
gpsMarkerSize: 'medium',
})
},
handleSetGpsMarkerSizeLarge() {
if (this.data.lockGpsMarkerSize || !mapEngine) {
return
}
mapEngine.handleSetGpsMarkerSize('large')
persistStoredUserSettings({
...loadStoredUserSettings(),
gpsMarkerSize: 'large',
})
},
handleSetGpsMarkerColorPreset(event: WechatMiniprogram.TouchEvent) {
if (this.data.lockGpsMarkerColor || !mapEngine) {
return
}
const color = event.currentTarget.dataset.color as GpsMarkerColorPreset | undefined
if (!color) {
return
}
mapEngine.handleSetGpsMarkerColorPreset(color)
persistStoredUserSettings({
...loadStoredUserSettings(),
gpsMarkerColorPreset: color,
})
},
handleSetSideButtonPlacementLeft() {
if (this.data.lockSideButtonPlacement) {
return
@@ -1909,14 +2341,76 @@ Page({
}
},
handleOpenContentCardDetail() {
if (mapEngine) {
handleOpenContentCardAction(event: WechatMiniprogram.BaseEvent) {
if (!mapEngine) {
return
}
wx.showToast({
title: '点击CTA',
icon: 'none',
duration: 900,
})
const actionType = event.currentTarget.dataset.type
const action = typeof actionType === 'string' ? mapEngine.openCurrentContentCardAction(actionType) : null
if (action === 'detail') {
wx.showToast({
title: '打开详情',
icon: 'none',
duration: 900,
})
mapEngine.openCurrentContentCardDetail()
return
}
if (action === 'quiz') {
return
}
if (action === 'photo') {
wx.chooseMedia({
count: 1,
mediaType: ['image'],
sourceType: ['camera'],
success: () => {
if (mapEngine) {
mapEngine.handleContentCardPhotoCaptured()
}
},
})
return
}
if (action === 'audio') {
if (!contentAudioRecorder) {
contentAudioRecorder = wx.getRecorderManager()
contentAudioRecorder.onStop(() => {
contentAudioRecording = false
if (mapEngine) {
mapEngine.handleContentCardAudioRecorded()
}
})
}
const recorder = contentAudioRecorder
if (!contentAudioRecording) {
contentAudioRecording = true
recorder.start({
duration: 8000,
format: 'mp3',
} as any)
wx.showToast({
title: '开始录音',
icon: 'none',
duration: 800,
})
} else {
recorder.stop()
}
}
},
handleContentQuizAnswer(event: WechatMiniprogram.BaseEvent) {
if (!mapEngine) {
return
}
const optionKey = event.currentTarget.dataset.key
if (typeof optionKey === 'string') {
mapEngine.handleContentCardQuizAnswer(optionKey)
}
},

View File

@@ -80,16 +80,44 @@
>
<view class="game-content-card__title">{{contentCardTitle}}</view>
<view class="game-content-card__body">{{contentCardBody}}</view>
<view class="game-content-card__action-row {{contentCardActionVisible ? 'game-content-card__action-row--split' : ''}}">
<view
wx:if="{{contentCardActionVisible}}"
class="game-content-card__action"
catchtap="handleOpenContentCardDetail"
>{{contentCardActionText}}</view>
<view class="game-content-card__action-row {{contentCardActions.length ? 'game-content-card__action-row--split' : ''}}">
<view class="game-content-card__cta-group" wx:if="{{contentCardActions.length}}">
<view
wx:for="{{contentCardActions}}"
wx:key="key"
class="game-content-card__action"
data-type="{{item.type}}"
data-key="{{item.key}}"
catchtap="handleOpenContentCardAction"
>{{item.label}}</view>
</view>
<view class="game-content-card__close" catchtap="handleCloseContentCard">关闭</view>
</view>
</view>
<view class="game-content-quiz" wx:if="{{contentQuizVisible}}">
<view class="game-content-quiz__panel">
<view class="game-content-quiz__header">
<view class="game-content-quiz__title">答题加分</view>
<view class="game-content-quiz__countdown">{{contentQuizCountdownText}}</view>
</view>
<view class="game-content-quiz__question">{{contentQuizQuestionText}}</view>
<view class="game-content-quiz__options">
<view
wx:for="{{contentQuizOptions}}"
wx:key="key"
class="game-content-quiz__option"
data-key="{{item.key}}"
catchtap="handleContentQuizAnswer"
>{{item.label}}</view>
</view>
<view
wx:if="{{contentQuizFeedbackVisible}}"
class="game-content-quiz__feedback game-content-quiz__feedback--{{contentQuizFeedbackTone}}"
>{{contentQuizFeedbackText}}</view>
</view>
</view>
<view class="game-punch-hint" wx:if="{{!showResultScene && showPunchHintBanner && punchHintText}}" style="top: {{topInsetHeight}}px;" catchtouchstart="handlePunchHintTap" catchtouchmove="handlePunchHintTap" catchtouchend="handlePunchHintTap">
<view class="game-punch-hint__text">{{punchHintText}}</view>
<view class="game-punch-hint__close" catchtouchstart="handlePunchHintTap" catchtouchmove="handlePunchHintTap" catchtouchend="handlePunchHintTap" catchtap="handleClosePunchHint">×</view>
@@ -329,9 +357,9 @@
</view>
<scroll-view class="game-info-modal__content" scroll-y enhanced show-scrollbar="true">
<view class="debug-section debug-section--info">
<view class="debug-section__header">
<view class="debug-section__header-row">
<view class="debug-section debug-section--info">
<view class="debug-section__header">
<view class="debug-section__header-row">
<view class="debug-section__header-main">
<view class="debug-section__title">01. 动画性能</view>
<view class="debug-section__desc">根据设备性能切换动画强度,低端机建议精简</view>
@@ -355,14 +383,219 @@
<view class="debug-section__header">
<view class="debug-section__header-row">
<view class="debug-section__header-main">
<view class="debug-section__title">02. 按钮习惯</view>
<view class="debug-section__desc">切换功能按钮显示在左侧还是右侧,适配左手/右手操作习惯</view>
<view class="debug-section__title">02. 轨迹选项</view>
<view class="debug-section__desc">控制不显示、彗尾拖尾、全轨迹三种显示方式</view>
</view>
<view class="debug-section__lock {{lockSideButtonPlacement ? 'debug-section__lock--active' : ''}}" data-key="lockSideButtonPlacement" bindtap="handleToggleSettingLock">
<text class="debug-section__lock-text">{{lockSideButtonPlacement ? '已锁' : '可改'}}</text>
<view class="debug-section__lock {{lockTrackMode ? 'debug-section__lock--active' : ''}}" data-key="lockTrackMode" bindtap="handleToggleSettingLock">
<text class="debug-section__lock-text">{{lockTrackMode ? '已锁' : '可改'}}</text>
</view>
</view>
</view>
<view class="info-panel__row">
<text class="info-panel__label">当前模式</text>
<text class="info-panel__value">
{{trackDisplayMode === 'none' ? '无' : (trackDisplayMode === 'tail' ? '彗尾' : '全轨迹')}}{{lockTrackMode ? ' · 已锁定' : ' · 可编辑'}}
</text>
</view>
<view class="control-row">
<view class="control-chip {{trackDisplayMode === 'none' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockTrackMode ? 'control-chip--disabled' : ''}}" bindtap="handleSetTrackModeNone">无</view>
<view class="control-chip {{trackDisplayMode === 'tail' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockTrackMode ? 'control-chip--disabled' : ''}}" bindtap="handleSetTrackModeTail">彗尾</view>
<view class="control-chip {{trackDisplayMode === 'full' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockTrackMode ? 'control-chip--disabled' : ''}}" bindtap="handleSetTrackModeFull">全轨迹</view>
</view>
</view>
<view class="debug-section debug-section--info">
<view class="debug-section__header">
<view class="debug-section__header-row">
<view class="debug-section__header-main">
<view class="debug-section__title">03. 轨迹尾巴</view>
<view class="debug-section__desc">拖尾模式下控制尾巴长短,跑得越快会在此基础上再拉长</view>
</view>
<view class="debug-section__lock {{lockTrackTailLength ? 'debug-section__lock--active' : ''}}" data-key="lockTrackTailLength" bindtap="handleToggleSettingLock">
<text class="debug-section__lock-text">{{lockTrackTailLength ? '已锁' : '可改'}}</text>
</view>
</view>
</view>
<view class="info-panel__row">
<text class="info-panel__label">当前长度</text>
<text class="info-panel__value">
{{trackTailLength === 'short' ? '短' : (trackTailLength === 'long' ? '长' : '中')}}{{lockTrackTailLength ? ' · 已锁定' : ' · 可编辑'}}
</text>
</view>
<view class="control-row">
<view class="control-chip {{trackTailLength === 'short' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockTrackTailLength ? 'control-chip--disabled' : ''}}" bindtap="handleSetTrackTailLengthShort">短</view>
<view class="control-chip {{trackTailLength === 'medium' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockTrackTailLength ? 'control-chip--disabled' : ''}}" bindtap="handleSetTrackTailLengthMedium">中</view>
<view class="control-chip {{trackTailLength === 'long' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockTrackTailLength ? 'control-chip--disabled' : ''}}" bindtap="handleSetTrackTailLengthLong">长</view>
</view>
</view>
<view class="debug-section debug-section--info">
<view class="debug-section__header">
<view class="debug-section__header-row">
<view class="debug-section__header-main">
<view class="debug-section__title">04. 轨迹颜色</view>
<view class="debug-section__desc">亮色轨迹调色盘,运行中会按速度和心率张力自动提亮</view>
</view>
<view class="debug-section__lock {{lockTrackColor ? 'debug-section__lock--active' : ''}}" data-key="lockTrackColor" bindtap="handleToggleSettingLock">
<text class="debug-section__lock-text">{{lockTrackColor ? '已锁' : '可改'}}</text>
</view>
</view>
</view>
<view class="info-panel__row">
<text class="info-panel__label">当前颜色</text>
<text class="info-panel__value">
{{trackColorPreset === 'mint' ? '薄荷' : (trackColorPreset === 'cyan' ? '青绿' : (trackColorPreset === 'sky' ? '天蓝' : (trackColorPreset === 'blue' ? '深蓝' : (trackColorPreset === 'violet' ? '紫罗兰' : (trackColorPreset === 'pink' ? '玫红' : (trackColorPreset === 'orange' ? '橙色' : '亮黄'))))))}}{{lockTrackColor ? ' · 已锁定' : ' · 可编辑'}}
</text>
</view>
<view class="control-row control-row--wrap">
<view class="control-chip {{trackColorPreset === 'mint' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockTrackColor ? 'control-chip--disabled' : ''}}" data-color="mint" bindtap="handleSetTrackColorPreset">薄荷</view>
<view class="control-chip {{trackColorPreset === 'cyan' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockTrackColor ? 'control-chip--disabled' : ''}}" data-color="cyan" bindtap="handleSetTrackColorPreset">青绿</view>
<view class="control-chip {{trackColorPreset === 'sky' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockTrackColor ? 'control-chip--disabled' : ''}}" data-color="sky" bindtap="handleSetTrackColorPreset">天蓝</view>
<view class="control-chip {{trackColorPreset === 'blue' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockTrackColor ? 'control-chip--disabled' : ''}}" data-color="blue" bindtap="handleSetTrackColorPreset">深蓝</view>
</view>
<view class="control-row control-row--wrap">
<view class="control-chip {{trackColorPreset === 'violet' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockTrackColor ? 'control-chip--disabled' : ''}}" data-color="violet" bindtap="handleSetTrackColorPreset">紫罗兰</view>
<view class="control-chip {{trackColorPreset === 'pink' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockTrackColor ? 'control-chip--disabled' : ''}}" data-color="pink" bindtap="handleSetTrackColorPreset">玫红</view>
<view class="control-chip {{trackColorPreset === 'orange' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockTrackColor ? 'control-chip--disabled' : ''}}" data-color="orange" bindtap="handleSetTrackColorPreset">橙色</view>
<view class="control-chip {{trackColorPreset === 'yellow' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockTrackColor ? 'control-chip--disabled' : ''}}" data-color="yellow" bindtap="handleSetTrackColorPreset">亮黄</view>
</view>
</view>
<view class="debug-section debug-section--info">
<view class="debug-section__header">
<view class="debug-section__header-row">
<view class="debug-section__header-main">
<view class="debug-section__title">05. 轨迹风格</view>
<view class="debug-section__desc">切换经典线条和流光轨迹风格,默认推荐流光</view>
</view>
<view class="debug-section__lock {{lockTrackStyle ? 'debug-section__lock--active' : ''}}" data-key="lockTrackStyle" bindtap="handleToggleSettingLock">
<text class="debug-section__lock-text">{{lockTrackStyle ? '已锁' : '可改'}}</text>
</view>
</view>
</view>
<view class="info-panel__row">
<text class="info-panel__label">当前风格</text>
<text class="info-panel__value">{{trackStyleProfile === 'neon' ? '流光' : '经典'}}{{lockTrackStyle ? ' · 已锁定' : ' · 可编辑'}}</text>
</view>
<view class="control-row">
<view class="control-chip {{trackStyleProfile === 'classic' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockTrackStyle ? 'control-chip--disabled' : ''}}" bindtap="handleSetTrackStyleClassic">经典</view>
<view class="control-chip {{trackStyleProfile === 'neon' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockTrackStyle ? 'control-chip--disabled' : ''}}" bindtap="handleSetTrackStyleNeon">流光</view>
</view>
</view>
<view class="debug-section debug-section--info">
<view class="debug-section__header">
<view class="debug-section__header-row">
<view class="debug-section__header-main">
<view class="debug-section__title">06. GPS点显示</view>
<view class="debug-section__desc">控制地图上的 GPS 定位点显示与隐藏</view>
</view>
<view class="debug-section__lock {{lockGpsMarkerVisible ? 'debug-section__lock--active' : ''}}" data-key="lockGpsMarkerVisible" bindtap="handleToggleSettingLock">
<text class="debug-section__lock-text">{{lockGpsMarkerVisible ? '已锁' : '可改'}}</text>
</view>
</view>
</view>
<view class="info-panel__row">
<text class="info-panel__label">当前状态</text>
<text class="info-panel__value">{{gpsMarkerVisible ? '显示' : '隐藏'}}{{lockGpsMarkerVisible ? ' · 已锁定' : ' · 可编辑'}}</text>
</view>
<view class="control-row">
<view class="control-chip {{gpsMarkerVisible ? 'control-chip--active' : 'control-chip--secondary'}} {{lockGpsMarkerVisible ? 'control-chip--disabled' : ''}}" bindtap="handleSetGpsMarkerVisibleOn">显示</view>
<view class="control-chip {{!gpsMarkerVisible ? 'control-chip--active' : 'control-chip--secondary'}} {{lockGpsMarkerVisible ? 'control-chip--disabled' : ''}}" bindtap="handleSetGpsMarkerVisibleOff">隐藏</view>
</view>
</view>
<view class="debug-section debug-section--info">
<view class="debug-section__header">
<view class="debug-section__header-row">
<view class="debug-section__header-main">
<view class="debug-section__title">07. GPS点大小</view>
<view class="debug-section__desc">控制定位点本体和朝向小三角的整体尺寸</view>
</view>
<view class="debug-section__lock {{lockGpsMarkerSize ? 'debug-section__lock--active' : ''}}" data-key="lockGpsMarkerSize" bindtap="handleToggleSettingLock">
<text class="debug-section__lock-text">{{lockGpsMarkerSize ? '已锁' : '可改'}}</text>
</view>
</view>
</view>
<view class="info-panel__row">
<text class="info-panel__label">当前大小</text>
<text class="info-panel__value">{{gpsMarkerSize === 'small' ? '小' : (gpsMarkerSize === 'large' ? '大' : '中')}}{{lockGpsMarkerSize ? ' · 已锁定' : ' · 可编辑'}}</text>
</view>
<view class="control-row">
<view class="control-chip {{gpsMarkerSize === 'small' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockGpsMarkerSize ? 'control-chip--disabled' : ''}}" bindtap="handleSetGpsMarkerSizeSmall">小</view>
<view class="control-chip {{gpsMarkerSize === 'medium' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockGpsMarkerSize ? 'control-chip--disabled' : ''}}" bindtap="handleSetGpsMarkerSizeMedium">中</view>
<view class="control-chip {{gpsMarkerSize === 'large' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockGpsMarkerSize ? 'control-chip--disabled' : ''}}" bindtap="handleSetGpsMarkerSizeLarge">大</view>
</view>
</view>
<view class="debug-section debug-section--info">
<view class="debug-section__header">
<view class="debug-section__header-row">
<view class="debug-section__header-main">
<view class="debug-section__title">08. GPS点颜色</view>
<view class="debug-section__desc">切换定位点主色,默认使用青绿高亮色</view>
</view>
<view class="debug-section__lock {{lockGpsMarkerColor ? 'debug-section__lock--active' : ''}}" data-key="lockGpsMarkerColor" bindtap="handleToggleSettingLock">
<text class="debug-section__lock-text">{{lockGpsMarkerColor ? '已锁' : '可改'}}</text>
</view>
</view>
</view>
<view class="info-panel__row">
<text class="info-panel__label">当前颜色</text>
<text class="info-panel__value">
{{gpsMarkerColorPreset === 'mint' ? '薄荷' : (gpsMarkerColorPreset === 'cyan' ? '青绿' : (gpsMarkerColorPreset === 'sky' ? '天蓝' : (gpsMarkerColorPreset === 'blue' ? '深蓝' : (gpsMarkerColorPreset === 'violet' ? '紫罗兰' : (gpsMarkerColorPreset === 'pink' ? '玫红' : (gpsMarkerColorPreset === 'orange' ? '橙色' : '亮黄'))))))}}{{lockGpsMarkerColor ? ' · 已锁定' : ' · 可编辑'}}
</text>
</view>
<view class="control-row control-row--wrap">
<view class="control-chip {{gpsMarkerColorPreset === 'mint' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockGpsMarkerColor ? 'control-chip--disabled' : ''}}" data-color="mint" bindtap="handleSetGpsMarkerColorPreset">薄荷</view>
<view class="control-chip {{gpsMarkerColorPreset === 'cyan' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockGpsMarkerColor ? 'control-chip--disabled' : ''}}" data-color="cyan" bindtap="handleSetGpsMarkerColorPreset">青绿</view>
<view class="control-chip {{gpsMarkerColorPreset === 'sky' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockGpsMarkerColor ? 'control-chip--disabled' : ''}}" data-color="sky" bindtap="handleSetGpsMarkerColorPreset">天蓝</view>
<view class="control-chip {{gpsMarkerColorPreset === 'blue' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockGpsMarkerColor ? 'control-chip--disabled' : ''}}" data-color="blue" bindtap="handleSetGpsMarkerColorPreset">深蓝</view>
</view>
<view class="control-row control-row--wrap">
<view class="control-chip {{gpsMarkerColorPreset === 'violet' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockGpsMarkerColor ? 'control-chip--disabled' : ''}}" data-color="violet" bindtap="handleSetGpsMarkerColorPreset">紫罗兰</view>
<view class="control-chip {{gpsMarkerColorPreset === 'pink' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockGpsMarkerColor ? 'control-chip--disabled' : ''}}" data-color="pink" bindtap="handleSetGpsMarkerColorPreset">玫红</view>
<view class="control-chip {{gpsMarkerColorPreset === 'orange' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockGpsMarkerColor ? 'control-chip--disabled' : ''}}" data-color="orange" bindtap="handleSetGpsMarkerColorPreset">橙色</view>
<view class="control-chip {{gpsMarkerColorPreset === 'yellow' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockGpsMarkerColor ? 'control-chip--disabled' : ''}}" data-color="yellow" bindtap="handleSetGpsMarkerColorPreset">亮黄</view>
</view>
</view>
<view class="debug-section debug-section--info">
<view class="debug-section__header">
<view class="debug-section__header-row">
<view class="debug-section__header-main">
<view class="debug-section__title">09. GPS点风格</view>
<view class="debug-section__desc">切换定位点底座风格,影响本体与外圈表现</view>
</view>
<view class="debug-section__lock {{lockGpsMarkerStyle ? 'debug-section__lock--active' : ''}}" data-key="lockGpsMarkerStyle" bindtap="handleToggleSettingLock">
<text class="debug-section__lock-text">{{lockGpsMarkerStyle ? '已锁' : '可改'}}</text>
</view>
</view>
</view>
<view class="info-panel__row">
<text class="info-panel__label">当前风格</text>
<text class="info-panel__value">{{gpsMarkerStyle === 'dot' ? '圆点' : (gpsMarkerStyle === 'disc' ? '圆盘' : (gpsMarkerStyle === 'badge' ? '徽章' : '信标'))}}{{lockGpsMarkerStyle ? ' · 已锁定' : ' · 可编辑'}}</text>
</view>
<view class="control-row control-row--wrap">
<view class="control-chip {{gpsMarkerStyle === 'dot' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockGpsMarkerStyle ? 'control-chip--disabled' : ''}}" bindtap="handleSetGpsMarkerStyleDot">圆点</view>
<view class="control-chip {{gpsMarkerStyle === 'beacon' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockGpsMarkerStyle ? 'control-chip--disabled' : ''}}" bindtap="handleSetGpsMarkerStyleBeacon">信标</view>
<view class="control-chip {{gpsMarkerStyle === 'disc' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockGpsMarkerStyle ? 'control-chip--disabled' : ''}}" bindtap="handleSetGpsMarkerStyleDisc">圆盘</view>
<view class="control-chip {{gpsMarkerStyle === 'badge' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockGpsMarkerStyle ? 'control-chip--disabled' : ''}}" bindtap="handleSetGpsMarkerStyleBadge">徽章</view>
</view>
</view>
<view class="debug-section debug-section--info">
<view class="debug-section__header">
<view class="debug-section__header-row">
<view class="debug-section__header-main">
<view class="debug-section__title">10. 按钮习惯</view>
<view class="debug-section__desc">切换功能按钮显示在左侧还是右侧,适配左手/右手操作习惯</view>
</view>
<view class="debug-section__lock {{lockSideButtonPlacement ? 'debug-section__lock--active' : ''}}" data-key="lockSideButtonPlacement" bindtap="handleToggleSettingLock">
<text class="debug-section__lock-text">{{lockSideButtonPlacement ? '已锁' : '可改'}}</text>
</view>
</view>
</view>
<view class="info-panel__row">
<text class="info-panel__label">当前习惯</text>
<text class="info-panel__value">{{sideButtonPlacement === 'right' ? '右手' : '左手'}}{{lockSideButtonPlacement ? ' · 已锁定' : ' · 可编辑'}}</text>
@@ -373,11 +606,11 @@
</view>
</view>
<view class="debug-section debug-section--info">
<view class="debug-section__header">
<view class="debug-section__header-row">
<view class="debug-section__header-main">
<view class="debug-section__title">03. 自动转图</view>
<view class="debug-section debug-section--info">
<view class="debug-section__header">
<view class="debug-section__header-row">
<view class="debug-section__header-main">
<view class="debug-section__title">11. 自动转图</view>
<view class="debug-section__desc">控制地图是否跟随朝向自动旋转,外部按钮与这里保持同步</view>
</view>
<view class="debug-section__lock {{lockAutoRotate ? 'debug-section__lock--active' : ''}}" data-key="lockAutoRotate" bindtap="handleToggleSettingLock">
@@ -395,11 +628,11 @@
</view>
</view>
<view class="debug-section debug-section--info">
<view class="debug-section__header">
<view class="debug-section__header-row">
<view class="debug-section__header-main">
<view class="debug-section__title">04. 指北针响应</view>
<view class="debug-section debug-section--info">
<view class="debug-section__header">
<view class="debug-section__header-row">
<view class="debug-section__header-main">
<view class="debug-section__title">12. 指北针响应</view>
<view class="debug-section__desc">切换指针的平滑与跟手程度,影响指北针响应手感</view>
</view>
<view class="debug-section__lock {{lockCompassTuning ? 'debug-section__lock--active' : ''}}" data-key="lockCompassTuning" bindtap="handleToggleSettingLock">
@@ -418,11 +651,11 @@
</view>
</view>
<view class="debug-section debug-section--info">
<view class="debug-section__header">
<view class="debug-section__header-row">
<view class="debug-section__header-main">
<view class="debug-section__title">05. 比例尺显示</view>
<view class="debug-section debug-section--info">
<view class="debug-section__header">
<view class="debug-section__header-row">
<view class="debug-section__header-main">
<view class="debug-section__title">13. 比例尺显示</view>
<view class="debug-section__desc">控制比例尺显示与否,默认沿用你的本地偏好</view>
</view>
<view class="debug-section__lock {{lockScaleRulerVisible ? 'debug-section__lock--active' : ''}}" data-key="lockScaleRulerVisible" bindtap="handleToggleSettingLock">
@@ -440,11 +673,11 @@
</view>
</view>
<view class="debug-section debug-section--info">
<view class="debug-section__header">
<view class="debug-section__header-row">
<view class="debug-section__header-main">
<view class="debug-section__title">06. 比例尺基准点</view>
<view class="debug-section debug-section--info">
<view class="debug-section__header">
<view class="debug-section__header-row">
<view class="debug-section__header-main">
<view class="debug-section__title">14. 比例尺基准点</view>
<view class="debug-section__desc">设置比例尺零点锚定位置,可跟随屏幕中心或指北针圆心</view>
</view>
<view class="debug-section__lock {{lockScaleRulerAnchor ? 'debug-section__lock--active' : ''}}" data-key="lockScaleRulerAnchor" bindtap="handleToggleSettingLock">
@@ -462,11 +695,11 @@
</view>
</view>
<view class="debug-section debug-section--info">
<view class="debug-section__header">
<view class="debug-section__header-row">
<view class="debug-section__header-main">
<view class="debug-section__title">07. 北参考</view>
<view class="debug-section debug-section--info">
<view class="debug-section__header">
<view class="debug-section__header-row">
<view class="debug-section__header-main">
<view class="debug-section__title">15. 北参考</view>
<view class="debug-section__desc">切换磁北/真北作为地图与指北针参考</view>
</view>
<view class="debug-section__lock {{lockNorthReference ? 'debug-section__lock--active' : ''}}" data-key="lockNorthReference" bindtap="handleToggleSettingLock">
@@ -484,11 +717,11 @@
</view>
</view>
<view class="debug-section debug-section--info">
<view class="debug-section__header">
<view class="debug-section__header-row">
<view class="debug-section__header-main">
<view class="debug-section__title">08. 心率设备</view>
<view class="debug-section debug-section--info">
<view class="debug-section__header">
<view class="debug-section__header-row">
<view class="debug-section__header-main">
<view class="debug-section__title">16. 心率设备</view>
<view class="debug-section__desc">清除已记住的首选心率带设备,下次重新选择</view>
</view>
<view class="debug-section__lock {{lockHeartRateDevice ? 'debug-section__lock--active' : ''}}" data-key="lockHeartRateDevice" bindtap="handleToggleSettingLock">
@@ -562,13 +795,13 @@
<view class="debug-section">
<view class="debug-section__header">
<view class="debug-section__title">Sensors</view>
<view class="debug-section__desc">定位、罗盘与心率带连接状态</view>
<view class="debug-section__desc">定位模拟、心率模拟、调试日志与方向状态</view>
</view>
<view class="control-row">
<view class="control-chip control-chip--primary" bindtap="handleConnectAllMockSources">一键连接模拟源</view>
<view class="control-chip control-chip--primary" bindtap="handleConnectAllMockSources">一键连接开发调试源</view>
<view class="control-chip control-chip--secondary" bindtap="handleOpenWebViewTest">测试 H5</view>
</view>
<view class="debug-group-title">定位</view>
<view class="debug-group-title">定位模拟</view>
<view class="info-panel__row">
<text class="info-panel__label">GPS</text>
<text class="info-panel__value">{{gpsTrackingText}}</text>
@@ -577,16 +810,24 @@
<text class="info-panel__label">Location Source</text>
<text class="info-panel__value">{{locationSourceText}}</text>
</view>
<view class="info-panel__row info-panel__row--stack">
<text class="info-panel__label">GPS Coord</text>
<text class="info-panel__value">{{gpsCoordText}}</text>
</view>
<view class="info-panel__row">
<text class="info-panel__label">GPS Logo</text>
<text class="info-panel__value">{{gpsLogoStatusText}}</text>
</view>
<view class="info-panel__row info-panel__row--stack">
<text class="info-panel__label">GPS Logo Src</text>
<text class="info-panel__value">{{gpsLogoSourceText}}</text>
</view>
<view class="info-panel__row info-panel__row--stack">
<text class="info-panel__label">定位模拟状态</text>
<text class="info-panel__value">{{mockBridgeStatusText}}</text>
</view>
<view class="info-panel__row info-panel__row--stack">
<text class="info-panel__label">GPS Coord</text>
<text class="info-panel__value">{{gpsCoordText}}</text>
</view>
<view class="info-panel__row info-panel__row--stack">
<text class="info-panel__label">Mock Bridge</text>
<text class="info-panel__value">{{mockBridgeStatusText}}</text>
</view>
<view class="info-panel__row info-panel__row--stack">
<text class="info-panel__label">Mock URL</text>
<text class="info-panel__label">定位模拟地址</text>
<view class="debug-inline-stack">
<input
class="debug-input"
@@ -596,8 +837,8 @@
/>
<view class="control-row control-row--compact">
<view class="control-chip control-chip--secondary" bindtap="handleSaveMockBridgeUrl">保存地址</view>
<view class="control-chip {{mockBridgeConnected ? 'control-chip--active' : 'control-chip--secondary'}}" bindtap="handleConnectMockLocationBridge">连接模拟</view>
<view class="control-chip control-chip--secondary" bindtap="handleDisconnectMockLocationBridge">断开模拟</view>
<view class="control-chip {{mockBridgeConnected ? 'control-chip--active' : 'control-chip--secondary'}}" bindtap="handleConnectMockLocationBridge">连接定位模拟</view>
<view class="control-chip control-chip--secondary" bindtap="handleDisconnectMockLocationBridge">断开定位模拟</view>
</view>
</view>
</view>
@@ -616,7 +857,7 @@
<view class="control-chip {{locationSourceMode === 'real' ? 'control-chip--active' : 'control-chip--secondary'}}" bindtap="handleSetRealLocationMode">真实定位</view>
<view class="control-chip {{locationSourceMode === 'mock' ? 'control-chip--active' : 'control-chip--secondary'}}" bindtap="handleSetMockLocationMode">模拟定位</view>
</view>
<view class="debug-group-title">心率</view>
<view class="debug-group-title">心率模拟</view>
<view class="info-panel__row">
<text class="info-panel__label">Heart Rate</text>
<text class="info-panel__value">{{heartRateStatusText}}</text>
@@ -657,11 +898,11 @@
<view class="control-chip control-chip--secondary" bindtap="handleClearPreferredHeartRateDevice">清除首选</view>
</view>
<view class="info-panel__row info-panel__row--stack" wx:if="{{heartRateSourceMode === 'mock'}}">
<text class="info-panel__label">Mock HR Bridge</text>
<text class="info-panel__label">心率模拟状态</text>
<text class="info-panel__value">{{mockHeartRateBridgeStatusText}}</text>
</view>
<view class="info-panel__row info-panel__row--stack" wx:if="{{heartRateSourceMode === 'mock'}}">
<text class="info-panel__label">Mock HR URL</text>
<text class="info-panel__label">心率模拟地址</text>
<view class="debug-inline-stack">
<input
class="debug-input"
@@ -671,8 +912,8 @@
/>
<view class="control-row control-row--compact">
<view class="control-chip control-chip--secondary" bindtap="handleSaveMockHeartRateBridgeUrl">保存地址</view>
<view class="control-chip {{mockHeartRateBridgeConnected ? 'control-chip--active' : 'control-chip--secondary'}}" bindtap="handleConnectMockHeartRateBridge">连接模拟心率源</view>
<view class="control-chip control-chip--secondary" bindtap="handleDisconnectMockHeartRateBridge">断开模拟心率源</view>
<view class="control-chip {{mockHeartRateBridgeConnected ? 'control-chip--active' : 'control-chip--secondary'}}" bindtap="handleConnectMockHeartRateBridge">连接心率模拟</view>
<view class="control-chip control-chip--secondary" bindtap="handleDisconnectMockHeartRateBridge">断开心率模拟</view>
</view>
</view>
</view>
@@ -680,6 +921,27 @@
<text class="info-panel__label">Mock BPM</text>
<text class="info-panel__value">{{mockHeartRateText}}</text>
</view>
<view class="debug-group-title">调试日志</view>
<view class="info-panel__row info-panel__row--stack">
<text class="info-panel__label">日志通道状态</text>
<text class="info-panel__value">{{mockDebugLogBridgeStatusText}}</text>
</view>
<view class="info-panel__row info-panel__row--stack">
<text class="info-panel__label">日志通道地址</text>
<view class="debug-inline-stack">
<input
class="debug-input"
value="{{mockDebugLogBridgeUrlDraft}}"
placeholder="ws://192.168.x.x:17865/mock-gps"
bindinput="handleMockDebugLogBridgeUrlInput"
/>
<view class="control-row control-row--compact">
<view class="control-chip control-chip--secondary" bindtap="handleSaveMockDebugLogBridgeUrl">保存地址</view>
<view class="control-chip {{mockDebugLogBridgeConnected ? 'control-chip--active' : 'control-chip--secondary'}}" bindtap="handleConnectMockDebugLogBridge">连接日志通道</view>
<view class="control-chip control-chip--secondary" bindtap="handleDisconnectMockDebugLogBridge">断开日志通道</view>
</view>
</view>
</view>
<view class="debug-group-title">方向</view>
<view class="info-panel__row">
<text class="info-panel__label">Heading Mode</text>

View File

@@ -1783,6 +1783,17 @@
font-size: 22rpx;
}
.control-row--wrap {
flex-wrap: wrap;
}
.control-row--wrap .control-chip {
flex: none;
width: calc(25% - 12rpx);
font-size: 22rpx;
padding: 18rpx 8rpx;
}
.control-row--single .control-chip {
flex: none;
width: 100%;
@@ -2068,6 +2079,13 @@
justify-content: space-between;
}
.game-content-card__cta-group {
display: flex;
align-items: center;
gap: 14rpx;
flex-wrap: wrap;
}
.game-content-card__action {
display: inline-flex;
align-items: center;
@@ -2094,6 +2112,91 @@
font-weight: 600;
}
.game-content-quiz {
position: fixed;
inset: 0;
z-index: 75;
display: flex;
align-items: center;
justify-content: center;
background: rgba(18, 28, 24, 0.26);
}
.game-content-quiz__panel {
width: 500rpx;
max-width: calc(100vw - 96rpx);
padding: 30rpx 30rpx 26rpx;
border-radius: 30rpx;
background: rgba(250, 252, 251, 0.98);
box-shadow: 0 20rpx 52rpx rgba(18, 38, 31, 0.18);
display: flex;
flex-direction: column;
gap: 20rpx;
}
.game-content-quiz__header {
display: flex;
align-items: center;
justify-content: space-between;
}
.game-content-quiz__title {
font-size: 34rpx;
font-weight: 700;
color: #17372e;
}
.game-content-quiz__countdown {
min-width: 88rpx;
padding: 8rpx 18rpx;
border-radius: 999rpx;
background: rgba(227, 238, 231, 0.96);
text-align: center;
font-size: 28rpx;
font-weight: 600;
color: #33584d;
}
.game-content-quiz__question {
font-size: 44rpx;
line-height: 1.25;
font-weight: 700;
color: #17372e;
text-align: center;
}
.game-content-quiz__options {
display: flex;
flex-direction: column;
gap: 14rpx;
}
.game-content-quiz__option {
min-height: 76rpx;
border-radius: 22rpx;
background: rgba(233, 241, 236, 0.98);
color: #1d5a46;
display: flex;
align-items: center;
justify-content: center;
font-size: 34rpx;
font-weight: 600;
}
.game-content-quiz__feedback {
text-align: center;
font-size: 30rpx;
font-weight: 700;
}
.game-content-quiz__feedback--success {
color: #1f8e53;
}
.game-content-quiz__feedback--error {
color: #bf4b3a;
}
.game-content-card--fx-pop {
animation: content-card-pop 0.5s cubic-bezier(0.18, 0.88, 0.2, 1);
}