From 42d1c236056c1c2c2362022e36ca52b7ec900a06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Pe=C3=B1a?= Date: Mon, 4 Feb 2019 22:26:54 +0100 Subject: [PATCH] feat: Added hex to HSL color conversion function (#231) --- src/hex2hsl.js | 56 ++++++++++++++++++++++++++++++++++++++++++++ src/index.js | 2 ++ test/hex2hsl.test.js | 37 +++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 src/hex2hsl.js create mode 100644 test/hex2hsl.test.js diff --git a/src/hex2hsl.js b/src/hex2hsl.js new file mode 100644 index 00000000..314eda7c --- /dev/null +++ b/src/hex2hsl.js @@ -0,0 +1,56 @@ +/* eslint-disable no-unused-vars */ +export default hex2hsl + +/** + * Original Source: https://stackoverflow.com/questions/46432335/hex-to-hsl-convert-javascript + * + * This method will convert colors in Hex to HSL format. + * + * @param {String} hex - The Hex value to be converted + * @return {String} - The HSL value of the color + */ + + +// eslint-disable-next-line complexity +function hex2hsl(hex) { + const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex) + + let r = parseInt(result[1], 16) + let g = parseInt(result[2], 16) + let b = parseInt(result[3], 16) + + r /= 255 + g /= 255 + b /= 255 + + const max = Math.max(r, g, b) + const min = Math.min(r, g, b) + + let h = (max + min) / 2 + let s = (max + min) / 2 + let l = (max + min) / 2 + + if (max === min) { + h = s = 0 // achromatic + } else { + const d = max - min + s = l > 0.5 ? d / (2 - max - min) : d / (max + min) + // eslint-disable-next-line default-case + switch (max) { + case r: h = (g - b) / d + (g < b ? 6 : 0) + break + case g: h = (b - r) / d + 2 + break + case b: h = (r - g) / d + 4 + break + } + h /= 6 + } + + s = s * 100 + s = Math.round(s) + l = l * 100 + l = Math.round(l) + h = Math.round(360 * h) + return `hsl(${h}, ${s}%, ${l}%)` +} diff --git a/src/index.js b/src/index.js index 7cc5c6c8..ceada9f9 100644 --- a/src/index.js +++ b/src/index.js @@ -27,6 +27,7 @@ import getOrdinalSuffix from './get-ordinal-suffix' import getQueryStringParam from './get-query-string-param' import getQueryStringValue from './get-query-string-value' import getMiddle from './getMiddle' +import hex2hsl from './hex2hsl' import hex2rgb from './hex2rgb' import inchesToMetric from './inches-to-metric' import initArray from './init-array' @@ -178,4 +179,5 @@ export { inchesToMetric, numberToString, largest, + hex2hsl, } diff --git a/test/hex2hsl.test.js b/test/hex2hsl.test.js new file mode 100644 index 00000000..c18959ee --- /dev/null +++ b/test/hex2hsl.test.js @@ -0,0 +1,37 @@ +import test from 'ava' +import {hex2hsl} from '../src' + +test('test red color', t => { + const hex = '#ff0000' + const expected = 'hsl(0, 100%, 50%)' + const actual = hex2hsl(hex) + t.deepEqual(actual, expected) +}) + +test('test green color', t => { + const hex = '#00ff00' + const expected = 'hsl(120, 100%, 50%)' + const actual = hex2hsl(hex) + t.deepEqual(actual, expected) +}) + +test('test blue color', t => { + const hex = '#0000ff' + const expected = 'hsl(240, 100%, 50%)' + const actual = hex2hsl(hex) + t.deepEqual(actual, expected) +}) + +test('test fabada color', t => { + const hex = '#fabada' + const expected = 'hsl(330, 86%, 85%)' + const actual = hex2hsl(hex) + t.deepEqual(actual, expected) +}) + +test('test black color', t => { + const hex = '#000000' + const expected = 'hsl(0, 0%, 0%)' + const actual = hex2hsl(hex) + t.deepEqual(actual, expected) +})