ESPTerm web interface submodule, separated to make testing and development easier
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
espterm-front-end/js/lib/color_utils.js

129 lines
3.5 KiB

/*
* Copyright (c) 2010 Tim Baumann
*
* 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:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// NOTE:
// Extracted from ColorTriangle and
// Converted to ES6 by MightyPork (2017)
/*******************
* Color conversion *
*******************/
const M = Math
const PI = M.PI
exports.hue_to_rgb = function (v1, v2, h) {
if (h < 0) h += 1
if (h > 1) h -= 1
if ((6 * h) < 1) return v1 + (v2 - v1) * 6 * h
if ((2 * h) < 1) return v2
if ((3 * h) < 2) return v1 + (v2 - v1) * ((2 / 3) - h) * 6
return v1
}
exports.hsl_to_rgb = function (h, s, l) {
h /= 2 * PI
let r, g, b
if (s === 0) {
r = g = b = l
} else {
let var_1, var_2
if (l < 0.5) var_2 = l * (1 + s)
else var_2 = (l + s) - (s * l)
var_1 = 2 * l - var_2
r = exports.hue_to_rgb(var_1, var_2, h + (1 / 3))
g = exports.hue_to_rgb(var_1, var_2, h)
b = exports.hue_to_rgb(var_1, var_2, h - (1 / 3))
}
return [r, g, b]
}
exports.rgb_to_hsl = function (r, g, b) {
const min = M.min(r, g, b)
const max = M.max(r, g, b)
const d = max - min // delta
let h, s, l
l = (max + min) / 2
if (d === 0) {
// gray
h = s = 0 // HSL results from 0 to 1
} else {
// chroma
if (l < 0.5) s = d / (max + min)
else s = d / (2 - max - min)
const d_r = (((max - r) / 6) + (d / 2)) / d
const d_g = (((max - g) / 6) + (d / 2)) / d
const d_b = (((max - b) / 6) + (d / 2)) / d // deltas
if (r === max) h = d_b - d_g
else if (g === max) h = (1 / 3) + d_r - d_b
else if (b === max) h = (2 / 3) + d_g - d_r
if (h < 0) h += 1
else if (h > 1) h -= 1
}
h *= 2 * PI
return [h, s, l]
}
exports.hex_to_rgb = function (hex) {
const groups = hex.match(/^#([A-Fa-f0-9]+)$/)
if (groups && groups[1].length % 3 === 0) {
hex = groups[1]
const bytes = hex.length / 3
const max = Math.pow(16, bytes) - 1
const r = parseInt(hex.slice(0 * bytes, 1 * bytes), 16) / max
const g = parseInt(hex.slice(1 * bytes, 2 * bytes), 16) / max
const b = parseInt(hex.slice(2 * bytes, 3 * bytes), 16) / max
return [r, g, b]
}
return [0, 0, 0]
}
function pad (n) {
if (n.length === 1) n = '0' + n
return n
}
exports.rgb255_to_hex = function (r, g, b) {
r = r.toString(16)
g = g.toString(16)
b = b.toString(16)
return `#${pad(r)}${pad(g)}${pad(b)}`
}
exports.rgb_to_hex = function (r, g, b) {
r = Math.round(r * 255).toString(16)
g = Math.round(g * 255).toString(16)
b = Math.round(b * 255).toString(16)
return `#${pad(r)}${pad(g)}${pad(b)}`
}