Skip to content

Commit 8438b80

Browse files
committed
Fix hint to use Leaflet CircleMarker and better randomized offsets
1 parent 2f8e87d commit 8438b80

File tree

1 file changed

+44
-3
lines changed

1 file changed

+44
-3
lines changed

components/Map.js

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,53 @@
11
import React, { useEffect, useMemo, useState } from "react";
22
import dynamic from "next/dynamic";
3-
import { Circle, Marker, Polyline, Popup, Tooltip, useMapEvents } from "react-leaflet";
3+
import { CircleMarker, Marker, Polyline, Tooltip, useMapEvents } from "react-leaflet";
44
import { useTranslation } from '@/components/useTranslations';
55
import 'leaflet/dist/leaflet.css';
66
import customPins from '../public/customPins.json' with { type: "module" };
77
import guestNameString from "@/serverUtils/guestNameFromString";
88
import CountryFlag from './utils/countryFlag';
9-
const hintMul = 5000000 / 20000; //5000000 for all countries (20,000 km)
9+
const hintMul = 7500000 / 20000; //7500000 for all countries (20,000 km)
10+
11+
// Simple seeded random for stable hint offset per round
12+
function seededRandom(seed) {
13+
const x = Math.sin(seed * 9999) * 10000;
14+
return x - Math.floor(x);
15+
}
16+
17+
// HintCircle component that scales with zoom
18+
function HintCircle({ location, gameOptions, round }) {
19+
const [zoom, setZoom] = useState(2);
20+
21+
const map = useMapEvents({
22+
zoomend: () => setZoom(map.getZoom()),
23+
});
24+
25+
const radius = hintMul * (gameOptions?.maxDist ?? 20000);
26+
const seed = round ?? 1;
27+
const radiusDeg = radius / 111000;
28+
29+
// Offset center by 5-95% of radius in a random direction
30+
// Use location coords as part of seed for more variation
31+
const locSeed = Math.abs(location.lat * 1000 + location.long * 1000) + seed;
32+
const offsetFraction = 0.05 + seededRandom(locSeed) * 0.9;
33+
const offsetAngle = seededRandom(locSeed * 7.3) * 2 * Math.PI;
34+
const offsetDeg = radiusDeg * offsetFraction;
35+
const centerLat = location.lat + offsetDeg * Math.cos(offsetAngle);
36+
const centerLng = location.long + offsetDeg * Math.sin(offsetAngle);
37+
38+
// Convert meters to pixels at current zoom
39+
// At zoom 0, 1 pixel ≈ 156543 meters at equator
40+
const metersPerPixel = 156543 / Math.pow(2, zoom);
41+
const pixelRadius = radius / metersPerPixel;
42+
43+
return (
44+
<CircleMarker
45+
center={{ lat: centerLat, lng: centerLng }}
46+
radius={pixelRadius}
47+
className="hintCircle"
48+
/>
49+
);
50+
}
1051

1152
// Dynamic import of react-leaflet components
1253
const MapContainer = dynamic(
@@ -249,7 +290,7 @@ const MapComponent = ({ shown, options, ws, session, pinPoint, setPinPoint, answ
249290
} */}
250291

251292
{showHint && location && (
252-
<Circle center={{ lat: location.lat, lng: location.long }} radius={hintMul * (gameOptions?.maxDist) ?? 0} className="hintCircle" />
293+
<HintCircle location={location} gameOptions={gameOptions} round={round} />
253294
)}
254295

255296
<TileLayer

0 commit comments

Comments
 (0)