--- title: rainbow quox date: 2024-12-03 tags: [computer, website, fursona, december adventure] summary: q.t. colour scheme generator header-includes: | ... the animal-inclined might know that [q.t.][qt] can change its colour any time it wants. if you click that link you can clearly see i have some tendencies, but it can in theory be anything. so something i have wanted for a while is a page where you can click a button and get a bespoke randomly-generated quox theme of your very own. so for today's [`@december adventure@`][decadv], i did that. (yesterday's was retroactively the AOC stuff.) [decadv]: https://eli.li/december-adventure :::banner [go here if you just want to play with the thing][thing] ::: [thing]: https://yummy.cricket/rainbow-quox you can also skip to [what i _actually_ ended up doing](#actual), if you don't care about the false starts. [qt]: https://gallery.niss.website/by-any/#qt # doing that ![this is the image i'm starting from.](rainbow-quox/front.avif){.floating .expandable .nobg .shaped} pretty much what i want to do, at least to begin with, is take the original colours of the image and move the hues around at random. if you look at [mdn], you might see this interesting [`hue-rotate()`][hr] thing that might do what i want. let's have a look. [mdn]: https://developer.mozilla.org/en-US/docs/Web/CSS [hr]: https://developer.mozilla.org/en-US/docs/Web/CSS/filter-function/hue-rotate > **Note:** `hue-rotate()` is specified as a matrix operation on the RGB color. It does not actually convert the color to the HSL model, which is a non-linear operation. Therefore, it may not preserve the saturation or lightness of the original color, especially for saturated colors. ![took a hot shower for too long](rainbow-quox/red.avif){.floating .right .nobg .expandable .shaped} well that doesn't sound very encouraging. but maybe it'll be fine. i shoved [all of the colours][jofo] to hue 0° (using krita's `@hue HSL@` blend mode), and used `hue-rotate()` to change it back to the 'main' colour of each region. it won't look exact, but it'll be close. right? [jofo]: https://johnnyforeigner.bandcamp.com/track/all-of-the-colours ![oh](rainbow-quox/dark.webp){.expandable .nobg} well that's no good at all. i guess that warning was serious. # ok what about blend modes all right, fine. what else. as a chronic over-user of `overlay`, i can certainly tell you that css has a few [blending modes][bm]. not as many as krita, which has approximately "too many", but enough for most purposes. one of them is `hue`. how about that. [bm]: https://developer.mozilla.org/en-US/docs/Web/CSS/blend-mode this takes a bit more messing, because i need to create a flood fill of one of the colours from that layer, and blend with that. so how about an SVG filter, i guess. or, six SVG filters---one for each layer, since you can't parametrise them. each one looks like this, with a different `flood-color`. ```svg ``` and… ![also no](rainbow-quox/dark2.webp){.expandable .nobg} i was expecting at least the same thing, but a different, also wrong, result is pretty cool. # drastic measures {#actual} ok, enough messing around, time to bite the bullet. separate _every_ colour into its own layer, and use those as masks for colour fills. ```css #spines { background: oklch(30.77% 0.1306 var(--hue)); --hue: 298.19; mask-image: url(front/spines.png); } /* etc… */ ``` since the hue is separated out into a variable, i can just randomise them all and instantly have _something_ working. ![some of these are kinda promising already??](rainbow-quox/quoxes1.avif){.expandable .hasborder #chaos} # digression about relative colours [» skip »](#js) another thing i played with was using [`@relative colours@`][relcol] to generate a whole palette from one starting colour. relative colours work like this: if you have an existing colour `--hi`, you can rotate its hue by half a turn (in real `oklch` this time!!!), keeping its luma and chroma the same, by saying this: ```css :root { --hi: #ea9aa1; --wow: oklch(from var(--hi) l c calc(h + 180)); } ```
\--hi
\--wow
[relcol]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_colors/Relative_colors so i tried that. after guessing a bunch of relative colours, i ended up with this: ![yeah that looks ok for a first try.](rainbow-quox/relative.avif){.expandable .nobg} # just do it in ~~java~~typescript. fine {#js} that was pretty cool, but i decided i actually want more flexibility. lighter and darker colour schemes. triadic schemes. whatever. maybe that would be possible in pure css with increasingly illegible relative colours. but the randomise button is going to need javascript anyway, so i might as well just fill in the colours directly. but `oklch` is still useful for generating consistent palettes. the constraints for a "good" q.t. are something like: 1. the spines should be a similar colour to its main body. 2. the same applies to the four fin colours; the belly colours; the sock colours; and the mask and claw colours. 3. the belly should be very different from the rest of the body. 4. the eyes should be a similar colour to the body, the fins, or the belly. 5. the vitiligo patches should match the colour that they are on. 6. the sock stripes should be pale and not too saturated. a good place to start is the same place everyone does: with complementary and triadic colours. :::{#patterns} ![colour triad ~120° from each other](rainbow-quox/triad.avif){.expandable .nobg} ![analogous fins & belly; complementing body](rainbow-quox/compl1.avif){.expandable .nobg} ![analogous fins and body; complementing belly](rainbow-quox/compl2.avif){.expandable .nobg} ::: using this as a starting point, i pick some evenly-spaced colours for each bit. the final palettes come out like this! :::{#result} - fins - body - belly - mask/claws/socks ![wasn't actually that hard if you ignore all the wrong turns](rainbow-quox/result.webp){ .right .expandable .nobg} ::: # ok what now it's not finished. some things i plan to add at, uh, some point, include: - put [chaos mode](#chaos) back in. - permalinks for colour schemes. to do this i need to write another random number generator, since `Math.random` can't be manually seeded. and by "write" i mean "look up online". - colour schemes with a light body and dark belly, rather than the other way around. - render onto a ``, or something. whatever's needed to be able to save the images without having to take a screenshot. :::banner [here's the link again to save you scrolling back up][thing] :::