Skip to content

Commit 4e7079e

Browse files
committed
add files
0 parents  commit 4e7079e

File tree

3 files changed

+232
-0
lines changed

3 files changed

+232
-0
lines changed

index.html

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<!DOCTYPE html>
2+
<head>
3+
<title>Trackmania Username Generator</title>
4+
<link rel="stylesheet" href="styles.css" />
5+
<script src="https://cdn.tailwindcss.com"></script>
6+
</head>
7+
<body>
8+
<div id="container">
9+
<h1 class="text-xl font-bold mb-5">Trackmania Username Generator</h1>
10+
<!-- username input -->
11+
<div id="usernameDiv" class="mb-5">
12+
<label for="username">Username:</label>
13+
<input
14+
type="text"
15+
id="username"
16+
name="username"
17+
class="relative bg-gray-50 ring-0 outline-none border border-neutral-500 text-neutral-900 placeholder-violet-700 text-sm rounded-lg focus:ring-violet-500 focus:border-violet-500 block w-64 p-2.5 checked:bg-emerald-500"
18+
/>
19+
</div>
20+
<!-- colors input (start and end) -->
21+
<div id="colorsDiv">
22+
<div class="flex items-center mb-2">
23+
<label for="startColor" class="mr-2">Start Color:</label>
24+
<input
25+
value="#FF0000"
26+
type="color"
27+
id="startColor"
28+
name="startColor"
29+
class="p-0.5 h-10 w-14 block bg-white border border-gray-200 cursor-pointer rounded-lg disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-900 dark:border-neutral-700"
30+
/>
31+
</div>
32+
<div class="mb-2">
33+
<div class="flex items-center">
34+
<label for="middleColor" class="mr-2">Middle Color:</label>
35+
<input
36+
type="color"
37+
id="middleColor"
38+
name="middleColor"
39+
class="p-0.5 h-10 w-14 block bg-white border border-gray-200 cursor-pointer rounded-lg disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-900 dark:border-neutral-700"
40+
/>
41+
</div>
42+
<div class="flex items-center">
43+
<br />
44+
<!-- checkbox for middle color -->
45+
<input
46+
type="checkbox"
47+
id="middleColorCheckbox"
48+
name="middleColorCheckbox"
49+
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
50+
/>
51+
<label
52+
for="middleColorCheckbox"
53+
class="ms-2 font-medium text-gray-900 dark:text-gray-300"
54+
>Use Middle Color</label
55+
>
56+
</div>
57+
</div>
58+
<div class="flex items-center">
59+
<label for="endColor" class="mr-2">End Color:</label>
60+
<input
61+
value="#0000FF"
62+
type="color"
63+
id="endColor"
64+
name="endColor"
65+
class="p-0.5 h-10 w-14 block bg-white border border-gray-200 cursor-pointer rounded-lg disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-900 dark:border-neutral-700"
66+
/>
67+
</div>
68+
</div>
69+
<div class="mb-2 mt-5">
70+
<h3 class="font-bold">Preview:</h3>
71+
<p class="result" id="result"></p>
72+
</div>
73+
<div class="my-2">
74+
<h3 class="font-bold">Code:</h3>
75+
<input
76+
type="text"
77+
id="tmResult"
78+
class="mb-3 relative bg-gray-50 ring-0 outline-none border border-neutral-500 text-neutral-900 placeholder-violet-700 text-sm rounded-lg focus:ring-violet-500 focus:border-violet-500 block w-64 p-2.5 checked:bg-emerald-500"
79+
/>
80+
<button
81+
id="copy"
82+
class="py-2.5 px-5 me-2 mb-2 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700"
83+
>
84+
Copy
85+
</button>
86+
</div>
87+
<p class="text-sm text-gray-500 mb-1">Text formatting coming soon!</p>
88+
<p class="text-sm text-gray-400 italic">
89+
Made by <a href="https://steveblox.github.io">SteveBlox</a>
90+
</p>
91+
</div>
92+
93+
<script src="main.js"></script>
94+
</body>

main.js

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
function hexToRgb(hex) {
2+
let result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
3+
return result
4+
? {
5+
r: parseInt(result[1], 16),
6+
g: parseInt(result[2], 16),
7+
b: parseInt(result[3], 16),
8+
}
9+
: null;
10+
}
11+
12+
function rgbToHex(r, g, b) {
13+
return (
14+
"#" +
15+
((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1).toUpperCase()
16+
);
17+
}
18+
19+
function interpolateColor(startRgb, endRgb, factor) {
20+
return {
21+
r: Math.round(startRgb.r + factor * (endRgb.r - startRgb.r)),
22+
g: Math.round(startRgb.g + factor * (endRgb.g - startRgb.g)),
23+
b: Math.round(startRgb.b + factor * (endRgb.b - startRgb.b)),
24+
};
25+
}
26+
27+
// Function to generate the gradient
28+
function generateGradient(startHex, endHex, steps, middleHex = null) {
29+
const startRgb = hexToRgb(startHex);
30+
const endRgb = hexToRgb(endHex);
31+
const gradient = [];
32+
33+
if (middleHex) {
34+
const middleRgb = hexToRgb(middleHex);
35+
const halfSteps = Math.floor(steps / 2);
36+
37+
for (let i = 0; i < halfSteps; i++) {
38+
const factor = i / (halfSteps - 1);
39+
const color = interpolateColor(startRgb, middleRgb, factor);
40+
gradient.push(shortenHex(rgbToHex(color[0], color[1], color[2])));
41+
}
42+
43+
for (let i = 0; i < steps - halfSteps; i++) {
44+
const factor = i / (steps - halfSteps - 1);
45+
const color = interpolateColor(middleRgb, endRgb, factor);
46+
gradient.push(shortenHex(rgbToHex(color[0], color[1], color[2])));
47+
}
48+
} else {
49+
for (let i = 0; i < steps; i++) {
50+
const factor = i / (steps - 1);
51+
const color = interpolateColor(startRgb, endRgb, factor);
52+
gradient.push(shortenHex(rgbToHex(color[0], color[1], color[2])));
53+
}
54+
}
55+
56+
return gradient;
57+
}
58+
59+
function shortenHex(hex) {
60+
// convert 6-digit hex color to 3-digit
61+
/*
62+
R = round(0xRR/0xFF*0xF)
63+
G = round(0xGG/0xFF*0xF)
64+
B = round(0xBB/0xFF*0xF)
65+
*/
66+
const r = Math.round((parseInt(hex.slice(1, 3), 16) / 255) * 15).toString(16);
67+
const g = Math.round((parseInt(hex.slice(3, 5), 16) / 255) * 15).toString(16);
68+
const b = Math.round((parseInt(hex.slice(5, 7), 16) / 255) * 15).toString(16);
69+
return `#${r}${g}${b}`.toUpperCase();
70+
}
71+
72+
const username = document.getElementById("username");
73+
const startInput = document.getElementById("startColor");
74+
const middleInput = document.getElementById("middleColor");
75+
const endInput = document.getElementById("endColor");
76+
const result = document.querySelector(".result");
77+
const tmResult = document.querySelector("#tmResult");
78+
const copy = document.querySelector("#copy");
79+
const middleColorCheckbox = document.querySelector("#middleColorCheckbox");
80+
function generateUsername() {
81+
const startColor = startInput.value;
82+
const middleColor = middleColorCheckbox.checked ? middleInput.value : null;
83+
const endColor = endInput.value;
84+
const name = username.value;
85+
console.log(
86+
`startColor: ${startColor}, middleColor: ${middleColor}, endColor: ${endColor}, name: ${name}`
87+
);
88+
const minNameLength = middleColorCheckbox.checked ? 4 : 2;
89+
if (!startColor || !endColor || !name || name.length < minNameLength) return;
90+
const gradient = generateGradient(
91+
startColor,
92+
endColor,
93+
name.length,
94+
middleColor
95+
);
96+
console.log(gradient);
97+
result.innerHTML = "";
98+
tmResult.value = "";
99+
for (let i = 0; i < name.length; i++) {
100+
result.innerHTML += `<span style="color: ${gradient[i]}; font-weight: bolder">${name[i]}</span>`;
101+
// the raw result, looks like this : $FF0[letter]$F0F[letter]
102+
tmResult.value += `$${gradient[i].slice(1)}${name[i]}`;
103+
}
104+
}
105+
username.addEventListener("input", generateUsername);
106+
startInput.addEventListener("input", generateUsername);
107+
middleInput.addEventListener("input", () => {
108+
middleColorCheckbox.checked = true;
109+
generateUsername();
110+
});
111+
endInput.addEventListener("input", generateUsername);
112+
middleColorCheckbox.addEventListener("change", generateUsername);
113+
114+
copy.addEventListener("click", function () {
115+
navigator.clipboard.writeText(tmResult.value);
116+
});

styles.css

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&family=Space+Mono&display=swap');
2+
3+
body {
4+
font-family: 'Montserrat', sans-serif;
5+
height: 100vh;
6+
width: 100vw;
7+
display: flex;
8+
justify-content: center;
9+
align-items: center;
10+
flex-direction: column;
11+
/* light green */
12+
background-color: #ffffff;
13+
}
14+
15+
/* Center .container x and y */
16+
#container {
17+
border-radius: 25px;
18+
padding: 2em;
19+
background: #fff;
20+
box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 29px 0px;
21+
22+
}

0 commit comments

Comments
 (0)