Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

husl

Package Overview
Dependencies
Maintainers
1
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

husl - npm Package Compare versions

Comparing version 4.0.2 to 5.0.0

164

husl.js
// Generated by CoffeeScript 1.7.1
(function() {
var L_to_Y, Y_to_L, conv, dotProduct, epsilon, fromLinear, kappa, m, m_inv, maxChroma, maxChromaD, refU, refV, refX, refY, refZ, rgbPrepare, root, round, toLinear, _hradExtremum, _maxChroma;
var L_to_Y, Y_to_L, conv, distanceFromPole, dotProduct, epsilon, fromLinear, getBounds, intersectLineLine, kappa, lengthOfRayUntilIntersect, m, m_inv, maxChromaForLH, maxSafeChromaForL, refU, refV, refX, refY, refZ, rgbPrepare, root, round, toLinear;
refX = 0.95047;
m = {
R: [3.240969941904521, -1.537383177570093, -0.498610760293],
G: [-0.96924363628087, 1.87596750150772, 0.041555057407175],
B: [0.055630079696993, -0.20397695888897, 1.056971514242878]
};
refY = 1.00000;
m_inv = {
X: [0.41239079926595, 0.35758433938387, 0.18048078840183],
Y: [0.21263900587151, 0.71516867876775, 0.072192315360733],
Z: [0.019330818715591, 0.11919477979462, 0.95053215224966]
};
refZ = 1.08883;
refX = 0.95045592705167;
refU = (4 * refX) / (refX + (15 * refY) + (3 * refZ));
refY = 1.0;
refV = (9 * refY) / (refX + (15 * refY) + (3 * refZ));
refZ = 1.089057750759878;
m = {
R: [3.240454162114103, -1.537138512797715, -0.49853140955601],
G: [-0.96926603050518, 1.876010845446694, 0.041556017530349],
B: [0.055643430959114, -0.20402591351675, 1.057225188223179]
};
refU = 0.19783000664283;
m_inv = {
X: [0.41245643908969, 0.3575760776439, 0.18043748326639],
Y: [0.21267285140562, 0.71515215528781, 0.072174993306559],
Z: [0.019333895582329, 0.1191920258813, 0.95030407853636]
};
refV = 0.46831999493879;
kappa = 24389 / 27;
kappa = 903.2962962;
epsilon = 216 / 24389;
epsilon = 0.0088564516;
_maxChroma = function(L, H) {
var cosH, hrad, sinH, sub1, sub2;
hrad = H / 360 * 2 * Math.PI;
sinH = Math.sin(hrad);
cosH = Math.cos(hrad);
getBounds = function(L) {
var bottom, channel, m1, m2, m3, ret, sub1, sub2, t, top1, top2, _i, _j, _len, _len1, _ref, _ref1, _ref2;
sub1 = Math.pow(L + 16, 3) / 1560896;
sub2 = sub1 > epsilon ? sub1 : L / kappa;
return function(channel) {
var bottom, lbottom, m1, m2, m3, rbottom, top, _ref;
_ref = m[channel], m1 = _ref[0], m2 = _ref[1], m3 = _ref[2];
top = (12739311 * m3 + 11700000 * m2 + 11120499 * m1) * sub2;
rbottom = 9608480 * m3 - 1921696 * m2;
lbottom = 1441272 * m3 - 4323816 * m1;
bottom = (rbottom * sinH + lbottom * cosH) * sub2;
return function(limit) {
return L * (top - 11700000 * limit) / (bottom + 1921696 * sinH * limit);
};
};
ret = [];
_ref = ['R', 'G', 'B'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
channel = _ref[_i];
_ref1 = m[channel], m1 = _ref1[0], m2 = _ref1[1], m3 = _ref1[2];
_ref2 = [0, 1];
for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
t = _ref2[_j];
top1 = (284517 * m1 - 94839 * m3) * sub2;
top2 = (838422 * m3 + 769860 * m2 + 731718 * m1) * L * sub2 - 769860 * t * L;
bottom = (632260 * m3 - 126452 * m2) * sub2 + 126452 * t;
ret.push([top1 / bottom, top2 / bottom]);
}
}
return ret;
};
_hradExtremum = function(L) {
var lhs, rhs, sub;
lhs = (Math.pow(L, 3) + 48 * Math.pow(L, 2) + 768 * L + 4096) / 1560896;
rhs = epsilon;
sub = lhs > rhs ? lhs : L / kappa;
return function(channel, limit) {
var bottom, hrad, m1, m2, m3, top, _ref;
_ref = m[channel], m1 = _ref[0], m2 = _ref[1], m3 = _ref[2];
top = (20 * m3 - 4 * m2) * sub + 4 * limit;
bottom = (3 * m3 - 9 * m1) * sub;
hrad = Math.atan2(top, bottom);
if (limit === 1) {
hrad += Math.PI;
}
return hrad;
};
intersectLineLine = function(line1, line2) {
return (line1[1] - line2[1]) / (line2[0] - line1[0]);
};
maxChroma = function(L, H) {
var C, channel, limit, mc1, mc2, result, _i, _j, _len, _len1, _ref, _ref1;
result = Infinity;
mc1 = _maxChroma(L, H);
_ref = ['R', 'G', 'B'];
distanceFromPole = function(point) {
return Math.sqrt(Math.pow(point[0], 2) + Math.pow(point[1], 2));
};
lengthOfRayUntilIntersect = function(theta, line) {
var b1, len, m1;
m1 = line[0], b1 = line[1];
len = b1 / (Math.sin(theta) - m1 * Math.cos(theta));
if (len < 0) {
return null;
}
return len;
};
maxSafeChromaForL = function(L) {
var b1, lengths, m1, x, _i, _len, _ref, _ref1;
lengths = [];
_ref = getBounds(L);
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
channel = _ref[_i];
mc2 = mc1(channel);
_ref1 = [0, 1];
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
limit = _ref1[_j];
C = mc2(limit);
if ((0 < C && C < result)) {
result = C;
}
}
_ref1 = _ref[_i], m1 = _ref1[0], b1 = _ref1[1];
x = intersectLineLine([m1, b1], [-1 / m1, 0]);
lengths.push(distanceFromPole([x, b1 + x * m1]));
}
return result;
return Math.min.apply(Math, lengths);
};
maxChromaD = function(L) {
var C, channel, he1, hrad, limit, minima_C, _i, _j, _len, _len1, _ref, _ref1;
minima_C = [];
he1 = _hradExtremum(L);
_ref = ['R', 'G', 'B'];
maxChromaForLH = function(L, H) {
var hrad, l, lengths, line, _i, _len, _ref;
hrad = H / 360 * Math.PI * 2;
lengths = [];
_ref = getBounds(L);
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
channel = _ref[_i];
_ref1 = [0, 1];
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
limit = _ref1[_j];
hrad = he1(channel, limit);
C = maxChroma(L, hrad * 180 / Math.PI);
minima_C.push(C);
line = _ref[_i];
l = lengthOfRayUntilIntersect(hrad, line);
if (l !== null) {
lengths.push(l);
}
}
return Math.min.apply(Math, minima_C);
return Math.min.apply(Math, lengths);
};

@@ -273,3 +263,3 @@

}
max = maxChroma(L, H);
max = maxChromaForLH(L, H);
C = max / 100 * S;

@@ -288,3 +278,3 @@ return [L, C, H];

}
max = maxChroma(L, H);
max = maxChromaForLH(L, H);
S = C / max * 100;

@@ -303,3 +293,3 @@ return [H, S, L];

}
max = maxChromaD(L);
max = maxSafeChromaForL(L);
C = max / 100 * S;

@@ -318,3 +308,3 @@ return [L, C, H];

}
max = maxChromaD(L);
max = maxSafeChromaForL(L);
S = C / max * 100;

@@ -416,9 +406,9 @@ return [H, S, L];

root._maxChroma = maxChroma;
root._rgbPrepare = rgbPrepare;
root._maxChromaD = maxChromaD;
root._getBounds = getBounds;
root._hradExtremum = _hradExtremum;
root._maxChromaForLH = maxChromaForLH;
root._rgbPrepare = rgbPrepare;
root._maxSafeChromaForL = maxSafeChromaForL;

@@ -425,0 +415,0 @@ if (!((typeof module !== "undefined" && module !== null) || (typeof jQuery !== "undefined" && jQuery !== null) || (typeof requirejs !== "undefined" && requirejs !== null))) {

@@ -5,3 +5,3 @@ {

"keywords": ["color", "color space", "CIE", "RGB", "HUSL", "HSL"],
"version": "4.0.2",
"version": "5.0.0",
"author": "Alexei Boronine <alexei@boronine.com>",

@@ -8,0 +8,0 @@ "main": "husl.js",

@@ -1,11 +0,31 @@

[![Build Status](https://secure.travis-ci.org/boronine/husl.png)](http://travis-ci.org/boronine/husl)
[![Build Status](https://travis-ci.org/boronine/husl.svg?branch=master)](https://travis-ci.org/boronine/husl)
# What is <abbr class="initialism">HUSL</abbr>?
[Explanation, demo, ports etc.](http://www.boronine.com/husl/)
HUSL is a [human-friendly](http://www.boronine.com/2012/03/26/Color-Spaces-for-Human-Beings/) alternative to the HSL color space. HSL was designed back in the 70s to be computationally cheap. It is a clever geometric transformation of the RGB color space and it does not take into account the complexities of human color vision.
# Usage
There have long existed color spaces designed for perceptual uniformity. One of these color spaces is [CIELUV](http://en.wikipedia.org/wiki/CIELUV) (and its cylindrically shaped brother CIE LCh<sub>uv</sub>. Like HSL, it defines hue and lightness, but instead of saturation it defines chroma. The problem with its chroma component is that it doesn't fit into a specific range. This makes it very hard to define colors programmatically. **HUSL is a modified version of the CIE LCh<sub>uv</sub> color space with a new saturation component**.
Client-side: include [husl.js](https://raw.githubusercontent.com/boronine/husl/master/husl.js) or [husl.min.js](https://raw.githubusercontent.com/boronine/husl/master/husl.min.js) in your webpage, access it as a global ``HUSL`` object or as a jQuery plugin with ``$.husl``.
[Demo, documentation etc.](http://www.boronine.com/husl)
Server-side: ``npm install husl``.
**husl.toHex(hue, saturation, lightness)**
*hue* is a number between 0 and 360, *saturation* and *lightness* are numbers between 0 and 100. This function returns the resulting color as a hex string.
**husl.toRGB(hue, saturation, lightness)**
Like above, but returns an array of 3 numbers between 0 and 1, for each RGB channel.
**husl.fromHex(hex)**
Takes a hex string and returns the HUSL color as defined above.
**husl.fromRGB(red, green, blue)**
Like above, but *red*, *green* and *blue* are passed as numbers between 0 and 1.
Use **husl.p.toHex**, **husl.p.toRGB**, **husl.p.fromHex** and **husl.p.fromRGB** for the pastel variant (HUSLp).
HUSL can also be used as a [Stylus](http://learnboost.github.com/stylus/) plugin. See [here](https://github.com/boronine/husl-stylus).
# Versioning

@@ -15,5 +35,5 @@

# Testing and Building Documentation
# Testing
Run `npm install` and `npm test`. Try `cake snapshot` to generate a JSON file of the entire gamut to be used for debugging and regression tests. The format of the file is as follows:
Run `npm install` and `npm test`. Try `coffee test/snapshot.coffee` to generate a JSON file of the entire gamut to be used for debugging and regression tests. The format of the file is as follows:

@@ -32,19 +52,5 @@ {

The command to build documentation is `cake build:docs`.
Building documentation requires some libraries to be installed. If you are running [Docker](https://www.docker.io/), a wise way to do it would be to run `cake docker:build` followed by `cake docker:run`. You will find yourself inside a Docker container with everything set up to run `cake build:docs`, the output will be written to the host file system.
If you are not using Docker, you can install the dependencies manually, they are listed in the Dockerfile.
# Ports
With the help of Robert McGinley, HUSL was also [ported to Python](https://github.com/boronine/pyhusl) (version 2 only).
A work-in-progress of C and Java ports is included in the repo, done by Lajos Ambrus. The Java port has some tests, added by [@Pimm](https://github.com/Pimm), but they are currently made to work with the Android SDK. It would be nice if someone made them more generic.
A [Ruby port](https://github.com/soulcutter/husler) has been started by [@soulcutter](https://github.com/soulcutter). I would love to see this done so that HUSL could be integrated into [SASS](http://sass-lang.com/).
# License
Copyright (C) 2012 Alexei Boronine
Copyright (C) 2014 Alexei Boronine

@@ -51,0 +57,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc