Files
srhtnin.github.io/Scripts/Garden/Users.js
T
2026-08-31 17:16:30 +02:00

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
);
}
}
);