rydmike / flex_color_picker

A highly customizable Flutter color picker.
BSD 3-Clause "New" or "Revised" License
198 stars 41 forks source link

Get Color Name #53

Closed TomasWard1 closed 1 year ago

TomasWard1 commented 1 year ago

Hello, the return type when the color is changed in DialogPicker is a material Color. This has no property of name, which I need to get to show to the user.

I know that you have each color name because you display it in the dialog.

How can I receive the picked color name? Is there a function to change from color to color name?

Thank you!

TomasWard1 commented 1 year ago

showColorName: true is the property I need to access

rydmike commented 1 year ago

Hi Tomas @TomasWard1,

Thank you for your question. Yes there are functions for this. The FlexColorPicker exposes almost all of its internal color tools via APIs. See for example ColorTools:

https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorTools-class.html#static-methods

With FlexColorPicker package imported, you can use the ColorTools static functions ColorTools.materialName and ColorTools.nameThatColor anywhere in your app on any Color value, without using the FlexColorPicker. You just pass them a Color and you get the String name back.

The FlexColorPicker uses these functions internally and provide them as exported tools as well. I use them and other color tools it provides frequently myself too outside of the color picker, on colors from the picker and other sources.

To get the Material 2 Color name use ColorTools.materialName:

https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorTools/materialName.html

It can return the Material 2 color name with, or without the index. All colors do not have a Material 2 color name, if it is not a Material 2 color, an empty string is returned.

To get the color name of the color closest matching the color from a "Name That Color" list of 1566 named colors, use ColorTools.nameThatColor:

https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorTools/nameThatColor.html

The returned color name is based on a Dart port of a JavaScript tool called 'ntc', short for "Name That Color". The javascript project and info about it can be found here http://chir.ag/projects/ntc.

This function always finds a name for a passed in color, at least I have not yet been able to pass it color value where alpha is #FF and have it not return a name. How useful the name is I leave to others to debate that came up with the 1566 color names, but at least colors get a name which can often be useful. Color values that are "close" to each other, in the sense that the colors looks fairly similar to each other, result in the same name, even if the value is a bit different.

Example


// Use any color value.
final Color myColor = Color(0x66F57C00);

// If the color has other alpha value than #FF, like above where it 
// is #66, then set alpha to #FF when using the functions, otherwise
// the name for the color is not found as value with alpha does not
// equal the named colors or material color, but we can of course
// find its equivalent with no alpha set.

// What is myColor's material color name, with index?
final String materialColorWithIndex = 
  ColorTools.materialName(myColor.withAlpha(0xFF)); // "Orange [700]"

// What is myColor's material color name, without index?
final String materialColorWithNoIndex = 
  ColorTools.materialName(myColor.withAlpha(0xFF), withIndex: false); // "Orange"

// What is myColor's "name that color" name?
final String namedColor = 
  ColorTools.nameThatColor(myColor.withAlpha(0xFF)) // "Gold Drop"

Hope this helps! If not feel free to elaborate you question further, and if it solved your issue/question, please feel free to close it. 😃

TomasWard1 commented 1 year ago

Thank you, that was a perfect answer. Follow up: Do you have something similar but to get the appropriate text color? For example, if the color is dark blue, I want the text to be white, or if the color is yellow, I want the text to be black.

You seem to use this logic when setting the color of the 'check mark' of a selected color. Could you tell me how to do it? Thanks!!

rydmike commented 1 year ago

You are welcome Tomas,

Yes there is indeed a feature to determine if a color used as background is better suited for dark (usually black) text or light (often white) color.

Using ThemeData.estimateBrightnessForColor

A feature to determine this is built into Flutter SDK. There is static function on ThemeData for it called estimateBrightnessForColor, see https://api.flutter.dev/flutter/material/ThemeData/estimateBrightnessForColor.html

This of course only gets you half way, it only tells you if the color is considered to have Brightness.light or Brightness.dark, if it is light it should use dark text for good contrast and wise versa.

To get just plain white or black as contrasting text color for a color, you can make a simple function for it, or just use the function body below inline if you just need it in one or two spots, as it is very short.

/// Return [Colors.black] if [color] is [Brightness.light] and [Colors.white] 
/// if [color] is [Brightness.dark].     
Color onColor(final Color color) =>
    ThemeData.estimateBrightnessForColor(color) == Brightness.light
        ? Colors.black
        : Colors.white;

ColorScheme onColors

If you are working with and using Theme.of(context).colorScheme colors, and especially if you are using Material 3 design, you should use the onColors you defined for your ColorScheme colors in your ThemeData.

For example, if the background container color is primary use onPrimary, for surface use onSurface, for background use onBackground. Basically there is a predefined onColor for almost every color in the theme's ColorScheme. When you use Material 3 color schemes the on colors are typically not plain black/white, they contain more or less of the container color, adding to the color expressiveness of Material 3 design.

To make a properly Material 3 designed and defined ColorScheme you can use the Material 3 web tool, or seed generate it in Flutter from a color using ColorScheme.fromSeed, which is the Flutter SDK tool for making a seed generated ColorScheme, if its features feels to restrictive you can use my package FlexSeedScheme and its SeedColorScheme.fromSeeds function for much more control over the seed generation algorithm, the result is still based on the same new color space invented by Google and used in Material 3.

Of course my FlexColorScheme package can help a lot with theming and color schemes. In my Flutter Vikings talk I also go through a lot of Flutter theming goodies and how the Material 3 seeded ColorScheme works. You can find it here.

Apologies for the shameless package plugs, but they might help in learning more about color usage in Flutter. 😃

TomasWard1 commented 1 year ago

You are the best person on the planet. Quick, concise answers. Incredible! keep it up. Thanks.