4

I've built a name-[rgb] Javascript object. Your basic:

namedColors = {
  AliceBlue: [240, 248, 255],
  AntiqueWhite: [250, 235, 215],
  ...

object. But it occurred to me that I should be able to take a name string, "AliceBlue", say .. and have JavaScript find some sort of RGB representation of it (hex is fine). I know there are at least 140 named colors tucked away in the browser, but I can't seem to find them.

Is there a CSS or "style=..." stunt that lets me look up an RGB representation of a color name?

backspaces
  • 3,802
  • 6
  • 34
  • 58
  • I'm not sure what your long term objective is but there are some "think outside of the box" solutions too. IIRC, you can set the named color on a DOM element you create on the fly, then inspect the computed styles... which I believe all return an RGB value. – scunliffe Oct 16 '14 at 22:18
  • 2
    possible duplicate of [Javascript function to convert color names to hex codes](http://stackoverflow.com/questions/1573053/javascript-function-to-convert-color-names-to-hex-codes) – Bojan Petkovski Oct 16 '14 at 22:18
  • easy to do with javascript or jQuery... but do you want a CSS only solution? – dhc Oct 16 '14 at 22:41
  • dhc: yup .. a simple function nameToRGB(name) -> any sort of rgb representation like hex string or rgb string. – backspaces Oct 17 '14 at 16:49
  • scunliffe, bojan: yup, the other SO is a dup, and the getComputedStyles approach look promising. I'll give it a try. [This is the pointer](http://www.backalleycoder.com/2010/10/05/converting-css-named-colors-to-rgb-and-hex/) that I think will do the trick – backspaces Oct 17 '14 at 16:58

5 Answers5

7

Minimal JavaScript function:

function nameToRgba(name) {
    var canvas = document.createElement('canvas');
    var context = canvas.getContext('2d');
    context.fillStyle = name;
    context.fillRect(0,0,1,1);
    return context.getImageData(0,0,1,1).data;
}
will
  • 316
  • 3
  • 3
4

This is the solution I ended up with. I realized that colors came in two types: css strings and webgl typed arrays (usually 4 floats or ints, depending).

Hell with it, let the browser figure it: create a 1x1 canvas, fill it with any string color, grab the pixel, and destructure into an rgba array. There are two utilities below that create the 1x1 2d canvas ctx, attached.

# Return an RGB array given any legal CSS color, null otherwise.
# http://www.w3schools.com/cssref/css_colors_legal.asp
# The string can be CadetBlue, #0f0, rgb(255,0,0), hsl(120,100%,50%)
# The rgba/hsla forms ok too, but we don't return the a.
# Note: The browser speaks for itself: we simply set a 1x1 canvas fillStyle
# to the string and create a pixel, returning the r,g,b values.
# Warning: r=g=b=0 can indicate an illegal string.  We test
# for a few obvious cases but beware of unexpected [0,0,0] results.
ctx1x1: u.createCtx 1, 1 # share across calls. closure wrapper better?
stringToRGB: (string) ->
  @ctx1x1.fillStyle = string
  @ctx1x1.fillRect 0, 0, 1, 1
  [r, g, b, a] = @ctx1x1.getImageData(0, 0, 1, 1).data
  return [r, g, b] if (r+g+b isnt 0) or
    (string.match(/^black$/i)) or
    (string in ["#000","#000000"]) or
    (string.match(/rgba{0,1}\(0,0,0/i)) or
    (string.match(/hsla{0,1}\(0,0%,0%/i))
  null

What I love about it is that The Browser Speaks For Itself. Any legal string works just fine. Only downside is that if the string is illegal you get black, so need to do a few checks. The error checking is not great, but I don't need it in my usage.

The utility functions:

# Create a new canvas of given width/height
createCanvas: (width, height) ->
  can = document.createElement 'canvas'
  can.width = width; can.height = height
  can
# As above, but returing the context object.
# Note ctx.canvas is the canvas for the ctx, and can be use as an image.
createCtx: (width, height) ->
  can = @createCanvas width, height
  can.getContext "2d"
backspaces
  • 3,802
  • 6
  • 34
  • 58
  • 1
    This is very much not JS, though, so as an answer to a javascript question, this isn't super great. Folks can probably figure out how to reimplement it using real JS, but it'd have been nicer to show the vanilla JS implementation instead. – Mike 'Pomax' Kamermans Jun 28 '21 at 18:27
2

Other approaches on this page use HTML5 Canvas.

But a straightforward alternative would be to derive the rgb() value from any color keyword using:

  • window.getComputedStyle()

Working Example:

const colorKeywordToRGB = (colorKeyword) => {

  // CREATE TEMPORARY ELEMENT
  let el = document.createElement('div');

  // APPLY COLOR TO TEMPORARY ELEMENT
  el.style.color = colorKeyword;

  // APPEND TEMPORARY ELEMENT
  document.body.appendChild(el);

  // RESOLVE COLOR AS RGB() VALUE
  let rgbValue = window.getComputedStyle(el).color;
  
  // REMOVE TEMPORARY ELEMENT
  document.body.removeChild(el);

  return rgbValue;
}

// BASIC COLORS
console.log('red:', colorKeywordToRGB('red'));
console.log('green:', colorKeywordToRGB('green'));
console.log('yellow:', colorKeywordToRGB('yellow'));
console.log('blue:', colorKeywordToRGB('blue'));

// SIMPLE COLORS
console.log('fuchsia:', colorKeywordToRGB('fuchsia'));
console.log('lime:', colorKeywordToRGB('lime'));
console.log('maroon:', colorKeywordToRGB('maroon'));
console.log('navy:', colorKeywordToRGB('navy'));
console.log('olive:', colorKeywordToRGB('olive'));
console.log('purple:', colorKeywordToRGB('purple'));
console.log('teal:', colorKeywordToRGB('teal'));
console.log('transparent:', colorKeywordToRGB('transparent'));

// ADVANCED COLORS
console.log('blanchedalmond:', colorKeywordToRGB('blanchedalmond'));
console.log('coral:', colorKeywordToRGB('coral'));
console.log('darkorchid:', colorKeywordToRGB('darkorchid'));
console.log('firebrick:', colorKeywordToRGB('firebrick'));
console.log('gainsboro:', colorKeywordToRGB('gainsboro'));
console.log('honeydew:', colorKeywordToRGB('honeydew'));
console.log('papayawhip:', colorKeywordToRGB('papayawhip'));
console.log('seashell:', colorKeywordToRGB('seashell'));
console.log('thistle:', colorKeywordToRGB('thistle'));
console.log('wheat:', colorKeywordToRGB('wheat'));

Further Reading:

Rounin
  • 27,134
  • 9
  • 83
  • 108
1

Have a look into Colors.js with the functions "name2hex" and "name2rgb" this libary returns the hex or rgb values of your color name.

retober
  • 366
  • 3
  • 17
  • Colors.name2hex looked promising, but took a look and it simply has a list of named colors with their hex values. Sigh. – backspaces Oct 17 '14 at 16:52
1

You can use a canvas to get the RGBA color from a name.

Please look at this fiddle: https://jsfiddle.net/AaronWatters/p1y298zk/19/

// We want to know the rgba values for this color name:
var testColor = "salmon"

// make a canvas
var canvas = $('<canvas width="100px" height="100px">');

// optional: display the canvas
var body = $(document.body);
canvas.appendTo(body);

// draw a rectangle on the canvas
var context = canvas[0].getContext("2d");
context.beginPath();
context.rect(0,0,100,100);
context.fillStyle = testColor;
context.fill();

// get the canvas image as an array
var imgData = context.getImageData(0, 0, 10, 10);
// rbga values for the element in the middle
var array = imgData.data.slice(50*4, 50*4+4);
// convert the opacity to 0..1
array[3] = array[3] / 255.0;

$("<div>The rgba for " + testColor + " is " + array + "</div>").appendTo(body);

This is how jp_doodle does color interpolation in transitions: https://aaronwatters.github.io/jp_doodle/080_transitions.html

Aaron Watters
  • 2,784
  • 3
  • 23
  • 37
  • note that there is no reason to use a 100x100 canvas, a 1x1 canvas will do the trick just fine, too, and removes the need for slicing. `const [r, g, b, a ] = Array.from(context.getImageData(0, 0, 1, 1).data);` followed by `return { r, g, b, a:a/255 };` But then that was basically the answer that got posted 4 years before this one anyway, just using webgl instead of 2d. – Mike 'Pomax' Kamermans Jun 28 '21 at 18:23
  • I wasn't sure about anti-aliasing at the rectangle edges -- so I used a larger canvas to be safe. – Aaron Watters Sep 30 '21 at 13:09