Skip to content

Commit 7bc2429

Browse files
authored
Merge pull request #2 from AaravAtGit/main
remove requirement of allowed colors and add colorpicker to site
1 parent ad1aa15 commit 7bc2429

2 files changed

Lines changed: 99 additions & 37 deletions

File tree

src/pages/api/canvas.ts

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,15 @@ import type { APIRoute } from "astro";
33
export const WIDTH = 32;
44
export const HEIGHT = 32;
55

6-
export const ALLOWED_COLORS = new Set([
7-
"#0a0a0a",
8-
"#c41e3a",
9-
"#e5e5e5",
10-
"#404040",
11-
"#3b82f6",
12-
"#22c55e",
13-
"#eab308",
14-
"#a855f7",
15-
"#f97316",
16-
]);
17-
186
const canvas: string[] = Array(WIDTH * HEIGHT).fill("#0a0a0a");
197

208
// ip -> timestamp
219
const rateLimitMap = new Map<string, number>();
2210

11+
function isValidColor(color: string): boolean {
12+
return /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(color);
13+
}
14+
2315
function getClientIp(request: Request): string {
2416
return (
2517
request.headers.get("x-forwarded-for")?.split(",")[0]?.trim() ??
@@ -88,7 +80,7 @@ export const POST: APIRoute = async ({ request }) => {
8880
x >= WIDTH ||
8981
y < 0 ||
9082
y >= HEIGHT ||
91-
!ALLOWED_COLORS.has(color)
83+
!isValidColor(color)
9284
) {
9385
return new Response(JSON.stringify({ error: "Invalid request" }), {
9486
status: 400,

src/pages/index.astro

Lines changed: 94 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,18 @@ const pastProjects = [
1919
link: "https://github.com/duykhanh09103/ytdlp-web-api",
2020
},
2121
];
22+
23+
const COLORS = [
24+
"#0a0a0a",
25+
"#c41e3a",
26+
"#e5e5e5",
27+
"#404040",
28+
"#3b82f6",
29+
"#22c55e",
30+
"#eab308",
31+
"#a855f7",
32+
"#f97316",
33+
];
2234
---
2335

2436
<Layout>
@@ -120,7 +132,34 @@ const pastProjects = [
120132

121133
<section class="info-section canvas-section">
122134
<canvas id="pixel-canvas"></canvas>
123-
<div class="palette" id="palette"></div>
135+
<div class="palette" id="palette">
136+
{
137+
COLORS.map((color) => (
138+
<div
139+
class="swatch"
140+
style={{ background: color }}
141+
data-color={color}
142+
title={color === "#0a0a0a" ? "erase" : color}
143+
/>
144+
))
145+
}
146+
<div class="swatch add-btn" title="custom color">
147+
<svg
148+
width="12"
149+
height="12"
150+
viewBox="0 0 24 24"
151+
fill="none"
152+
stroke="currentColor"
153+
stroke-width="3"
154+
stroke-linecap="round"
155+
stroke-linejoin="round"
156+
>
157+
<line x1="12" y1="5" x2="12" y2="19" />
158+
<line x1="5" y1="12" x2="19" y2="12" />
159+
</svg>
160+
<input type="color" class="picker-input" />
161+
</div>
162+
</div>
124163
<pre class="curl-example" id="curl-example"></pre>
125164
</section>
126165
</main>
@@ -406,23 +445,52 @@ const pastProjects = [
406445
justify-content: center;
407446
}
408447

409-
:global(.swatch) {
448+
.swatch {
410449
width: 20px;
411450
height: 20px;
412451
border: 1px solid #262626;
413452
cursor: pointer;
414453
transition: outline 0.1s;
415454
}
416455

417-
:global(.swatch[data-color="#0a0a0a"]) {
456+
.swatch[data-color="#0a0a0a"] {
418457
border-color: #404040;
419458
}
420459

421-
:global(.swatch.active) {
460+
.swatch.active {
422461
outline: 2px solid #e5e5e5;
423462
outline-offset: 1px;
424463
}
425464

465+
.swatch.add-btn {
466+
position: relative;
467+
background: var(--custom-color, #111);
468+
color: #737373;
469+
display: flex;
470+
align-items: center;
471+
justify-content: center;
472+
border: 1px dashed #404040;
473+
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
474+
}
475+
476+
.picker-input {
477+
position: absolute;
478+
inset: -1px;
479+
width: calc(100% + 2px);
480+
height: calc(100% + 2px);
481+
opacity: 0;
482+
cursor: pointer;
483+
padding: 0;
484+
border: none;
485+
}
486+
487+
.swatch.add-btn:hover {
488+
color: #fff;
489+
border-color: #e5e5e5;
490+
background: var(--custom-color, rgba(255, 255, 255, 0.15));
491+
filter: brightness(1.2);
492+
}
493+
426494
.curl-example {
427495
font-family: monospace;
428496
font-size: 0.75rem;
@@ -538,17 +606,6 @@ const pastProjects = [
538606
const HEIGHT = 32;
539607
const POLL_MS = 3000;
540608

541-
const COLORS = [
542-
"#0a0a0a",
543-
"#c41e3a",
544-
"#e5e5e5",
545-
"#404040",
546-
"#3b82f6",
547-
"#22c55e",
548-
"#eab308",
549-
"#a855f7",
550-
"#f97316",
551-
];
552609

553610
const canvas = document.getElementById("pixel-canvas") as HTMLCanvasElement;
554611
if (!canvas) throw new Error("canvas not found");
@@ -582,13 +639,11 @@ const pastProjects = [
582639
curlEl.textContent = curlCommand(x, y);
583640
}
584641

585-
const palette = document.getElementById("palette")!;
586-
for (const color of COLORS) {
587-
const swatch = document.createElement("div");
588-
swatch.className = "swatch" + (color === selectedColor ? " active" : "");
589-
swatch.style.background = color;
590-
swatch.dataset.color = color;
591-
swatch.title = color === "#0a0a0a" ? "erase" : color;
642+
const swatches = document.querySelectorAll(".swatch:not(.add-btn)");
643+
swatches.forEach((swatch) => {
644+
const color = (swatch as HTMLElement).dataset.color!;
645+
if (color === selectedColor) swatch.classList.add("active");
646+
592647
swatch.addEventListener("click", () => {
593648
selectedColor = color;
594649
document
@@ -598,8 +653,23 @@ const pastProjects = [
598653
render();
599654
updateCurl(selectedCell?.x ?? null, selectedCell?.y ?? null);
600655
});
601-
palette.appendChild(swatch);
602-
}
656+
});
657+
658+
const picker = document.querySelector(".picker-input") as HTMLInputElement;
659+
picker.oninput = () => {
660+
selectedColor = picker.value;
661+
662+
const addBtn = picker.parentElement as HTMLElement;
663+
addBtn.style.setProperty("--custom-color", selectedColor);
664+
addBtn.style.borderStyle = "solid";
665+
addBtn.style.borderColor = "rgba(255,255,255,0.1)";
666+
667+
document
668+
.querySelectorAll(".swatch")
669+
.forEach((s) => s.classList.remove("active"));
670+
updateCurl(selectedCell?.x ?? null, selectedCell?.y ?? null);
671+
render();
672+
};
603673

604674
function render() {
605675
for (let y = 0; y < HEIGHT; y++) {

0 commit comments

Comments
 (0)