Implement 2D galaxy view
This commit is contained in:
parent
718a9b5da6
commit
b51200f3e8
|
@ -2,7 +2,6 @@
|
|||
import Layout from '../../layouts/Layout.astro';
|
||||
import NavBar from '../../components/NavBar.astro';
|
||||
import { getUserByAccessToken } from '../../lib/db/users';
|
||||
import { getAllPlanets } from '../../lib/db/planets';
|
||||
import locationManager from '../../lib/classes/managers/LocationManager';
|
||||
import ResourceBar from '../../components/ResourceBar.astro';
|
||||
|
||||
|
@ -13,89 +12,157 @@ if(loggedToken === null || username === "") return Astro.redirect('/logout');
|
|||
const checkUser = await getUserByAccessToken(loggedToken);
|
||||
if(checkUser === null || checkUser.username !== username) return Astro.redirect('/logout');
|
||||
|
||||
const allPlanets = await getAllPlanets();
|
||||
const allGalaxies = locationManager.galaxies;
|
||||
|
||||
const formattedPlanets = allPlanets.map(planet => {
|
||||
let i = 0;
|
||||
const galaxies = allGalaxies.map(galaxy => {
|
||||
return {
|
||||
name: planet.name,
|
||||
owner: locationManager.getUser(planet.owner)?.username ?? "Unowned"
|
||||
numericId: i++,
|
||||
name: galaxy.name,
|
||||
style: {
|
||||
left: 0,
|
||||
top: 0,
|
||||
color: "red"
|
||||
},
|
||||
sectors: galaxy.sectors.map(sector => {
|
||||
return {
|
||||
id: sector._id.toString(),
|
||||
name: sector.name
|
||||
};
|
||||
})
|
||||
};
|
||||
})
|
||||
|
||||
for(const galaxy of galaxies) {
|
||||
for(let i = 0; i < 100; i++) {
|
||||
galaxy.style.left = Math.random() * 1200 + 20;
|
||||
galaxy.style.top = Math.random() * 380 + 20;
|
||||
const overlap = galaxies.slice(0, galaxy.numericId).some(otherGalaxy => {
|
||||
const dx = galaxy.style.left - otherGalaxy.style.left;
|
||||
const dy = galaxy.style.top - otherGalaxy.style.top;
|
||||
const distance = Math.sqrt(dx * dx + dy * dy);
|
||||
return distance < 100;
|
||||
});
|
||||
if(!overlap) {
|
||||
galaxy.style.color = "white"
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
---
|
||||
|
||||
<Layout title="Galaxy view">
|
||||
<NavBar loggedIn="true" active="galaxyView" />
|
||||
<ResourceBar />
|
||||
<ul>
|
||||
{formattedPlanets.map(planet => <li>{planet.name} ({planet.owner})</li>)}
|
||||
</ul>
|
||||
<div class="container">
|
||||
<div class="galaxy-container">
|
||||
{galaxies.map(galaxy => <>
|
||||
<a href="#">
|
||||
<div class="galaxy-icon" style={`left: ${galaxy.style.left}px; top: ${galaxy.style.top}px; background-color: ${galaxy.style.color};`}>
|
||||
<div class="galaxy-name" data-sectors={JSON.stringify(galaxy.sectors)}>{galaxy.name}</div>
|
||||
</div>
|
||||
</a>
|
||||
</>)}
|
||||
</div>
|
||||
<div class="galaxy-details">
|
||||
<h2></h2>
|
||||
<div class="galaxy-sector-list">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
|
||||
<style>
|
||||
* {
|
||||
<style is:global>
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
color: white;
|
||||
}
|
||||
|
||||
main {
|
||||
margin: auto;
|
||||
padding: 1rem;
|
||||
width: 800px;
|
||||
max-width: calc(100% - 2rem);
|
||||
color: white;
|
||||
font-size: 20px;
|
||||
line-height: 1.6;
|
||||
|
||||
.galaxy-container {
|
||||
width: 70%;
|
||||
height: 500px;
|
||||
background-color: blue;
|
||||
margin-left: 50px;
|
||||
margin-right: auto;
|
||||
margin-top: 50px;
|
||||
position: relative;
|
||||
}
|
||||
.astro-a {
|
||||
|
||||
.galaxy-icon {
|
||||
position:absolute;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background-color: white;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.galaxy-icon:hover {
|
||||
background-color: yellow !important;
|
||||
}
|
||||
|
||||
.galaxy-name {
|
||||
position: absolute;
|
||||
top: -32px;
|
||||
left: 50%;
|
||||
transform: translatex(-50%);
|
||||
width: 220px;
|
||||
height: auto;
|
||||
z-index: -1;
|
||||
top: 40px;
|
||||
left: -5px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 4rem;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
.galaxy-details {
|
||||
width: 23%;
|
||||
height: 500px;
|
||||
margin-top: 50px;
|
||||
margin-right: 50px;
|
||||
}
|
||||
|
||||
.galaxy-details h2 {
|
||||
text-align: center;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.text-gradient {
|
||||
background-image: var(--accent-gradient);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-size: 400%;
|
||||
background-position: 0%;
|
||||
.galaxy-sector-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.instructions {
|
||||
margin-bottom: 2rem;
|
||||
border: 1px solid rgba(var(--accent-light), 25%);
|
||||
background: linear-gradient(rgba(var(--accent-dark), 66%), rgba(var(--accent-dark), 33%));
|
||||
padding: 1.5rem;
|
||||
border-radius: 8px;
|
||||
.galaxy-sector-list div {
|
||||
text-align: center;
|
||||
background-color: gray;
|
||||
margin-top: 10px;
|
||||
border-radius: 10px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
function gvinit() {
|
||||
const galaxyIcons = document.querySelectorAll('.galaxy-icon');
|
||||
const galaxyDetails = document.querySelector('.galaxy-details');
|
||||
const galaxySectorList = document.querySelector('.galaxy-sector-list');
|
||||
|
||||
if(!galaxyIcons) return;
|
||||
if(!galaxyDetails) return;
|
||||
if(!galaxySectorList) return;
|
||||
|
||||
galaxyIcons.forEach(icon => {
|
||||
icon.addEventListener('click', (e) => {
|
||||
const galaxy = icon.querySelector('.galaxy-name');
|
||||
if(!galaxy) return;
|
||||
|
||||
const sectors: Array<{ id: string, name: string }> = JSON.parse(galaxy.getAttribute('data-sectors') ?? "[]");
|
||||
const galaxyNameField = galaxyDetails.querySelector('h2');
|
||||
if(!galaxyNameField) return;
|
||||
galaxyNameField.innerText = (icon.querySelector('.galaxy-name') as HTMLElement)?.innerText;
|
||||
galaxySectorList.innerHTML = "";
|
||||
sectors.forEach(sector => {
|
||||
const sectorDiv = document.createElement('div');
|
||||
sectorDiv.innerText = sector.name;
|
||||
sectorDiv.setAttribute('data-id', sector.id);
|
||||
galaxySectorList.appendChild(sectorDiv);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
.instructions code {
|
||||
font-size: 0.8em;
|
||||
font-weight: bold;
|
||||
background: rgba(var(--accent-light), 12%);
|
||||
color: rgb(var(--accent-light));
|
||||
border-radius: 4px;
|
||||
padding: 0.3em 0.4em;
|
||||
}
|
||||
|
||||
.instructions strong {
|
||||
color: rgb(var(--accent-light));
|
||||
}
|
||||
|
||||
.link-card-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr));
|
||||
gap: 2rem;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
gvinit();
|
||||
</script>
|
Loading…
Reference in New Issue