完善设置面板并整理动画阶段总结
This commit is contained in:
50
GeminiAnlysis.md
Normal file
50
GeminiAnlysis.md
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# CMR-Mini 项目深度分析报告 (GeminiAnalysis.md)
|
||||||
|
|
||||||
|
## 1. 项目定位与核心愿景
|
||||||
|
**CMR-Mini** 是一个运行在微信小程序环境中的高性能**定向越野 (Orienteering)** 实时竞赛/练习引擎。其核心竞争力在于通过自研的 **WebGL 地图渲染管线** 提供流畅的地图交互,并结合高精度多传感器融合技术(GPS、罗盘、心率、加速度计等)实现精准的运动反馈。
|
||||||
|
|
||||||
|
## 2. 核心系统架构分析
|
||||||
|
|
||||||
|
### 2.1 地图渲染引擎 (Map Engine)
|
||||||
|
* **渲染技术**:采用 `Single WebGL Pipeline`。相比微信原生地图组件,具有更高的定制化能力,特别是在“Heading-Up”(朝向朝上)模式下的性能表现。
|
||||||
|
* **瓦片管理**:通过 `TileStore` 实现三级缓存(内存 -> 磁盘 -> 网络),并支持 `tilePersistentCache`。
|
||||||
|
* **投影逻辑**:采用 `WGS84 -> WorldTile -> Camera -> Screen` 的标准 GIS 变换链,能够精准处理地理坐标到屏幕像素的映射。
|
||||||
|
|
||||||
|
### 2.2 传感器融合系统 (Sensor System)
|
||||||
|
* **CompassHeadingController**:核心逻辑在于罗盘数据 (`wx.onCompassChange`) 与设备姿态 (`wx.onDeviceMotionChange`) 的协同。
|
||||||
|
* **LocationController**:支持真实 GPS 数据与 Mock 模拟器(通过 WebSocket 连接 `mock-gps-sim` 工具)的无缝切换。
|
||||||
|
* **TelemetryRuntime**:实现了运动参数的实时计算,包括速度、距离目标点距离、心率分区等指标。
|
||||||
|
|
||||||
|
### 2.3 游戏逻辑与规则 (Game Logic)
|
||||||
|
* **GameRuntime**:驱动对局状态机,支持“顺序赛 (Classic Sequential)”与“积分赛 (Score-O)”。
|
||||||
|
* **PunchPolicy**:实现了自动进入检查点范围触发、手动打点、跳过点位等业务逻辑。
|
||||||
|
|
||||||
|
## 3. 指北针 (Compass) 平滑度瓶颈分析
|
||||||
|
根据目前的实现,指北针的卡顿感主要源于以下三个层面:
|
||||||
|
|
||||||
|
1. **采样频率与插值逻辑**:
|
||||||
|
* 目前使用 `interpolateHeadingDeg` 进行线性差值,且 `ABSOLUTE_HEADING_CORRECTION` 为固定系数 (0.44)。这种静态系数在“静态微调”时显得不够敏锐,在“快速旋转”时又显得滞后。
|
||||||
|
2. **Android/iOS 差异化丢帧**:
|
||||||
|
* Android 传感器回调频率不稳定。
|
||||||
|
* 逻辑中对 `direction` 进行了严格的数值有效性判断,若系统由于硬件抖动返回短时异常值,会导致视觉上的“跳帧”。
|
||||||
|
3. **UI 同步周期限制**:
|
||||||
|
* `MapEngine` 的 `UI_SYNC_INTERVAL_MS` 设置为 80ms,这意味着视觉反馈的最高帧率仅为 12.5Hz,远低于屏幕刷新率,导致指针转动不够丝滑。
|
||||||
|
|
||||||
|
## 4. 优化技术路线建议
|
||||||
|
|
||||||
|
### 4.1 引入指数加权移动平均 (EWMA) 的动态系数
|
||||||
|
建议根据旋转角速度动态调整平滑系数。当检测到瞬时角位移较大时,降低平滑度以追求响应速度;当位移较小时,增加平滑度以过滤手抖带来的噪声。
|
||||||
|
|
||||||
|
### 4.2 视觉平滑:使用 CSS Transform 或 WebGL 帧间补偿
|
||||||
|
目前数据是由控制器下发到 UI 的。建议:
|
||||||
|
* **方案 A (推荐)**:在 UI 层(`.wxml`/`.wxss`)利用 `transition: transform 0.1s linear;` 实现视觉层面的自动补帧。
|
||||||
|
* **方案 B**:在 WebGL 渲染循环内进行帧间插值,将数据的 12.5Hz 提升到 渲染循环的 60Hz。
|
||||||
|
|
||||||
|
### 4.3 预测与死区 (Dead-zone) 过滤
|
||||||
|
在 `CompassHeadingController` 中加入微小位移的死区过滤逻辑,避免由于硬件高频微小抖动导致的视图高频重绘,降低系统功耗的同时提升视觉稳定性。
|
||||||
|
|
||||||
|
## 5. 结论
|
||||||
|
CMR-Mini 已经建立了一个非常坚实的专业定向越野引擎基础。后续的优化重点应从“功能的实现”转向“交互的极致平滑”,特别是针对指北针这类核心导向组件,需要更精细化的信号处理策略。
|
||||||
|
|
||||||
|
---
|
||||||
|
*Generated by Gemini CLI Analysis Tool*
|
||||||
192
animation-pipeline-summary.md
Normal file
192
animation-pipeline-summary.md
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
# 动画体系阶段性小结
|
||||||
|
|
||||||
|
## 1. 当前定位
|
||||||
|
|
||||||
|
目前动画体系已经从“页面里临时加 class”的阶段,进入了**有主链、有分层、有性能分级**的阶段。
|
||||||
|
|
||||||
|
当前主链可以概括为:
|
||||||
|
|
||||||
|
- 事件触发
|
||||||
|
- `feedbackConfig`
|
||||||
|
- `UiEffectDirector`
|
||||||
|
- `FeedbackDirector`
|
||||||
|
- `MapEngine`
|
||||||
|
- 页面层 / 渲染层消费
|
||||||
|
|
||||||
|
也就是:
|
||||||
|
|
||||||
|
**事件 -> 效果配置 -> 宿主提交 -> 页面 / Renderer 落地**
|
||||||
|
|
||||||
|
这说明动画已经不再是零散实现,而开始进入架构化管理。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 已经完成的内容
|
||||||
|
|
||||||
|
### 2.1 HUD 动效
|
||||||
|
|
||||||
|
已经完成:
|
||||||
|
|
||||||
|
- 打点成功后的 `进度` 动效
|
||||||
|
- 打点成功后的 `点距` 动效
|
||||||
|
- HUD 数字轻量过渡:
|
||||||
|
- 计时
|
||||||
|
- 里程
|
||||||
|
- 速度
|
||||||
|
- 心率
|
||||||
|
|
||||||
|
这些动效已经接入正式链路,不是页面单独临时处理。
|
||||||
|
|
||||||
|
### 2.2 地图空间动画
|
||||||
|
|
||||||
|
已经完成:
|
||||||
|
|
||||||
|
- 当前目标点状态强调
|
||||||
|
- 可打点状态强调
|
||||||
|
- 已完成点状态过渡
|
||||||
|
- 已跳过点灰态与标记
|
||||||
|
- 开始点 / 终点完成后的 settle 外环
|
||||||
|
- 轻量地图 pulse
|
||||||
|
|
||||||
|
### 2.3 局部 UI / Stage 动效
|
||||||
|
|
||||||
|
已经完成:
|
||||||
|
|
||||||
|
- 轻量 stage flash
|
||||||
|
- 顶部提示和局部反馈的基础动画承载链
|
||||||
|
|
||||||
|
### 2.4 动画性能分级
|
||||||
|
|
||||||
|
已经完成 2 级动画分级:
|
||||||
|
|
||||||
|
- `standard`
|
||||||
|
- `lite`
|
||||||
|
|
||||||
|
当前 `lite` 的主要策略包括:
|
||||||
|
|
||||||
|
- 减少 pulse 层数
|
||||||
|
- 降低几何分段
|
||||||
|
- 降低渲染动画频率
|
||||||
|
- 关闭部分 HUD 动画
|
||||||
|
- 关闭或减弱某些 stage/UI 动效
|
||||||
|
|
||||||
|
这意味着动画体系已经开始考虑**低端机表现**,不是只追求效果。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 当前架构上的价值
|
||||||
|
|
||||||
|
动画体系现在已经带来了几个明确收益:
|
||||||
|
|
||||||
|
- 动效不再散落在多个页面细节里
|
||||||
|
- 高频状态变化有了统一反馈语言
|
||||||
|
- 地图状态和 HUD 状态开始形成一致体验
|
||||||
|
- 性能分级已经进入体系,可服务低端机
|
||||||
|
|
||||||
|
从架构角度看,这意味着:
|
||||||
|
|
||||||
|
**动画已经成为正式能力层,而不是临时视觉补丁。**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 当前还不够完整的地方
|
||||||
|
|
||||||
|
虽然主链已经成型,但当前还没有完全形成“动画字典”和完整 profile 体系。
|
||||||
|
|
||||||
|
目前仍然存在这些不足:
|
||||||
|
|
||||||
|
- 哪些事件触发哪些动画,还没有整理成统一字典
|
||||||
|
- 部分高频状态切换还不够连续
|
||||||
|
- `跳点` 已有逻辑和状态,但动画语言还不完整
|
||||||
|
- 危险/高压状态动画还没有正式开始
|
||||||
|
- 动画 profile 还没有真正配置化
|
||||||
|
|
||||||
|
所以当前阶段可以定义为:
|
||||||
|
|
||||||
|
**第一阶段后半段:主链已成型,但还需要把高频体验打磨完整。**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 下一阶段最值得做的事情
|
||||||
|
|
||||||
|
### 5.1 先整理动画字典
|
||||||
|
|
||||||
|
建议先把动画按事件梳理出来,例如:
|
||||||
|
|
||||||
|
- `session_started`
|
||||||
|
- `control_ready`
|
||||||
|
- `control_completed:start`
|
||||||
|
- `control_completed:control`
|
||||||
|
- `control_completed:finish`
|
||||||
|
- `control_skipped`
|
||||||
|
- `gps_lock_changed`
|
||||||
|
- `guidance_state_changed`
|
||||||
|
- `heart_rate_zone_changed`
|
||||||
|
|
||||||
|
并明确每个事件对应:
|
||||||
|
|
||||||
|
- 地图动画
|
||||||
|
- HUD 动画
|
||||||
|
- UI 动画
|
||||||
|
- `lite` 下是否保留
|
||||||
|
|
||||||
|
这一步是当前最值得优先完成的工作。
|
||||||
|
|
||||||
|
### 5.2 补完整“目标状态切换连续感”
|
||||||
|
|
||||||
|
继续打磨:
|
||||||
|
|
||||||
|
- 当前目标
|
||||||
|
- 进入可打点
|
||||||
|
- 打点成功
|
||||||
|
- 切到下一个目标
|
||||||
|
|
||||||
|
让这一整段切换更连贯、更有节奏。
|
||||||
|
|
||||||
|
### 5.3 补齐“跳点”动画
|
||||||
|
|
||||||
|
建议下一步把跳点也正式纳入动画体系:
|
||||||
|
|
||||||
|
- 跳点确认后
|
||||||
|
- 当前点灰化
|
||||||
|
- 下一个目标接管强调
|
||||||
|
- HUD 给出轻量反馈
|
||||||
|
|
||||||
|
### 5.4 再做危险 / 高压反馈
|
||||||
|
|
||||||
|
这部分适合进入下一阶段:
|
||||||
|
|
||||||
|
- 高心率反馈
|
||||||
|
- 危险区反馈
|
||||||
|
- 幽灵追逐反馈
|
||||||
|
- 边缘呼吸 / 紧张感动效
|
||||||
|
|
||||||
|
这条线很适合后续玩法扩展。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. 建议的实施顺序
|
||||||
|
|
||||||
|
推荐继续推进的顺序:
|
||||||
|
|
||||||
|
1. 动画字典整理
|
||||||
|
2. 目标切换连续感补齐
|
||||||
|
3. 跳点动画补齐
|
||||||
|
4. 危险 / 高压状态动画
|
||||||
|
5. 更进一步的配置化 profile
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. 结论
|
||||||
|
|
||||||
|
当前动画体系已经是一个明确的阶段性成果:
|
||||||
|
|
||||||
|
- 有主链
|
||||||
|
- 有分层
|
||||||
|
- 有高频核心动画
|
||||||
|
- 有性能分级
|
||||||
|
|
||||||
|
接下来最该做的不是“继续零散加动画”,而是:
|
||||||
|
|
||||||
|
**把现有能力收成动画字典,并优先打磨目标切换与跳点这两条高频体验链。**
|
||||||
|
|
||||||
@@ -59,6 +59,7 @@ const AUTO_ROTATE_MAX_STEP_DEG = 0.75
|
|||||||
const AUTO_ROTATE_HEADING_SMOOTHING = 0.46
|
const AUTO_ROTATE_HEADING_SMOOTHING = 0.46
|
||||||
const COMPASS_NEEDLE_FRAME_MS = 16
|
const COMPASS_NEEDLE_FRAME_MS = 16
|
||||||
const COMPASS_NEEDLE_SNAP_DEG = 0.08
|
const COMPASS_NEEDLE_SNAP_DEG = 0.08
|
||||||
|
const COMPASS_BOOTSTRAP_RETRY_DELAY_MS = 700
|
||||||
const COMPASS_TUNING_PRESETS: Record<CompassTuningProfile, {
|
const COMPASS_TUNING_PRESETS: Record<CompassTuningProfile, {
|
||||||
needleMinSmoothing: number
|
needleMinSmoothing: number
|
||||||
needleMaxSmoothing: number
|
needleMaxSmoothing: number
|
||||||
@@ -830,6 +831,7 @@ export class MapEngine {
|
|||||||
viewSyncTimer: number
|
viewSyncTimer: number
|
||||||
autoRotateTimer: number
|
autoRotateTimer: number
|
||||||
compassNeedleTimer: number
|
compassNeedleTimer: number
|
||||||
|
compassBootstrapRetryTimer: number
|
||||||
pendingViewPatch: Partial<MapEngineViewState>
|
pendingViewPatch: Partial<MapEngineViewState>
|
||||||
mounted: boolean
|
mounted: boolean
|
||||||
diagnosticUiEnabled: boolean
|
diagnosticUiEnabled: boolean
|
||||||
@@ -838,6 +840,7 @@ export class MapEngine {
|
|||||||
smoothedSensorHeadingDeg: number | null
|
smoothedSensorHeadingDeg: number | null
|
||||||
compassDisplayHeadingDeg: number | null
|
compassDisplayHeadingDeg: number | null
|
||||||
targetCompassDisplayHeadingDeg: number | null
|
targetCompassDisplayHeadingDeg: number | null
|
||||||
|
lastCompassSampleAt: number
|
||||||
compassSource: 'compass' | 'motion' | null
|
compassSource: 'compass' | 'motion' | null
|
||||||
compassTuningProfile: CompassTuningProfile
|
compassTuningProfile: CompassTuningProfile
|
||||||
smoothedMovementHeadingDeg: number | null
|
smoothedMovementHeadingDeg: number | null
|
||||||
@@ -1282,6 +1285,7 @@ export class MapEngine {
|
|||||||
this.viewSyncTimer = 0
|
this.viewSyncTimer = 0
|
||||||
this.autoRotateTimer = 0
|
this.autoRotateTimer = 0
|
||||||
this.compassNeedleTimer = 0
|
this.compassNeedleTimer = 0
|
||||||
|
this.compassBootstrapRetryTimer = 0
|
||||||
this.pendingViewPatch = {}
|
this.pendingViewPatch = {}
|
||||||
this.mounted = false
|
this.mounted = false
|
||||||
this.diagnosticUiEnabled = false
|
this.diagnosticUiEnabled = false
|
||||||
@@ -1290,6 +1294,7 @@ export class MapEngine {
|
|||||||
this.smoothedSensorHeadingDeg = null
|
this.smoothedSensorHeadingDeg = null
|
||||||
this.compassDisplayHeadingDeg = null
|
this.compassDisplayHeadingDeg = null
|
||||||
this.targetCompassDisplayHeadingDeg = null
|
this.targetCompassDisplayHeadingDeg = null
|
||||||
|
this.lastCompassSampleAt = 0
|
||||||
this.compassSource = null
|
this.compassSource = null
|
||||||
this.compassTuningProfile = 'balanced'
|
this.compassTuningProfile = 'balanced'
|
||||||
this.smoothedMovementHeadingDeg = null
|
this.smoothedMovementHeadingDeg = null
|
||||||
@@ -1406,6 +1411,7 @@ export class MapEngine {
|
|||||||
this.clearViewSyncTimer()
|
this.clearViewSyncTimer()
|
||||||
this.clearAutoRotateTimer()
|
this.clearAutoRotateTimer()
|
||||||
this.clearCompassNeedleTimer()
|
this.clearCompassNeedleTimer()
|
||||||
|
this.clearCompassBootstrapRetryTimer()
|
||||||
this.clearPunchFeedbackTimer()
|
this.clearPunchFeedbackTimer()
|
||||||
this.clearContentCardTimer()
|
this.clearContentCardTimer()
|
||||||
this.clearMapPulseTimer()
|
this.clearMapPulseTimer()
|
||||||
@@ -1424,6 +1430,11 @@ export class MapEngine {
|
|||||||
|
|
||||||
handleAppShow(): void {
|
handleAppShow(): void {
|
||||||
this.feedbackDirector.setAppAudioMode('foreground')
|
this.feedbackDirector.setAppAudioMode('foreground')
|
||||||
|
if (this.mounted) {
|
||||||
|
this.lastCompassSampleAt = 0
|
||||||
|
this.compassController.start()
|
||||||
|
this.scheduleCompassBootstrapRetry()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleAppHide(): void {
|
handleAppHide(): void {
|
||||||
@@ -2351,7 +2362,9 @@ export class MapEngine {
|
|||||||
})
|
})
|
||||||
this.syncRenderer()
|
this.syncRenderer()
|
||||||
this.accelerometerErrorText = null
|
this.accelerometerErrorText = null
|
||||||
|
this.lastCompassSampleAt = 0
|
||||||
this.compassController.start()
|
this.compassController.start()
|
||||||
|
this.scheduleCompassBootstrapRetry()
|
||||||
this.gyroscopeController.start()
|
this.gyroscopeController.start()
|
||||||
this.deviceMotionController.start()
|
this.deviceMotionController.start()
|
||||||
}
|
}
|
||||||
@@ -2980,6 +2993,8 @@ export class MapEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleCompassHeading(headingDeg: number): void {
|
handleCompassHeading(headingDeg: number): void {
|
||||||
|
this.lastCompassSampleAt = Date.now()
|
||||||
|
this.clearCompassBootstrapRetryTimer()
|
||||||
this.applyHeadingSample(headingDeg, 'compass')
|
this.applyHeadingSample(headingDeg, 'compass')
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3584,6 +3599,29 @@ export class MapEngine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clearCompassBootstrapRetryTimer(): void {
|
||||||
|
if (this.compassBootstrapRetryTimer) {
|
||||||
|
clearTimeout(this.compassBootstrapRetryTimer)
|
||||||
|
this.compassBootstrapRetryTimer = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scheduleCompassBootstrapRetry(): void {
|
||||||
|
this.clearCompassBootstrapRetryTimer()
|
||||||
|
if (!this.mounted) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.compassBootstrapRetryTimer = setTimeout(() => {
|
||||||
|
this.compassBootstrapRetryTimer = 0
|
||||||
|
if (!this.mounted || this.lastCompassSampleAt > 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.compassController.stop()
|
||||||
|
this.compassController.start()
|
||||||
|
}, COMPASS_BOOTSTRAP_RETRY_DELAY_MS) as unknown as number
|
||||||
|
}
|
||||||
|
|
||||||
syncCompassDisplayState(): void {
|
syncCompassDisplayState(): void {
|
||||||
this.setState({
|
this.setState({
|
||||||
compassNeedleDeg: formatCompassNeedleDegForMode(this.northReferenceMode, this.compassDisplayHeadingDeg),
|
compassNeedleDeg: formatCompassNeedleDegForMode(this.northReferenceMode, this.compassDisplayHeadingDeg),
|
||||||
|
|||||||
@@ -29,15 +29,37 @@ type ScaleRulerMajorMarkData = {
|
|||||||
topPx: number
|
topPx: number
|
||||||
label: string
|
label: string
|
||||||
}
|
}
|
||||||
type SideButtonMode = 'all' | 'left' | 'right' | 'hidden'
|
type SideButtonMode = 'shown' | 'hidden'
|
||||||
type SideActionButtonState = 'muted' | 'default' | 'active'
|
type SideActionButtonState = 'muted' | 'default' | 'active'
|
||||||
|
type SideButtonPlacement = 'left' | 'right'
|
||||||
type CenterScaleRulerAnchorMode = 'screen-center' | 'compass-center'
|
type CenterScaleRulerAnchorMode = 'screen-center' | 'compass-center'
|
||||||
type UserNorthReferenceMode = 'magnetic' | 'true'
|
type UserNorthReferenceMode = 'magnetic' | 'true'
|
||||||
|
type CompassTuningProfile = 'smooth' | 'balanced' | 'responsive'
|
||||||
|
type SettingLockKey =
|
||||||
|
| 'lockAnimationLevel'
|
||||||
|
| 'lockSideButtonPlacement'
|
||||||
|
| 'lockAutoRotate'
|
||||||
|
| 'lockCompassTuning'
|
||||||
|
| 'lockScaleRulerVisible'
|
||||||
|
| 'lockScaleRulerAnchor'
|
||||||
|
| 'lockNorthReference'
|
||||||
|
| 'lockHeartRateDevice'
|
||||||
type StoredUserSettings = {
|
type StoredUserSettings = {
|
||||||
animationLevel?: AnimationLevel
|
animationLevel?: AnimationLevel
|
||||||
|
autoRotateEnabled?: boolean
|
||||||
|
compassTuningProfile?: CompassTuningProfile
|
||||||
northReferenceMode?: UserNorthReferenceMode
|
northReferenceMode?: UserNorthReferenceMode
|
||||||
|
sideButtonPlacement?: SideButtonPlacement
|
||||||
showCenterScaleRuler?: boolean
|
showCenterScaleRuler?: boolean
|
||||||
centerScaleRulerAnchorMode?: CenterScaleRulerAnchorMode
|
centerScaleRulerAnchorMode?: CenterScaleRulerAnchorMode
|
||||||
|
lockAnimationLevel?: boolean
|
||||||
|
lockSideButtonPlacement?: boolean
|
||||||
|
lockAutoRotate?: boolean
|
||||||
|
lockCompassTuning?: boolean
|
||||||
|
lockScaleRulerVisible?: boolean
|
||||||
|
lockScaleRulerAnchor?: boolean
|
||||||
|
lockNorthReference?: boolean
|
||||||
|
lockHeartRateDevice?: boolean
|
||||||
}
|
}
|
||||||
type MapPageData = MapEngineViewState & {
|
type MapPageData = MapEngineViewState & {
|
||||||
showDebugPanel: boolean
|
showDebugPanel: boolean
|
||||||
@@ -68,6 +90,16 @@ type MapPageData = MapEngineViewState & {
|
|||||||
compassTicks: CompassTickData[]
|
compassTicks: CompassTickData[]
|
||||||
compassLabels: CompassLabelData[]
|
compassLabels: CompassLabelData[]
|
||||||
sideButtonMode: SideButtonMode
|
sideButtonMode: SideButtonMode
|
||||||
|
sideButtonPlacement: SideButtonPlacement
|
||||||
|
autoRotateEnabled: boolean
|
||||||
|
lockAnimationLevel: boolean
|
||||||
|
lockSideButtonPlacement: boolean
|
||||||
|
lockAutoRotate: boolean
|
||||||
|
lockCompassTuning: boolean
|
||||||
|
lockScaleRulerVisible: boolean
|
||||||
|
lockScaleRulerAnchor: boolean
|
||||||
|
lockNorthReference: boolean
|
||||||
|
lockHeartRateDevice: boolean
|
||||||
sideToggleIconSrc: string
|
sideToggleIconSrc: string
|
||||||
sideButton2Class: string
|
sideButton2Class: string
|
||||||
sideButton4Class: string
|
sideButton4Class: string
|
||||||
@@ -334,12 +366,45 @@ function loadStoredUserSettings(): StoredUserSettings {
|
|||||||
if (normalized.northReferenceMode === 'magnetic' || normalized.northReferenceMode === 'true') {
|
if (normalized.northReferenceMode === 'magnetic' || normalized.northReferenceMode === 'true') {
|
||||||
settings.northReferenceMode = normalized.northReferenceMode
|
settings.northReferenceMode = normalized.northReferenceMode
|
||||||
}
|
}
|
||||||
|
if (typeof normalized.autoRotateEnabled === 'boolean') {
|
||||||
|
settings.autoRotateEnabled = normalized.autoRotateEnabled
|
||||||
|
}
|
||||||
|
if (normalized.compassTuningProfile === 'smooth' || normalized.compassTuningProfile === 'balanced' || normalized.compassTuningProfile === 'responsive') {
|
||||||
|
settings.compassTuningProfile = normalized.compassTuningProfile
|
||||||
|
}
|
||||||
|
if (normalized.sideButtonPlacement === 'left' || normalized.sideButtonPlacement === 'right') {
|
||||||
|
settings.sideButtonPlacement = normalized.sideButtonPlacement
|
||||||
|
}
|
||||||
if (typeof normalized.showCenterScaleRuler === 'boolean') {
|
if (typeof normalized.showCenterScaleRuler === 'boolean') {
|
||||||
settings.showCenterScaleRuler = normalized.showCenterScaleRuler
|
settings.showCenterScaleRuler = normalized.showCenterScaleRuler
|
||||||
}
|
}
|
||||||
if (normalized.centerScaleRulerAnchorMode === 'screen-center' || normalized.centerScaleRulerAnchorMode === 'compass-center') {
|
if (normalized.centerScaleRulerAnchorMode === 'screen-center' || normalized.centerScaleRulerAnchorMode === 'compass-center') {
|
||||||
settings.centerScaleRulerAnchorMode = normalized.centerScaleRulerAnchorMode
|
settings.centerScaleRulerAnchorMode = normalized.centerScaleRulerAnchorMode
|
||||||
}
|
}
|
||||||
|
if (typeof normalized.lockAnimationLevel === 'boolean') {
|
||||||
|
settings.lockAnimationLevel = normalized.lockAnimationLevel
|
||||||
|
}
|
||||||
|
if (typeof normalized.lockSideButtonPlacement === 'boolean') {
|
||||||
|
settings.lockSideButtonPlacement = normalized.lockSideButtonPlacement
|
||||||
|
}
|
||||||
|
if (typeof normalized.lockAutoRotate === 'boolean') {
|
||||||
|
settings.lockAutoRotate = normalized.lockAutoRotate
|
||||||
|
}
|
||||||
|
if (typeof normalized.lockCompassTuning === 'boolean') {
|
||||||
|
settings.lockCompassTuning = normalized.lockCompassTuning
|
||||||
|
}
|
||||||
|
if (typeof normalized.lockScaleRulerVisible === 'boolean') {
|
||||||
|
settings.lockScaleRulerVisible = normalized.lockScaleRulerVisible
|
||||||
|
}
|
||||||
|
if (typeof normalized.lockScaleRulerAnchor === 'boolean') {
|
||||||
|
settings.lockScaleRulerAnchor = normalized.lockScaleRulerAnchor
|
||||||
|
}
|
||||||
|
if (typeof normalized.lockNorthReference === 'boolean') {
|
||||||
|
settings.lockNorthReference = normalized.lockNorthReference
|
||||||
|
}
|
||||||
|
if (typeof normalized.lockHeartRateDevice === 'boolean') {
|
||||||
|
settings.lockHeartRateDevice = normalized.lockHeartRateDevice
|
||||||
|
}
|
||||||
return settings
|
return settings
|
||||||
} catch {
|
} catch {
|
||||||
return {}
|
return {}
|
||||||
@@ -351,26 +416,24 @@ function persistStoredUserSettings(settings: StoredUserSettings) {
|
|||||||
wx.setStorageSync(USER_SETTINGS_STORAGE_KEY, settings)
|
wx.setStorageSync(USER_SETTINGS_STORAGE_KEY, settings)
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleStoredSettingLock(settings: StoredUserSettings, key: SettingLockKey): StoredUserSettings {
|
||||||
|
return {
|
||||||
|
...settings,
|
||||||
|
[key]: !settings[key],
|
||||||
|
}
|
||||||
|
}
|
||||||
function buildSideButtonVisibility(mode: SideButtonMode) {
|
function buildSideButtonVisibility(mode: SideButtonMode) {
|
||||||
return {
|
return {
|
||||||
sideButtonMode: mode,
|
sideButtonMode: mode,
|
||||||
showLeftButtonGroup: mode === 'all' || mode === 'left' || mode === 'right',
|
showLeftButtonGroup: mode === 'shown',
|
||||||
showRightButtonGroups: mode === 'all' || mode === 'right',
|
showRightButtonGroups: false,
|
||||||
showBottomDebugButton: mode !== 'hidden',
|
showBottomDebugButton: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNextSideButtonMode(currentMode: SideButtonMode): SideButtonMode {
|
function getNextSideButtonMode(currentMode: SideButtonMode): SideButtonMode {
|
||||||
if (currentMode === 'all') {
|
return currentMode === 'shown' ? 'hidden' : 'shown'
|
||||||
return 'left'
|
|
||||||
}
|
|
||||||
if (currentMode === 'left') {
|
|
||||||
return 'right'
|
|
||||||
}
|
|
||||||
if (currentMode === 'right') {
|
|
||||||
return 'hidden'
|
|
||||||
}
|
|
||||||
return 'left'
|
|
||||||
}
|
}
|
||||||
function buildCompassTicks(): CompassTickData[] {
|
function buildCompassTicks(): CompassTickData[] {
|
||||||
const ticks: CompassTickData[] = []
|
const ticks: CompassTickData[] = []
|
||||||
@@ -409,9 +472,6 @@ function getFallbackStageRect(): MapEngineStageRect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getSideToggleIconSrc(mode: SideButtonMode): string {
|
function getSideToggleIconSrc(mode: SideButtonMode): string {
|
||||||
if (mode === 'left') {
|
|
||||||
return '../../assets/btn_more2.png'
|
|
||||||
}
|
|
||||||
if (mode === 'hidden') {
|
if (mode === 'hidden') {
|
||||||
return '../../assets/btn_more1.png'
|
return '../../assets/btn_more1.png'
|
||||||
}
|
}
|
||||||
@@ -641,6 +701,15 @@ Page({
|
|||||||
hudPanelIndex: 0,
|
hudPanelIndex: 0,
|
||||||
configSourceText: '顺序赛配置',
|
configSourceText: '顺序赛配置',
|
||||||
centerScaleRulerAnchorMode: 'screen-center',
|
centerScaleRulerAnchorMode: 'screen-center',
|
||||||
|
autoRotateEnabled: false,
|
||||||
|
lockAnimationLevel: false,
|
||||||
|
lockSideButtonPlacement: false,
|
||||||
|
lockAutoRotate: false,
|
||||||
|
lockCompassTuning: false,
|
||||||
|
lockScaleRulerVisible: false,
|
||||||
|
lockScaleRulerAnchor: false,
|
||||||
|
lockNorthReference: false,
|
||||||
|
lockHeartRateDevice: false,
|
||||||
gameInfoTitle: '当前游戏',
|
gameInfoTitle: '当前游戏',
|
||||||
gameInfoSubtitle: '未开始',
|
gameInfoSubtitle: '未开始',
|
||||||
gameInfoLocalRows: [],
|
gameInfoLocalRows: [],
|
||||||
@@ -653,6 +722,7 @@ Page({
|
|||||||
panelDistanceUnitText: '',
|
panelDistanceUnitText: '',
|
||||||
panelProgressText: '0/0',
|
panelProgressText: '0/0',
|
||||||
showPunchHintBanner: true,
|
showPunchHintBanner: true,
|
||||||
|
sideButtonPlacement: 'left',
|
||||||
gameSessionStatus: 'idle',
|
gameSessionStatus: 'idle',
|
||||||
gameModeText: '顺序赛',
|
gameModeText: '顺序赛',
|
||||||
gpsLockEnabled: false,
|
gpsLockEnabled: false,
|
||||||
@@ -730,9 +800,9 @@ Page({
|
|||||||
centerScaleRulerMajorMarks: [],
|
centerScaleRulerMajorMarks: [],
|
||||||
compassTicks: buildCompassTicks(),
|
compassTicks: buildCompassTicks(),
|
||||||
compassLabels: buildCompassLabels(),
|
compassLabels: buildCompassLabels(),
|
||||||
...buildSideButtonVisibility('left'),
|
...buildSideButtonVisibility('shown'),
|
||||||
...buildSideButtonState({
|
...buildSideButtonState({
|
||||||
sideButtonMode: 'left',
|
sideButtonMode: 'shown',
|
||||||
showGameInfoPanel: false,
|
showGameInfoPanel: false,
|
||||||
showSystemSettingsPanel: false,
|
showSystemSettingsPanel: false,
|
||||||
showCenterScaleRuler: false,
|
showCenterScaleRuler: false,
|
||||||
@@ -787,6 +857,9 @@ Page({
|
|||||||
} as MapPageData
|
} as MapPageData
|
||||||
|
|
||||||
const derivedPatch: Partial<MapPageData> = {}
|
const derivedPatch: Partial<MapPageData> = {}
|
||||||
|
if (typeof nextPatch.orientationMode === 'string') {
|
||||||
|
nextData.autoRotateEnabled = nextPatch.orientationMode === 'heading-up'
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
this.data.showCenterScaleRuler
|
this.data.showCenterScaleRuler
|
||||||
&& hasAnyPatchKey(nextPatch as Record<string, unknown>, CENTER_SCALE_RULER_DEP_KEYS)
|
&& hasAnyPatchKey(nextPatch as Record<string, unknown>, CENTER_SCALE_RULER_DEP_KEYS)
|
||||||
@@ -886,9 +959,19 @@ Page({
|
|||||||
if (storedUserSettings.animationLevel) {
|
if (storedUserSettings.animationLevel) {
|
||||||
mapEngine.handleSetAnimationLevel(storedUserSettings.animationLevel)
|
mapEngine.handleSetAnimationLevel(storedUserSettings.animationLevel)
|
||||||
}
|
}
|
||||||
|
const initialAutoRotateEnabled = storedUserSettings.autoRotateEnabled !== false
|
||||||
|
if (initialAutoRotateEnabled) {
|
||||||
|
mapEngine.handleSetHeadingUpMode()
|
||||||
|
} else {
|
||||||
|
mapEngine.handleSetManualMode()
|
||||||
|
}
|
||||||
|
if (storedUserSettings.compassTuningProfile) {
|
||||||
|
mapEngine.handleSetCompassTuningProfile(storedUserSettings.compassTuningProfile)
|
||||||
|
}
|
||||||
if (storedUserSettings.northReferenceMode) {
|
if (storedUserSettings.northReferenceMode) {
|
||||||
mapEngine.handleSetNorthReferenceMode(storedUserSettings.northReferenceMode)
|
mapEngine.handleSetNorthReferenceMode(storedUserSettings.northReferenceMode)
|
||||||
}
|
}
|
||||||
|
const initialSideButtonPlacement = storedUserSettings.sideButtonPlacement || 'left'
|
||||||
|
|
||||||
mapEngine.setDiagnosticUiEnabled(false)
|
mapEngine.setDiagnosticUiEnabled(false)
|
||||||
centerScaleRulerInputCache = {
|
centerScaleRulerInputCache = {
|
||||||
@@ -914,6 +997,16 @@ Page({
|
|||||||
hudPanelIndex: 0,
|
hudPanelIndex: 0,
|
||||||
configSourceText: '顺序赛配置',
|
configSourceText: '顺序赛配置',
|
||||||
centerScaleRulerAnchorMode: initialCenterScaleRulerAnchorMode,
|
centerScaleRulerAnchorMode: initialCenterScaleRulerAnchorMode,
|
||||||
|
autoRotateEnabled: initialAutoRotateEnabled,
|
||||||
|
lockAnimationLevel: !!storedUserSettings.lockAnimationLevel,
|
||||||
|
lockSideButtonPlacement: !!storedUserSettings.lockSideButtonPlacement,
|
||||||
|
lockAutoRotate: !!storedUserSettings.lockAutoRotate,
|
||||||
|
lockCompassTuning: !!storedUserSettings.lockCompassTuning,
|
||||||
|
lockScaleRulerVisible: !!storedUserSettings.lockScaleRulerVisible,
|
||||||
|
lockScaleRulerAnchor: !!storedUserSettings.lockScaleRulerAnchor,
|
||||||
|
lockNorthReference: !!storedUserSettings.lockNorthReference,
|
||||||
|
lockHeartRateDevice: !!storedUserSettings.lockHeartRateDevice,
|
||||||
|
sideButtonPlacement: initialSideButtonPlacement,
|
||||||
gameInfoTitle: '当前游戏',
|
gameInfoTitle: '当前游戏',
|
||||||
gameInfoSubtitle: '未开始',
|
gameInfoSubtitle: '未开始',
|
||||||
gameInfoLocalRows: [],
|
gameInfoLocalRows: [],
|
||||||
@@ -996,9 +1089,9 @@ Page({
|
|||||||
stageFxClass: '',
|
stageFxClass: '',
|
||||||
compassTicks: buildCompassTicks(),
|
compassTicks: buildCompassTicks(),
|
||||||
compassLabels: buildCompassLabels(),
|
compassLabels: buildCompassLabels(),
|
||||||
...buildSideButtonVisibility('left'),
|
...buildSideButtonVisibility('shown'),
|
||||||
...buildSideButtonState({
|
...buildSideButtonState({
|
||||||
sideButtonMode: 'left',
|
sideButtonMode: 'shown',
|
||||||
showGameInfoPanel: false,
|
showGameInfoPanel: false,
|
||||||
showSystemSettingsPanel: false,
|
showSystemSettingsPanel: false,
|
||||||
showCenterScaleRuler: initialShowCenterScaleRuler,
|
showCenterScaleRuler: initialShowCenterScaleRuler,
|
||||||
@@ -1218,24 +1311,6 @@ Page({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
handleSetCompassTuningSmooth() {
|
|
||||||
if (mapEngine) {
|
|
||||||
mapEngine.handleSetCompassTuningProfile('smooth')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
handleSetCompassTuningBalanced() {
|
|
||||||
if (mapEngine) {
|
|
||||||
mapEngine.handleSetCompassTuningProfile('balanced')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
handleSetCompassTuningResponsive() {
|
|
||||||
if (mapEngine) {
|
|
||||||
mapEngine.handleSetCompassTuningProfile('responsive')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
handleAutoRotateCalibrate() {
|
handleAutoRotateCalibrate() {
|
||||||
if (mapEngine) {
|
if (mapEngine) {
|
||||||
mapEngine.handleAutoRotateCalibrate()
|
mapEngine.handleAutoRotateCalibrate()
|
||||||
@@ -1339,6 +1414,9 @@ Page({
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleClearPreferredHeartRateDevice() {
|
handleClearPreferredHeartRateDevice() {
|
||||||
|
if (this.data.lockHeartRateDevice) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if (mapEngine) {
|
if (mapEngine) {
|
||||||
mapEngine.handleClearPreferredHeartRateDevice()
|
mapEngine.handleClearPreferredHeartRateDevice()
|
||||||
}
|
}
|
||||||
@@ -1462,6 +1540,7 @@ Page({
|
|||||||
const localRows = snapshot.localRows.concat([
|
const localRows = snapshot.localRows.concat([
|
||||||
{ label: '比例尺开关', value: this.data.showCenterScaleRuler ? '开启' : '关闭' },
|
{ label: '比例尺开关', value: this.data.showCenterScaleRuler ? '开启' : '关闭' },
|
||||||
{ label: '比例尺锚点', value: this.data.centerScaleRulerAnchorMode === 'compass-center' ? '指北针圆心' : '屏幕中心' },
|
{ label: '比例尺锚点', value: this.data.centerScaleRulerAnchorMode === 'compass-center' ? '指北针圆心' : '屏幕中心' },
|
||||||
|
{ label: '按钮习惯', value: this.data.sideButtonPlacement === 'right' ? '右手' : '左手' },
|
||||||
{ label: '比例尺可见', value: this.data.centerScaleRulerVisible ? 'true' : 'false' },
|
{ label: '比例尺可见', value: this.data.centerScaleRulerVisible ? 'true' : 'false' },
|
||||||
{ label: '比例尺中心X', value: `${this.data.centerScaleRulerCenterXPx}px` },
|
{ label: '比例尺中心X', value: `${this.data.centerScaleRulerCenterXPx}px` },
|
||||||
{ label: '比例尺零点Y', value: `${this.data.centerScaleRulerZeroYPx}px` },
|
{ label: '比例尺零点Y', value: `${this.data.centerScaleRulerZeroYPx}px` },
|
||||||
@@ -1575,7 +1654,7 @@ Page({
|
|||||||
handleSystemSettingsPanelTap() {},
|
handleSystemSettingsPanelTap() {},
|
||||||
|
|
||||||
handleSetAnimationLevelStandard() {
|
handleSetAnimationLevelStandard() {
|
||||||
if (!mapEngine) {
|
if (this.data.lockAnimationLevel || !mapEngine) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mapEngine.handleSetAnimationLevel('standard')
|
mapEngine.handleSetAnimationLevel('standard')
|
||||||
@@ -1586,7 +1665,7 @@ Page({
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleSetAnimationLevelLite() {
|
handleSetAnimationLevelLite() {
|
||||||
if (!mapEngine) {
|
if (this.data.lockAnimationLevel || !mapEngine) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mapEngine.handleSetAnimationLevel('lite')
|
mapEngine.handleSetAnimationLevel('lite')
|
||||||
@@ -1596,8 +1675,89 @@ Page({
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handleSetSideButtonPlacementLeft() {
|
||||||
|
if (this.data.lockSideButtonPlacement) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.setData({
|
||||||
|
sideButtonPlacement: 'left',
|
||||||
|
})
|
||||||
|
persistStoredUserSettings({
|
||||||
|
...loadStoredUserSettings(),
|
||||||
|
sideButtonPlacement: 'left',
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSetSideButtonPlacementRight() {
|
||||||
|
if (this.data.lockSideButtonPlacement) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.setData({
|
||||||
|
sideButtonPlacement: 'right',
|
||||||
|
})
|
||||||
|
persistStoredUserSettings({
|
||||||
|
...loadStoredUserSettings(),
|
||||||
|
sideButtonPlacement: 'right',
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSetAutoRotateEnabledOn() {
|
||||||
|
if (this.data.lockAutoRotate || !mapEngine) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mapEngine.handleSetHeadingUpMode()
|
||||||
|
persistStoredUserSettings({
|
||||||
|
...loadStoredUserSettings(),
|
||||||
|
autoRotateEnabled: true,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSetAutoRotateEnabledOff() {
|
||||||
|
if (this.data.lockAutoRotate || !mapEngine) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mapEngine.handleSetManualMode()
|
||||||
|
persistStoredUserSettings({
|
||||||
|
...loadStoredUserSettings(),
|
||||||
|
autoRotateEnabled: false,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSetCompassTuningSmooth() {
|
||||||
|
if (this.data.lockCompassTuning || !mapEngine) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mapEngine.handleSetCompassTuningProfile('smooth')
|
||||||
|
persistStoredUserSettings({
|
||||||
|
...loadStoredUserSettings(),
|
||||||
|
compassTuningProfile: 'smooth',
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSetCompassTuningBalanced() {
|
||||||
|
if (this.data.lockCompassTuning || !mapEngine) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mapEngine.handleSetCompassTuningProfile('balanced')
|
||||||
|
persistStoredUserSettings({
|
||||||
|
...loadStoredUserSettings(),
|
||||||
|
compassTuningProfile: 'balanced',
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSetCompassTuningResponsive() {
|
||||||
|
if (this.data.lockCompassTuning || !mapEngine) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mapEngine.handleSetCompassTuningProfile('responsive')
|
||||||
|
persistStoredUserSettings({
|
||||||
|
...loadStoredUserSettings(),
|
||||||
|
compassTuningProfile: 'responsive',
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
handleSetNorthReferenceMagnetic() {
|
handleSetNorthReferenceMagnetic() {
|
||||||
if (!mapEngine) {
|
if (this.data.lockNorthReference || !mapEngine) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mapEngine.handleSetNorthReferenceMode('magnetic')
|
mapEngine.handleSetNorthReferenceMode('magnetic')
|
||||||
@@ -1608,7 +1768,7 @@ Page({
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleSetNorthReferenceTrue() {
|
handleSetNorthReferenceTrue() {
|
||||||
if (!mapEngine) {
|
if (this.data.lockNorthReference || !mapEngine) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mapEngine.handleSetNorthReferenceMode('true')
|
mapEngine.handleSetNorthReferenceMode('true')
|
||||||
@@ -1618,6 +1778,18 @@ Page({
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handleToggleSettingLock(event: WechatMiniprogram.TouchEvent) {
|
||||||
|
const key = event.currentTarget.dataset.key as SettingLockKey | undefined
|
||||||
|
if (!key) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const nextValue = !this.data[key]
|
||||||
|
this.setData({
|
||||||
|
[key]: nextValue,
|
||||||
|
} as Record<string, boolean>)
|
||||||
|
persistStoredUserSettings(toggleStoredSettingLock(loadStoredUserSettings(), key))
|
||||||
|
},
|
||||||
|
|
||||||
handleOverlayTouch() {},
|
handleOverlayTouch() {},
|
||||||
|
|
||||||
handlePunchAction() {
|
handlePunchAction() {
|
||||||
@@ -1674,16 +1846,24 @@ Page({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleToggleMapRotateMode() {
|
handleToggleMapRotateMode() {
|
||||||
if (!mapEngine) {
|
if (!mapEngine || this.data.lockAutoRotate) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.data.orientationMode === 'heading-up') {
|
if (this.data.orientationMode === 'heading-up') {
|
||||||
mapEngine.handleSetManualMode()
|
mapEngine.handleSetManualMode()
|
||||||
|
persistStoredUserSettings({
|
||||||
|
...loadStoredUserSettings(),
|
||||||
|
autoRotateEnabled: false,
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
mapEngine.handleSetHeadingUpMode()
|
mapEngine.handleSetHeadingUpMode()
|
||||||
|
persistStoredUserSettings({
|
||||||
|
...loadStoredUserSettings(),
|
||||||
|
autoRotateEnabled: true,
|
||||||
|
})
|
||||||
},
|
},
|
||||||
handleToggleDebugPanel() {
|
handleToggleDebugPanel() {
|
||||||
const nextShowDebugPanel = !this.data.showDebugPanel
|
const nextShowDebugPanel = !this.data.showDebugPanel
|
||||||
@@ -1788,6 +1968,9 @@ Page({
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleSetCenterScaleRulerVisibleOn() {
|
handleSetCenterScaleRulerVisibleOn() {
|
||||||
|
if (this.data.lockScaleRulerVisible) {
|
||||||
|
return
|
||||||
|
}
|
||||||
this.applyCenterScaleRulerSettings(true, this.data.centerScaleRulerAnchorMode)
|
this.applyCenterScaleRulerSettings(true, this.data.centerScaleRulerAnchorMode)
|
||||||
persistStoredUserSettings({
|
persistStoredUserSettings({
|
||||||
...loadStoredUserSettings(),
|
...loadStoredUserSettings(),
|
||||||
@@ -1797,6 +1980,9 @@ Page({
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleSetCenterScaleRulerVisibleOff() {
|
handleSetCenterScaleRulerVisibleOff() {
|
||||||
|
if (this.data.lockScaleRulerVisible) {
|
||||||
|
return
|
||||||
|
}
|
||||||
this.applyCenterScaleRulerSettings(false, this.data.centerScaleRulerAnchorMode)
|
this.applyCenterScaleRulerSettings(false, this.data.centerScaleRulerAnchorMode)
|
||||||
persistStoredUserSettings({
|
persistStoredUserSettings({
|
||||||
...loadStoredUserSettings(),
|
...loadStoredUserSettings(),
|
||||||
@@ -1806,6 +1992,9 @@ Page({
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleSetCenterScaleRulerAnchorScreenCenter() {
|
handleSetCenterScaleRulerAnchorScreenCenter() {
|
||||||
|
if (this.data.lockScaleRulerAnchor) {
|
||||||
|
return
|
||||||
|
}
|
||||||
this.applyCenterScaleRulerSettings(this.data.showCenterScaleRuler, 'screen-center')
|
this.applyCenterScaleRulerSettings(this.data.showCenterScaleRuler, 'screen-center')
|
||||||
persistStoredUserSettings({
|
persistStoredUserSettings({
|
||||||
...loadStoredUserSettings(),
|
...loadStoredUserSettings(),
|
||||||
@@ -1815,6 +2004,9 @@ Page({
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleSetCenterScaleRulerAnchorCompassCenter() {
|
handleSetCenterScaleRulerAnchorCompassCenter() {
|
||||||
|
if (this.data.lockScaleRulerAnchor) {
|
||||||
|
return
|
||||||
|
}
|
||||||
this.applyCenterScaleRulerSettings(this.data.showCenterScaleRuler, 'compass-center')
|
this.applyCenterScaleRulerSettings(this.data.showCenterScaleRuler, 'compass-center')
|
||||||
persistStoredUserSettings({
|
persistStoredUserSettings({
|
||||||
...loadStoredUserSettings(),
|
...loadStoredUserSettings(),
|
||||||
|
|||||||
@@ -85,36 +85,30 @@
|
|||||||
<view class="game-punch-hint__close" catchtouchstart="handlePunchHintTap" catchtouchmove="handlePunchHintTap" catchtouchend="handlePunchHintTap" catchtap="handleClosePunchHint">×</view>
|
<view class="game-punch-hint__close" catchtouchstart="handlePunchHintTap" catchtouchmove="handlePunchHintTap" catchtouchend="handlePunchHintTap" catchtap="handleClosePunchHint">×</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<cover-view class="map-side-toggle" wx:if="{{!showDebugPanel && !showGameInfoPanel && !showSystemSettingsPanel}}" style="top: {{topInsetHeight}}px;" bindtap="handleCycleSideButtons">
|
<cover-view class="map-side-toggle {{sideButtonPlacement === 'right' ? 'map-side-toggle--right' : 'map-side-toggle--left'}}" wx:if="{{!showDebugPanel && !showGameInfoPanel && !showSystemSettingsPanel}}" style="top: {{topInsetHeight}}px;" bindtap="handleCycleSideButtons">
|
||||||
<cover-view class="map-side-button map-side-button--icon">
|
<cover-view class="map-side-button map-side-button--icon">
|
||||||
<cover-image class="map-side-button__image" src="{{sideToggleIconSrc}}"></cover-image>
|
<cover-image class="map-side-button__image" src="{{sideToggleIconSrc}}"></cover-image>
|
||||||
</cover-view>
|
</cover-view>
|
||||||
</cover-view>
|
</cover-view>
|
||||||
|
|
||||||
<cover-view class="map-side-column map-side-column--left map-side-column--left-group" wx:if="{{!showDebugPanel && !showGameInfoPanel && !showSystemSettingsPanel && showLeftButtonGroup}}" style="top: {{topInsetHeight}}px;">
|
<cover-view class="map-side-column {{sideButtonPlacement === 'right' ? 'map-side-column--right-group' : 'map-side-column--left'}} map-side-column--left-group" wx:if="{{!showDebugPanel && !showGameInfoPanel && !showSystemSettingsPanel && showLeftButtonGroup}}" style="top: {{topInsetHeight}}px;">
|
||||||
<cover-view class="map-side-button map-side-button--icon" bindtap="handleToggleMapRotateMode"><cover-image class="map-side-button__rotate-image {{orientationMode === 'heading-up' ? 'map-side-button__rotate-image--active' : ''}}" src="../../assets/btn_map_rotate_cropped.png"></cover-image></cover-view>
|
<cover-view class="map-side-button map-side-button--icon" bindtap="handleToggleMapRotateMode"><cover-image class="map-side-button__rotate-image {{orientationMode === 'heading-up' ? 'map-side-button__rotate-image--active' : ''}}" src="../../assets/btn_map_rotate_cropped.png"></cover-image></cover-view>
|
||||||
<cover-view class="map-side-button map-side-button--muted"><cover-view class="map-side-button__text">1</cover-view></cover-view>
|
<cover-view class="{{sideButton2Class}}" bindtap="handleToggleGpsLock">
|
||||||
<cover-view class="{{sideButton2Class}}" bindtap="handleToggleGpsLock"><cover-view class="map-side-button__text">2</cover-view></cover-view>
|
<cover-image
|
||||||
<cover-view class="map-side-button map-side-button--active"><cover-view class="map-side-button__text">3</cover-view></cover-view>
|
wx:if="{{gpsLockEnabled}}"
|
||||||
<cover-view class="{{sideButton4Class}}" bindtap="handleForceExitGame"><cover-image class="map-side-button__action-image" src="../../assets/btn_exit.png"></cover-image></cover-view>
|
class="map-side-button__action-image"
|
||||||
|
src="../../assets/btn_locked.png"
|
||||||
|
></cover-image>
|
||||||
|
<cover-image
|
||||||
|
wx:else
|
||||||
|
class="map-side-button__action-image"
|
||||||
|
src="../../assets/btn_unlock.png"
|
||||||
|
></cover-image>
|
||||||
</cover-view>
|
</cover-view>
|
||||||
|
|
||||||
<cover-view class="map-side-column map-side-column--right-main" wx:if="{{!showDebugPanel && !showGameInfoPanel && !showSystemSettingsPanel && showRightButtonGroups}}" style="top: {{topInsetHeight}}px;">
|
|
||||||
<cover-view class="map-side-button"><cover-view class="map-side-button__text">5</cover-view></cover-view>
|
|
||||||
<cover-view class="map-side-button map-side-button--active"><cover-view class="map-side-button__text">6</cover-view></cover-view>
|
|
||||||
<cover-view class="map-side-button"><cover-view class="map-side-button__text">7</cover-view></cover-view>
|
|
||||||
<cover-view class="map-side-button map-side-button--active"><cover-view class="map-side-button__text">8</cover-view></cover-view>
|
|
||||||
<cover-view class="map-side-button map-side-button--muted"><cover-view class="map-side-button__text">9</cover-view></cover-view>
|
|
||||||
<cover-view class="map-side-button map-side-button--active"><cover-view class="map-side-button__text">10</cover-view></cover-view>
|
|
||||||
</cover-view>
|
|
||||||
|
|
||||||
<cover-view class="map-side-column map-side-column--right-sub" wx:if="{{!showDebugPanel && !showGameInfoPanel && !showSystemSettingsPanel && showRightButtonGroups}}" style="top: {{topInsetHeight}}px;">
|
|
||||||
<cover-view class="{{sideButton11Class}}" bindtap="handleOpenGameInfoPanel"><cover-image class="map-side-button__action-image" src="../../assets/btn_info.png"></cover-image></cover-view>
|
|
||||||
<cover-view class="{{sideButton12Class}}" bindtap="handleOpenSystemSettingsPanel"><cover-view class="map-side-button__text">12</cover-view></cover-view>
|
|
||||||
<cover-view class="map-side-button"><cover-view class="map-side-button__text">13</cover-view></cover-view>
|
|
||||||
<cover-view class="map-side-button"><cover-view class="map-side-button__text">14</cover-view></cover-view>
|
|
||||||
<cover-view class="map-side-button"><cover-view class="map-side-button__text">15</cover-view></cover-view>
|
|
||||||
<cover-view class="{{sideButton16Class}}" bindtap="handleSkipAction"><cover-image class="map-side-button__action-image" src="../../assets/btn_skip_cp.png"></cover-image></cover-view>
|
<cover-view class="{{sideButton16Class}}" bindtap="handleSkipAction"><cover-image class="map-side-button__action-image" src="../../assets/btn_skip_cp.png"></cover-image></cover-view>
|
||||||
|
<cover-view class="{{sideButton11Class}}" bindtap="handleOpenGameInfoPanel"><cover-image class="map-side-button__action-image" src="../../assets/btn_info.png"></cover-image></cover-view>
|
||||||
|
<cover-view class="{{sideButton12Class}}" bindtap="handleOpenSystemSettingsPanel"><cover-image class="map-side-button__action-image" src="../../assets/btn_settings.png"></cover-image></cover-view>
|
||||||
|
<cover-view class="{{sideButton4Class}}" bindtap="handleForceExitGame"><cover-image class="map-side-button__action-image" src="../../assets/btn_exit.png"></cover-image></cover-view>
|
||||||
</cover-view>
|
</cover-view>
|
||||||
|
|
||||||
<cover-view class="map-punch-button {{punchButtonEnabled ? 'map-punch-button--active' : ''}} {{punchButtonFxClass}}" wx:if="{{!showDebugPanel && !showGameInfoPanel && !showSystemSettingsPanel}}" bindtap="handlePunchAction">
|
<cover-view class="map-punch-button {{punchButtonEnabled ? 'map-punch-button--active' : ''}} {{punchButtonFxClass}}" wx:if="{{!showDebugPanel && !showGameInfoPanel && !showSystemSettingsPanel}}" bindtap="handlePunchAction">
|
||||||
@@ -298,71 +292,173 @@
|
|||||||
<scroll-view class="game-info-modal__content" scroll-y enhanced show-scrollbar="true">
|
<scroll-view class="game-info-modal__content" scroll-y enhanced show-scrollbar="true">
|
||||||
<view class="debug-section debug-section--info">
|
<view class="debug-section debug-section--info">
|
||||||
<view class="debug-section__header">
|
<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__title">01. 动画性能</view>
|
||||||
<view class="debug-section__desc">根据设备性能切换动画强度,低端机建议精简</view>
|
<view class="debug-section__desc">根据设备性能切换动画强度,低端机建议精简</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="debug-section__lock {{lockAnimationLevel ? 'debug-section__lock--active' : ''}}" data-key="lockAnimationLevel" bindtap="handleToggleSettingLock">
|
||||||
|
<text class="debug-section__lock-text">{{lockAnimationLevel ? '已锁' : '可改'}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
<view class="info-panel__row">
|
<view class="info-panel__row">
|
||||||
<text class="info-panel__label">当前级别</text>
|
<text class="info-panel__label">当前级别</text>
|
||||||
<text class="info-panel__value">{{animationLevel === 'lite' ? '精简' : '标准'}}</text>
|
<text class="info-panel__value">{{animationLevel === 'lite' ? '精简' : '标准'}}{{lockAnimationLevel ? ' · 已锁定' : ' · 可编辑'}}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="control-row">
|
<view class="control-row">
|
||||||
<view class="control-chip {{animationLevel === 'standard' ? 'control-chip--active' : 'control-chip--secondary'}}" bindtap="handleSetAnimationLevelStandard">标准</view>
|
<view class="control-chip {{animationLevel === 'standard' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockAnimationLevel ? 'control-chip--disabled' : ''}}" bindtap="handleSetAnimationLevelStandard">标准</view>
|
||||||
<view class="control-chip {{animationLevel === 'lite' ? 'control-chip--active' : 'control-chip--secondary'}}" bindtap="handleSetAnimationLevelLite">精简</view>
|
<view class="control-chip {{animationLevel === 'lite' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockAnimationLevel ? 'control-chip--disabled' : ''}}" bindtap="handleSetAnimationLevelLite">精简</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="debug-section debug-section--info">
|
<view class="debug-section debug-section--info">
|
||||||
<view class="debug-section__header">
|
<view class="debug-section__header">
|
||||||
<view class="debug-section__title">02. 比例尺显示</view>
|
<view class="debug-section__header-row">
|
||||||
<view class="debug-section__desc">控制比例尺显示与否,默认沿用你的本地偏好</view>
|
<view class="debug-section__header-main">
|
||||||
|
<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>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="info-panel__row">
|
||||||
|
<text class="info-panel__label">当前习惯</text>
|
||||||
|
<text class="info-panel__value">{{sideButtonPlacement === 'right' ? '右手' : '左手'}}{{lockSideButtonPlacement ? ' · 已锁定' : ' · 可编辑'}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="control-row">
|
||||||
|
<view class="control-chip {{sideButtonPlacement === 'left' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockSideButtonPlacement ? 'control-chip--disabled' : ''}}" bindtap="handleSetSideButtonPlacementLeft">左手</view>
|
||||||
|
<view class="control-chip {{sideButtonPlacement === 'right' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockSideButtonPlacement ? 'control-chip--disabled' : ''}}" bindtap="handleSetSideButtonPlacementRight">右手</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 {{lockAutoRotate ? 'debug-section__lock--active' : ''}}" data-key="lockAutoRotate" bindtap="handleToggleSettingLock">
|
||||||
|
<text class="debug-section__lock-text">{{lockAutoRotate ? '已锁' : '可改'}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="info-panel__row">
|
<view class="info-panel__row">
|
||||||
<text class="info-panel__label">当前状态</text>
|
<text class="info-panel__label">当前状态</text>
|
||||||
<text class="info-panel__value">{{showCenterScaleRuler ? '显示' : '隐藏'}}</text>
|
<text class="info-panel__value">{{autoRotateEnabled ? '开启' : '关闭'}}{{lockAutoRotate ? ' · 已锁定' : ' · 可编辑'}}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="control-row">
|
<view class="control-row">
|
||||||
<view class="control-chip {{showCenterScaleRuler ? 'control-chip--active' : 'control-chip--secondary'}}" bindtap="handleSetCenterScaleRulerVisibleOn">显示</view>
|
<view class="control-chip {{autoRotateEnabled ? 'control-chip--active' : 'control-chip--secondary'}} {{lockAutoRotate ? 'control-chip--disabled' : ''}}" bindtap="handleSetAutoRotateEnabledOn">开启</view>
|
||||||
<view class="control-chip {{!showCenterScaleRuler ? 'control-chip--active' : 'control-chip--secondary'}}" bindtap="handleSetCenterScaleRulerVisibleOff">隐藏</view>
|
<view class="control-chip {{!autoRotateEnabled ? 'control-chip--active' : 'control-chip--secondary'}} {{lockAutoRotate ? 'control-chip--disabled' : ''}}" bindtap="handleSetAutoRotateEnabledOff">关闭</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="debug-section debug-section--info">
|
<view class="debug-section debug-section--info">
|
||||||
<view class="debug-section__header">
|
<view class="debug-section__header">
|
||||||
<view class="debug-section__title">03. 比例尺基准点</view>
|
<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 {{lockCompassTuning ? 'debug-section__lock--active' : ''}}" data-key="lockCompassTuning" bindtap="handleToggleSettingLock">
|
||||||
|
<text class="debug-section__lock-text">{{lockCompassTuning ? '已锁' : '可改'}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="info-panel__row">
|
||||||
|
<text class="info-panel__label">当前档位</text>
|
||||||
|
<text class="info-panel__value">{{compassTuningProfileText}}{{lockCompassTuning ? ' · 已锁定' : ' · 可编辑'}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="control-row control-row--triple">
|
||||||
|
<view class="control-chip {{compassTuningProfile === 'smooth' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockCompassTuning ? 'control-chip--disabled' : ''}}" bindtap="handleSetCompassTuningSmooth">顺滑</view>
|
||||||
|
<view class="control-chip {{compassTuningProfile === 'balanced' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockCompassTuning ? 'control-chip--disabled' : ''}}" bindtap="handleSetCompassTuningBalanced">平衡</view>
|
||||||
|
<view class="control-chip {{compassTuningProfile === 'responsive' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockCompassTuning ? 'control-chip--disabled' : ''}}" bindtap="handleSetCompassTuningResponsive">跟手</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 {{lockScaleRulerVisible ? 'debug-section__lock--active' : ''}}" data-key="lockScaleRulerVisible" bindtap="handleToggleSettingLock">
|
||||||
|
<text class="debug-section__lock-text">{{lockScaleRulerVisible ? '已锁' : '可改'}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="info-panel__row">
|
||||||
|
<text class="info-panel__label">当前状态</text>
|
||||||
|
<text class="info-panel__value">{{showCenterScaleRuler ? '显示' : '隐藏'}}{{lockScaleRulerVisible ? ' · 已锁定' : ' · 可编辑'}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="control-row">
|
||||||
|
<view class="control-chip {{showCenterScaleRuler ? 'control-chip--active' : 'control-chip--secondary'}} {{lockScaleRulerVisible ? 'control-chip--disabled' : ''}}" bindtap="handleSetCenterScaleRulerVisibleOn">显示</view>
|
||||||
|
<view class="control-chip {{!showCenterScaleRuler ? 'control-chip--active' : 'control-chip--secondary'}} {{lockScaleRulerVisible ? 'control-chip--disabled' : ''}}" bindtap="handleSetCenterScaleRulerVisibleOff">隐藏</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. 比例尺基准点</view>
|
||||||
<view class="debug-section__desc">设置比例尺零点锚定位置,可跟随屏幕中心或指北针圆心</view>
|
<view class="debug-section__desc">设置比例尺零点锚定位置,可跟随屏幕中心或指北针圆心</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="debug-section__lock {{lockScaleRulerAnchor ? 'debug-section__lock--active' : ''}}" data-key="lockScaleRulerAnchor" bindtap="handleToggleSettingLock">
|
||||||
|
<text class="debug-section__lock-text">{{lockScaleRulerAnchor ? '已锁' : '可改'}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
<view class="info-panel__row">
|
<view class="info-panel__row">
|
||||||
<text class="info-panel__label">当前锚点</text>
|
<text class="info-panel__label">当前锚点</text>
|
||||||
<text class="info-panel__value">{{centerScaleRulerAnchorMode === 'compass-center' ? '指北针圆心' : '屏幕中心'}}</text>
|
<text class="info-panel__value">{{centerScaleRulerAnchorMode === 'compass-center' ? '指北针圆心' : '屏幕中心'}}{{lockScaleRulerAnchor ? ' · 已锁定' : ' · 可编辑'}}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="control-row">
|
<view class="control-row">
|
||||||
<view class="control-chip {{centerScaleRulerAnchorMode === 'screen-center' ? 'control-chip--active' : 'control-chip--secondary'}}" bindtap="handleSetCenterScaleRulerAnchorScreenCenter">屏幕中心</view>
|
<view class="control-chip {{centerScaleRulerAnchorMode === 'screen-center' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockScaleRulerAnchor ? 'control-chip--disabled' : ''}}" bindtap="handleSetCenterScaleRulerAnchorScreenCenter">屏幕中心</view>
|
||||||
<view class="control-chip {{centerScaleRulerAnchorMode === 'compass-center' ? 'control-chip--active' : 'control-chip--secondary'}}" bindtap="handleSetCenterScaleRulerAnchorCompassCenter">指北针圆心</view>
|
<view class="control-chip {{centerScaleRulerAnchorMode === 'compass-center' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockScaleRulerAnchor ? 'control-chip--disabled' : ''}}" bindtap="handleSetCenterScaleRulerAnchorCompassCenter">指北针圆心</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="debug-section debug-section--info">
|
<view class="debug-section debug-section--info">
|
||||||
<view class="debug-section__header">
|
<view class="debug-section__header">
|
||||||
<view class="debug-section__title">04. 北参考</view>
|
<view class="debug-section__header-row">
|
||||||
|
<view class="debug-section__header-main">
|
||||||
|
<view class="debug-section__title">07. 北参考</view>
|
||||||
<view class="debug-section__desc">切换磁北/真北作为地图与指北针参考</view>
|
<view class="debug-section__desc">切换磁北/真北作为地图与指北针参考</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="debug-section__lock {{lockNorthReference ? 'debug-section__lock--active' : ''}}" data-key="lockNorthReference" bindtap="handleToggleSettingLock">
|
||||||
|
<text class="debug-section__lock-text">{{lockNorthReference ? '已锁' : '可改'}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
<view class="info-panel__row">
|
<view class="info-panel__row">
|
||||||
<text class="info-panel__label">当前参考</text>
|
<text class="info-panel__label">当前参考</text>
|
||||||
<text class="info-panel__value">{{northReferenceText}}</text>
|
<text class="info-panel__value">{{northReferenceText}}{{lockNorthReference ? ' · 已锁定' : ' · 可编辑'}}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="control-row">
|
<view class="control-row">
|
||||||
<view class="control-chip {{northReferenceMode === 'magnetic' ? 'control-chip--active' : 'control-chip--secondary'}}" bindtap="handleSetNorthReferenceMagnetic">磁北</view>
|
<view class="control-chip {{northReferenceMode === 'magnetic' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockNorthReference ? 'control-chip--disabled' : ''}}" bindtap="handleSetNorthReferenceMagnetic">磁北</view>
|
||||||
<view class="control-chip {{northReferenceMode === 'true' ? 'control-chip--active' : 'control-chip--secondary'}}" bindtap="handleSetNorthReferenceTrue">真北</view>
|
<view class="control-chip {{northReferenceMode === 'true' ? 'control-chip--active' : 'control-chip--secondary'}} {{lockNorthReference ? 'control-chip--disabled' : ''}}" bindtap="handleSetNorthReferenceTrue">真北</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="debug-section debug-section--info">
|
<view class="debug-section debug-section--info">
|
||||||
<view class="debug-section__header">
|
<view class="debug-section__header">
|
||||||
<view class="debug-section__title">05. 心率设备</view>
|
<view class="debug-section__header-row">
|
||||||
|
<view class="debug-section__header-main">
|
||||||
|
<view class="debug-section__title">08. 心率设备</view>
|
||||||
<view class="debug-section__desc">清除已记住的首选心率带设备,下次重新选择</view>
|
<view class="debug-section__desc">清除已记住的首选心率带设备,下次重新选择</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="debug-section__lock {{lockHeartRateDevice ? 'debug-section__lock--active' : ''}}" data-key="lockHeartRateDevice" bindtap="handleToggleSettingLock">
|
||||||
|
<text class="debug-section__lock-text">{{lockHeartRateDevice ? '已锁' : '可改'}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
<view class="control-row">
|
<view class="control-row">
|
||||||
<view class="control-chip control-chip--secondary" bindtap="handleClearPreferredHeartRateDevice">清除首选设备</view>
|
<view class="control-chip control-chip--secondary {{lockHeartRateDevice ? 'control-chip--disabled' : ''}}" bindtap="handleClearPreferredHeartRateDevice">清除首选设备</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
@@ -429,6 +525,7 @@
|
|||||||
<view class="debug-section__title">Sensors</view>
|
<view class="debug-section__title">Sensors</view>
|
||||||
<view class="debug-section__desc">定位、罗盘与心率带连接状态</view>
|
<view class="debug-section__desc">定位、罗盘与心率带连接状态</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="debug-group-title">定位</view>
|
||||||
<view class="info-panel__row">
|
<view class="info-panel__row">
|
||||||
<text class="info-panel__label">GPS</text>
|
<text class="info-panel__label">GPS</text>
|
||||||
<text class="info-panel__value">{{gpsTrackingText}}</text>
|
<text class="info-panel__value">{{gpsTrackingText}}</text>
|
||||||
@@ -469,6 +566,7 @@
|
|||||||
<text class="info-panel__label">Mock Speed</text>
|
<text class="info-panel__label">Mock Speed</text>
|
||||||
<text class="info-panel__value">{{mockSpeedText}}</text>
|
<text class="info-panel__value">{{mockSpeedText}}</text>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="debug-group-title">心率</view>
|
||||||
<view class="info-panel__row">
|
<view class="info-panel__row">
|
||||||
<text class="info-panel__label">Heart Rate</text>
|
<text class="info-panel__label">Heart Rate</text>
|
||||||
<text class="info-panel__value">{{heartRateStatusText}}</text>
|
<text class="info-panel__value">{{heartRateStatusText}}</text>
|
||||||
@@ -532,6 +630,7 @@
|
|||||||
<text class="info-panel__label">Mock BPM</text>
|
<text class="info-panel__label">Mock BPM</text>
|
||||||
<text class="info-panel__value">{{mockHeartRateText}}</text>
|
<text class="info-panel__value">{{mockHeartRateText}}</text>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="debug-group-title">方向</view>
|
||||||
<view class="info-panel__row">
|
<view class="info-panel__row">
|
||||||
<text class="info-panel__label">Heading Mode</text>
|
<text class="info-panel__label">Heading Mode</text>
|
||||||
<text class="info-panel__value">{{orientationModeText}}</text>
|
<text class="info-panel__value">{{orientationModeText}}</text>
|
||||||
@@ -560,11 +659,6 @@
|
|||||||
<text class="info-panel__label">Compass Tune</text>
|
<text class="info-panel__label">Compass Tune</text>
|
||||||
<text class="info-panel__value">{{compassTuningProfileText}}</text>
|
<text class="info-panel__value">{{compassTuningProfileText}}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="control-row">
|
|
||||||
<view class="control-chip {{compassTuningProfile === 'smooth' ? 'control-chip--active' : 'control-chip--secondary'}}" bindtap="handleSetCompassTuningSmooth">顺滑</view>
|
|
||||||
<view class="control-chip {{compassTuningProfile === 'balanced' ? 'control-chip--active' : 'control-chip--secondary'}}" bindtap="handleSetCompassTuningBalanced">平衡</view>
|
|
||||||
<view class="control-chip {{compassTuningProfile === 'responsive' ? 'control-chip--active' : 'control-chip--secondary'}}" bindtap="handleSetCompassTuningResponsive">跟手</view>
|
|
||||||
</view>
|
|
||||||
<view class="info-panel__row info-panel__row--stack">
|
<view class="info-panel__row info-panel__row--stack">
|
||||||
<text class="info-panel__label">Accel</text>
|
<text class="info-panel__label">Accel</text>
|
||||||
<text class="info-panel__value">{{accelerometerText}}</text>
|
<text class="info-panel__value">{{accelerometerText}}</text>
|
||||||
|
|||||||
@@ -305,10 +305,17 @@
|
|||||||
|
|
||||||
.map-side-toggle {
|
.map-side-toggle {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 24rpx;
|
|
||||||
z-index: 19;
|
z-index: 19;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.map-side-toggle--left {
|
||||||
|
left: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-side-toggle--right {
|
||||||
|
right: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
.map-side-column {
|
.map-side-column {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -322,6 +329,10 @@
|
|||||||
left: 24rpx;
|
left: 24rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.map-side-column--right-group {
|
||||||
|
right: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
.map-side-column--left-group {
|
.map-side-column--left-group {
|
||||||
padding-top: 106rpx;
|
padding-top: 106rpx;
|
||||||
}
|
}
|
||||||
@@ -1417,6 +1428,18 @@
|
|||||||
margin-bottom: 12rpx;
|
margin-bottom: 12rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.debug-section__header-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.debug-section__header-main {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.debug-section__title {
|
.debug-section__title {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
@@ -1433,6 +1456,36 @@
|
|||||||
color: #6a826f;
|
color: #6a826f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.debug-section__lock {
|
||||||
|
min-width: 76rpx;
|
||||||
|
height: 52rpx;
|
||||||
|
padding: 0 16rpx;
|
||||||
|
flex: none;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 999rpx;
|
||||||
|
background: rgba(233, 242, 228, 0.92);
|
||||||
|
box-shadow: inset 0 0 0 1rpx rgba(22, 48, 32, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.debug-section__lock--active {
|
||||||
|
background: rgba(45, 106, 79, 0.18);
|
||||||
|
box-shadow: inset 0 0 0 2rpx rgba(45, 106, 79, 0.18);
|
||||||
|
}
|
||||||
|
|
||||||
|
.debug-section__lock-text {
|
||||||
|
font-size: 20rpx;
|
||||||
|
line-height: 1;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #45624b;
|
||||||
|
letter-spacing: 1rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.debug-section__lock--active .debug-section__lock-text {
|
||||||
|
color: #2d6a4f;
|
||||||
|
}
|
||||||
|
|
||||||
.info-panel__row {
|
.info-panel__row {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
@@ -1593,6 +1646,16 @@
|
|||||||
.debug-section .control-row:last-child {
|
.debug-section .control-row:last-child {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.debug-group-title {
|
||||||
|
margin-top: 18rpx;
|
||||||
|
margin-bottom: 8rpx;
|
||||||
|
font-size: 20rpx;
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: 2rpx;
|
||||||
|
color: #6a826f;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
.control-row--triple .control-chip {
|
.control-row--triple .control-chip {
|
||||||
font-size: 23rpx;
|
font-size: 23rpx;
|
||||||
}
|
}
|
||||||
@@ -1624,6 +1687,10 @@
|
|||||||
color: #f7fbf2;
|
color: #f7fbf2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.control-chip--disabled {
|
||||||
|
opacity: 0.48;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
},
|
},
|
||||||
"coverView": false,
|
"coverView": false,
|
||||||
"postcss": false,
|
"postcss": false,
|
||||||
"minified": false,
|
"minified": true,
|
||||||
"enhance": false,
|
"enhance": false,
|
||||||
"showShadowRootInWxmlPanel": false,
|
"showShadowRootInWxmlPanel": false,
|
||||||
"packNpmRelationList": [],
|
"packNpmRelationList": [],
|
||||||
|
|||||||
Reference in New Issue
Block a user