feat(map): generate mathematically accurate 100x50 world dot matrix and align country pinpoint coordinates
This commit is contained in:
1 parent
eb09f43454
commit
c3f9ab43ab
3 files changed
+114
-77
No files matched your search
@@ -31,51 +31,62 @@ interface GeoPayload {
|
||||
}
|
||||
|
||||
/**
|
||||
* 80x40 Equirectangular World Map Dot-Matrix Bitmask
|
||||
* 100x50 High-Accuracy Equirectangular World Map Dot-Matrix Bitmask
|
||||
* Mathematically aligned with Natural Earth 50m physical geography
|
||||
* '#' = Landmass dot | '.' = Ocean
|
||||
* Matches 2:1 aspect ratio (1000x500 SVG viewBox)
|
||||
*/
|
||||
const WORLD_DOT_MATRIX: string[] = [
|
||||
"................................................................................",
|
||||
"..........................##########............................................",
|
||||
".................#####...############......................#####................",
|
||||
"........#####...######...############.........####.......##############.........",
|
||||
".....#################....##########........#######...####################......",
|
||||
"....###################....########........#########.#######################....",
|
||||
"....###################......####.........###################################...",
|
||||
"......#################...................####################################..",
|
||||
"........###############..................######################################.",
|
||||
".........##############.................#####.################################..",
|
||||
".........#############..................####..###############################...",
|
||||
"..........###########...................#####..##############################...",
|
||||
"..........##########....................######.############################.....",
|
||||
"...........########.......#.............##################################......",
|
||||
"............#######.....####.............################################.......",
|
||||
".............###..##......###...........#########..#####################........",
|
||||
"................####....................#########....###################........",
|
||||
".................###...................###########....#####...#########.........",
|
||||
"..................###..................############....###.....#######..........",
|
||||
"...................###................#############....##.......#####...........",
|
||||
"....................#######...........#############.............#####.#.........",
|
||||
"....................#########.........#############..............####.##........",
|
||||
"....................##########.........###########................######........",
|
||||
"....................###########.........#########..................#######......",
|
||||
"....................############.........########.................####.###......",
|
||||
".....................###########..........#######...............................",
|
||||
"......................#########...........######......................#####.....",
|
||||
"......................########............######....................#########...",
|
||||
".......................######.............#####....................##########...",
|
||||
".......................#####...............####....................##########...",
|
||||
".......................####................###.....................#########....",
|
||||
".......................###..................#.......................#######.....",
|
||||
".......................##................................................#..##..",
|
||||
".......................##...................................................#...",
|
||||
".......................#........................................................",
|
||||
"................................................................................",
|
||||
"................................................................................",
|
||||
"................................................................................",
|
||||
"................................................................................",
|
||||
"................................................................................",
|
||||
"....................................................................................................",
|
||||
"...........................######....#######........................................................",
|
||||
"....................###########################.....########..#######..##.#####.....................",
|
||||
"...............###############################......#######.......####....########.....###.##.......",
|
||||
"...............###############...#############.........#........####.#################.#####........",
|
||||
"#..#############################..###########..#.....########.######################################",
|
||||
"#################################..#######.####.....################################################",
|
||||
".################################..####....######..#################################################",
|
||||
".########################..######...###........###.###############################################..",
|
||||
"..######....#######################............###..######################################...####...",
|
||||
"####.........######################............###########################################...##..###",
|
||||
"..............######################............###########################################.##......",
|
||||
"...............#####################...........##############################################.......",
|
||||
"...............################................#################.##########################.........",
|
||||
"...............###############...........###...###########################################..........",
|
||||
"................##############...............#.#####################################.#####..........",
|
||||
".................###########...##............########################################.#.............",
|
||||
".................#######..###...............########################################.##..#..........",
|
||||
".....##...........#####..######..............########################################...............",
|
||||
"......#............##############............######################..#############.#......#.........",
|
||||
".....................######.#.####........##.#####################....####..#####..##.....#.........",
|
||||
"........................###..#####...........#####################....###..#.####..##.....#.....#...",
|
||||
"..........................########...........####################.....###..######.####.##...#...#...",
|
||||
".....#......................########..........##################......#.#...###.######.......#.#.#..",
|
||||
"......#.................#..##########..............#############......#.....###########..........##.",
|
||||
"..#.....................##.#############............##########...............################...###.",
|
||||
".##...#....................##############............#########...#............################......",
|
||||
"..#........#...............##############....##......#########........#........########.#########..#",
|
||||
"###....#....................############.............###########....................#######.#.###..#",
|
||||
"#......####.................############........#....############..................########.....#..#",
|
||||
"###..#....###.................#########..............########.##.##...............##########..####.#",
|
||||
"..............#...............#########..............#######..##.................############..##.#.",
|
||||
"...................#..........#######.................######..#..................############.......",
|
||||
"..............................#######.................#####......................############.......",
|
||||
"............................########..................####.......................####..######....##.",
|
||||
".............................######....................................................#####......##",
|
||||
".............................####........................................................###.....###",
|
||||
"##..........................####................................#.........................##....###.",
|
||||
"............................####............................#........#..........................#...",
|
||||
".............................###.#.....#..............................#.........................##..",
|
||||
".............................####......##.....................................................#.....",
|
||||
"..................................#..#....#.........................................................",
|
||||
"................................###.................................................................",
|
||||
"..............................####...........................#########.######################..#....",
|
||||
".....................###....######............####################################################..",
|
||||
".........#########################.........#######################################################..",
|
||||
"....#############################..###.###########################################################..",
|
||||
".#..#############################################################################################...",
|
||||
"#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.",
|
||||
"....................................................................................................",
|
||||
];
|
||||
|
||||
export default function VisitorWorldMap() {
|
||||
@@ -568,6 +579,7 @@ export default function VisitorWorldMap() {
|
||||
|
||||
{/* Expand to Fullscreen War-Room Button */}
|
||||
<button
|
||||
id="world-map-header-expand-btn"
|
||||
type="button"
|
||||
onClick={() => {
|
||||
haptic.openModal();
|
||||
@@ -601,14 +613,14 @@ export default function VisitorWorldMap() {
|
||||
id="ocean-dot-matrix"
|
||||
x="0"
|
||||
y="0"
|
||||
width="12.5"
|
||||
height="12.5"
|
||||
width="10"
|
||||
height="10"
|
||||
patternUnits="userSpaceOnUse"
|
||||
>
|
||||
<circle
|
||||
cx="6.25"
|
||||
cy="6.25"
|
||||
r="1"
|
||||
cx="5"
|
||||
cy="5"
|
||||
r="0.85"
|
||||
className="fill-current opacity-[0.06] dark:opacity-[0.08]"
|
||||
/>
|
||||
</pattern>
|
||||
@@ -624,7 +636,7 @@ export default function VisitorWorldMap() {
|
||||
key={dot.key}
|
||||
cx={dot.cx}
|
||||
cy={dot.cy}
|
||||
r="2.6"
|
||||
r="2.2"
|
||||
/>
|
||||
))}
|
||||
</g>
|
||||
@@ -677,6 +689,7 @@ export default function VisitorWorldMap() {
|
||||
<span>Your Location</span>
|
||||
</span>
|
||||
<button
|
||||
id="world-map-legend-expand-btn"
|
||||
type="button"
|
||||
onClick={() => {
|
||||
haptic.tap();
|
||||
@@ -913,11 +926,11 @@ export default function VisitorWorldMap() {
|
||||
id="fullscreen-ocean-matrix"
|
||||
x="0"
|
||||
y="0"
|
||||
width="12.5"
|
||||
height="12.5"
|
||||
width="10"
|
||||
height="10"
|
||||
patternUnits="userSpaceOnUse"
|
||||
>
|
||||
<circle cx="6.25" cy="6.25" r="1" className="fill-current opacity-[0.06] dark:opacity-[0.10]" />
|
||||
<circle cx="5" cy="5" r="0.85" className="fill-current opacity-[0.06] dark:opacity-[0.10]" />
|
||||
</pattern>
|
||||
</defs>
|
||||
|
||||
@@ -925,7 +938,7 @@ export default function VisitorWorldMap() {
|
||||
|
||||
<g className="fill-current opacity-[0.25] dark:opacity-[0.35]">
|
||||
{landDots.map((dot) => (
|
||||
<circle key={dot.key} cx={dot.cx} cy={dot.cy} r="2.6" />
|
||||
<circle key={dot.key} cx={dot.cx} cy={dot.cy} r="2.2" />
|
||||
))}
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
+49
-25
@@ -5,31 +5,55 @@ export const prerender = false;
|
||||
// Country code to coordinates (normalized 0-100% on Equirectangular / Mercator map)
|
||||
// and country display metadata
|
||||
export const COUNTRY_COORDS: Record<string, { name: string; flag: string; x: number; y: number }> = {
|
||||
PH: { name: 'Philippines', flag: '🇵🇭', x: 81.5, y: 55.2 },
|
||||
US: { name: 'United States', flag: '🇺🇸', x: 23.5, y: 38.0 },
|
||||
CA: { name: 'Canada', flag: '🇨🇦', x: 22.0, y: 27.0 },
|
||||
GB: { name: 'United Kingdom', flag: '🇬🇧', x: 48.0, y: 28.5 },
|
||||
DE: { name: 'Germany', flag: '🇩🇪', x: 51.5, y: 29.5 },
|
||||
FR: { name: 'France', flag: '🇫🇷', x: 49.5, y: 33.0 },
|
||||
NL: { name: 'Netherlands', flag: '🇳🇱', x: 50.2, y: 28.8 },
|
||||
SG: { name: 'Singapore', flag: '🇸🇬', x: 78.5, y: 59.5 },
|
||||
JP: { name: 'Japan', flag: '🇯🇵', x: 86.8, y: 40.0 },
|
||||
KR: { name: 'South Korea', flag: '🇰🇷', x: 84.0, y: 40.5 },
|
||||
AU: { name: 'Australia', flag: '🇦🇺', x: 87.0, y: 76.0 },
|
||||
NZ: { name: 'New Zealand', flag: '🇳🇿', x: 94.5, y: 84.0 },
|
||||
IN: { name: 'India', flag: '🇮🇳', x: 72.0, y: 48.5 },
|
||||
BR: { name: 'Brazil', flag: '🇧🇷', x: 34.5, y: 68.0 },
|
||||
AE: { name: 'United Arab Emirates', flag: '🇦🇪', x: 63.8, y: 46.5 },
|
||||
VN: { name: 'Vietnam', flag: '🇻🇳', x: 79.5, y: 53.0 },
|
||||
ID: { name: 'Indonesia', flag: '🇮🇩', x: 81.0, y: 63.5 },
|
||||
MY: { name: 'Malaysia', flag: '🇲🇾', x: 78.0, y: 58.0 },
|
||||
ES: { name: 'Spain', flag: '🇪🇸', x: 47.0, y: 36.5 },
|
||||
IT: { name: 'Italy', flag: '🇮🇹', x: 52.5, y: 34.8 },
|
||||
SE: { name: 'Sweden', flag: '🇸🇪', x: 53.0, y: 22.0 },
|
||||
CH: { name: 'Switzerland', flag: '🇨🇭', x: 50.8, y: 32.5 },
|
||||
IE: { name: 'Ireland', flag: '🇮🇪', x: 46.2, y: 29.0 },
|
||||
HK: { name: 'Hong Kong', flag: '🇭🇰', x: 80.5, y: 49.5 },
|
||||
TW: { name: 'Taiwan', flag: '🇹🇼', x: 82.8, y: 49.0 },
|
||||
PH: { name: 'Philippines', flag: '🇵🇭', x: 83.8, y: 42.9 },
|
||||
US: { name: 'United States', flag: '🇺🇸', x: 22.6, y: 27.9 },
|
||||
CA: { name: 'Canada', flag: '🇨🇦', x: 20.5, y: 18.8 },
|
||||
GB: { name: 'United Kingdom', flag: '🇬🇧', x: 49.4, y: 20.3 },
|
||||
DE: { name: 'Germany', flag: '🇩🇪', x: 52.9, y: 21.6 },
|
||||
FR: { name: 'France', flag: '🇫🇷', x: 50.6, y: 24.3 },
|
||||
NL: { name: 'Netherlands', flag: '🇳🇱', x: 51.5, y: 21.0 },
|
||||
SG: { name: 'Singapore', flag: '🇸🇬', x: 78.8, y: 49.3 },
|
||||
JP: { name: 'Japan', flag: '🇯🇵', x: 88.4, y: 29.9 },
|
||||
KR: { name: 'South Korea', flag: '🇰🇷', x: 85.5, y: 30.1 },
|
||||
AU: { name: 'Australia', flag: '🇦🇺', x: 87.2, y: 64.0 },
|
||||
NZ: { name: 'New Zealand', flag: '🇳🇿', x: 98.6, y: 72.7 },
|
||||
IN: { name: 'India', flag: '🇮🇳', x: 71.9, y: 38.6 },
|
||||
BR: { name: 'Brazil', flag: '🇧🇷', x: 35.6, y: 57.9 },
|
||||
AE: { name: 'United Arab Emirates', flag: '🇦🇪', x: 65.0, y: 37.0 },
|
||||
VN: { name: 'Vietnam', flag: '🇻🇳', x: 80.1, y: 42.2 },
|
||||
ID: { name: 'Indonesia', flag: '🇮🇩', x: 81.6, y: 50.4 },
|
||||
MY: { name: 'Malaysia', flag: '🇲🇾', x: 78.3, y: 47.7 },
|
||||
ES: { name: 'Spain', flag: '🇪🇸', x: 49.0, y: 27.5 },
|
||||
IT: { name: 'Italy', flag: '🇮🇹', x: 53.5, y: 26.7 },
|
||||
SE: { name: 'Sweden', flag: '🇸🇪', x: 55.2, y: 16.6 },
|
||||
CH: { name: 'Switzerland', flag: '🇨🇭', x: 52.3, y: 24.0 },
|
||||
IE: { name: 'Ireland', flag: '🇮🇪', x: 47.7, y: 20.3 },
|
||||
HK: { name: 'Hong Kong', flag: '🇭🇰', x: 81.7, y: 37.6 },
|
||||
TW: { name: 'Taiwan', flag: '🇹🇼', x: 83.6, y: 36.8 },
|
||||
CN: { name: 'China', flag: '🇨🇳', x: 78.9, y: 30.1 },
|
||||
MX: { name: 'Mexico', flag: '🇲🇽', x: 21.5, y: 36.9 },
|
||||
PL: { name: 'Poland', flag: '🇵🇱', x: 55.3, y: 21.2 },
|
||||
NO: { name: 'Norway', flag: '🇳🇴', x: 52.4, y: 16.4 },
|
||||
FI: { name: 'Finland', flag: '🇫🇮', x: 57.2, y: 15.6 },
|
||||
TH: { name: 'Thailand', flag: '🇹🇭', x: 78.1, y: 41.2 },
|
||||
ZA: { name: 'South Africa', flag: '🇿🇦', x: 56.4, y: 67.0 },
|
||||
AR: { name: 'Argentina', flag: '🇦🇷', x: 32.3, y: 71.3 },
|
||||
CL: { name: 'Chile', flag: '🇨🇱', x: 30.1, y: 69.8 },
|
||||
EG: { name: 'Egypt', flag: '🇪🇬', x: 58.6, y: 35.1 },
|
||||
SA: { name: 'Saudi Arabia', flag: '🇸🇦', x: 62.5, y: 36.7 },
|
||||
TR: { name: 'Turkey', flag: '🇹🇷', x: 59.8, y: 28.4 },
|
||||
IL: { name: 'Israel', flag: '🇮🇱', x: 59.7, y: 32.8 },
|
||||
UA: { name: 'Ukraine', flag: '🇺🇦', x: 58.7, y: 23.1 },
|
||||
RO: { name: 'Romania', flag: '🇷🇴', x: 56.9, y: 24.5 },
|
||||
BE: { name: 'Belgium', flag: '🇧🇪', x: 51.2, y: 21.9 },
|
||||
AT: { name: 'Austria', flag: '🇦🇹', x: 54.0, y: 23.6 },
|
||||
CZ: { name: 'Czechia', flag: '🇨🇿', x: 54.3, y: 22.3 },
|
||||
PT: { name: 'Portugal', flag: '🇵🇹', x: 47.7, y: 28.1 },
|
||||
GR: { name: 'Greece', flag: '🇬🇷', x: 56.1, y: 28.3 },
|
||||
DK: { name: 'Denmark', flag: '🇩🇰', x: 52.6, y: 18.7 },
|
||||
PK: { name: 'Pakistan', flag: '🇵🇰', x: 69.3, y: 33.1 },
|
||||
BD: { name: 'Bangladesh', flag: '🇧🇩', x: 75.1, y: 36.8 },
|
||||
RU: { name: 'Russia', flag: '🇷🇺', x: 79.3, y: 15.8 },
|
||||
};
|
||||
|
||||
// In-memory country visitor counters across edge runtime instances
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "node_modules/wrangler/config-schema.json",
|
||||
"name": "curved-cloud",
|
||||
"name": "portfolioo",
|
||||
"compatibility_date": "2026-10-12",
|
||||
"kv_namespaces": [
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user