GithubHelp home page GithubHelp logo

material-foundation / material-color-utilities Goto Github PK

View Code? Open in Web Editor NEW
1.5K 30.0 126.0 2.95 MB

Color libraries for Material You

License: Apache License 2.0

Dart 21.42% Java 17.01% TypeScript 20.44% C++ 21.30% Swift 19.84%
dart-library dart-package material-design typescript-library cpp-library java-library

material-color-utilities's Introduction

Material Color Utilities

Algorithms and utilities that power the Material Design 3 (M3) color system, including choosing theme colors from images and creating tones of colors; all in a new color space.

materialyou.mp4

Library availability

Language Availability Location
C++
Dart pub package
Java MDC-Android
Swift
TypeScript npm package
GLSL Coming soon

Need another platform/language? Check the existing issues or open a new one.

Usage

Cheat sheet

library cheat sheet

Components

The library is composed of multiple components, each with its own folder and tests, each as small as possible.

This enables easy merging and updating of subsets into other libraries, such as Material Design Components, Android System UI, etc. Not all consumers will need every component — ex. MDC doesn’t need quantization/scoring/image extraction.

Components Purpose
blend Interpolate, harmonize, animate, and gradate colors in HCT
contrast Measure contrast, obtain contrastful colors
dislike Check and fix universally disliked colors
dynamiccolor Obtain colors that adjust based on UI state (dark theme, style, preferences, contrast requirements, etc.)
hct A new color space (hue, chrome, tone) based on CAM16 x L*, that accounts for viewing conditions
palettes Tonal palette — range of colors that varies only in tone
Core palette — set of tonal palettes needed to create Material color schemes
quantize Turn an image into N colors; composed of Celebi, which runs Wu, then WSMeans
scheme Create static and dynamic color schemes from a single color or a core palette
score Rank colors for suitability for theming
temperature Obtain analogous and complementary colors
utilities Color — convert between color spaces needed to implement HCT/CAM16
Math — functions for ex. ensuring hue is between 0 and 360, clamping, etc.
String - convert between strings and integers

Background

The Science of Color & Design - Material Design

Design tooling

The Material Theme Builder Figma plugin and web tool are recommended for design workflows. The Material Theme Builder delivers dynamic color to where design is done. Designers can take an existing design, and see what it looks like under different themes, with just a couple clicks.

material-color-utilities's People

Contributors

cushon avatar guidezpl avatar kluever avatar material-admin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

material-color-utilities's Issues

.js in import of ESM

I am using Yarn to download this package:

yarn add @material/material-color-utilities

After fixing #29 I got these error:

$ C:\files\src\hct\node_modules\.bin\ts-node-esm .\index.ts
C:\files\src\hct\node_modules\ts-node\dist-raw\node-esm-resolve-implementation.js:383
    throw new ERR_MODULE_NOT_FOUND(
          ^
CustomError: Cannot find module 'C:\files\src\hct\node_modules\@material\material-color-utilities\dist\blend\blend' imported from C:\files\src\hct\node_modules\@material\material-color-utilities\dist\index.js
    at finalizeResolution (C:\files\src\hct\node_modules\ts-node\dist-raw\node-esm-resolve-implementation.js:383:11)
    at moduleResolve (C:\files\src\hct\node_modules\ts-node\dist-raw\node-esm-resolve-implementation.js:818:10)
    at Object.defaultResolve (C:\files\src\hct\node_modules\ts-node\dist-raw\node-esm-resolve-implementation.js:929:11)
    at C:\files\src\hct\node_modules\ts-node\src\esm.ts:228:33
    at entrypointFallback (C:\files\src\hct\node_modules\ts-node\src\esm.ts:179:34)
    at resolve (C:\files\src\hct\node_modules\ts-node\src\esm.ts:227:12)
    at resolve (C:\files\src\hct\node_modules\ts-node\src\child\child-loader.ts:19:39)
    at ESMLoader.resolve (node:internal/modules/esm/loader:580:30)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:294:18)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:80:40)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

When I checking dist\index.js:

export * from './blend/blend';

I made some changes to this:

export * from './blend/blend.js';

After I adding .js to all imports. It works perfect to me.

More info: export - JavaScript | MDN

Remaining roadmap: Adding gradient functionality, blend modes, GLSL shader

There was a note in the HCT blog post on material.io about gradient functionality as well as a mention in this project's README: "Color interpolation in HCT ... Harmonizing, animations, gradients [using Blend]."

Is this a manual affair? Were there (perhaps scrapped) plans to still add features in the Blend topic?

Surely I can create my own Gradient subclass in Flutter that lerps utilizing Blend.hctHue, but I did not want to spend that time if this package still has a roadmap.

The other features mentioned in that blog all sound exciting, too, like legible text on any background, filters and blend modes, and the GLSL shader.

Add package support

This issue tracks package support for the various languages/platforms.

  • Dart: pub.dev
  • Java: Apache Maven
  • TypeScript: NPM

Need a helper for getting seed colors for the material3 color system

I am happy that this library exposes the Hct class which was used under the hood in Material library's MaterialColors.getColorRoles() like this:

    Hct hctColor = Hct.fromInt(color);
    hctColor.setTone(tone);
    return hctColor.toInt();

Basically, I used it to get color roles for a seed color, which as per material specs are at tonal values of 10, 40, 90 and 100.

All good, but now my designer wants me to use the exact color code for the onAccentContainer role, which would be the seed color at tonal value of 10. How do I generate this seed color, so that after setTone(10) I would get the exact color code he wants, while also supporting all the other material color system tones?

How can I add to the theme generator the secondary color?

In the M3 Theme Web Generator, it is possible to set not only the primary color but also secondary, tertiary, and neutral.

How can I set them to generate the theme?

This is the current function:
const theme = themeFromSourceColor(argbFromHex(primary), [{},]);
How can I add something like:
const theme = themeFromSourceColor(argbFromHex(primary), argbFromHex(secondary), argbFromHex(tertiary), argbFromHex(error), argbFromHex(neutral), [{},]);
or something similar?

Thanks 🙏

Swift library

What about library on Swift (instead of planned library on Objective-C)?

Rust library

What about library on Rust (instead of planned library on C/C++)?

Getting the color tone value in a palette

My usecase is generating relative tones. Right now, I have to loop through TonalPalette results with floating point precision to get the nearest tone value of my input color. Would it be possible to add a helper fn that returns the tone value of input color in the palette that TonalPalette creates?

Kotlin Library

While Java Library works find for JVM target, it would be great to have a Kotlin Library for Kotlin/Native.

Add RGBA utility

We have hex conversion utilities (hexFromArgb and argbFromHex) already, RGBA conversion utilites would also be a nice quality of life addition!

I'd offer a pull request, but #11 (comment)

TypeScript implementation:

import * as colorUtils from './color_utils';

interface Rgba {
  r: number
  g: number
  b: number
  a: number
}

/**
 * @param argb ARGB representation of a color.
 * @return RGBA representation of a color.
 */
const rbgaFromArgb = (argb: number): Rgba => {
  const r = colorUtils.redFromArgb(argb)
  const g = colorUtils.greenFromArgb(argb)
  const b = colorUtils.blueFromArgb(argb)
  const a = colorUtils.alphaFromArgb(argb)

  return { r, g, b, a }
}

/**
 * @param rgba RGBA representation of a color.
 * @returns ARGB representation of a color.
 */
const argbFromRgba = (rgba: Rgba): number => {
  return (rgba.a << 24) | (rgba.r << 16) | (rgba.g << 8) | rgba.b
}

TypeScript Library - Surface Tint + Elevations

It seems that the typescript library doesn't account for the md.sys.color.surface-tint-color token which should default to the primary color.

In addition, is there a POV on how elevations should be handled?

I think at present it would require manually compositing the surface color + primary color (possibly to be replaced the aforementioned surface tint color) with opacity at a given elevation per the specification. Implemented as a custom color today?

Is there an example of how to use HCT to accomplish this to get the tonal variations for the elevations?

Thank you in advance! The library and concepts are awesome!

Add "type": "module" to support Node's ES module loader

For the TypeScript package, the published package.json does not include a { "type": "module" } specification, which means that Node treats the package modules as CommonJS modules. However, the compiled output only contains ECMAScript modules (e.g. export statements).

This means that the package cannot be imported using vanilla Node.js, because it treats the package/modules as CommonJS modules. There isn't really a way to override this behaviour as a library user.

This results in syntax errors, for example:

(node:11542) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/my-project/node_modules/@material/material-color-utilities/dist/index.js:17
export * from './blend/blend';
^^^^^^

SyntaxError: Unexpected token 'export'
    at Object.compileFunction (node:vm:352:18)
    at wrapSafe (node:internal/modules/cjs/loader:1027:15)
    at Module._compile (node:internal/modules/cjs/loader:1063:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Module.load (node:internal/modules/cjs/loader:975:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:170:29)
    at ModuleJob.run (node:internal/modules/esm/module_job:198:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:385:24)

Node.js v17.8.0

This should be resolvable by either publishing CommonJS modules, or by making it explicit that this package uses ECMAScript modules. The latter can be achieved by adding {"type": "module"} to package.json or by using .mjs extensions. In addition, all compiled imports should explicitly specify the file extension (see #35).

See also:

Feature request: Kotlin Multiplatform support

Similar to #49 I'd like to request a kotlin implementation but instead of asking for JDK one I ask it to be multiplatform library so that it can be used from both Android and iOS (and web, native etc..)

Do you accept pull requests?

Is this repo a read-only mirror of some internal repo? I see that all pull requests was closed without merging with comment "Fixed internally.".

Does it make sense to make pull requests?

Broken TonalPalette equality operator in dart

In TonalPalette, when one of the palettes was not generated using the _fromHueAndChroma operator, the following code is called:

return _cache.values.toSet().containsAll(other._cache.values);
. The issue is that when one of the palettes's cache was not filled, the comparision results in a empty set contains an empty set, for example. This results in operator== resulting in true, always, even when the palettes are different. An testcase for this it https://github.com/kalildev/material_color_utilities_issue .

Typescript Library - argbFromHex - Incorrect Parsing

The argbFromHex function does not parse hex values correctly when the hex value is 8 characters long (excluding the #). It incorrectly assumes the last two characters are the blue channel when it's actually the alpha channel.

Example: 50% opacity as represented by the 80 in the input (black)

Input: #80 (equivalent to #7f7f7f)

Incorrect Output: 4278190208 (equivalent to #80) ... a blue

export const argbFromHex = (hex: string) => {
hex = hex.replace('#', '');
const isThree = hex.length === 3;
const isSix = hex.length === 6;
const isEight = hex.length === 8;
if (!isThree && !isSix && !isEight) {
throw new Error('unexpected hex ' + hex);
}
let r = 0;
let g = 0;
let b = 0;
if (isThree) {
r = parseIntHex(hex.slice(0, 1).repeat(2));
g = parseIntHex(hex.slice(1, 2).repeat(2));
b = parseIntHex(hex.slice(2, 3).repeat(2));
} else if (isSix) {
r = parseIntHex(hex.slice(0, 2));
g = parseIntHex(hex.slice(2, 4));
b = parseIntHex(hex.slice(4, 6));
} else if (isEight) {
r = parseIntHex(hex.slice(2, 4));
g = parseIntHex(hex.slice(4, 6));
b = parseIntHex(hex.slice(6, 8));
}
return (
((255 << 24) | ((r & 0x0ff) << 16) | ((g & 0x0ff) << 8) | (b & 0x0ff)) >>>
0);
};

themeFromImage call promise never resolve.

Hi there, I have tried themeFromImage, the returned promise never resolved, no result and no error. Am I missing anything?

const image = document.getElementById('brandlogo');
themeFromImage(image)
.then(theme => {
console.log('theme', theme);
})
.catch(err => message.error(err.message))
.finally(() => console.log('finished'));

The chroma results seem incorrect for colors near amber

Ref: color amber (0xffffbf00) / RGB(255, 191, 0) / HSV(hue: 45° (44.941), saturation: 100% (1.000), value: 100% (1.000)) // hsla(45, 100%, 50%, 1.0) // hsluv H: 57.150, S: 100.026, L: 81.031 // CIELuv L: 81.031, C: 99.176, H: 57.150

HCT tests for this color produces a chroma of 60.7, yet it is fully saturated using all other tested spaces/models (see above).
HCT tests have been run using the dart package imported as well as using the test web page for .Net C##. The results are identical using either approach (web tests or inline/imported dart packages).

Is this correct or is this a result of the CAM16 derivation?

We are excited about HCT and hope to use it to classify and describe colors, e.g. pale, vivid, dull, etc. To replace HSV with HCT -- the desired approach -- we would rely heavily on the chroma and tonal values produced by HCT.

Typescript Library - hexFromArgb - Missing Alpha

The hexFromArgb function is missing the alpha component in its output. This is also related to Issue: Typescript Library - argbFromHex - Incorrect Parsing #33

Input: 2147483648
Expected: #80
Actual: #000000

export const hexFromArgb = (argb: number) => {
const r = colorUtils.redFromArgb(argb);
const g = colorUtils.greenFromArgb(argb);
const b = colorUtils.blueFromArgb(argb);
const outParts = [r.toString(16), g.toString(16), b.toString(16)];
// Pad single-digit output values
for (const [i, part] of outParts.entries()) {
if (part.length === 1) {
outParts[i] = '0' + part;
}
}
return '#' + outParts.join('');
};

NPM package.json missing "main" definition

When using the TypeScript library I ran into the following error:

Module not found: Error: Can't resolve '@material/material-color-utilities' in '...'

This is due to the following line missing in package.json:

"main": "./dist/index.js",

This in package version 0.1.1

Python Library

I hope support for cli, terminal based application can have a library color generator will be avalible

HCT produces unexpected RGB values

This is most noticable when the seed color is yellow:

Untitled
Background color is Primary 98.

I have made a graph that shows the RGB value, with chroma set to 100:
different-models
I included CAM16 (that also seems to be broken) and HSL as a reference. These images were made using my C# library, but it shouldn't have any differences, as most of it is just the Java version copy-pasted. I also added every test from the Dart library, which are all passing.

Setting the chroma to a lower value seems to alleviate the problem a bit:
different-chromas
This was made with Flutter, here is the code for that:

import 'package:flutter/material.dart';
import 'package:material_color_utilities/material_color_utilities.dart';

void main() {
  runApp(CustomPaint(
    painter: ColorsPainter(),
  ));
}

class ColorsPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    for (double x = 0; x < 360; x++) {
      for (double y = 0; y < 100; y++) {
        HctColor hct = HctColor.from(x, 100, y);
        canvas.drawCircle(Offset(x, y), 1, Paint()..color = Color(hct.toInt()));
      }
    }
  }

  @override
  bool shouldRepaint(ColorsPainter oldDelegate) {
    return false;
  }
}

Flutter code for the CAM16 graph (produces the same result as C# above):

import 'package:flutter/material.dart';
import 'package:material_color_utilities/material_color_utilities.dart';

void main() {
  runApp(CustomPaint(
    painter: ColorsPainter(),
  ));
}

class ColorsPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    for (double x = 0; x < 360; x++) {
      for (double y = 0; y < 100; y++) {
        Cam16 cam = Cam16.fromJch(y, 100, x);
        canvas.drawCircle(
            Offset(x, y), 1, Paint()..color = Color(cam.viewedInSRgb));
      }
    }
  }

  @override
  bool shouldRepaint(ColorsPainter oldDelegate) {
    return false;
  }
}

Kotlin Multiplatform library

Hello, it'd be cool to support Kotlin Multiplatform as there are already apps with their UI implemented in Kotlin on both iOS and Android.

Making it can be fairly easy as you can start by converting the Java code to Kotlin before improving the API and ensuring you don't depend on JVM only APIs.

Improvement of image_utils

I think if(image.complete) image.onload() should be added after image.onload = () => {...} (line 42) in file material-color-utilities/typescript/utils/image_utils.ts.

This allows it to take the color of the loaded image.

How is neutral color created?

Sorry if this is not the right place to ask but I want to know how the neutral color is created. Is it hard coded to certain shade of gray or is it derived from the primary color? If so, what is the calculation for conversion between primary and neutral color?

Not accepting external contributions

The issues tab of several GitHub repos are full of front-end developers asking for updates on Material 3/You. MDC, Angular, everyone is wondering how/when they can start using Material 3.

Frankly, I'm tried of seeing devs whine, sometimes for years, about Material support in Angular or X/Y/Z projects instead of contributing to the development of the libraries themselves.

Lack of HCT support is the only thing keeping me from using Material 3's color system in a web app today. I was surprised to see a TypeScript library with no accompanying Sass library. I was shocked to see that this repo is not open to external contributions. I didn't even know it existed until a Google employee pointed me to it.

I'm willing to do a line-by-line port of the TypeScript material-color-utilities to Sass, this week, if that port has a path to release.

Some questions:

  1. Is Sass support planned?
  2. If Sass support is planned, is development underway?
  3. If Sass support is planned, when is it expected to be released?
  4. If Sass support is planned, can the development work be done in public?
  5. If no one has started working on Sass support, does a port created by an external developer have a chance of being included in this repo?
  6. Why is this repo not referenced anywhere on material.io?

.NET Library

Per the README, humbly requesting a .NET Library written in C# to be added to the roadmap if possible.

Update the value of the Dart package's `repository` field

Hi, I see this is a read-only mirror (so I'm opening an issue instead of a PR). It would be useful to update the value the the Dart package's repository field to include information about the package's path within the repo - as well as the repo's url itself. This helps tooling know where to find the dart code, now which commits actually affect the dart package, ...

Here's what the field should look like:

repository: https://github.com/material-foundation/material-color-utilities/tree/main/dart

Thanks!

Question about Scheme and/or ColorPalette behavior

Consider the following code:

import 'package:flutter/material.dart';
import 'package:material_color_utilities/material_color_utilities.dart';

void main() {
  const color = Colors.blue;
  final scheme = Scheme.light(color.value);
}

Should color.value be equal to scheme.primary? Right now these two values are different.

I can see that Scheme.light calls CorePalette.of(color) and then assign corePalette.primary.get(40) as the primary color. Maybe another question would be should corePalette.primary.get(40) be equal to the color that was provided initially?

I was also reading the color system page, and seems like the primary color should have a tone of 40. So I'm just wondering what's the expected behavior when using Scheme.light and/or CorePlatte.of?

High level description of algorithms

I'm very interested in high level description of algorithms and formulas from this project.

Do you mind to write a blog post about how all these things work? 🙏

Change of Copyright notice

Hello! According to the Appendix of Apache License 2.0, if you want to license your software under this License you should "attach the boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information". This condition is not met now. Please add a copyright notice in the appropriate form, including the year of the software development and your name and surname. Thank you in advance

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Easy access to material Design colors

There is no package for dart native to get material colors.

In Flutter you can get colors like this Colors.orange using the Flutter package material.

image

Can we add a way to use the colors?.

We can use Colors.orange like in the packge or change it so that it will not collide inside Flutter projects.

Incorrect Array size in score.ts

Line 67 of score.ts has the line const hueProportions = new Array<number>(360).fill(0); to allocate an array of size 360 to cache proportions of hues. Hues can range up to 360 so the size should be 361 or else the highest index available is 359 and caching a hue of 360 will have the array auto-grow to accommodate.

Typescript Library - Custom Colors - CSS Variables

The applyTheme function as referenced below, creates CSS variables on a given target element and scopes everything to the sys token type. However, custom colors are not factored in. Given that the custom colors do account for "color", "on", and "container" (as well as light/dark) is there a convention for how these should be tokenized. Also, is there a reason that the convention would/wouldn't be applied in the applyTheme function ?

export function applyTheme(theme: Theme, options?: {
dark?: boolean,
target?: HTMLElement,
}) {
const target = options?.target || document.body;
const isDark = options?.dark ?? false;
const scheme = isDark ? theme.schemes.dark : theme.schemes.light;
for (const [key, value] of Object.entries(scheme.toJSON())) {
const token = key.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
const color = hexFromArgb(value);
target.style.setProperty(`--md-sys-color-${token}`, color);
}
}

Inappropriate result when tone value is high

For input color #3F51B5 (looks indigo or blue), tone 99 value is #fefbff (looks pink or purple). I belive the correct color should be very light indigo or blue. This problem happens both in Material Theme Builder and Java code.

Test code:

import palettes.CorePalette;

import java.lang.*;

public class Main {

    public static void main(String[] args) {
        CorePalette palette = CorePalette.of(0x3F51B5);
        System.out.printf("#%08x\n", palette.a1.tone(99));
        System.out.printf("#%08x\n", palette.a1.tone(95));
    }
}

Material Theme Builder result:

image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.