Introducing ColorFunc - A Ridiculously Flexible Palette Generator

Introducing ColorFunc - A Ridiculously Flexible Palette Generator

Sponsored by 3-hour sleep cycles.

TLDR; I wanted to define palette generation with functions. Here's it is: color-func.vercel.app

Here's the repo: github.com/2manypistachios/ColorFunc

Here's the 6-second problem from Tailwind docs: tailwindcss.com/docs/customizing-colors#gen..

image.png

Motivation:

  1. Some websites LIE about how their algorithms generate color palettes
  2. Exporting colors from most palette websites is painful.
  3. Most palette websites introduce wasteful overhead.

Interestingly, most palette generators are trending to higher levels of abstraction with AI, making it even harder to programmatically define a color scheme / know what's REALLY going on.

However, there are some pretty excellent resources of this abstraction done well:

  1. huemint.com -- IMO, the best AI generator due to taking into account HOW a color will be used. It differentiates between background and emphasis colors. (I plan on adding integration to huemint using their API, and let my program generate the shades + naming scheme.)

  2. khroma.co -- Select 50 schemes for an AI to learn your preferences rather than a prebuilt non-adapting AI.

But since I use chakra-ui, if I want to override a theme entirely, I need to generate 10x shades, for Y amount of colors I want to replace. (This is also a pain with Tailwind).

image.png

Smart watch actually got pretty close to solving my needs. That said, it introduced another problem: redefining one set of colors might cause conflicts with the other colors.

image.png

I needed a solution that let me programmatically say: give me red, and generate x number of shades, and another color or two that wouldn't conflict.

Solution

Here's my solution where I say, give me red, and generate x number of shades.

image.png

Walkthrough

  1. Define your starting color. Every shade and hue will be generated off this.

image.png

| 2. Define your color scheme. Mathematically, schemes are just x-degrees around a color wheel.

Since a circle is 360 degrees, a complementary color is right on the opposite side, 180 degrees over.

I took all of the standard schemes and figured out the math:

image.png

You can also define a custom scheme, which works off a starting & ending degree, and how many steps you would take in between.

For example, the complementary scheme starts at 180 and ends on 180.

| 3. Next, define the shades.

Here's an example where the shades have no change in saturation, but a noticeable change in brightness. Schemes without a change in saturation are considered more 'clay-like.'

image.png

Here's one where the saturation increases only at the edges (typically the most bright and most dark)

image.png

Using saturation as an effect on the edges actually produces some good results.

image.png

To mathematically design that V shape, you can you a f(x) = abs(x) = |x| to create that shape. With a loop counter of 3, meaning it will generate 3 shades, I set a function of abs(x-1) * 20, which means that I would have no saturation in the middle shade, while I would have saturation on the darkest and lightest shades.

The math library accepts some complex formulas.

image.png

To generate:

image.png

| 4. To use these colors you can grab the JSON export or the CSS vars export. The JSON obj is also exposed in the console if you want to play around with it. I plan on additionally adding CSS vars and modularity to defining these names. (Currently using chakra-based naming style)

image.png image.png

| 5. Finally, there's a login / save functionality. Clicking on these boxes will load the math functions across the app. I have a plan to display popular public themes, although I wasn't able to complete it for this hackathon.

image.png

Programming Challenges

  • It took me several iterations to figure out how to organize everything into a simple: first color -> hues -> shades step, which really simplified my workflow.
  • Auth0 worked like a charm, so much so, that I panicked and thought 'it couldn't be that easy, and spent a long time overthinking my setup and going through the documentation
  • Figuring out the color math took a bit, since I was more familiar with RGB rather than HSL, HSL which is way more flexible than the math shown above. Check out some of the reading at the bottom if you're more curious.
  • Updating react state. Since I have multiple variables that go into the color formula, and I need to update those variables in multiple places, I had a terribly convoluted parent hierarchy until I picked up recoil, although it was more first time using a third-party state library.

Final Thoughts

In some distant future, I'll work on a backwardation process, where my site can detect patterns for third-party color themes and extend them. I also think that creating an AI that determines preferences based on clear mathematical principles, could be very powerful. In other words, rather than letting an AI generate some internal math that generates themes, I would have an AI that generates that math to quickly create countless themes.

Tech-Stack

  • Nextjs-Auth0, Authentication Library
  • Chakra-UI, Visual Library
  • Recoil, State Management
  • FaunaDB, Database
  • React Color, Color Components
  • Mathjs, Math ... in JS
  • Color, Color.

Good Reading