From b5a6b1b68da471c0ef06ecca1aacf77de1804c35 Mon Sep 17 00:00:00 2001 From: "soroush.asadi" Date: Mon, 1 Jun 2026 21:38:25 +0330 Subject: [PATCH] fix(website): accurate Iran border on homepage map + slow on/off marker blink MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaced the rough 40-point hand-drawn polygon with the real national border (74 vertices, Natural Earth via world.geo.json) and fitted the projection bounding box to Iran's true extent, so the silhouette is recognisable and café markers stay aligned. Reworked the marker animation from a radar-style expanding ring into a slow 3.6s ease-in-out lamp fade (opacity 1->0.2->1) with a halo that glows on and off in sync. Verified via the SVG timeline: opacity 1.0 at 0s, 0.2 at 1.8s, 1.0 at 3.6s. Co-Authored-By: Claude Opus 4.8 --- .../components/sections/iran-map-section.tsx | 111 +++++++++--------- 1 file changed, 56 insertions(+), 55 deletions(-) diff --git a/web/website/src/components/sections/iran-map-section.tsx b/web/website/src/components/sections/iran-map-section.tsx index ab02846..b70c952 100644 --- a/web/website/src/components/sections/iran-map-section.tsx +++ b/web/website/src/components/sections/iran-map-section.tsx @@ -22,11 +22,14 @@ type MarkersApiResponse = { // ── Coordinate transform ────────────────────────────────────────────────────── -// Iran bounding box (degrees) -const MIN_LNG = 44; -const MAX_LNG = 64; -const MIN_LAT = 24; -const MAX_LAT = 41; +// Iran bounding box (degrees) — fitted to the real border extent +// (lng 44.11–63.32, lat 25.08–39.71) with a small margin so the +// silhouette fills the viewBox. Markers reproject with the same box, +// so they stay aligned with the outline. +const MIN_LNG = 43.6; +const MAX_LNG = 63.8; +const MIN_LAT = 24.6; +const MAX_LAT = 40.2; const SVG_W = 600; const SVG_H = 500; @@ -41,34 +44,24 @@ function toPt([lng, lat]: [number, number]) { } // ── Iran silhouette ──────────────────────────────────────────────────────────── -// Simplified 40-point polygon; approximate but recognisable. -// Coordinates are [longitude, latitude] going clockwise from NW. +// Real national border, simplified to 74 vertices (source: Natural Earth via +// world.geo.json). Coordinates are [longitude, latitude]; the ring starts on +// the Caspian (NE) and runs clockwise. Projected through toX/toY below, the +// same transform used for the café markers, so dots land in the right place. const IRAN_OUTLINE: [number, number][] = [ - // NW corner / Turkey-Armenia-Azerbaijan - [44.8, 39.6], [45.5, 39.2], [46.2, 38.9], - [46.8, 39.1], [47.6, 38.9], - // Caspian coast (the concave notch heading south then north again) - [48.3, 38.4], [49.0, 37.5], [49.9, 37.2], - [51.0, 36.9], [52.2, 36.8], [53.0, 36.7], - [54.0, 37.1], [54.7, 37.5], - // NE / Turkmenistan - [55.6, 37.4], [56.9, 37.1], [57.7, 36.8], - [58.7, 37.5], [59.4, 36.8], [60.1, 36.7], - // East / Afghanistan - [61.2, 36.5], [61.3, 35.7], [62.0, 35.5], - [62.5, 34.0], [63.0, 33.0], [63.2, 31.5], - // SE / Pakistan – Oman Sea - [61.8, 29.8], [60.9, 29.5], [60.0, 27.5], - [59.0, 25.9], [58.5, 25.4], - // South coast (Persian Gulf, west-bound) - [57.5, 25.3], [56.4, 25.9], [55.6, 26.0], - [54.5, 27.0], [53.4, 27.3], [52.4, 28.0], - [51.1, 28.4], [50.4, 29.1], [49.0, 29.6], - [48.5, 30.2], [48.2, 30.8], - // West / Iraq border - [47.7, 31.0], [47.2, 32.0], [46.8, 33.2], - [46.2, 34.4], [45.5, 36.0], [45.0, 37.0], - [44.8, 38.1], [44.5, 38.9], [44.8, 39.6], + [53.92, 37.20], [54.80, 37.39], [55.51, 37.96], [56.18, 37.94], [56.62, 38.12], [57.33, 38.03], + [58.44, 37.52], [59.23, 37.41], [60.38, 36.53], [61.12, 36.49], [61.21, 35.65], [60.80, 34.40], + [60.53, 33.68], [60.96, 33.53], [60.54, 32.98], [60.86, 32.18], [60.94, 31.55], [61.70, 31.38], + [61.78, 30.74], [60.87, 29.83], [61.37, 29.30], [61.77, 28.70], [62.73, 28.26], [62.76, 27.38], + [63.23, 27.22], [63.32, 26.76], [61.87, 26.24], [61.50, 25.08], [59.62, 25.38], [58.53, 25.61], + [57.40, 25.74], [56.97, 26.97], [56.49, 27.14], [55.72, 26.96], [54.72, 26.48], [53.49, 26.81], + [52.48, 27.58], [51.52, 27.87], [50.85, 28.81], [50.12, 30.15], [49.58, 29.99], [48.94, 30.32], + [48.57, 29.93], [48.01, 30.45], [48.00, 30.99], [47.69, 30.98], [47.85, 31.71], [47.33, 32.47], + [46.11, 33.02], [45.42, 33.97], [45.65, 34.75], [46.15, 35.09], [46.08, 35.68], [45.42, 35.98], + [44.77, 37.17], [44.23, 37.97], [44.42, 38.28], [44.11, 39.43], [44.79, 39.71], [44.95, 39.34], + [45.46, 38.87], [46.14, 38.74], [46.51, 38.77], [47.69, 39.51], [48.06, 39.58], [48.36, 39.29], + [48.01, 38.79], [48.63, 38.27], [48.88, 38.32], [49.20, 37.58], [50.15, 37.37], [50.84, 36.87], + [52.26, 36.70], [53.83, 36.97], ]; const IRAN_PATH = @@ -153,42 +146,50 @@ async function IranMapSvg() { ))} - {/* Café blinking dots */} + {/* Café markers — each glows slowly on and off like a small lamp. + Halo and core brighten/dim together (ease-in-out), staggered so the + map twinkles organically rather than pulsing in unison. */} {markers.map((m, idx) => { const cx = toX(m.longitude); const cy = toY(m.latitude); - // Stagger animation delay so dots don't all pulse in sync - const delay = `${(idx * 0.4) % 2}s`; + const delay = `${((idx * 0.7) % 3.6).toFixed(2)}s`; + const dur = "3.6s"; + // ease-in-out for a smooth lamp-like fade + const ease = "0.4 0 0.6 1; 0.4 0 0.6 1"; return ( - {/* Outer pulse ring */} - - + {/* Soft halo */} + - {/* Core dot */} - + {/* Core dot — turns on (bright, slightly larger) and off (dim) */} + +