Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules/
package-lock.json
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ $ npm install color-string
### Parsing

```js
colorString.getRgb("#FFF") // [255, 255, 255]
colorString.getRgb("blue") // [0, 0, 255]
colorString.getRgb("blue") // [0, 0, 255]
colorString.getRgb("#FFF") // [255, 255, 255]
colorString.getRgba("#FFFA") //[255, 255, 255, 0.67]}
colorString.getRgba("#FFFFFFAA") // [255, 255, 255, 0.67]}

colorString.getRgba("rgba(200, 60, 60, 0.3)") // [200, 60, 60, 0.3]
colorString.getRgba("rgb(200, 200, 200)") // [200, 200, 200, 1]
Expand All @@ -33,6 +35,8 @@ colorString.getAlpha("rgba(200, 0, 12, 0.6)") // 0.6

```js
colorString.hexString([255, 255, 255]) // "#FFFFFF"
colorString.hexString([0, 0, 255, 0.4]) // "#0000FF66"
colorString.hexString([0, 0, 255], 0.4) // "#0000FF66"
colorString.rgbString([255, 255, 255]) // "rgb(255, 255, 255)"
colorString.rgbString([0, 0, 255, 0.4]) // "rgba(0, 0, 255, 0.4)"
colorString.rgbString([0, 0, 255], 0.4) // "rgba(0, 0, 255, 0.4)"
Expand Down
28 changes: 22 additions & 6 deletions color-string.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,35 @@ function getRgba(string) {
if (!string) {
return;
}
var abbr = /^#([a-fA-F0-9]{3})$/i,
hex = /^#([a-fA-F0-9]{6})$/i,
var abbr = /^#([a-fA-F0-9]{3,4})$/i,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/^#([a-fA-F0-9]{3,4})$/ or /^#([a-f0-9]{3,4})$/i works here, no need to specify the case insensitivity twice.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know, but I think it comes from the original code. Since it doesn't change the result, I would leave it as-is.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The upstream code has var abbr = /^#([a-f0-9]{3,4})$/i;: https://github.com/Qix-/color-string/blob/master/index.js#L50

hex = /^#([a-fA-F0-9]{6}([a-fA-F0-9]{2})?)$/i,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above. I would remove the A-F part to make this shorter and thus more readable:
/^#([a-f0-9]{6})([a-f0-9]{2})?$/i

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upstream is var hex = /^#([a-f0-9]{6})([a-f0-9]{2})?$/i;: https://github.com/Qix-/color-string/blob/master/index.js#L51

rgba = /^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i,
per = /^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i,
keyword = /(\w+)/;

var rgb = [0, 0, 0],
a = 1,
match = string.match(abbr);
match = string.match(abbr),
hexAlpha = "";
if (match) {
match = match[1];
hexAlpha = match[3];
for (var i = 0; i < rgb.length; i++) {
rgb[i] = parseInt(match[i] + match[i], 16);
}
if (hexAlpha) {
a = Math.round((parseInt(hexAlpha + hexAlpha, 16) / 255) * 100) / 100;
}
}
else if (match = string.match(hex)) {
hexAlpha = match[2];
match = match[1];
for (var i = 0; i < rgb.length; i++) {
rgb[i] = parseInt(match.slice(i * 2, i * 2 + 2), 16);
}
if (hexAlpha) {
a = Math.round((parseInt(hexAlpha, 16) / 255) * 100) / 100;
}
}
else if (match = string.match(rgba)) {
for (var i = 0; i < rgb.length; i++) {
Expand Down Expand Up @@ -136,9 +145,16 @@ function getAlpha(string) {
}

// generators
function hexString(rgb) {
return "#" + hexDouble(rgb[0]) + hexDouble(rgb[1])
+ hexDouble(rgb[2]);
function hexString(rgba, a) {
var a = (a !== undefined && rgba.length === 3) ? a : rgba[3];
return "#" + hexDouble(rgba[0])
+ hexDouble(rgba[1])
+ hexDouble(rgba[2])
+ (
(a >= 0 && a < 1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a === 1 will cause a problem here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fine because if a === 1 (opaque), the alpha component is removed from the hex color (#RRGGBB instead of #RRGGBBAA).

Copy link
Author

@loicbourgois loicbourgois Feb 4, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a === 1, then there is no transparency, so I think we don't need to set the alpha component. I imagine returning only a color formatted as #rrggbb would be a bit faster for the following operations.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@etimberg What do you think ?

? hexDouble(Math.round(a * 255))
: ""
);
}

function rgbString(rgba, alpha) {
Expand Down
27 changes: 22 additions & 5 deletions test/basic.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
var string = require("../color-string"),
assert = require("assert");
var string = require("../color-string");
var assert = require("assert");


assert.deepEqual(string.getRgba("#fef"), [255, 238, 255, 1]);
assert.deepEqual(string.getRgba("#fffFEF"), [255, 255, 239,1]);
assert.deepEqual(string.getRgba("#fffFEF"), [255, 255, 239, 1]);
assert.deepEqual(string.getRgba("rgb(244, 233, 100)"), [244, 233, 100, 1]);
assert.deepEqual(string.getRgba("rgb(100%, 30%, 90%)"), [255, 77, 229, 1]);
assert.deepEqual(string.getRgba("transparent"), [0, 0, 0, 0]);
Expand Down Expand Up @@ -33,6 +33,12 @@ assert.equal(string.getAlpha("hwb(244, 100%, 100%, 0.6)"), 0.6);
assert.equal(string.getAlpha("hwb(244, 100%, 100%)"), 1);

// alpha
assert.deepEqual(string.getRgba("#feff"), [255, 238, 255, 1]);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it probably would have been preferable to copy the tests from upstream to keep things in sync as much as possible instead of writing our own

assert.deepEqual(string.getRgba("#fef0"), [255, 238, 255, 0]);
assert.deepEqual(string.getRgba("#fefa"), [255, 238, 255, 0.67]);
assert.deepEqual(string.getRgba("#c814e933"), [200, 20, 233, 0.2]);
assert.deepEqual(string.getRgba("#c814e900"), [200, 20, 233, 0]);
assert.deepEqual(string.getRgba("#c814e9ff"), [200, 20, 233, 1]);
assert.deepEqual(string.getRgba("rgba(200, 20, 233, 0.2)"), [200, 20, 233, 0.2]);
assert.deepEqual(string.getRgba("rgba(200, 20, 233, 0)"), [200, 20, 233, 0]);
assert.deepEqual(string.getRgba("rgba(100%, 30%, 90%, 0.2)"), [255, 77, 229, 0.2]);
Expand All @@ -43,8 +49,8 @@ assert.deepEqual(string.getHwb("hwb(200, 20%, 33%, 0.2)"), [200, 20, 33, 0.2]);
assert.deepEqual(string.getRgb("#fef"), [255, 238, 255]);
assert.deepEqual(string.getRgb("rgba(200, 20, 233, 0.2)"), [200, 20, 233]);
assert.deepEqual(string.getHsl("hsl(240, 100%, 50.5%)"), [240, 100, 50.5]);
assert.deepEqual(string.getRgba('rgba(0,0,0,0)'), [0, 0, 0, 0]);
assert.deepEqual(string.getHsla('hsla(0,0%,0%,0)'), [0, 0, 0, 0]);
assert.deepEqual(string.getRgba("rgba(0,0,0,0)"), [0, 0, 0, 0]);
assert.deepEqual(string.getHsla("hsla(0,0%,0%,0)"), [0, 0, 0, 0]);
assert.deepEqual(string.getHwb("hwb(400, 10%, 200%, 0)"), [360, 10, 100, 0]);

// range
Expand All @@ -57,9 +63,20 @@ assert.deepEqual(string.getHwb("hwb(400, 10%, 200%, 10)"), [360, 10, 100, 1]);
assert.strictEqual(string.getRgba("yellowblue"), undefined);
assert.strictEqual(string.getRgba("hsl(100, 10%, 10%)"), undefined);
assert.strictEqual(string.getRgba("hwb(100, 10%, 10%)"), undefined);
assert.strictEqual(string.getRgba("#1"), undefined);
assert.strictEqual(string.getRgba("#f"), undefined);
assert.strictEqual(string.getRgba("#4f"), undefined);
assert.strictEqual(string.getRgba("#45ab4"), undefined);
assert.strictEqual(string.getRgba("#45ab45e"), undefined);

// generators
assert.equal(string.hexString([255, 10, 35]), "#FF0A23");
assert.equal(string.hexString([255, 10, 35, 1]), "#FF0A23");
assert.equal(string.hexString([255, 10, 35], 1), "#FF0A23");
assert.equal(string.hexString([255, 10, 35, 0.3]), "#FF0A234D");
assert.equal(string.hexString([255, 10, 35], 0.3), "#FF0A234D");
assert.equal(string.hexString([255, 10, 35, 0]), "#FF0A2300");
assert.equal(string.hexString([255, 10, 35], 0), "#FF0A2300");

assert.equal(string.rgbString([255, 10, 35]), "rgb(255, 10, 35)");
assert.equal(string.rgbString([255, 10, 35, 0.3]), "rgba(255, 10, 35, 0.3)");
Expand Down