feat: Add planet markers to IslandUniverse map
- Display planets as ringed spheres in outer ring - Add getPlanetColor helper for planet themes - Planet markers show name and member count - Click handler ready for future navigation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
7faf0b180b
commit
5ffec6bcec
|
|
@ -185,6 +185,76 @@ export default function IslandUniverse({ onClose, onIslandClick }) {
|
|||
markers.push({ marker, island, el });
|
||||
});
|
||||
|
||||
// Add planet markers (positioned in outer ring)
|
||||
planets.forEach((planet, idx) => {
|
||||
const angle = (idx / Math.max(planets.length, 1)) * Math.PI * 2;
|
||||
const radius = 18 + (idx % 3) * 4;
|
||||
const lng = centerLng + Math.cos(angle) * radius;
|
||||
const lat = centerLat + Math.sin(angle) * radius;
|
||||
|
||||
const el = document.createElement('div');
|
||||
el.className = 'universe-planet-marker';
|
||||
|
||||
const planetColor = getPlanetColor(planet.theme || 'default');
|
||||
const memberCount = planet.member_count || 0;
|
||||
|
||||
el.innerHTML = `
|
||||
<div class="universe-planet-shape" style="
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
transition: all 0.4s ease;
|
||||
animation: universePlanetOrbit 12s linear infinite;
|
||||
filter: drop-shadow(0 0 25px ${planetColor}99);
|
||||
">
|
||||
<svg width="100" height="100" viewBox="0 0 100 100">
|
||||
<defs>
|
||||
<radialGradient id="pg-${idx}" cx="35%" cy="35%">
|
||||
<stop offset="0%" stop-color="${planetColor}" />
|
||||
<stop offset="100%" stop-color="${planetColor}" stop-opacity="0.6" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<ellipse cx="50" cy="50" rx="45" ry="12" fill="none" stroke="${planetColor}" stroke-width="3" opacity="0.5" transform="rotate(-20 50 50)"/>
|
||||
<circle cx="50" cy="50" r="30" fill="url(#pg-${idx})"/>
|
||||
</svg>
|
||||
<div style="
|
||||
position: absolute;
|
||||
bottom: -30px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: rgba(20, 10, 40, 0.95);
|
||||
color: white;
|
||||
padding: 6px 12px;
|
||||
border-radius: 12px;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
white-space: nowrap;
|
||||
border: 1px solid ${planetColor}66;
|
||||
">
|
||||
<span style="color: ${planetColor};">🪐 ${planet.name || 'Planet'}</span>
|
||||
<span style="font-size: 9px; color: rgba(255,255,255,0.6); display: block;">
|
||||
${memberCount} ${t('universe.members')}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
el.addEventListener('mouseenter', () => {
|
||||
setHoveredIsland({ ...planet, isPlanet: true, username: planet.name });
|
||||
});
|
||||
el.addEventListener('mouseleave', () => setHoveredIsland(null));
|
||||
el.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
console.log('[IslandUniverse] Clicked planet:', planet.name);
|
||||
// TODO: Navigate to planet page when ready
|
||||
});
|
||||
|
||||
const marker = new maplibregl.Marker({ element: el, anchor: 'center' })
|
||||
.setLngLat([lng, lat])
|
||||
.addTo(map);
|
||||
|
||||
markers.push({ marker, planet, el, isPlanet: true });
|
||||
});
|
||||
|
||||
markersRef.current = markers;
|
||||
|
||||
// Slow rotation animation
|
||||
|
|
@ -328,6 +398,22 @@ function getTerrainColor(terrainType) {
|
|||
return palettes[terrainType] || palettes['tropical'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get planet theme color
|
||||
*/
|
||||
function getPlanetColor(theme) {
|
||||
const palettes = {
|
||||
'default': '#9b59b6',
|
||||
'tech': '#3498db',
|
||||
'gaming': '#e74c3c',
|
||||
'music': '#1abc9c',
|
||||
'art': '#e91e63',
|
||||
'science': '#00bcd4',
|
||||
'sports': '#ff9800',
|
||||
};
|
||||
return palettes[theme] || palettes['default'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a detailed island SVG shape (bigger, more features)
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue