Material 3 Dynamic Colour System: UI Palette Generator

Introduction

To get the important part out of the way first, this is a post for you to install the library for yourself to test it out with your interfaces.

Get Familiar

Try It Out In-Game

Material 3

Material 3 is Google’s latest Material Design standard. With it came something amazing which would be their new Dynamic Colour System. This system is able to generate different palettes from a source colour, providing an array of different “colour roles”.

Functionality

Example 1

Note that for every element on here, its colour was generated by the system, from the primary colour. That’s all it requires.

Source

You can pick this up from here: Dynamic Colour System.

Documentation

Out of respect for my own incompetence, I’ve kept functionality pretty limited for now (although, I’m not too sure what else I could do with this).

Using it is pretty simple:

local colour_library = require(script.colour_library);
local light_theme, dark_theme;

light_theme = colour_library.theme_from_colour(colour_library.from_hex("#17b485"), {
    is_content = true; -- is_content will allow for more dynamic pallets.
    -- The hue will change regardless of is_content.
    -- However, with is_content disabled, the chroma will be constant between all hues.
});

dark_theme = colour_library.theme_from_colour(colour_library.from_hex("#17b485"), {
    is_content = true;
    dark = true;
});

These will both return a table of colours, with the added a1, a2, a3, n1, n2 classes for retrieving custom tones - I’ll explain after the properties.

UIScheme {
		primary = Color3;
		on_primary = Color3;
		primary_container = Color3;
		on_primary_container = Color3;
		secondary = Color3;
		on_secondary = Color3;
		secondary_container = Color3;
		on_secondary_container = Color3;
		tertiary = Color3;
		on_tertiary = Color3;
		tertiary_container = Color3;
		on_tertiary_container = Color3;
		_error = Color3;
		on_error = Color3;
		error_container = Color3;
		on_error_container = Color3;
		background = Color3;
		on_background = Color3;
		surface = Color3;
		on_surface = Color3;
		surface_variant = Color3;
		on_surface_variant = Color3;
		outline = Color3;
		outline_variant = Color3;
		shadow = Color3;
		scrim = Color3;
		inverse_surface = Color3;
		inverse_on_surface = Color3;
		inverse_primary = Color3;
		_a1 = TonalPalette;
		_a2 = TonalPalette;
		_a3 = TonalPalette;
		_n1 = TonalPalette;
		_n2 = TonalPalette;
	}

Here, you can see all the options, allowing you automatically set a UI’s desired colour to a linked property, which will allow for much easier switching between themes and source colours.

As for TonalPalette(s):

TonalPalette {
    self:tone(tone<0-100>) -> argb<number>;
}

You could use this in such context:

-- Propose you weren't a big fan of the tone 80 for the primary colour, you want 90.
dark_theme.primary = colour_library.from_argb(dark_theme._a1:tone(90));

If anything’s unclear, or you encounter bugs, have fixes, suggestions, whatever, please leave a comment.

Known Bugs

  • For some tone intervals, a colour’s chroma maybe appear asymmetrical to its TonalPalette, although I’ve tested a few-thousand colours and this doesn’t appear to be common - still a possibility. Direct cause is unknown, just that tone is culprit.
    • I believe to have identified, and corrected, the cause of this bug. If this persists, please let me know.
13 Likes

I think you should provide a test place for users to view what palettes will be made with their given selection (like what you have with the example image)

2 Likes

Hi! Thanks for the reply. I did some bug-fixing which should be resolved now, and I’ll get to work on this right now! Great idea.

1 Like

You can try the preview game out here.

1 Like

can you make the test place open source editable?

maybe to have what the hex values get change to…

and as bonus 2.0, a real sample GUI UI that shows the changes!

Yes, of course. Should be uncopylocked now.

I’m confused about the other stuff though. Why would you need the hex values and the GUI does show changes as you change the colour.

You should see something like this:

I’m not sure what you did to create this as Google uses complex algorithms, but I have a complete, official from reviewed Google source code translated version from the material-foundation/material-color-utilities typescript library. At first glance it seems more clean and bug-free.

MaterialThemeUtils.rbxm (24.8 KB)

1 Like

Hi, sorry if I seem to have stepped on your toes? I don’t really think DevForum is the place for passive aggressiveness, nor is it the place to self-promote. Have a good one, though.

Edit: I took a look at your work, and this also appears to be off-topic, as it does not provide the utility offered in the original post. This is specifically for generating colour palettes, according to Material 3’s new Dynamic Colour System - this functionality can not be found within your model.

I’m curious as to where you can find passive aggressiveness in my reply. I noticed a library that doesn’t completely implement Material 3 and contains many bugs, and I provided code representing the actual API for Google javascript material 3 functionality. This is not my module, it is 100% google javascript code translated into lua.

The model not only creates color schemes but also creates color groups. I’m not sure what code you’re looking at that doesn’t provide Material 3 functionality.

Could you point out the many bugs?