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

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

View File

@@ -0,0 +1,87 @@
export type ControlPointStyleId = 'classic-ring' | 'solid-dot' | 'double-ring' | 'badge' | 'pulse-core'
export type CourseLegStyleId = 'classic-leg' | 'dashed-leg' | 'glow-leg' | 'progress-leg'
export interface ControlPointStyleEntry {
style: ControlPointStyleId
colorHex: string
sizeScale?: number
accentRingScale?: number
glowStrength?: number
labelScale?: number
labelColorHex?: string
}
export interface CourseLegStyleEntry {
style: CourseLegStyleId
colorHex: string
widthScale?: number
glowStrength?: number
}
export interface ScoreBandStyleEntry extends ControlPointStyleEntry {
min: number
max: number
}
export interface SequentialCourseStyleConfig {
controls: {
default: ControlPointStyleEntry
current: ControlPointStyleEntry
completed: ControlPointStyleEntry
skipped: ControlPointStyleEntry
start: ControlPointStyleEntry
finish: ControlPointStyleEntry
}
legs: {
default: CourseLegStyleEntry
completed: CourseLegStyleEntry
}
}
export interface ScoreOCourseStyleConfig {
controls: {
default: ControlPointStyleEntry
focused: ControlPointStyleEntry
collected: ControlPointStyleEntry
start: ControlPointStyleEntry
finish: ControlPointStyleEntry
scoreBands: ScoreBandStyleEntry[]
}
}
export interface CourseStyleConfig {
sequential: SequentialCourseStyleConfig
scoreO: ScoreOCourseStyleConfig
}
export const DEFAULT_COURSE_STYLE_CONFIG: CourseStyleConfig = {
sequential: {
controls: {
default: { style: 'classic-ring', colorHex: '#cc006b', sizeScale: 1, labelScale: 1 },
current: { style: 'pulse-core', colorHex: '#38fff2', sizeScale: 1.08, accentRingScale: 1.28, glowStrength: 0.9, labelScale: 1.08, labelColorHex: '#fff4fb' },
completed: { style: 'solid-dot', colorHex: '#7e838a', sizeScale: 0.88, labelScale: 0.96 },
skipped: { style: 'badge', colorHex: '#8a9198', sizeScale: 0.9, accentRingScale: 1.12, labelScale: 0.94 },
start: { style: 'double-ring', colorHex: '#cc006b', sizeScale: 1.04, accentRingScale: 1.3, labelScale: 1.02 },
finish: { style: 'double-ring', colorHex: '#cc006b', sizeScale: 1.08, accentRingScale: 1.34, glowStrength: 0.32, labelScale: 1.06, labelColorHex: '#fff4de' },
},
legs: {
default: { style: 'classic-leg', colorHex: '#cc006b', widthScale: 1 },
completed: { style: 'progress-leg', colorHex: '#7a8088', widthScale: 0.92, glowStrength: 0.24 },
},
},
scoreO: {
controls: {
default: { style: 'badge', colorHex: '#cc006b', sizeScale: 0.96, accentRingScale: 1.1, labelScale: 1.02 },
focused: { style: 'pulse-core', colorHex: '#fff0fa', sizeScale: 1.12, accentRingScale: 1.36, glowStrength: 1, labelScale: 1.12, labelColorHex: '#fffafc' },
collected: { style: 'solid-dot', colorHex: '#d6dae0', sizeScale: 0.82, labelScale: 0.92 },
start: { style: 'double-ring', colorHex: '#cc006b', sizeScale: 1.02, accentRingScale: 1.24, labelScale: 1.02 },
finish: { style: 'double-ring', colorHex: '#cc006b', sizeScale: 1.06, accentRingScale: 1.28, glowStrength: 0.26, labelScale: 1.04, labelColorHex: '#fff4de' },
scoreBands: [
{ min: 0, max: 19, style: 'badge', colorHex: '#56ccf2', sizeScale: 0.88, accentRingScale: 1.06, labelScale: 0.94 },
{ min: 20, max: 49, style: 'badge', colorHex: '#f2c94c', sizeScale: 1.02, accentRingScale: 1.18, labelScale: 1.02 },
{ min: 50, max: 999999, style: 'badge', colorHex: '#eb5757', sizeScale: 1.14, accentRingScale: 1.32, glowStrength: 0.72, labelScale: 1.1 },
],
},
},
}

View File

@@ -0,0 +1,109 @@
export type GpsMarkerStyleId = 'dot' | 'beacon' | 'disc' | 'badge'
export type GpsMarkerSizePreset = 'small' | 'medium' | 'large'
export type GpsMarkerAnimationProfile = 'minimal' | 'dynamic-runner' | 'warning-reactive'
export type GpsMarkerMotionState = 'idle' | 'moving' | 'fast-moving' | 'warning'
export type GpsMarkerColorPreset =
| 'mint'
| 'cyan'
| 'sky'
| 'blue'
| 'violet'
| 'pink'
| 'orange'
| 'yellow'
export type GpsMarkerLogoMode = 'center-badge'
export interface GpsMarkerColorPresetEntry {
colorHex: string
ringColorHex: string
indicatorColorHex: string
}
export const GPS_MARKER_COLOR_PRESET_MAP: Record<GpsMarkerColorPreset, GpsMarkerColorPresetEntry> = {
mint: {
colorHex: '#18b39a',
ringColorHex: '#ffffff',
indicatorColorHex: '#9bfff0',
},
cyan: {
colorHex: '#1db7cf',
ringColorHex: '#ffffff',
indicatorColorHex: '#b2f7ff',
},
sky: {
colorHex: '#54a3ff',
ringColorHex: '#ffffff',
indicatorColorHex: '#d6efff',
},
blue: {
colorHex: '#4568ff',
ringColorHex: '#ffffff',
indicatorColorHex: '#bec9ff',
},
violet: {
colorHex: '#8658ff',
ringColorHex: '#ffffff',
indicatorColorHex: '#dbcaff',
},
pink: {
colorHex: '#ff5cb5',
ringColorHex: '#ffffff',
indicatorColorHex: '#ffd0ea',
},
orange: {
colorHex: '#ff9238',
ringColorHex: '#ffffff',
indicatorColorHex: '#ffd7b0',
},
yellow: {
colorHex: '#f3c72b',
ringColorHex: '#ffffff',
indicatorColorHex: '#fff1ae',
},
}
export interface GpsMarkerStyleConfig {
visible: boolean
style: GpsMarkerStyleId
size: GpsMarkerSizePreset
colorPreset: GpsMarkerColorPreset
colorHex: string
ringColorHex: string
indicatorColorHex: string
showHeadingIndicator: boolean
animationProfile: GpsMarkerAnimationProfile
motionState: GpsMarkerMotionState
motionIntensity: number
pulseStrength: number
headingAlpha: number
effectScale: number
wakeStrength: number
warningGlowStrength: number
indicatorScale: number
logoScale: number
logoUrl: string
logoMode: GpsMarkerLogoMode
}
export const DEFAULT_GPS_MARKER_STYLE_CONFIG: GpsMarkerStyleConfig = {
visible: true,
style: 'beacon',
size: 'medium',
colorPreset: 'cyan',
colorHex: GPS_MARKER_COLOR_PRESET_MAP.cyan.colorHex,
ringColorHex: GPS_MARKER_COLOR_PRESET_MAP.cyan.ringColorHex,
indicatorColorHex: GPS_MARKER_COLOR_PRESET_MAP.cyan.indicatorColorHex,
showHeadingIndicator: true,
animationProfile: 'dynamic-runner',
motionState: 'idle',
motionIntensity: 0,
pulseStrength: 1,
headingAlpha: 1,
effectScale: 1,
wakeStrength: 0,
warningGlowStrength: 0,
indicatorScale: 1,
logoScale: 1,
logoUrl: '',
logoMode: 'center-badge',
}

View File

@@ -0,0 +1,92 @@
export type TrackDisplayMode = 'none' | 'full' | 'tail'
export type TrackStyleProfile = 'classic' | 'neon'
export type TrackTailLengthPreset = 'short' | 'medium' | 'long'
export type TrackColorPreset =
| 'mint'
| 'cyan'
| 'sky'
| 'blue'
| 'violet'
| 'pink'
| 'orange'
| 'yellow'
export interface TrackColorPresetEntry {
colorHex: string
headColorHex: string
}
export const TRACK_TAIL_LENGTH_METERS: Record<TrackTailLengthPreset, number> = {
short: 32,
medium: 52,
long: 78,
}
export const TRACK_COLOR_PRESET_MAP: Record<TrackColorPreset, TrackColorPresetEntry> = {
mint: {
colorHex: '#15a38d',
headColorHex: '#63fff0',
},
cyan: {
colorHex: '#18b8c9',
headColorHex: '#7cf4ff',
},
sky: {
colorHex: '#4a9cff',
headColorHex: '#c9eeff',
},
blue: {
colorHex: '#3a63ff',
headColorHex: '#9fb4ff',
},
violet: {
colorHex: '#7c4dff',
headColorHex: '#d0b8ff',
},
pink: {
colorHex: '#ff4fb3',
headColorHex: '#ffc0ec',
},
orange: {
colorHex: '#ff8a2b',
headColorHex: '#ffd0a3',
},
yellow: {
colorHex: '#f0c419',
headColorHex: '#fff0a8',
},
}
export interface TrackVisualizationConfig {
mode: TrackDisplayMode
style: TrackStyleProfile
tailLength: TrackTailLengthPreset
colorPreset: TrackColorPreset
tailMeters: number
tailMaxSeconds: number
fadeOutWhenStill: boolean
stillSpeedKmh: number
fadeOutDurationMs: number
colorHex: string
headColorHex: string
widthPx: number
headWidthPx: number
glowStrength: number
}
export const DEFAULT_TRACK_VISUALIZATION_CONFIG: TrackVisualizationConfig = {
mode: 'full',
style: 'neon',
tailLength: 'medium',
colorPreset: 'mint',
tailMeters: TRACK_TAIL_LENGTH_METERS.medium,
tailMaxSeconds: 30,
fadeOutWhenStill: true,
stillSpeedKmh: 0.6,
fadeOutDurationMs: 3000,
colorHex: TRACK_COLOR_PRESET_MAP.mint.colorHex,
headColorHex: TRACK_COLOR_PRESET_MAP.mint.headColorHex,
widthPx: 4.2,
headWidthPx: 6.8,
glowStrength: 0.2,
}