mirror of
https://git.srhtnin.garden/sarah/srhtnin.github.io.git
synced 2026-10-13 18:38:11 +02:00
339 lines
5.7 KiB
JavaScript
339 lines
5.7 KiB
JavaScript
const DefaultColourPickerValue = "#000000";
|
|
|
|
|
|
function IsValidPlayerColour(
|
|
Colour
|
|
) {
|
|
return (
|
|
typeof Colour === "string" &&
|
|
/^#[0-9A-Fa-f]{6}$/.test(
|
|
Colour
|
|
)
|
|
);
|
|
}
|
|
|
|
|
|
function GetRelativeLuminance(
|
|
Colour
|
|
) {
|
|
const Channels = [
|
|
Colour.slice(1, 3),
|
|
Colour.slice(3, 5),
|
|
Colour.slice(5, 7)
|
|
].map(
|
|
Channel => {
|
|
const Value =
|
|
parseInt(
|
|
Channel,
|
|
16
|
|
) / 255;
|
|
|
|
return Value <= 0.04045
|
|
? Value / 12.92
|
|
: Math.pow(
|
|
(Value + 0.055) /
|
|
1.055,
|
|
2.4
|
|
);
|
|
}
|
|
);
|
|
|
|
return (
|
|
0.2126 * Channels[0] +
|
|
0.7152 * Channels[1] +
|
|
0.0722 * Channels[2]
|
|
);
|
|
}
|
|
|
|
|
|
function GetContrastRatio(
|
|
FirstLuminance,
|
|
SecondLuminance
|
|
) {
|
|
const Lighter = Math.max(
|
|
FirstLuminance,
|
|
SecondLuminance
|
|
);
|
|
|
|
const Darker = Math.min(
|
|
FirstLuminance,
|
|
SecondLuminance
|
|
);
|
|
|
|
return (
|
|
Lighter + 0.05
|
|
) / (
|
|
Darker + 0.05
|
|
);
|
|
}
|
|
|
|
|
|
function GetPlayerColourOutline(
|
|
Colour
|
|
) {
|
|
const ColourLuminance =
|
|
GetRelativeLuminance(
|
|
Colour
|
|
);
|
|
|
|
const LightLuminance =
|
|
GetRelativeLuminance(
|
|
"#cdd6f4"
|
|
);
|
|
|
|
const DarkLuminance =
|
|
GetRelativeLuminance(
|
|
"#11111b"
|
|
);
|
|
|
|
const LightContrast =
|
|
GetContrastRatio(
|
|
ColourLuminance,
|
|
LightLuminance
|
|
);
|
|
|
|
const DarkContrast =
|
|
GetContrastRatio(
|
|
ColourLuminance,
|
|
DarkLuminance
|
|
);
|
|
|
|
|
|
if (
|
|
DarkContrast >=
|
|
LightContrast
|
|
) {
|
|
return null;
|
|
}
|
|
|
|
|
|
return "var(--Text)";
|
|
}
|
|
|
|
|
|
function GetPlayerColourShadow(
|
|
Outline
|
|
) {
|
|
const Shadows = [];
|
|
|
|
for (let Y = -2; Y <= 2; Y++) {
|
|
for (let X = -2; X <= 2; X++) {
|
|
if (X === 0 && Y === 0) {
|
|
continue;
|
|
}
|
|
|
|
Shadows.push(
|
|
`${X}px ${Y}px 0 ${Outline}`
|
|
);
|
|
}
|
|
}
|
|
|
|
return Shadows.join(
|
|
", "
|
|
);
|
|
}
|
|
|
|
|
|
function ApplyPlayerColour(
|
|
Element,
|
|
Colour
|
|
) {
|
|
Element.style.removeProperty(
|
|
"color"
|
|
);
|
|
|
|
Element.style.removeProperty(
|
|
"text-shadow"
|
|
);
|
|
|
|
if (
|
|
!IsValidPlayerColour(
|
|
Colour
|
|
)
|
|
) {
|
|
return;
|
|
}
|
|
|
|
const Outline =
|
|
GetPlayerColourOutline(
|
|
Colour
|
|
);
|
|
|
|
Element.style.color =
|
|
Colour;
|
|
|
|
|
|
if (Outline !== null) {
|
|
Element.style.textShadow =
|
|
GetPlayerColourShadow(
|
|
Outline
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
async function GetProfile() {
|
|
const Response = await fetch(
|
|
ApiUrl + "/Profile.php",
|
|
{
|
|
method: "POST",
|
|
|
|
headers: {
|
|
"Content-Type": "application/json"
|
|
},
|
|
|
|
body: JSON.stringify({
|
|
SaveKey: GetSaveKey()
|
|
})
|
|
}
|
|
);
|
|
|
|
return await Response.json();
|
|
}
|
|
|
|
|
|
async function SetUsername(
|
|
Username
|
|
) {
|
|
const Response = await fetch(
|
|
ApiUrl + "/SetUsername.php",
|
|
{
|
|
method: "POST",
|
|
|
|
headers: {
|
|
"Content-Type": "application/json"
|
|
},
|
|
|
|
body: JSON.stringify({
|
|
SaveKey: GetSaveKey(),
|
|
Username: Username
|
|
})
|
|
}
|
|
);
|
|
|
|
return await Response.json();
|
|
}
|
|
|
|
async function SetColour(
|
|
Colour
|
|
) {
|
|
const Response =
|
|
await fetch(
|
|
ApiUrl +
|
|
"/SetColour.php",
|
|
{
|
|
method: "POST",
|
|
|
|
headers: {
|
|
"Content-Type":
|
|
"application/json"
|
|
},
|
|
|
|
body: JSON.stringify({
|
|
SaveKey:
|
|
GetSaveKey(),
|
|
|
|
Colour:
|
|
Colour
|
|
})
|
|
}
|
|
);
|
|
|
|
return await Response.json();
|
|
}
|
|
|
|
async function RenderUser() {
|
|
const Profile =
|
|
await GetProfile();
|
|
|
|
const UsernameDisplay =
|
|
document.getElementById(
|
|
"UsernameDisplay"
|
|
);
|
|
|
|
const UsernameForm =
|
|
document.getElementById(
|
|
"UsernameForm"
|
|
);
|
|
|
|
if (
|
|
Profile.Success &&
|
|
Profile.Username !== null
|
|
) {
|
|
UsernameDisplay.textContent =
|
|
Profile.Username;
|
|
|
|
ApplyPlayerColour(
|
|
UsernameDisplay,
|
|
Profile.Colour
|
|
);
|
|
|
|
UsernameForm.hidden = true;
|
|
|
|
return;
|
|
}
|
|
|
|
UsernameDisplay.textContent =
|
|
"Unnamed";
|
|
|
|
ApplyPlayerColour(
|
|
UsernameDisplay,
|
|
null
|
|
);
|
|
|
|
UsernameForm.hidden = false;
|
|
}
|
|
|
|
|
|
async function SubmitUsername(
|
|
Event
|
|
) {
|
|
Event.preventDefault();
|
|
|
|
const Input =
|
|
document.getElementById(
|
|
"UsernameInput"
|
|
);
|
|
|
|
const Message =
|
|
document.getElementById(
|
|
"UsernameMessage"
|
|
);
|
|
|
|
const Result =
|
|
await SetUsername(
|
|
Input.value
|
|
);
|
|
|
|
if (!Result.Success) {
|
|
Message.textContent =
|
|
Result.Error;
|
|
|
|
return;
|
|
}
|
|
|
|
Message.textContent =
|
|
"Username set.";
|
|
|
|
await RenderUser();
|
|
await RenderLeaderboard();
|
|
}
|
|
|
|
|
|
document.addEventListener(
|
|
"DOMContentLoaded",
|
|
() => {
|
|
const UsernameForm =
|
|
document.getElementById(
|
|
"UsernameForm"
|
|
);
|
|
|
|
if (UsernameForm !== null) {
|
|
UsernameForm.addEventListener(
|
|
"submit",
|
|
SubmitUsername
|
|
);
|
|
}
|
|
}
|
|
);
|