From ba15f30bbf23522074533a7c91e2d4620b6a3580 Mon Sep 17 00:00:00 2001 From: Wanjohi <71614375+wanjohiryan@users.noreply.github.com> Date: Sun, 1 Sep 2024 01:19:15 +0300 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20Add=20game=20card=20with=20?= =?UTF-8?q?better=20colors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/www/src/routes/home/index.tsx | 27 +++++++++++ packages/ui/src/card.tsx | 75 ++++++++++++------------------ 2 files changed, 58 insertions(+), 44 deletions(-) diff --git a/apps/www/src/routes/home/index.tsx b/apps/www/src/routes/home/index.tsx index 46a0ae1d..221f8dec 100644 --- a/apps/www/src/routes/home/index.tsx +++ b/apps/www/src/routes/home/index.tsx @@ -56,6 +56,33 @@ export default component$(() => { // teams: 10 }} /> + + + > diff --git a/packages/ui/src/card.tsx b/packages/ui/src/card.tsx index f2e67a39..330be8fd 100644 --- a/packages/ui/src/card.tsx +++ b/packages/ui/src/card.tsx @@ -13,45 +13,39 @@ export const Card = component$(({ game }: Props) => { const ringColor = useSignal(undefined); const imgRef = useSignal(); - // Function to extract dominant color const extractColor = $((img: HTMLImageElement) => { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); - if (!ctx) return; + if (!ctx) return "rgb(200,200,200)"; // Fallback light gray canvas.width = img.naturalWidth; canvas.height = img.naturalHeight; ctx.drawImage(img, 0, 0, img.naturalWidth, img.naturalHeight); - const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); - const data = imageData.data; + const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height).data; + let r = 0, g = 0, b = 0, count = 0; - let r = 0, g = 0, b = 0; - - for (let i = 0; i < data.length; i += 4) { - r += data[i]; - g += data[i + 1]; - b += data[i + 2]; + for (let i = 0; i < imageData.length; i += 4) { + // Only consider brighter pixels + if (imageData[i] > 150 || imageData[i + 1] > 150 || imageData[i + 2] > 150) { + r += imageData[i]; + g += imageData[i + 1]; + b += imageData[i + 2]; + count++; + } } - r = Math.floor(r / (data.length / 4)); - g = Math.floor(g / (data.length / 4)); - b = Math.floor(b / (data.length / 4)); + if (count === 0) return "rgb(200,200,200)"; // Fallback if no bright pixels found - return `rgb(${r},${g},${b})`; - }); + r = Math.floor(r / count); + g = Math.floor(g / count); + b = Math.floor(b / count); - // Function to darken a color - const darkenColor = $((color: string | undefined, amount: number) => { - if (!color) return color; - - const rgb = color.match(/\d+/g); - if (!rgb || rgb.length !== 3) return color; - - const darkenChannel = (channel: number) => Math.max(0, channel - amount); - const r = darkenChannel(parseInt(rgb[0])); - const g = darkenChannel(parseInt(rgb[1])); - const b = darkenChannel(parseInt(rgb[2])); + // Ensure the color is light enough + const minBrightness = 100; + r = Math.max(r, minBrightness); + g = Math.max(g, minBrightness); + b = Math.max(b, minBrightness); return `rgb(${r},${g},${b})`; }); @@ -61,19 +55,14 @@ export const Card = component$(({ game }: Props) => { const img = imgRef.value; if (img) { + const processImage = async () => { + backgroundColor.value = await extractColor(img); + }; + if (img.complete) { - const extractedColor = await extractColor(img); - backgroundColor.value = extractedColor; - ringColor.value = await darkenColor(extractedColor, 30); + await processImage(); } else { - await new Promise((resolve) => { - img.onload = async () => { - const extractedColor = await extractColor(img); - backgroundColor.value = extractedColor; - ringColor.value = await darkenColor(extractedColor, 30); - resolve(); - }; - }); + img.onload = processImage; } } }); @@ -82,12 +71,10 @@ export const Card = component$(({ game }: Props) => { + class="min-w-[250px] group cursor-pointer backdrop-blur-sm select-none w-full group rounded-3xl text-primary-950/70 duration-300 transition-colors flex flex-col"> - + {game.name} @@ -95,9 +82,9 @@ export const Card = component$(({ game }: Props) => {