feat(hunt): track walking distance via GPS, show live locations on map
Add foreground-only GPS distance tracking for hunts
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Client-only team color assignment for the live map.
|
||||
*
|
||||
* A fixed 20-color high-contrast palette is shuffled once per page-load and
|
||||
* assigned to teams by their stable order (the order returned by the map
|
||||
* endpoint). Colors are team-shared but NOT persisted, so a refresh may
|
||||
* reassign them. Every member of a team resolves to the same color.
|
||||
*/
|
||||
|
||||
const PALETTE = [
|
||||
'#e6194b',
|
||||
'#3cb44b',
|
||||
'#4363d8',
|
||||
'#f58231',
|
||||
'#911eb4',
|
||||
'#46f0f0',
|
||||
'#f032e6',
|
||||
'#bcf60c',
|
||||
'#fabebe',
|
||||
'#008080',
|
||||
'#e6beff',
|
||||
'#9a6324',
|
||||
'#fffac8',
|
||||
'#800000',
|
||||
'#aaffc3',
|
||||
'#808000',
|
||||
'#ffd8b1',
|
||||
'#000075',
|
||||
'#808080',
|
||||
'#ff4d00'
|
||||
] as const;
|
||||
|
||||
function shuffled<T>(input: readonly T[]): T[] {
|
||||
const arr = [...input];
|
||||
for (let i = arr.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
[arr[i], arr[j]] = [arr[j]!, arr[i]!];
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
/** Darken a hex color by a factor (0..1) for trail lines. */
|
||||
export function darken(hex: string, factor = 0.75): string {
|
||||
const n = parseInt(hex.slice(1), 16);
|
||||
const r = Math.round(((n >> 16) & 255) * factor);
|
||||
const g = Math.round(((n >> 8) & 255) * factor);
|
||||
const b = Math.round((n & 255) * factor);
|
||||
return `#${((1 << 24) | (r << 16) | (g << 8) | b).toString(16).slice(1)}`;
|
||||
}
|
||||
|
||||
export function useTeamColors() {
|
||||
// Shuffled once per composable instance (i.e. per page-load).
|
||||
const colors = shuffled(PALETTE);
|
||||
|
||||
/** Build a teamId -> color map from an ordered list of team ids. */
|
||||
function assign(orderedTeamIds: number[]): Map<number, string> {
|
||||
const map = new Map<number, string>();
|
||||
orderedTeamIds.forEach((id, i) => {
|
||||
map.set(id, colors[i % colors.length]!);
|
||||
});
|
||||
return map;
|
||||
}
|
||||
|
||||
return { assign, colors, darken };
|
||||
}
|
||||
Reference in New Issue
Block a user