From b2096daeca32e206e2ac7df8abf0890df44b7d60 Mon Sep 17 00:00:00 2001 From: Corwin Date: Tue, 23 Apr 2024 22:19:23 +0100 Subject: [PATCH] add colour converter --- website/agb/src/app/colour/colour.tsx | 133 ++++++++++++++++++++++++++ website/agb/src/app/colour/page.tsx | 10 ++ 2 files changed, 143 insertions(+) create mode 100644 website/agb/src/app/colour/colour.tsx create mode 100644 website/agb/src/app/colour/page.tsx diff --git a/website/agb/src/app/colour/colour.tsx b/website/agb/src/app/colour/colour.tsx new file mode 100644 index 00000000..77d11789 --- /dev/null +++ b/website/agb/src/app/colour/colour.tsx @@ -0,0 +1,133 @@ +"use client"; + +import { ContentBlock } from "../contentBlock"; +import { useState } from "react"; +import { styled } from "styled-components"; + +interface Colour { + r: number; + g: number; + b: number; +} + +function fromHex(hex: string): Colour { + if (hex.startsWith("#")) { + hex = hex.slice(1); + } + + const c = parseInt(hex, 16); + + return { + r: c & 255, + g: (c >> 8) & 255, + b: (c >> 16) & 255, + }; +} + +function toHex(colour: Colour): string { + const hex = (colour.r | (colour.g << 8) | (colour.b << 16)) + .toString(16) + .padStart(6, "0"); + + return `#${hex}`; +} + +function fromRgb15(colour: number): Colour { + const r = colour & 31; + const g = (colour >> 5) & 31; + const b = (colour >> 10) & 31; + + function upScale(a: number) { + return a << 3; + } + return { + r: upScale(r), + g: upScale(g), + b: upScale(b), + }; +} + +function toRgb15(colour: Colour): number { + const { r, g, b } = colour; + return ((r >> 3) & 31) | (((g >> 3) & 31) << 5) | (((b >> 3) & 31) << 10); +} + +export default function ColourPicker() { + const [colour, setColour] = useState(fromHex("#FFFFFF")); + const gbaColour = fromRgb15(toRgb15(colour)); + + const hexColour = toHex(colour); + const gbaHexColour = toHex(gbaColour); + const gbaU16 = `0x${toRgb15(colour).toString(16)}`; + + function setHexColour(colour: string) { + setColour(fromHex(colour)); + } + + function setGbaHexColour(colour: string) { + setColour(fromRgb15(toRgb15(fromHex(colour)))); + } + + return ( + +

agbrs colour converter

+ + +

Regular RGB8

+ setHexColour(evt.target.value)} + /> + setHexColour(evt.target.value)} + /> +
+ +

GBA RGB5

+ setGbaHexColour(evt.target.value)} + /> + setGbaHexColour(evt.target.value)} + /> + + setColour(fromRgb15(parseInt(evt.target.value, 16))) + } + /> +
+
+
+ ); +} + +const PickerColumn = styled.div` + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; + min-width: 40%; +`; + +const PickerWrapper = styled.div` + display: flex; + justify-content: space-around; +`; + +const Input = styled.input` + width: 100%; +`; + +const ColourInput = styled(Input)` + height: 100px; + color: #33a012; +`; diff --git a/website/agb/src/app/colour/page.tsx b/website/agb/src/app/colour/page.tsx new file mode 100644 index 00000000..6d760631 --- /dev/null +++ b/website/agb/src/app/colour/page.tsx @@ -0,0 +1,10 @@ +import { Metadata } from "next"; +import ColourPicker from "./colour"; + +export const metadata: Metadata = { + title: "Colour Converter", +}; + +export default function ColourPickerPage() { + return ; +}