UNPKG

@nathanfaucett/color

Version:

color for the browser and node.js

227 lines (171 loc) 5.76 kB
var mathf = require("@nathanfaucett/mathf"), vec3 = require("@nathanfaucett/vec3"), vec4 = require("@nathanfaucett/vec4"), isNumber = require("@nathanfaucett/is_number"), isString = require("@nathanfaucett/is_string"), colorNames = require("./colorNames"); var color = exports; color.ArrayType = typeof(Float32Array) !== "undefined" ? Float32Array : mathf.ArrayType; color.create = function(r, g, b, a) { var out = new color.ArrayType(4); out[0] = isNumber(r) ? r : 0; out[1] = isNumber(g) ? g : 0; out[2] = isNumber(b) ? b : 0; out[3] = isNumber(a) ? a : 1; return out; }; color.copy = vec4.copy; color.clone = function(a) { var out = new color.ArrayType(4); out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; return out; }; color.setRGB = vec3.set; color.setRGBA = vec4.set; color.add = vec4.add; color.sub = vec4.sub; color.mul = vec4.mul; color.div = vec4.div; color.sadd = vec4.sadd; color.ssub = vec4.ssub; color.smul = vec4.smul; color.sdiv = vec4.sdiv; color.lengthSqValues = vec4.lengthSqValues; color.lengthValues = vec4.lengthValues; color.invLengthValues = vec4.invLengthValues; color.dot = vec4.dot; color.lengthSq = vec4.lengthSq; color.length = vec4.length; color.invLength = vec4.invLength; color.setLength = vec4.setLength; color.normalize = vec4.normalize; color.lerp = vec4.lerp; color.min = vec4.min; color.max = vec4.max; color.clamp = vec4.clamp; color.equals = vec4.equals; color.notEquals = vec4.notEquals; var cmin = color.create(0, 0, 0, 0), cmax = color.create(1, 1, 1, 1); color.cnormalize = function(out, a) { return color.clamp(out, a, cmin, cmax); }; color.str = function(out) { return "Color(" + out[0] + ", " + out[1] + ", " + out[2] + ", " + out[3] + ")"; }; color.string = color.toString = color.str; color.set = function(out, r, g, b, a) { if (isNumber(r)) { out[0] = isNumber(r) ? r : 0; out[1] = isNumber(g) ? g : 0; out[2] = isNumber(b) ? b : 0; out[3] = isNumber(a) ? a : 1; } else if (isString(r)) { color.fromStyle(out, r); } else if (r && r.length === +r.length) { out[0] = r[0] || 0; out[1] = r[1] || 0; out[2] = r[2] || 0; out[3] = r[3] || 1; } return out; }; function to256(value) { return (value * 255) | 0; } color.toRGB = function(out, alpha) { if (isNumber(alpha)) { return "rgba(" + to256(out[0]) + "," + to256(out[1]) + "," + to256(out[2]) + "," + (mathf.clamp01(alpha) || 0) + ")"; } else { return "rgb(" + to256(out[0]) + "," + to256(out[1]) + "," + to256(out[2]) + ")"; } }; color.toRGBA = function(out) { return "rgba(" + to256(out[0]) + "," + to256(out[1]) + "," + to256(out[2]) + "," + (mathf.clamp01(out[3]) || 0) + ")"; }; function toHEX(value) { value = mathf.clamp(value * 255, 0, 255) | 0; if (value < 16) { return "0" + value.toString(16); } else if (value < 255) { return value.toString(16); } else { return "ff"; } } color.toHEX = function(out) { return "#" + toHEX(out[0]) + toHEX(out[1]) + toHEX(out[2]); }; var rgb255 = /^rgb\((\d+),(?:\s+)?(\d+),(?:\s+)?(\d+)\)$/i, inv255 = 1 / 255; color.fromRGB = function(out, style) { var values = rgb255.exec(style); out[0] = mathf.min(255, Number(values[1])) * inv255; out[1] = mathf.min(255, Number(values[2])) * inv255; out[2] = mathf.min(255, Number(values[3])) * inv255; out[3] = 1; return out; }; var rgba255 = /^rgba\((\d+),(?:\s+)?(\d+),(?:\s+)?(\d+),(?:\s+)?((?:\.)?\d+(?:\.\d+)?)\)$/i; color.fromRGBA = function(out, style) { var values = rgba255.exec(style); out[0] = mathf.min(255, Number(values[1])) * inv255; out[1] = mathf.min(255, Number(values[2])) * inv255; out[2] = mathf.min(255, Number(values[3])) * inv255; out[3] = mathf.min(1, Number(values[4])); return out; }; var rgb100 = /^rgb\((\d+)\%,(?:\s+)?(\d+)\%,(?:\s+)?(\d+)\%\)$/i, inv100 = 1 / 100; color.fromRGB100 = function(out, style) { var values = rgb100.exec(style); out[0] = mathf.min(100, Number(values[1])) * inv100; out[1] = mathf.min(100, Number(values[2])) * inv100; out[2] = mathf.min(100, Number(values[3])) * inv100; out[3] = 1; return out; }; color.fromHEX = function(out, style) { out[0] = parseInt(style.substr(1, 2), 16) * inv255; out[1] = parseInt(style.substr(3, 2), 16) * inv255; out[2] = parseInt(style.substr(5, 2), 16) * inv255; out[3] = 1; return out; }; var hex3to6 = /#(.)(.)(.)/, hex3to6String = "#$1$1$2$2$3$3"; color.fromHEX3 = function(out, style) { style = style.replace(hex3to6, hex3to6String); out[0] = parseInt(style.substr(1, 2), 16) * inv255; out[1] = parseInt(style.substr(3, 2), 16) * inv255; out[2] = parseInt(style.substr(5, 2), 16) * inv255; out[3] = 1; return out; }; color.fromColorName = function(out, style) { return color.fromHEX(out, colorNames[style.toLowerCase()]); }; var hex6 = /^\#([0.0-9a-f]{6})$/i, hex3 = /^\#([0.0-9a-f])([0.0-9a-f])([0.0-9a-f])$/i, colorName = /^(\w+)$/i; color.fromStyle = function(out, style) { if (rgb255.test(style)) { return color.fromRGB(out, style); } else if (rgba255.test(style)) { return color.fromRGBA(out, style); } else if (rgb100.test(style)) { return color.fromRGB100(out, style); } else if (hex6.test(style)) { return color.fromHEX(out, style); } else if (hex3.test(style)) { return color.fromHEX3(out, style); } else if (colorName.test(style)) { return color.fromColorName(out, style); } else { return out; } }; color.colorNames = colorNames;