var lerp = require('lerp');
Color utility class
var Color = require('pex-color').Color;
var red = new Color(1.0, 0.0, 0.0, 1.0);
var green = Color.fromHSL(0.2, 1.0, 0.0, 0.5);
Dependencies imports
var lerp = require('lerp');
RGBA color constructorr
- red component { Number 0..1 } = 0g
- green component { Number 0..1 } = 0b
- blue component { Number 0..1 } = 0a
- alpha component { Number 0..1 } = 1
function Color(r, g, b, a) {
this.r = (r !== undefined) ? r : 0;
this.g = (g !== undefined) ? g : 0;
this.b = (b !== undefined) ? b : 0;
this.a = (a !== undefined) ? a : 1;
}
RGBA color constructor functionr
- red component { Number 0..1 } = 0g
- green component { Number 0..1 } = 0b
- blue component { Number 0..1 } = 0a
- alpha opacity { Number 0..1 } = 1
Color.create = function(r, g, b, a) {
return new Color(r, g, b, a);
};
Color.fromRGB = Color.create;
Creates new color from array of 4 values [r, g, b, a]a
- array of rgba values { Array of Numbers 0..1 } = [0, 0, 0, 1]
Color.fromArray = function(a) {
return new Color(a[0], a[1], a[2], a[3]);
};
Creates new color from array of 4 byte values [r, g, b, a]a
- array of rgba values { Array of Numbers/Int 0..255 } = [0, 0, 0, 255]
Color.fromByteArray = function(a) {
return new Color(a[0]/255, a[1]/255, a[2]/255, (a.length == 4) ? a[3]/255 : 255);
};
Creates new color from hue, saturation and valueh
- hue { Number 0..1 } = 0s
- saturation { Number 0..1 } = 0v
- value { Number 0..1 } = 0a
- alpha opacity { Number 0..1 } = 1
Color.fromHSV = function(h, s, v, a) {
var c = new Color();
c.setHSV(h, s, v, a);
return c;
};
Creates new color from hue, saturation and lightnessh
- hue { Number 0..1 } = 0s
- saturation { Number 0..1 } = 0l
- lightness { Number 0..1 } = 0a
- alpha opacity { Number 0..1 } = 1
Color.fromHSL = function(h, s, l, a) {
var c = new Color();
c.setHSL(h, s, l, a);
return c;
};
Creates new color from html hex value e.g. #FF0000hex
- html hex color string (with or without #) { String }
Color.fromHex = function(hex) {
var c = new Color();
c.setHex(hex);
return c;
};
Creates new color from XYZ representation
x - { Number 0..1 }
y - { Number 0..1 }
z - { Number 0..1 }
Color.fromXYZ = function(x, y, z) {
var c = new Color();
c.setXYZ(x, y, z);
return c;
};
Creates new color from Lab representation
l - { Number 0..100 }
a - { Number -128..127 }
b - { Number -128..127 }
Color.fromLab = function(l, a, b) {
var c = new Color();
c.setLab(l, a, b);
return c;
};
r
- red component { Number 0..1 } = 0g
- green component { Number 0..1 } = 0b
- blue component { Number 0..1 } = 0a
- alpha opacity { Number 0..1 } = 1
Color.prototype.set = function(r, g, b, a) {
this.r = r;
this.g = g;
this.b = b;
this.a = (a !== undefined) ? a : 1;
return this;
};
Sets rgb color values from a hue, saturation, value and alphah
- hue { Number 0..1 } = 0s
- saturation { Number 0..1 } = 0v
- value { Number 0..1 } = 0a
- alpha opacity { Number 0..1 } = 1
Color.prototype.setHSV = function(h, s, v, a) {
a = a || 1;
var i = Math.floor(h * 6);
var f = h * 6 - i;
var p = v * (1 - s);
var q = v * (1 - f * s);
var t = v * (1 - (1 - f) * s);
switch (i % 6) {
case 0: this.r = v; this.g = t; this.b = p; break;
case 1: this.r = q; this.g = v; this.b = p; break;
case 2: this.r = p; this.g = v; this.b = t; break;
case 3: this.r = p; this.g = q; this.b = v; break;
case 4: this.r = t; this.g = p; this.b = v; break;
case 5: this.r = v; this.g = p; this.b = q; break;
}
this.a = a;
return this;
};
Returns hue, saturation, value and alpha of color as
{ Object h:0.1, s:0..1, v:0..1, a:0..1 }
Color.prototype.getHSV = function() {
var r = this.r;
var g = this.g;
var b = this.b;
var max = Math.max(r, g, b);
var min = Math.min(r, g, b);
var h;
var v = max;
var d = max - min;
var s = max === 0 ? 0 : d / max;
if (max === min) {
h = 0; // achromatic
}
else {
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;
}
return { h: h, s: s, v: v, a: this.a };
};
Sets rgb color values from a hue, saturation, lightness and alphah
- hue { Number 0..1 } = 0s
- saturation { Number 0..1 } = 0l
- lightness { Number 0..1 } = 0a
- alpha opacity { Number 0..1 } = 1
Based on https://gist.github.com/mjijackson/5311256
Color.prototype.setHSL = function(h, s, l, a) {
a = a || 1;
function hue2rgb(p, q, t) {
if (t < 0) { t += 1; }
if (t > 1) { t -= 1; }
if (t < 1/6) { return p + (q - p) * 6 * t; }
if (t < 1/2) { return q; }
if (t < 2/3) { return p + (q - p) * (2/3 - t) * 6; }
return p;
}
if (s === 0) {
this.r = this.g = this.b = l; // achromatic
}
else {
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
this.r = hue2rgb(p, q, h + 1/3);
this.g = hue2rgb(p, q, h);
this.b = hue2rgb(p, q, h - 1/3);
this.a = a;
}
return this;
};
Returns hue, saturation, lightness and alpha of color as
{ Object h:0.1, s:0..1, l:0..1, a:0..1 }
Based on https://gist.github.com/mjijackson/5311256
Color.prototype.getHSL = function() {
var r = this.r;
var g = this.g;
var b = this.b;
var max = Math.max(r, g, b);
var min = Math.min(r, g, b);
var l = (max + min) / 2;
var h;
var s;
if (max === min) {
h = s = 0; // achromatic
}
else {
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
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;
}
return { h: h, s: s, l: l, a: this.a };
};
Sets rgb color values from a html hex value e.g. #FF0000hex
- html hex color string (with or without #) { String }
Color.prototype.setHex = function(hex) {
hex = hex.replace(/^#/, "");
var num = parseInt(hex, 16);
var color = [ num >> 16, num >> 8 & 255, num & 255 ].map(function(val) {
return val / 255;
});
this.r = color[0];
this.g = color[1];
this.b = color[2];
return this;
};
Color.prototype.getHex = function() {
var color = [ this.r, this.g, this.b ].map(function(val) {
return Math.floor(val * 255);
});
return "#" + ((color[2] | color[1] << 8 | color[0] << 16) | 1 << 24)
.toString(16)
.slice(1)
.toUpperCase();
};
Sets rgb color values from XYZ
x - { Number 0..1 }
y - { Number 0..1 }
z - { Number 0..1 }
Color.prototype.setXYZ = function(x, y, z) {
var rgb = {
r: x * 3.2406 + y * -1.5372 + z * -0.4986,
g: x * -0.9689 + y * 1.8758 + z * 0.0415,
b: x * 0.0557 + y * -0.2040 + z * 1.0570
};
[ "r", "g", "b" ].forEach(function(key) {
rgb[key] /= 100;
if (rgb[key] < 0) {
rgb[key] = 0;
}
if (rgb[key] > 0.0031308) {
rgb[key] = 1.055 * Math.pow(rgb[key], (1 / 2.4)) - 0.055;
}
else {
rgb[key] *= 12.92;
}
});
this.r = rgb.r;
this.g = rgb.g;
this.b = rgb.b;
this.a = 1.0;
return this;
};
Color.prototype.getXYZ = function() {
var rgb = this.clone();
[ "r", "g", "b" ].forEach(function(key) {
if (rgb[key] > 0.04045) {
rgb[key] = Math.pow(((rgb[key] + 0.055) / 1.055), 2.4);
} else {
rgb[key] /= 12.92;
}
rgb[key] = rgb[key] * 100;
});
return {
x: rgb.r * 0.4124 + rgb.g * 0.3576 + rgb.b * 0.1805,
y: rgb.r * 0.2126 + rgb.g * 0.7152 + rgb.b * 0.0722,
z: rgb.r * 0.0193 + rgb.g * 0.1192 + rgb.b * 0.9505
};
};
Sets rgb color values from Lab
l - { Number 0..100 }
a - { Number -128..127 }
b - { Number -128..127 }
Color.prototype.setLab = function(l, a, b) {
var y = (l + 16) / 116;
var x = a / 500 + y;
var z = y - b / 200;
var xyz = { x: x, y: y, z: z };
var pow;
[ "x", "y", "z" ].forEach(function(key) {
pow = Math.pow(xyz[key], 3);
if (pow > 0.008856) {
xyz[key] = pow;
}
else {
xyz[key] = (xyz[key] - 16 / 116) / 7.787;
}
});
var color = Color.fromXYZ(xyz.x, xyz.y, xyz.z);
this.r = color.r;
this.g = color.g;
this.b = color.b;
this.a = color.a;
return this;
};
Returns Lab representation of this color as
{ Object l: 0..100, a: -128..127, b: -128..127 }
Color.prototype.getLab = function() {
var white = { x: 95.047, y: 100.000, z: 108.883 };
var xyz = this.getXYZ();
[ "x", "y", "z" ].forEach(function(key) {
xyz[key] /= white[key];
if (xyz[key] > 0.008856) {
xyz[key] = Math.pow(xyz[key], 1 / 3);
}
else {
xyz[key] = (7.787 * xyz[key]) + (16 / 116);
}
});
return {
l: 116 * xyz.y - 16,
a: 500 * (xyz.x - xyz.y),
b: 200 * (xyz.y - xyz.z)
};
};
Copies rgba values from another color into this instancec
- another color to copy values from { Color }
Color.prototype.copy = function(c) {
this.r = c.r;
this.g = c.g;
this.b = c.b;
this.a = c.a;
return this;
};
Color.prototype.clone = function() {
return new Color(this.r, this.g, this.b, this.a);
};
Color.prototype.hash = function() {
return 1 * this.r + 12 * this.g + 123 * this.b + 1234 * this.a;
};
Returns distance (CIE76) between this and given color using Lab representation { Number }
Based on http://en.wikipedia.org/wiki/Color_difference
Color.prototype.distance = function(color) {
var lab1 = this.getLab();
var lab2 = color.getLab();
var dl = lab2.l - lab1.l;
var da = lab2.a - lab1.a;
var db = lab2.b - lab1.b;
return Math.sqrt(dl * dl, da * da, db * db);
};
Creates new color from linearly interpolated two colorsstartColor
- { Color }endColor
- { Color } t
- interpolation ratio { Number 0..1 }mode
- interpolation mode : ‘rgb’, ‘hsv’, ‘hsl’ { String } = ‘rgb’
Color.lerp = function(startColor, endColor, t, mode) {
mode = mode || 'rgb';
if (mode === 'rgb') {
return Color.fromRGB(
lerp(startColor.r, endColor.r, t),
lerp(startColor.g, endColor.g, t),
lerp(startColor.b, endColor.b, t),
lerp(startColor.a, endColor.a, t)
);
}
else if (mode === 'hsv') {
var startHSV = startColor.getHSV();
var endHSV = endColor.getHSV();
return Color.fromHSV(
lerp(startHSV.h, endHSV.h, t),
lerp(startHSV.s, endHSV.s, t),
lerp(startHSV.v, endHSV.v, t),
lerp(startHSV.a, endHSV.a, t)
);
}
else if (mode === 'hsl') {
var startHSL = startColor.getHSL();
var endHSL = endColor.getHSL();
return Color.fromHSL(
lerp(startHSL.h, endHSL.h, t),
lerp(startHSL.s, endHSL.s, t),
lerp(startHSL.l, endHSL.l, t),
lerp(startHSL.a, endHSL.a, t)
);
}
else {
return startColor;
}
};
Color.Transparent = new Color(0, 0, 0, 0);
Color.None = new Color(0, 0, 0, 0);
Color.Black = new Color(0, 0, 0, 1);
Color.White = new Color(1, 1, 1, 1);
Color.DarkGrey = new Color(0.25, 0.25, 0.25, 1);
Color.Grey = new Color(0.5, 0.5, 0.5, 1);
Color.LightGrey = new Color(0.75, 0.75, 0.75, 1);
Color.Red = new Color(1, 0, 0, 1);
Color.Green = new Color(0, 1, 0, 1);
Color.Blue = new Color(0, 0, 1, 1);
Color.Yellow = new Color(1, 1, 0, 1);
Color.Pink = new Color(1, 0, 1, 1);
Color.Cyan = new Color(0, 1, 1, 1);
Color.Orange = new Color(1, 0.5, 0, 1);
module.exports = Color;