Refine compass and ruler overlay
This commit is contained in:
96
communication-guidelines.md
Normal file
96
communication-guidelines.md
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
# 沟通协作建议
|
||||||
|
|
||||||
|
这份文档用于约定后续在 UI 微调、交互细改、规则补充时,怎样沟通最有效,减少来回修改。
|
||||||
|
|
||||||
|
## 1. 需求描述的推荐格式
|
||||||
|
|
||||||
|
后续尽量按下面 4 个点描述需求:
|
||||||
|
|
||||||
|
### 改动对象
|
||||||
|
明确指出这次只改什么。
|
||||||
|
|
||||||
|
例如:
|
||||||
|
- 比例尺和指北针顶部数字之间的距离
|
||||||
|
- 某个按钮的高亮状态
|
||||||
|
- 某条提示文案
|
||||||
|
|
||||||
|
### 不要改
|
||||||
|
明确指出哪些相邻元素不要动。
|
||||||
|
|
||||||
|
例如:
|
||||||
|
- 不要改顶部数字和小箭头之间的距离
|
||||||
|
- 不要动比例尺刻度算法
|
||||||
|
- 不要改地图引擎逻辑
|
||||||
|
|
||||||
|
### 目标效果
|
||||||
|
说明你想达到什么视觉或交互结果。
|
||||||
|
|
||||||
|
例如:
|
||||||
|
- 更靠近一点
|
||||||
|
- 改成 4 到 5 像素的空隙
|
||||||
|
- 只在可点击时高亮
|
||||||
|
|
||||||
|
### 验证标准
|
||||||
|
说明你用什么标准判断“改对了”。
|
||||||
|
|
||||||
|
例如:
|
||||||
|
- 看起来贴近,但不要重叠
|
||||||
|
- 指北针仍然盖住比例尺
|
||||||
|
- 缩放时要实时变化,不要手势结束后再跳
|
||||||
|
|
||||||
|
## 2. 推荐的需求表达模板
|
||||||
|
|
||||||
|
可以直接按这个模板发:
|
||||||
|
|
||||||
|
```text
|
||||||
|
改动对象:
|
||||||
|
不要改:
|
||||||
|
目标:
|
||||||
|
验证标准:
|
||||||
|
```
|
||||||
|
|
||||||
|
例如:
|
||||||
|
|
||||||
|
```text
|
||||||
|
改动对象:比例尺和顶部角度数字之间的距离
|
||||||
|
不要改:顶部角度数字和小箭头之间的距离
|
||||||
|
目标:再近一点
|
||||||
|
验证标准:看起来大约 4~5px,不重叠
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. 为什么这样最有效
|
||||||
|
|
||||||
|
很多来回修改,通常不是功能做不了,而是:
|
||||||
|
|
||||||
|
- 一次需求里混了两层甚至三层改动
|
||||||
|
- 没说清楚“哪块不要动”
|
||||||
|
- 验收标准只有感觉,没有边界
|
||||||
|
|
||||||
|
一旦把“改什么”和“不要改什么”拆开,误改概率会明显下降。
|
||||||
|
|
||||||
|
## 4. 开发执行的约定
|
||||||
|
|
||||||
|
后续默认按下面方式执行:
|
||||||
|
|
||||||
|
- 先复述这次只改哪一层
|
||||||
|
- 真实执行时只改这一层
|
||||||
|
- 不顺手带改别的部分
|
||||||
|
- 改完明确说明:
|
||||||
|
- 改了什么
|
||||||
|
- 没改什么
|
||||||
|
|
||||||
|
## 5. 最适合哪些场景
|
||||||
|
|
||||||
|
这套方式尤其适合:
|
||||||
|
|
||||||
|
- UI 间距微调
|
||||||
|
- 按钮状态和图标切换
|
||||||
|
- HUD 显示调整
|
||||||
|
- 地图表现修正
|
||||||
|
- 规则字段补充
|
||||||
|
|
||||||
|
## 6. 一句话原则
|
||||||
|
|
||||||
|
后续最有效的协作方式是:
|
||||||
|
|
||||||
|
**需求把边界说死,修改一次只动一层。**
|
||||||
@@ -23,7 +23,7 @@ const RENDER_MODE = 'Single WebGL Pipeline'
|
|||||||
const PROJECTION_MODE = 'WGS84 -> WorldTile -> Camera -> Screen'
|
const PROJECTION_MODE = 'WGS84 -> WorldTile -> Camera -> Screen'
|
||||||
const MAP_NORTH_OFFSET_DEG = 0
|
const MAP_NORTH_OFFSET_DEG = 0
|
||||||
let MAGNETIC_DECLINATION_DEG = -6.91
|
let MAGNETIC_DECLINATION_DEG = -6.91
|
||||||
let MAGNETIC_DECLINATION_TEXT = '6.91掳 W'
|
let MAGNETIC_DECLINATION_TEXT = '6.91˚ W'
|
||||||
const MIN_ZOOM = 15
|
const MIN_ZOOM = 15
|
||||||
const MAX_ZOOM = 20
|
const MAX_ZOOM = 20
|
||||||
const DEFAULT_ZOOM = 17
|
const DEFAULT_ZOOM = 17
|
||||||
@@ -129,6 +129,7 @@ export interface MapEngineViewState {
|
|||||||
tileTranslateX: number
|
tileTranslateX: number
|
||||||
tileTranslateY: number
|
tileTranslateY: number
|
||||||
tileSizePx: number
|
tileSizePx: number
|
||||||
|
previewScale: number
|
||||||
stageWidth: number
|
stageWidth: number
|
||||||
stageHeight: number
|
stageHeight: number
|
||||||
stageLeft: number
|
stageLeft: number
|
||||||
@@ -232,6 +233,8 @@ const VIEW_SYNC_KEYS: Array<keyof MapEngineViewState> = [
|
|||||||
'mapName',
|
'mapName',
|
||||||
'configStatusText',
|
'configStatusText',
|
||||||
'zoom',
|
'zoom',
|
||||||
|
'centerTileX',
|
||||||
|
'centerTileY',
|
||||||
'rotationDeg',
|
'rotationDeg',
|
||||||
'rotationText',
|
'rotationText',
|
||||||
'rotationMode',
|
'rotationMode',
|
||||||
@@ -263,6 +266,11 @@ const VIEW_SYNC_KEYS: Array<keyof MapEngineViewState> = [
|
|||||||
'networkFetchCount',
|
'networkFetchCount',
|
||||||
'cacheHitRateText',
|
'cacheHitRateText',
|
||||||
'tileSizePx',
|
'tileSizePx',
|
||||||
|
'previewScale',
|
||||||
|
'stageWidth',
|
||||||
|
'stageHeight',
|
||||||
|
'stageLeft',
|
||||||
|
'stageTop',
|
||||||
'statusText',
|
'statusText',
|
||||||
'gpsTracking',
|
'gpsTracking',
|
||||||
'gpsTrackingText',
|
'gpsTrackingText',
|
||||||
@@ -393,12 +401,16 @@ function formatRotationText(rotationDeg: number): string {
|
|||||||
return `${Math.round(normalizeRotationDeg(rotationDeg))}deg`
|
return `${Math.round(normalizeRotationDeg(rotationDeg))}deg`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeDegreeDisplayText(text: string): string {
|
||||||
|
return text.replace(/[°掳•]/g, '˚')
|
||||||
|
}
|
||||||
|
|
||||||
function formatHeadingText(headingDeg: number | null): string {
|
function formatHeadingText(headingDeg: number | null): string {
|
||||||
if (headingDeg === null) {
|
if (headingDeg === null) {
|
||||||
return '--'
|
return '--'
|
||||||
}
|
}
|
||||||
|
|
||||||
return `${Math.round(normalizeRotationDeg(headingDeg))}掳`
|
return `${Math.round(normalizeRotationDeg(headingDeg))}˚`
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatDevicePoseText(pose: 'upright' | 'tilted' | 'flat'): string {
|
function formatDevicePoseText(pose: 'upright' | 'tilted' | 'flat'): string {
|
||||||
@@ -1011,6 +1023,7 @@ export class MapEngine {
|
|||||||
tileTranslateX: 0,
|
tileTranslateX: 0,
|
||||||
tileTranslateY: 0,
|
tileTranslateY: 0,
|
||||||
tileSizePx: 0,
|
tileSizePx: 0,
|
||||||
|
previewScale: 1,
|
||||||
stageWidth: 0,
|
stageWidth: 0,
|
||||||
stageHeight: 0,
|
stageHeight: 0,
|
||||||
stageLeft: 0,
|
stageLeft: 0,
|
||||||
@@ -2114,7 +2127,7 @@ export class MapEngine {
|
|||||||
|
|
||||||
applyRemoteMapConfig(config: RemoteMapConfig): void {
|
applyRemoteMapConfig(config: RemoteMapConfig): void {
|
||||||
MAGNETIC_DECLINATION_DEG = config.magneticDeclinationDeg
|
MAGNETIC_DECLINATION_DEG = config.magneticDeclinationDeg
|
||||||
MAGNETIC_DECLINATION_TEXT = config.magneticDeclinationText
|
MAGNETIC_DECLINATION_TEXT = normalizeDegreeDisplayText(config.magneticDeclinationText)
|
||||||
this.minZoom = config.minZoom
|
this.minZoom = config.minZoom
|
||||||
this.maxZoom = config.maxZoom
|
this.maxZoom = config.maxZoom
|
||||||
this.defaultZoom = config.defaultZoom
|
this.defaultZoom = config.defaultZoom
|
||||||
@@ -3168,6 +3181,9 @@ export class MapEngine {
|
|||||||
this.previewScale = scale
|
this.previewScale = scale
|
||||||
this.previewOriginX = originX
|
this.previewOriginX = originX
|
||||||
this.previewOriginY = originY
|
this.previewOriginY = originY
|
||||||
|
this.setState({
|
||||||
|
previewScale: scale,
|
||||||
|
}, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
resetPreviewState(): void {
|
resetPreviewState(): void {
|
||||||
|
|||||||
@@ -18,11 +18,24 @@ type CompassLabelData = {
|
|||||||
radius: number
|
radius: number
|
||||||
className: string
|
className: string
|
||||||
}
|
}
|
||||||
|
type ScaleRulerMinorTickData = {
|
||||||
|
key: string
|
||||||
|
topPx: number
|
||||||
|
long: boolean
|
||||||
|
}
|
||||||
|
type ScaleRulerMajorMarkData = {
|
||||||
|
key: string
|
||||||
|
topPx: number
|
||||||
|
label: string
|
||||||
|
}
|
||||||
type SideButtonMode = 'all' | 'left' | 'right' | 'hidden'
|
type SideButtonMode = 'all' | 'left' | 'right' | 'hidden'
|
||||||
type SideActionButtonState = 'muted' | 'default' | 'active'
|
type SideActionButtonState = 'muted' | 'default' | 'active'
|
||||||
|
type CenterScaleRulerAnchorMode = 'screen-center' | 'compass-center'
|
||||||
type MapPageData = MapEngineViewState & {
|
type MapPageData = MapEngineViewState & {
|
||||||
showDebugPanel: boolean
|
showDebugPanel: boolean
|
||||||
showGameInfoPanel: boolean
|
showGameInfoPanel: boolean
|
||||||
|
showCenterScaleRuler: boolean
|
||||||
|
centerScaleRulerAnchorMode: CenterScaleRulerAnchorMode
|
||||||
statusBarHeight: number
|
statusBarHeight: number
|
||||||
topInsetHeight: number
|
topInsetHeight: number
|
||||||
hudPanelIndex: number
|
hudPanelIndex: number
|
||||||
@@ -45,12 +58,23 @@ type MapPageData = MapEngineViewState & {
|
|||||||
sideButton2Class: string
|
sideButton2Class: string
|
||||||
sideButton4Class: string
|
sideButton4Class: string
|
||||||
sideButton11Class: string
|
sideButton11Class: string
|
||||||
|
sideButton13Class: string
|
||||||
|
sideButton14Class: string
|
||||||
sideButton16Class: string
|
sideButton16Class: string
|
||||||
|
centerScaleRulerVisible: boolean
|
||||||
|
centerScaleRulerCenterXPx: number
|
||||||
|
centerScaleRulerZeroYPx: number
|
||||||
|
centerScaleRulerHeightPx: number
|
||||||
|
centerScaleRulerAxisBottomPx: number
|
||||||
|
centerScaleRulerZeroVisible: boolean
|
||||||
|
centerScaleRulerZeroLabel: string
|
||||||
|
centerScaleRulerMinorTicks: ScaleRulerMinorTickData[]
|
||||||
|
centerScaleRulerMajorMarks: ScaleRulerMajorMarkData[]
|
||||||
showLeftButtonGroup: boolean
|
showLeftButtonGroup: boolean
|
||||||
showRightButtonGroups: boolean
|
showRightButtonGroups: boolean
|
||||||
showBottomDebugButton: boolean
|
showBottomDebugButton: boolean
|
||||||
}
|
}
|
||||||
const INTERNAL_BUILD_VERSION = 'map-build-232'
|
const INTERNAL_BUILD_VERSION = 'map-build-252'
|
||||||
const CLASSIC_REMOTE_GAME_CONFIG_URL = 'https://oss-mbh5.colormaprun.com/gotomars/event/classic-sequential.json'
|
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'
|
const SCORE_O_REMOTE_GAME_CONFIG_URL = 'https://oss-mbh5.colormaprun.com/gotomars/event/score-o.json'
|
||||||
let mapEngine: MapEngine | null = null
|
let mapEngine: MapEngine | null = null
|
||||||
@@ -132,7 +156,7 @@ function getSideActionButtonClass(state: SideActionButtonState): string {
|
|||||||
return 'map-side-button map-side-button--default'
|
return 'map-side-button map-side-button--default'
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildSideButtonState(data: Pick<MapPageData, 'sideButtonMode' | 'showGameInfoPanel' | 'skipButtonEnabled' | 'gameSessionStatus' | 'gpsLockEnabled' | 'gpsLockAvailable'>) {
|
function buildSideButtonState(data: Pick<MapPageData, 'sideButtonMode' | 'showGameInfoPanel' | 'showCenterScaleRuler' | 'centerScaleRulerAnchorMode' | 'skipButtonEnabled' | 'gameSessionStatus' | 'gpsLockEnabled' | 'gpsLockAvailable'>) {
|
||||||
const sideButton2State: SideActionButtonState = !data.gpsLockAvailable
|
const sideButton2State: SideActionButtonState = !data.gpsLockAvailable
|
||||||
? 'muted'
|
? 'muted'
|
||||||
: data.gpsLockEnabled
|
: data.gpsLockEnabled
|
||||||
@@ -140,6 +164,12 @@ function buildSideButtonState(data: Pick<MapPageData, 'sideButtonMode' | 'showGa
|
|||||||
: 'default'
|
: 'default'
|
||||||
const sideButton4State: SideActionButtonState = data.gameSessionStatus === 'idle' ? 'default' : 'active'
|
const sideButton4State: SideActionButtonState = data.gameSessionStatus === 'idle' ? 'default' : 'active'
|
||||||
const sideButton11State: SideActionButtonState = data.showGameInfoPanel ? 'active' : 'default'
|
const sideButton11State: SideActionButtonState = data.showGameInfoPanel ? 'active' : 'default'
|
||||||
|
const sideButton13State: SideActionButtonState = data.showCenterScaleRuler ? 'active' : 'default'
|
||||||
|
const sideButton14State: SideActionButtonState = !data.showCenterScaleRuler
|
||||||
|
? 'muted'
|
||||||
|
: data.centerScaleRulerAnchorMode === 'compass-center'
|
||||||
|
? 'active'
|
||||||
|
: 'default'
|
||||||
const sideButton16State: SideActionButtonState = data.skipButtonEnabled ? 'default' : 'muted'
|
const sideButton16State: SideActionButtonState = data.skipButtonEnabled ? 'default' : 'muted'
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -147,10 +177,182 @@ function buildSideButtonState(data: Pick<MapPageData, 'sideButtonMode' | 'showGa
|
|||||||
sideButton2Class: getSideActionButtonClass(sideButton2State),
|
sideButton2Class: getSideActionButtonClass(sideButton2State),
|
||||||
sideButton4Class: getSideActionButtonClass(sideButton4State),
|
sideButton4Class: getSideActionButtonClass(sideButton4State),
|
||||||
sideButton11Class: getSideActionButtonClass(sideButton11State),
|
sideButton11Class: getSideActionButtonClass(sideButton11State),
|
||||||
|
sideButton13Class: getSideActionButtonClass(sideButton13State),
|
||||||
|
sideButton14Class: getSideActionButtonClass(sideButton14State),
|
||||||
sideButton16Class: getSideActionButtonClass(sideButton16State),
|
sideButton16Class: getSideActionButtonClass(sideButton16State),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getRpxUnitInPx(): number {
|
||||||
|
const systemInfo = wx.getSystemInfoSync()
|
||||||
|
return systemInfo.windowWidth / 750
|
||||||
|
}
|
||||||
|
|
||||||
|
function worldTileYToLat(worldTileY: number, zoom: number): number {
|
||||||
|
const scale = Math.pow(2, zoom)
|
||||||
|
const n = Math.PI - (2 * Math.PI * worldTileY) / scale
|
||||||
|
return (180 / Math.PI) * Math.atan(Math.sinh(n))
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNiceDistanceMeters(rawDistanceMeters: number): number {
|
||||||
|
if (!Number.isFinite(rawDistanceMeters) || rawDistanceMeters <= 0) {
|
||||||
|
return 50
|
||||||
|
}
|
||||||
|
|
||||||
|
const exponent = Math.floor(Math.log10(rawDistanceMeters))
|
||||||
|
const base = Math.pow(10, exponent)
|
||||||
|
const normalized = rawDistanceMeters / base
|
||||||
|
|
||||||
|
if (normalized <= 1) {
|
||||||
|
return base
|
||||||
|
}
|
||||||
|
if (normalized <= 2) {
|
||||||
|
return 2 * base
|
||||||
|
}
|
||||||
|
if (normalized <= 5) {
|
||||||
|
return 5 * base
|
||||||
|
}
|
||||||
|
return 10 * base
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatScaleDistanceLabel(distanceMeters: number): string {
|
||||||
|
if (distanceMeters >= 1000) {
|
||||||
|
const distanceKm = distanceMeters / 1000
|
||||||
|
const formatted = distanceKm >= 10 ? distanceKm.toFixed(0) : distanceKm.toFixed(1)
|
||||||
|
return `${formatted.replace(/\.0$/, '')} km`
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${Math.round(distanceMeters)} m`
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildCenterScaleRulerPatch(data: Pick<MapPageData, 'showCenterScaleRuler' | 'centerScaleRulerAnchorMode' | 'stageWidth' | 'stageHeight' | 'topInsetHeight' | 'zoom' | 'centerTileY' | 'tileSizePx' | 'previewScale'>) {
|
||||||
|
if (!data.showCenterScaleRuler) {
|
||||||
|
return {
|
||||||
|
centerScaleRulerVisible: false,
|
||||||
|
centerScaleRulerCenterXPx: 0,
|
||||||
|
centerScaleRulerZeroYPx: 0,
|
||||||
|
centerScaleRulerHeightPx: 0,
|
||||||
|
centerScaleRulerAxisBottomPx: 0,
|
||||||
|
centerScaleRulerZeroVisible: false,
|
||||||
|
centerScaleRulerZeroLabel: '0 m',
|
||||||
|
centerScaleRulerMinorTicks: [] as ScaleRulerMinorTickData[],
|
||||||
|
centerScaleRulerMajorMarks: [] as ScaleRulerMajorMarkData[],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data.stageWidth || !data.stageHeight) {
|
||||||
|
return {
|
||||||
|
centerScaleRulerVisible: false,
|
||||||
|
centerScaleRulerCenterXPx: 0,
|
||||||
|
centerScaleRulerZeroYPx: 0,
|
||||||
|
centerScaleRulerHeightPx: 0,
|
||||||
|
centerScaleRulerAxisBottomPx: 0,
|
||||||
|
centerScaleRulerZeroVisible: false,
|
||||||
|
centerScaleRulerZeroLabel: '0 m',
|
||||||
|
centerScaleRulerMinorTicks: [] as ScaleRulerMinorTickData[],
|
||||||
|
centerScaleRulerMajorMarks: [] as ScaleRulerMajorMarkData[],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const topPadding = 12
|
||||||
|
const rpxUnitPx = getRpxUnitInPx()
|
||||||
|
const compassBottomPaddingPx = 248 * rpxUnitPx
|
||||||
|
const compassDialRadiusPx = (196 * rpxUnitPx) / 2
|
||||||
|
const compassHeadingOverlayHeightPx = 40 * rpxUnitPx
|
||||||
|
const compassOcclusionPaddingPx = 10 * rpxUnitPx
|
||||||
|
const zeroYPx = data.centerScaleRulerAnchorMode === 'compass-center'
|
||||||
|
? Math.round(data.stageHeight - compassBottomPaddingPx - compassDialRadiusPx)
|
||||||
|
: Math.round(data.stageHeight / 2)
|
||||||
|
const fallbackHeight = Math.max(zeroYPx - topPadding, 160)
|
||||||
|
const coveredBottomPx = data.centerScaleRulerAnchorMode === 'compass-center'
|
||||||
|
? Math.round(compassDialRadiusPx + compassHeadingOverlayHeightPx + compassOcclusionPaddingPx)
|
||||||
|
: 0
|
||||||
|
|
||||||
|
if (
|
||||||
|
!data.tileSizePx
|
||||||
|
|| !Number.isFinite(data.zoom)
|
||||||
|
|| !Number.isFinite(data.centerTileY)
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
centerScaleRulerVisible: true,
|
||||||
|
centerScaleRulerCenterXPx: Math.round(data.stageWidth / 2),
|
||||||
|
centerScaleRulerZeroYPx: zeroYPx,
|
||||||
|
centerScaleRulerHeightPx: fallbackHeight,
|
||||||
|
centerScaleRulerAxisBottomPx: coveredBottomPx,
|
||||||
|
centerScaleRulerZeroVisible: data.centerScaleRulerAnchorMode !== 'compass-center',
|
||||||
|
centerScaleRulerZeroLabel: '0 m',
|
||||||
|
centerScaleRulerMinorTicks: [] as ScaleRulerMinorTickData[],
|
||||||
|
centerScaleRulerMajorMarks: [] as ScaleRulerMajorMarkData[],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const centerLat = worldTileYToLat(data.centerTileY + 0.5, data.zoom)
|
||||||
|
const metersPerTile = Math.cos(centerLat * Math.PI / 180) * 40075016.686 / Math.pow(2, data.zoom)
|
||||||
|
const metersPerPixel = metersPerTile / data.tileSizePx
|
||||||
|
const effectivePreviewScale = Number.isFinite(data.previewScale) && data.previewScale > 0 ? data.previewScale : 1
|
||||||
|
const effectiveMetersPerPixel = metersPerPixel / effectivePreviewScale
|
||||||
|
const rulerHeight = Math.floor(zeroYPx - topPadding)
|
||||||
|
|
||||||
|
if (!Number.isFinite(effectiveMetersPerPixel) || effectiveMetersPerPixel <= 0 || rulerHeight < 120) {
|
||||||
|
return {
|
||||||
|
centerScaleRulerVisible: true,
|
||||||
|
centerScaleRulerCenterXPx: Math.round(data.stageWidth / 2),
|
||||||
|
centerScaleRulerZeroYPx: zeroYPx,
|
||||||
|
centerScaleRulerHeightPx: Math.max(rulerHeight, fallbackHeight),
|
||||||
|
centerScaleRulerAxisBottomPx: coveredBottomPx,
|
||||||
|
centerScaleRulerZeroVisible: data.centerScaleRulerAnchorMode !== 'compass-center',
|
||||||
|
centerScaleRulerZeroLabel: '0 m',
|
||||||
|
centerScaleRulerMinorTicks: [] as ScaleRulerMinorTickData[],
|
||||||
|
centerScaleRulerMajorMarks: [] as ScaleRulerMajorMarkData[],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const labelDistanceMeters = getNiceDistanceMeters(effectiveMetersPerPixel * 80)
|
||||||
|
const minorDistanceMeters = labelDistanceMeters / 8
|
||||||
|
const minorStepPx = minorDistanceMeters / effectiveMetersPerPixel
|
||||||
|
const visibleTopLimitPx = rulerHeight - coveredBottomPx
|
||||||
|
const minorTicks: ScaleRulerMinorTickData[] = []
|
||||||
|
const majorMarks: ScaleRulerMajorMarkData[] = []
|
||||||
|
|
||||||
|
for (let index = 1; index <= 200; index += 1) {
|
||||||
|
const topPx = Math.round(rulerHeight - index * minorStepPx)
|
||||||
|
if (topPx < 0) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if (topPx >= visibleTopLimitPx) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
const isHalfMajor = index % 4 === 0
|
||||||
|
const isLabelMajor = index % 8 === 0
|
||||||
|
minorTicks.push({
|
||||||
|
key: `minor-${index}`,
|
||||||
|
topPx,
|
||||||
|
long: isHalfMajor,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (isLabelMajor) {
|
||||||
|
majorMarks.push({
|
||||||
|
key: `major-${index}`,
|
||||||
|
topPx,
|
||||||
|
label: formatScaleDistanceLabel((index / 8) * labelDistanceMeters),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
centerScaleRulerVisible: true,
|
||||||
|
centerScaleRulerCenterXPx: Math.round(data.stageWidth / 2),
|
||||||
|
centerScaleRulerZeroYPx: zeroYPx,
|
||||||
|
centerScaleRulerHeightPx: rulerHeight,
|
||||||
|
centerScaleRulerAxisBottomPx: coveredBottomPx,
|
||||||
|
centerScaleRulerZeroVisible: data.centerScaleRulerAnchorMode !== 'compass-center',
|
||||||
|
centerScaleRulerZeroLabel: '0 m',
|
||||||
|
centerScaleRulerMinorTicks: minorTicks,
|
||||||
|
centerScaleRulerMajorMarks: majorMarks,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function buildEmptyGameInfoSnapshot(): MapEngineGameInfoSnapshot {
|
function buildEmptyGameInfoSnapshot(): MapEngineGameInfoSnapshot {
|
||||||
return {
|
return {
|
||||||
title: '当前游戏',
|
title: '当前游戏',
|
||||||
@@ -170,10 +372,12 @@ Page({
|
|||||||
data: {
|
data: {
|
||||||
showDebugPanel: false,
|
showDebugPanel: false,
|
||||||
showGameInfoPanel: false,
|
showGameInfoPanel: false,
|
||||||
|
showCenterScaleRuler: false,
|
||||||
statusBarHeight: 0,
|
statusBarHeight: 0,
|
||||||
topInsetHeight: 12,
|
topInsetHeight: 12,
|
||||||
hudPanelIndex: 0,
|
hudPanelIndex: 0,
|
||||||
configSourceText: '顺序赛配置',
|
configSourceText: '顺序赛配置',
|
||||||
|
centerScaleRulerAnchorMode: 'screen-center',
|
||||||
gameInfoTitle: '当前游戏',
|
gameInfoTitle: '当前游戏',
|
||||||
gameInfoSubtitle: '未开始',
|
gameInfoSubtitle: '未开始',
|
||||||
gameInfoLocalRows: [],
|
gameInfoLocalRows: [],
|
||||||
@@ -246,12 +450,23 @@ Page({
|
|||||||
mapPulseFxClass: '',
|
mapPulseFxClass: '',
|
||||||
stageFxVisible: false,
|
stageFxVisible: false,
|
||||||
stageFxClass: '',
|
stageFxClass: '',
|
||||||
|
centerScaleRulerVisible: false,
|
||||||
|
centerScaleRulerCenterXPx: 0,
|
||||||
|
centerScaleRulerZeroYPx: 0,
|
||||||
|
centerScaleRulerHeightPx: 0,
|
||||||
|
centerScaleRulerAxisBottomPx: 0,
|
||||||
|
centerScaleRulerZeroVisible: false,
|
||||||
|
centerScaleRulerZeroLabel: '0 m',
|
||||||
|
centerScaleRulerMinorTicks: [],
|
||||||
|
centerScaleRulerMajorMarks: [],
|
||||||
compassTicks: buildCompassTicks(),
|
compassTicks: buildCompassTicks(),
|
||||||
compassLabels: buildCompassLabels(),
|
compassLabels: buildCompassLabels(),
|
||||||
...buildSideButtonVisibility('left'),
|
...buildSideButtonVisibility('left'),
|
||||||
...buildSideButtonState({
|
...buildSideButtonState({
|
||||||
sideButtonMode: 'left',
|
sideButtonMode: 'left',
|
||||||
showGameInfoPanel: false,
|
showGameInfoPanel: false,
|
||||||
|
showCenterScaleRuler: false,
|
||||||
|
centerScaleRulerAnchorMode: 'screen-center',
|
||||||
skipButtonEnabled: false,
|
skipButtonEnabled: false,
|
||||||
gameSessionStatus: 'idle',
|
gameSessionStatus: 'idle',
|
||||||
gpsLockEnabled: false,
|
gpsLockEnabled: false,
|
||||||
@@ -298,6 +513,7 @@ Page({
|
|||||||
|
|
||||||
this.setData({
|
this.setData({
|
||||||
...nextData,
|
...nextData,
|
||||||
|
...buildCenterScaleRulerPatch(mergedData),
|
||||||
...buildSideButtonState(mergedData),
|
...buildSideButtonState(mergedData),
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -391,11 +607,24 @@ Page({
|
|||||||
...buildSideButtonState({
|
...buildSideButtonState({
|
||||||
sideButtonMode: 'left',
|
sideButtonMode: 'left',
|
||||||
showGameInfoPanel: false,
|
showGameInfoPanel: false,
|
||||||
|
showCenterScaleRuler: false,
|
||||||
|
centerScaleRulerAnchorMode: 'screen-center',
|
||||||
skipButtonEnabled: false,
|
skipButtonEnabled: false,
|
||||||
gameSessionStatus: 'idle',
|
gameSessionStatus: 'idle',
|
||||||
gpsLockEnabled: false,
|
gpsLockEnabled: false,
|
||||||
gpsLockAvailable: false,
|
gpsLockAvailable: false,
|
||||||
}),
|
}),
|
||||||
|
...buildCenterScaleRulerPatch({
|
||||||
|
...(mapEngine.getInitialData() as MapPageData),
|
||||||
|
showCenterScaleRuler: false,
|
||||||
|
centerScaleRulerAnchorMode: 'screen-center',
|
||||||
|
stageWidth: 0,
|
||||||
|
stageHeight: 0,
|
||||||
|
topInsetHeight: Math.max(statusBarHeight + 12, menuButtonBottom + 20),
|
||||||
|
zoom: 0,
|
||||||
|
centerTileY: 0,
|
||||||
|
tileSizePx: 0,
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -807,10 +1036,19 @@ Page({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const snapshot = mapEngine.getGameInfoSnapshot()
|
const snapshot = mapEngine.getGameInfoSnapshot()
|
||||||
|
const localRows = snapshot.localRows.concat([
|
||||||
|
{ label: '比例尺开关', value: this.data.showCenterScaleRuler ? '开启' : '关闭' },
|
||||||
|
{ label: '比例尺锚点', value: this.data.centerScaleRulerAnchorMode === 'compass-center' ? '指北针圆心' : '屏幕中心' },
|
||||||
|
{ label: '比例尺可见', value: this.data.centerScaleRulerVisible ? 'true' : 'false' },
|
||||||
|
{ label: '比例尺中心X', value: `${this.data.centerScaleRulerCenterXPx}px` },
|
||||||
|
{ label: '比例尺零点Y', value: `${this.data.centerScaleRulerZeroYPx}px` },
|
||||||
|
{ label: '比例尺高度', value: `${this.data.centerScaleRulerHeightPx}px` },
|
||||||
|
{ label: '比例尺主刻度数', value: String(this.data.centerScaleRulerMajorMarks.length) },
|
||||||
|
])
|
||||||
this.setData({
|
this.setData({
|
||||||
gameInfoTitle: snapshot.title,
|
gameInfoTitle: snapshot.title,
|
||||||
gameInfoSubtitle: snapshot.subtitle,
|
gameInfoSubtitle: snapshot.subtitle,
|
||||||
gameInfoLocalRows: snapshot.localRows,
|
gameInfoLocalRows: localRows,
|
||||||
gameInfoGlobalRows: snapshot.globalRows,
|
gameInfoGlobalRows: snapshot.globalRows,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -823,6 +1061,8 @@ Page({
|
|||||||
...buildSideButtonState({
|
...buildSideButtonState({
|
||||||
sideButtonMode: this.data.sideButtonMode,
|
sideButtonMode: this.data.sideButtonMode,
|
||||||
showGameInfoPanel: true,
|
showGameInfoPanel: true,
|
||||||
|
showCenterScaleRuler: this.data.showCenterScaleRuler,
|
||||||
|
centerScaleRulerAnchorMode: this.data.centerScaleRulerAnchorMode,
|
||||||
skipButtonEnabled: this.data.skipButtonEnabled,
|
skipButtonEnabled: this.data.skipButtonEnabled,
|
||||||
gameSessionStatus: this.data.gameSessionStatus,
|
gameSessionStatus: this.data.gameSessionStatus,
|
||||||
gpsLockEnabled: this.data.gpsLockEnabled,
|
gpsLockEnabled: this.data.gpsLockEnabled,
|
||||||
@@ -837,6 +1077,8 @@ Page({
|
|||||||
...buildSideButtonState({
|
...buildSideButtonState({
|
||||||
sideButtonMode: this.data.sideButtonMode,
|
sideButtonMode: this.data.sideButtonMode,
|
||||||
showGameInfoPanel: false,
|
showGameInfoPanel: false,
|
||||||
|
showCenterScaleRuler: this.data.showCenterScaleRuler,
|
||||||
|
centerScaleRulerAnchorMode: this.data.centerScaleRulerAnchorMode,
|
||||||
skipButtonEnabled: this.data.skipButtonEnabled,
|
skipButtonEnabled: this.data.skipButtonEnabled,
|
||||||
gameSessionStatus: this.data.gameSessionStatus,
|
gameSessionStatus: this.data.gameSessionStatus,
|
||||||
gpsLockEnabled: this.data.gpsLockEnabled,
|
gpsLockEnabled: this.data.gpsLockEnabled,
|
||||||
@@ -878,6 +1120,8 @@ Page({
|
|||||||
...buildSideButtonState({
|
...buildSideButtonState({
|
||||||
sideButtonMode: nextMode,
|
sideButtonMode: nextMode,
|
||||||
showGameInfoPanel: this.data.showGameInfoPanel,
|
showGameInfoPanel: this.data.showGameInfoPanel,
|
||||||
|
showCenterScaleRuler: this.data.showCenterScaleRuler,
|
||||||
|
centerScaleRulerAnchorMode: this.data.centerScaleRulerAnchorMode,
|
||||||
skipButtonEnabled: this.data.skipButtonEnabled,
|
skipButtonEnabled: this.data.skipButtonEnabled,
|
||||||
gameSessionStatus: this.data.gameSessionStatus,
|
gameSessionStatus: this.data.gameSessionStatus,
|
||||||
gpsLockEnabled: this.data.gpsLockEnabled,
|
gpsLockEnabled: this.data.gpsLockEnabled,
|
||||||
@@ -909,6 +1153,8 @@ Page({
|
|||||||
...buildSideButtonState({
|
...buildSideButtonState({
|
||||||
sideButtonMode: this.data.sideButtonMode,
|
sideButtonMode: this.data.sideButtonMode,
|
||||||
showGameInfoPanel: false,
|
showGameInfoPanel: false,
|
||||||
|
showCenterScaleRuler: this.data.showCenterScaleRuler,
|
||||||
|
centerScaleRulerAnchorMode: this.data.centerScaleRulerAnchorMode,
|
||||||
skipButtonEnabled: this.data.skipButtonEnabled,
|
skipButtonEnabled: this.data.skipButtonEnabled,
|
||||||
gameSessionStatus: this.data.gameSessionStatus,
|
gameSessionStatus: this.data.gameSessionStatus,
|
||||||
gpsLockEnabled: this.data.gpsLockEnabled,
|
gpsLockEnabled: this.data.gpsLockEnabled,
|
||||||
@@ -923,6 +1169,8 @@ Page({
|
|||||||
...buildSideButtonState({
|
...buildSideButtonState({
|
||||||
sideButtonMode: this.data.sideButtonMode,
|
sideButtonMode: this.data.sideButtonMode,
|
||||||
showGameInfoPanel: this.data.showGameInfoPanel,
|
showGameInfoPanel: this.data.showGameInfoPanel,
|
||||||
|
showCenterScaleRuler: this.data.showCenterScaleRuler,
|
||||||
|
centerScaleRulerAnchorMode: this.data.centerScaleRulerAnchorMode,
|
||||||
skipButtonEnabled: this.data.skipButtonEnabled,
|
skipButtonEnabled: this.data.skipButtonEnabled,
|
||||||
gameSessionStatus: this.data.gameSessionStatus,
|
gameSessionStatus: this.data.gameSessionStatus,
|
||||||
gpsLockEnabled: this.data.gpsLockEnabled,
|
gpsLockEnabled: this.data.gpsLockEnabled,
|
||||||
@@ -931,6 +1179,46 @@ Page({
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handleToggleCenterScaleRuler() {
|
||||||
|
const nextEnabled = !this.data.showCenterScaleRuler
|
||||||
|
this.data.showCenterScaleRuler = nextEnabled
|
||||||
|
const mergedData = {
|
||||||
|
...this.data,
|
||||||
|
showCenterScaleRuler: nextEnabled,
|
||||||
|
} as MapPageData
|
||||||
|
|
||||||
|
this.setData({
|
||||||
|
showCenterScaleRuler: nextEnabled,
|
||||||
|
...buildCenterScaleRulerPatch(mergedData),
|
||||||
|
...buildSideButtonState(mergedData),
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
handleToggleCenterScaleRulerAnchor() {
|
||||||
|
if (!this.data.showCenterScaleRuler) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextAnchorMode: CenterScaleRulerAnchorMode = this.data.centerScaleRulerAnchorMode === 'screen-center'
|
||||||
|
? 'compass-center'
|
||||||
|
: 'screen-center'
|
||||||
|
this.data.centerScaleRulerAnchorMode = nextAnchorMode
|
||||||
|
const mergedData = {
|
||||||
|
...this.data,
|
||||||
|
centerScaleRulerAnchorMode: nextAnchorMode,
|
||||||
|
} as MapPageData
|
||||||
|
|
||||||
|
this.setData({
|
||||||
|
centerScaleRulerAnchorMode: nextAnchorMode,
|
||||||
|
...buildCenterScaleRulerPatch(mergedData),
|
||||||
|
...buildSideButtonState(mergedData),
|
||||||
|
})
|
||||||
|
|
||||||
|
if (this.data.showGameInfoPanel) {
|
||||||
|
this.syncGameInfoPanelSnapshot()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
handleDebugPanelTap() {},
|
handleDebugPanelTap() {},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -37,11 +37,25 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<view class="map-stage__overlay-center-layer" wx:if="{{!showDebugPanel && !showGameInfoPanel}}">
|
||||||
|
<view class="center-scale-ruler" wx:if="{{centerScaleRulerVisible}}" style="left: {{centerScaleRulerCenterXPx}}px; top: {{centerScaleRulerZeroYPx}}px; height: {{centerScaleRulerHeightPx}}px;">
|
||||||
|
<view class="center-scale-ruler__axis" style="bottom: {{centerScaleRulerAxisBottomPx}}px;"></view>
|
||||||
|
<view class="center-scale-ruler__arrow"></view>
|
||||||
|
<view wx:if="{{centerScaleRulerZeroVisible}}" class="center-scale-ruler__tick center-scale-ruler__tick--major center-scale-ruler__tick--zero" style="top: {{centerScaleRulerHeightPx}}px;"></view>
|
||||||
|
<view wx:if="{{centerScaleRulerZeroVisible}}" class="center-scale-ruler__label center-scale-ruler__label--zero" style="top: {{centerScaleRulerHeightPx}}px;">{{centerScaleRulerZeroLabel}}</view>
|
||||||
|
<view wx:for="{{centerScaleRulerMinorTicks}}" wx:key="key" class="center-scale-ruler__tick {{item.long ? 'center-scale-ruler__tick--major' : ''}}" style="top: {{item.topPx}}px;"></view>
|
||||||
|
<view wx:for="{{centerScaleRulerMajorMarks}}" wx:key="key" class="center-scale-ruler__label" style="top: {{item.topPx}}px;">{{item.label}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
<view class="map-stage__overlay">
|
<view class="map-stage__overlay">
|
||||||
<view class="map-stage__bottom">
|
<view class="map-stage__bottom">
|
||||||
<view class="compass-widget">
|
<view class="compass-widget">
|
||||||
|
<view class="compass-widget__heading-wrap">
|
||||||
<view class="compass-widget__heading">{{sensorHeadingText}}</view>
|
<view class="compass-widget__heading">{{sensorHeadingText}}</view>
|
||||||
|
<view class="compass-widget__edge-arrow-wrap">
|
||||||
<view class="compass-widget__edge-arrow"></view>
|
<view class="compass-widget__edge-arrow"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
<view class="compass-widget__dial {{orientationMode === 'heading-up' ? 'compass-widget__dial--active' : ''}}">
|
<view class="compass-widget__dial {{orientationMode === 'heading-up' ? 'compass-widget__dial--active' : ''}}">
|
||||||
<view class="compass-widget__glass"></view>
|
<view class="compass-widget__glass"></view>
|
||||||
<view class="compass-widget__inner-shadow"></view>
|
<view class="compass-widget__inner-shadow"></view>
|
||||||
@@ -93,8 +107,8 @@
|
|||||||
<cover-view class="map-side-column map-side-column--right-sub" wx:if="{{!showDebugPanel && !showGameInfoPanel && showRightButtonGroups}}" style="top: {{topInsetHeight}}px;">
|
<cover-view class="map-side-column map-side-column--right-sub" wx:if="{{!showDebugPanel && !showGameInfoPanel && 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="{{sideButton11Class}}" bindtap="handleOpenGameInfoPanel"><cover-image class="map-side-button__action-image" src="../../assets/btn_info.png"></cover-image></cover-view>
|
||||||
<cover-view class="map-side-button"><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">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="{{sideButton13Class}}" bindtap="handleToggleCenterScaleRuler"><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="{{sideButton14Class}}" bindtap="handleToggleCenterScaleRulerAnchor"><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="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>
|
</cover-view>
|
||||||
|
|||||||
@@ -97,6 +97,86 @@
|
|||||||
z-index: 4;
|
z-index: 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.map-stage__overlay-center-layer {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center-scale-ruler {
|
||||||
|
position: absolute;
|
||||||
|
width: 220rpx;
|
||||||
|
transform: translate(-50%, -100%);
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center-scale-ruler__axis {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 4rpx;
|
||||||
|
margin-left: -2rpx;
|
||||||
|
border-radius: 999rpx;
|
||||||
|
background: rgba(19, 20, 18, 0.92);
|
||||||
|
}
|
||||||
|
|
||||||
|
.center-scale-ruler__arrow {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
top: -34rpx;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
margin-left: -14rpx;
|
||||||
|
border-left: 14rpx solid transparent;
|
||||||
|
border-right: 14rpx solid transparent;
|
||||||
|
border-bottom: 34rpx solid rgba(19, 20, 18, 0.96);
|
||||||
|
}
|
||||||
|
|
||||||
|
.center-scale-ruler__tick {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
width: 18rpx;
|
||||||
|
height: 4rpx;
|
||||||
|
margin-left: -9rpx;
|
||||||
|
margin-top: -2rpx;
|
||||||
|
border-radius: 999rpx;
|
||||||
|
background: rgba(19, 20, 18, 0.82);
|
||||||
|
}
|
||||||
|
|
||||||
|
.center-scale-ruler__tick--major {
|
||||||
|
width: 32rpx;
|
||||||
|
margin-left: -16rpx;
|
||||||
|
height: 5rpx;
|
||||||
|
margin-top: -2.5rpx;
|
||||||
|
background: rgba(12, 14, 12, 0.96);
|
||||||
|
}
|
||||||
|
|
||||||
|
.center-scale-ruler__tick--zero {
|
||||||
|
width: 34rpx;
|
||||||
|
margin-left: -17rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center-scale-ruler__label {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: 18rpx;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
font-size: 22rpx;
|
||||||
|
line-height: 1;
|
||||||
|
font-weight: 800;
|
||||||
|
color: rgba(19, 20, 18, 0.96);
|
||||||
|
text-shadow: 0 1rpx 0 rgba(255, 255, 255, 0.28);
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center-scale-ruler__label--zero {
|
||||||
|
transform: translateY(-24%);
|
||||||
|
font-size: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
.map-stage__topbar {
|
.map-stage__topbar {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
@@ -329,14 +409,38 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 6rpx;
|
gap: 6rpx;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
position: relative;
|
||||||
|
z-index: 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
.compass-widget__heading-wrap {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0;
|
||||||
|
position: relative;
|
||||||
|
z-index: 21;
|
||||||
}
|
}
|
||||||
|
|
||||||
.compass-widget__heading {
|
.compass-widget__heading {
|
||||||
font-size: 14rpx;
|
min-width: 96rpx;
|
||||||
|
padding: 6rpx 12rpx;
|
||||||
|
font-size: 20rpx;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: rgba(32, 42, 34, 0.72);
|
color: rgba(32, 42, 34, 0.72);
|
||||||
text-shadow: 0 1rpx 0 rgba(255, 255, 255, 0.35);
|
text-shadow: 0 1rpx 0 rgba(255, 255, 255, 0.35);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.compass-widget__edge-arrow-wrap {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 40rpx;
|
||||||
|
height: 20rpx;
|
||||||
|
margin-top: -2rpx;
|
||||||
|
margin-bottom: -4rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.compass-widget__dial {
|
.compass-widget__dial {
|
||||||
@@ -519,8 +623,6 @@
|
|||||||
.compass-widget__edge-arrow {
|
.compass-widget__edge-arrow {
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
margin-top: -2rpx;
|
|
||||||
margin-bottom: -4rpx;
|
|
||||||
border-left: 8rpx solid transparent;
|
border-left: 8rpx solid transparent;
|
||||||
border-right: 8rpx solid transparent;
|
border-right: 8rpx solid transparent;
|
||||||
border-top: 14rpx solid rgba(58, 49, 37, 0.72);
|
border-top: 14rpx solid rgba(58, 49, 37, 0.72);
|
||||||
@@ -530,12 +632,16 @@
|
|||||||
|
|
||||||
.compass-widget__hint {
|
.compass-widget__hint {
|
||||||
max-width: 196rpx;
|
max-width: 196rpx;
|
||||||
font-size: 14rpx;
|
padding: 4rpx 10rpx;
|
||||||
|
border-radius: 999rpx;
|
||||||
|
background: rgba(219, 238, 212, 0.94);
|
||||||
|
font-size: 16rpx;
|
||||||
line-height: 1.3;
|
line-height: 1.3;
|
||||||
color: #d62828;
|
color: #d62828;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
text-shadow: 0 1rpx 0 rgba(255, 255, 255, 0.24);
|
text-shadow: 0 1rpx 0 rgba(255, 255, 255, 0.24);
|
||||||
|
box-shadow: 0 2rpx 8rpx rgba(22, 48, 32, 0.08);
|
||||||
}
|
}
|
||||||
.race-panel-swiper {
|
.race-panel-swiper {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|||||||
Reference in New Issue
Block a user