Skip to content

Commit

Permalink
Feature/4 digit hexes (#6)
Browse files Browse the repository at this point in the history
* Update devDependencies

* Add eslint

* Lint

* Support 4-digit hexes and refactor

* BREAKING CHANGE: Always return rgba() values

Before this change, hex-to-rgba would sometimes
return rgb() values if the the color was
completely opaque.

After this change, hex-to-rgba will always return
an rgba() value - if the color is opaque, the a
value will simply be set to 1.

* Update documentation

* Update changelog

* Remove lockfile

* Add node 8 and 9 to test environments

* Stop breaking node 5 support

* 1.0.0
  • Loading branch information
misund committed Nov 1, 2017
1 parent 0267360 commit 6987950
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 107 deletions.
3 changes: 3 additions & 0 deletions .eslintrc.json
@@ -0,0 +1,3 @@
{
"extends": "airbnb"
}
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -38,3 +38,6 @@ jspm_packages

# Build
build/

# Lockfile
package-lock.json
7 changes: 3 additions & 4 deletions .travis.yml
@@ -1,8 +1,7 @@
language: node_js
node_js:
- "9"
- "8"
- "7"
- "7.4"
- "7.3"
- "6"
- "6.1"
- "5.11"
- "5"
53 changes: 39 additions & 14 deletions README.md
@@ -1,39 +1,64 @@
[![Build Status](https://travis-ci.org/misund/hex-to-rgba.svg?branch=master)](https://travis-ci.org/misund/hex-to-rgba)

`hex-to-rgba` turns an old-fashioned css hex color value string into an rgb() string.
`hex-to-rgba` turns an old-fashioned css hex color value string into an rgba() string.

If you specify an alpha value, you'll get a rgba() string instead.
Optionally pass in an alpha value. The passed alpha value will override any alpha value from 4- or 8-digit hexes. If you don't pass in an alpha value at all, we will default to an alpha value of 1 (completely opaque).

## Install
Supports 3-, 4-, 6- and 8-digit hex values with or without a leading hash.

## Installation
```sh
$ npm install --save hex-to-rgba
```

## Usage
```js
var hexToRgba = require("hex-to-rgba");

hexToRgba('112233'); // "rgb(17, 34, 51)"
hexToRgba('#112233'); // "rgb(17, 34, 51)"
hexToRgba('112233'); // "rgba(17, 34, 51, 1)"
hexToRgba('#112233'); // "rgba(17, 34, 51, 1)"
hexToRgba('112233', '0.5'); // "rgba(17, 34, 51, 0.5)"
hexToRgba('#112233', 0.75); // "rgba(17, 34, 51, 0.75)"

hexToRgba('123'); // "rgb(17, 34, 51)"
hexToRgba('#123'); // "rgb(17, 34, 51)"
hexToRgba('123', 0.2) // "rgba(17, 34, 51, 0.2)"
hexToRgba('#123', 0.2) // "rgba(17, 34, 51, 0.2)"

hexToRgba('11223344') // "rgba(17, 34, 51, 0.27)"
hexToRgba('#11223344') // "rgba(17, 34, 51, 0.27)"
hexToRgba('11223344', '0.5') // "rgba(17, 34, 51, 0.5)"
hexToRgba('#11223344', 0.75) // "rgba(17, 34, 51, 0.75)"

hexToRgba('123'); // "rgba(17, 34, 51, 1)"
hexToRgba('#123'); // "rgba(17, 34, 51, 1)"
hexToRgba('123', 0.2) // "rgba(17, 34, 51, 0.2)"
hexToRgba('#123', 0.2) // "rgba(17, 34, 51, 0.2)"

hexToRgba('1234'); // "rgba(17, 34, 51, 0.27)"
hexToRgba('#1234'); // "rgba(17, 34, 51, 0.27)"
hexToRgba('1234', 0.5) // "rgba(17, 34, 51, 0.5)"
hexToRgba('#1234', 0.75) // "rgba(17, 34, 51, 0.75)"
```

Testing
```
npm run build && npm test
```

## Signature
`hexToRgba(hex, a)`
`hexToRgba(hex, a=1)`

## Parameters
* `hex`: The hex value to convert. (examples: `'123456'`, `'#123456'`, `'123'`, `'#123'`)
* `a`: An alpha value to apply. (optional) (examples: `'0.5'`, `0.25`)
* `hex`: The hex color value to convert to rgba. (examples: `'123456'`, `'#123456'`, `'123'`, `'#123'`)
* `a`: An alpha value to apply. (optional, default: 1) (examples: `'0.5'`, `0.25`)

## Returns
An rgb or rgba value. (examples: `'rgb(11, 22, 33)'`, `'rgba(11, 22, 33, 0.5)'`)
An rgba() string. (examples: `'rgba(11, 22, 33, 1)'`, `'rgba(11, 22, 33, 0.5)'`)

## Changelog
**1.0.0**
- BREAKING CHANGE: Always return rgba(); even if the color is completely opaque
- Support 4-digit hexes
- Add typescript type declaration (props @gillchristian)
**0.2.0**
- Support 8-digit hexes
**0.1.0**
- Initial release
- Support 6-digit hexes
- Support 3-digit hexes
15 changes: 10 additions & 5 deletions package.json
@@ -1,6 +1,6 @@
{
"name": "hex-to-rgba",
"version": "0.2.0",
"version": "1.0.0",
"description": "Converts hexadecimal color codes to rgb()/rgba() values.",
"main": "build/index.js",
"scripts": {
Expand All @@ -25,9 +25,14 @@
},
"homepage": "https://github.com/misund/hex-to-rgba#readme",
"devDependencies": {
"babel-cli": "^6.22.2",
"babel-preset-es2015": "^6.22.0",
"babel-register": "^6.22.0",
"mocha": "^3.2.0"
"babel-cli": "^6.26.0",
"babel-preset-es2015": "^6.24.1",
"babel-register": "^6.26.0",
"eslint": "4.8.0",
"eslint-config-airbnb": "15.1.0",
"eslint-plugin-import": "2.7.0",
"eslint-plugin-jsx-a11y": "5.1.1",
"eslint-plugin-react": "7.4.0",
"mocha": "^3.5.3"
}
}
71 changes: 46 additions & 25 deletions src/index.js
@@ -1,3 +1,44 @@
const removeHash = hex => (hex.startsWith('#') ? hex.slice(1) : hex);

const parseHex = (nakedHex) => {
const isShort = (
3 === nakedHex.length
|| 4 === nakedHex.length
);

const twoDigitHexR = isShort ? `${nakedHex.slice(0, 1)}${nakedHex.slice(0, 1)}` : nakedHex.slice(0, 2);
const twoDigitHexG = isShort ? `${nakedHex.slice(1, 2)}${nakedHex.slice(1, 2)}` : nakedHex.slice(2, 4);
const twoDigitHexB = isShort ? `${nakedHex.slice(2, 3)}${nakedHex.slice(2, 3)}` : nakedHex.slice(4, 6);
const twoDigitHexA = ((isShort ? `${nakedHex.slice(3, 4)}${nakedHex.slice(3, 4)}` : nakedHex.slice(6, 8)) || 'ff');

// const numericA = +((parseInt(a, 16) / 255).toFixed(2));

return {
r: twoDigitHexR,
g: twoDigitHexG,
b: twoDigitHexB,
a: twoDigitHexA,
};
};

const hexToDecimal = hex => parseInt(hex, 16);

const hexesToDecimals = ({ r, g, b, a }) => ({
r: hexToDecimal(r),
g: hexToDecimal(g),
b: hexToDecimal(b),
a: +((hexToDecimal(a) / 255).toFixed(2)),
});

const isNumeric = n => !isNaN(parseFloat(n)) && isFinite(n);

const formatRgb = (decimalObject, parameterA) => {
const { r, g, b, a: parsedA } = decimalObject;
const a = isNumeric(parameterA) ? parameterA : parsedA;

return `rgba(${r}, ${g}, ${b}, ${a})`;
};

/**
* Turns an old-fashioned css hex color value into a rgb color value.
*
Expand All @@ -7,32 +48,12 @@
* @param An alpha value to apply. (optional) ('0.5', '0.25')
* @return An rgb or rgba value. ('rgb(11, 22, 33)'. 'rgba(11, 22, 33, 0.5)')
*/
const hexToRgba = function(hex, a) {
const fixHex = (hex) => {
let newHex = hex.startsWith('#') ? hex.slice(1) : hex;

if (newHex.length === 3) {
newHex = `${newHex.slice(0, 1)}${newHex.slice(0, 1)}${newHex.slice(1, 2)}${newHex.slice(1, 2)}${newHex.slice(2, 3)}${newHex.slice(2, 3)}`;
}


return newHex;
};
const hexToRgba = (hex, a) => {
const hashlessHex = removeHash(hex);
const hexObject = parseHex(hashlessHex);
const decimalObject = hexesToDecimals(hexObject);

const newHex = fixHex(hex);
const r = parseInt(newHex.substring(0, 2), 16);
const g = parseInt(newHex.substring(2, 4), 16);
const b = parseInt(newHex.substring(4, 6), 16);

let o;
if (newHex.length === 8) {
o = +((parseInt(newHex.substring(6, 8), 16)/255).toFixed(2));
}
o = isNumeric(a) ? a : o;

return isNumeric(o) ? `rgba(${r}, ${g}, ${b}, ${o})` : `rgb(${r}, ${g}, ${b})`;
return formatRgb(decimalObject, a);
};

const isNumeric = n => !isNaN(parseFloat(n)) && isFinite(n);

module.exports = hexToRgba;

0 comments on commit 6987950

Please sign in to comment.