javascriptsassmaterial-designluminance

How to Generate Material 3 Color Palettes in JS/SCSS?


Background:

I'm trying to generate a color palette in SASS/JS based on Google's Material Theme Builder 3 which requires tonal palette's to be generated based on relative luminance and not lightness/brightness function.

enter image description here

Problem:

I can get the luminance value using the following function in SCSS:

@function get-luminance($color) {
    $colors: (
        'red': red($color),
        'green': green($color),
        'blue': blue($color),
    );

    @each $name, $value in $colors {
        $adjusted: 0;
        $value: $value / 255;

        @if $value < 0.03928 {
            $value: $value / 12.92;
        } @else {
            $value: ($value + 0.055) / 1.055;
            $value: math.pow($value, 2.4);
        }

        $colors: map-merge($colors, ($name: $value));
    }

    @return (map-get($colors, 'red') * 0.2126) + (map-get($colors, 'green') * 0.7152) + (map-get($colors, 'blue') * 0.0722);
}

But what I'm looking for is to create a function that can adjust a certain color's luminance e.g.

@function adjust-luminance($color, $luminance-value) {
    // Calculations required to adjust luminance here
    @return $adjusted-luminance-color;
}

$seed-color: #6750A4;

.color-tone-99 {
    background: adjust-luminance($seed-color, 97.4); // Output: #FFFBFE
}

I haven't been able to figure out the calculations part above. I've also come across this Color Luminance Figma plugin that does it in Figma but how does it do it is the question.

Any help would be highly appreciated!

Thanks


Solution

  • Material 3 uses a new system called HCT:

    It turns out James O'Leary, Color Scientist, Platforms & Ecosystems at Google developed a brand new, perceptually accurate, color system is called HCT, which stands for hue, chroma, tone.

    He has written a great article explaining why and how it was created here: The Science of Color & Design.

    The Material Foundation has also released their codebase in TypeScript here: Material Color Utilities GitHub Repo.

    How To Generate Material 3 Color Palette in JavaScript:

    1. Install the Material Color Utilities via NPM:

    npm i @material/material-color-utilities

    2. Import the Utilities:

    import { argbFromHex, hexFromArgb, themeFromSourceColor, TonalPalette } from '@material/material-color-utilities';

    3. Getting Theme JSON:

    const m3ThemeColorsJSON = themeFromSourceColor(argbFromHex('#6750A4'), []);

    4. This will return a JSON map of ARGB colors, to convert them to HEX colors, use the hexFromArgb() function. Example:

    const primary = hexFromArgb(theme.schemes.light.primary);

    5. If you want to get a color from the Tonal Palette, use the following:

    const primary98 = TonalPalette.fromInt(primary).tone(98);

    Support in SCSS:

    The Material Foundation intends to release a version in SCSS in the future but anybody can use this in JavaScript to generate an SCSS file in the meantime.