dark-firepit.cloud/src/lib/People.svelte

327 lines
9.0 KiB
Svelte
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script>
import iconAether from '../assets/icons/aether.png';
import iconJillo from '../assets/icons/jillo.png';
import iconMarco from '../assets/icons/marco.png';
import iconMayflower from '../assets/icons/mayflower.png';
import iconOatmealine from '../assets/icons/oatmealine.png';
import iconOrdinaryManner from '../assets/icons/ordinarymanner.png';
import iconWinter from '../assets/icons/winter.png';
import iconZydra from '../assets/icons/zydra.png';
const people = [
{
icon: iconAether,
name: 'Aether',
description: `
Mathematician, category theory enthusiast, functional programmer and overall dork. Turned half
the server into furries. One half of the server administration.
<br>
<blockquote>
<i>"i'm growing kinda fond of yandex! however, there is one thing i have to try... [typing noises] gay... furry porn..."</i>
</blockquote>
`,
site: 'https://aether.gay/',
pronouns: 'they/it',
bottom: `
<small>Profile picture by <a target="_blank" rel="noreferrer" href="https://twitter.com/DumbDogDoodles">@DumbDugDoodles</a>.</small>
`
},
{
icon: iconOatmealine,
name: 'oatmealine',
description: `
Web developer, modder and overall programming masochist with a tendency and intent to use its power to commit
immense crime, both literally and spiritually. The other half of the server administration. Made this website!
<br>
<blockquote>
<i>"if you go far enough east into Russia, you end up in the farlands"</i>
</blockquote>
`,
site: 'https://oat.zone/',
pronouns: 'it/her',
bottom: `
<small>Profile picture by <a href="https://twitter.com/NeoVen0m">@NeoVen0m</a>.</small>
`
},
{
icon: iconMarco,
name: 'Marco'
},
{
icon: iconOrdinaryManner,
name: 'OrdinaryManner',
description: `
Moth enthusiast and artist, occasional modder and overall thing-doer. Quite fluffy. Do not recite
<a target="_blank" rel="noreferrer" href="https://www.youtube.com/watch?v=d0RmRJsgP28">this video</a> near him.
<br><br>
<img src="https://howto.smooch.computer/i/1uuw2.png">
<br><br>
`,
pronouns: 'he/him'
},
{
icon: iconWinter,
name: 'winter',
description: `
Local low-level developer and rhythm game enthusiast. In case of an investigation by any federal entity or similar,
we do not have any involvement with this person, we do not know how they are here, probably added by
a third party, we do not support any actions by them.
<br><br>
`,
site: 'https://wint0r.zone/',
pronouns: 'any except he'
},
{
icon: iconJillo,
name: 'Jillo',
description: `
The server maid! Partly sentient chip-controlled goo girl who lives on the server taking care of music, pronouns,
colors, <i>the counter</i> and other utility features. Also provides surveillance devices and partially acts as one.
<br>
<blockquote>
<i>";p slide whistle sound effect"</i>
</blockquote>
`,
site: 'https://oat.zone/#characters/jillo.chr',
siteDisplay: 'oat.zone:characters/jillo.chr',
pronouns: 'it/her'
},
{
icon: iconMayflower,
name: 'Mayflower',
description: `
A being of pure chaos, described by most as the equivalent of a neodymium magnet near electronics. Kokichi kinnie.
Commits programming crimes both willingly and unwillingly.
<br>
<blockquote>
<i>"do you know what an x86 is?"</i><br>
<i>"yes i do. that is the Intel®"</i>
</blockquote>
`,
site: 'https://mayf.pink/',
pronouns: 'any'
},
{
icon: iconZydra,
name: 'Zydra',
description: `
Bait for buses. No longer SSHes into their server as root. Should not be trusted around hammers, curtains, or
a set of 2 wedding videos.
<br><br>
🧩 🥛
<br><br>
`,
site: 'https://zydra.space/',
pronouns: 'she/they'
}
];
let overlay;
let personSelected = false;
let personSelectedDims = [0, 0];
function navigateUp(el) {
if (el.classList.contains('person')) return el;
return navigateUp(el.parentElement);
}
function clickPerson(event) {
if (personSelected) return;
const el = navigateUp(event.target);
const overlayPerson = el.cloneNode(true);
const back = document.createElement('div');
back.classList.add('overlay-back')
overlayPerson.insertBefore(back, overlayPerson.firstChild);
el.classList.add('hidden');
overlayPerson.classList.add('selected');
overlayPerson.style.left = `${el.offsetLeft}px`;
overlayPerson.style.top = `${el.offsetTop}px`;
personSelectedDims = [el.offsetWidth, el.offsetHeight];
overlayPerson.animate([
{ top: `${el.offsetTop}px`, left: `${el.offsetLeft}px` },
{ top: 0, left: 0, width: '100%', height: '100%' }
], {
duration: 700,
iterations: 1,
easing: 'cubic-bezier(0.25, 1, 0.5, 1)',
fill: 'forwards'
});
overlay.innerHTML = '';
overlay.appendChild(overlayPerson);
personSelected = el;
}
function closePerson() {
if (personSelected) {
const overlayPerson = overlay.children[0];
overlayPerson.animate([
{ top: 0, left: 0, width: '100%', height: '100%' },
{ top: `${personSelected.offsetTop}px`, left: `${personSelected.offsetLeft}px`, width: `${personSelectedDims[0]}px`, height: `${personSelectedDims[1]}px` }
], {
duration: 500,
iterations: 1,
easing: 'cubic-bezier(0.25, 1, 0.5, 1)',
fill: 'forwards'
});
personSelected = false;
setTimeout(() => {
for (const el of document.querySelectorAll('.person')) {
el.classList.remove('hidden');
if (!personSelected) overlay.innerHTML = '';
}
}, 500);
}
}
</script>
<style>
.people-container {
width: 100%;
padding: 0.5em;
border-radius: 40px;
}
.people {
width: 100%;
display: flex;
flex-direction: row;
align-items: flex-start;
align-content: flex-start;
justify-content: center;
gap: 1em;
position: relative;
flex-wrap: wrap;
}
.person {
width: 140px;
border: 1.5px solid #999;
border-radius: 20px;
display: flex;
align-items: center;
flex-direction: column;
transition-timing-function: ease-out;
height: 175px;
transition: width 0.5s, height 0.45s, top 0.5s, left 0.45s, background-color 0.1s;
background-color: transparent;
gap: 0.7em;
color: #fff;
overflow: hidden;
backdrop-filter: blur(12px);
font-weight: 300;
}
.person:not(.selected):not(.disabled) {
cursor: pointer;
}
.person:not(.selected):not(.disabled):hover {
background-color: rgba(255, 255, 255, 0.04);
}
.person:global(.hidden) {
opacity: 0;
}
.person:global(.selected) {
position: absolute;
z-index: 1;
}
.person:global(.selected).marco {
background-image: url('/giygas.gif');
}
.person-icon {
width: 86px;
height: auto;
border-radius: 100%;
margin: 1em;
}
.person-icon-fake {
margin: 14px;
min-width: 86px;
min-height: 86px;
border-radius: 100%;
background-color: #444;
display: flex;
align-items: center;
justify-content: center;
font-size: 32px;
}
.person-name {
font-weight: 600;
font-size: large;
text-align: center;
max-width: 130px;
}
.person-bottom {
flex-grow: 1;
display: flex;
flex-direction: row;
align-items: flex-end;
align-content: flex-end;
justify-content: center;
padding: 2em;
}
.person-desc {
text-align: left;
opacity: 0;
transition: opacity 0.5s;
width: 450px;
max-width: 80vw;
margin: 1.5em;
}
.person:global(.selected) .person-desc {
opacity: 1;
}
.people-overlay {
pointer-events: none;
position: absolute;
width: 100%;
height: 100%;
}
.people-overlay.has-person {
pointer-events: auto;
z-index: 2;
}
</style>
<div class="people-container center">
<div class="people">
<div class="people-overlay" bind:this={overlay} on:click={closePerson} on:keypress={closePerson} class:has-person={personSelected}></div>
{#each people as p}
<button class="person" class:marco={p.name === 'Marco'} on:click={clickPerson}>
<img src="{p.icon}" width="256" height="256" class="person-icon" alt="{p.name}'s icon">
<div class="person-name">{p.name}</div>
<div class="person-desc">
{#if p.description}
{@html p.description}
{/if}
{#if p.site}
🔗 <a target="_blank" rel="noreferrer" href="{p.site}">{p.siteDisplay || p.site.replace('https://','').replace('/','')}</a><br>
{/if}
{#if p.pronouns}
🏷️ <i>{p.pronouns}</i><br>
{/if}
</div>
{#if p.bottom}
<div class="person-bottom">
{@html p.bottom}
</div>
{/if}
</button>
{/each}
<button class="person disabled">
<div class="person-icon-fake">
+7
</div>
<div class="person-name">...and others</div>
</button>
</div>
</div>