-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
68 lines (60 loc) · 1.69 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
'use strict'
const colorTable = require('./colors.js')
const lookupCache = {}
// calculate the euclidian difference between the two RGB points,
// this is not the visual distance!
// https://en.wikipedia.org/wiki/Color_difference
function getSquareDistance(color1, color2) {
let rgbDistance = (
Math.pow(color2.r - color1.r, 2) +
Math.pow(color2.g - color1.g, 2) +
Math.pow(color2.b - color1.b, 2)
)
return rgbDistance
}
// convert rgb object to simple string for lookup object
// eg {r:45, g: 0, b: 155} to 'r45g0b155'
function colorToId(color) {
return `r${color.r}g${color.g}b${color.b}`
}
// checks that color is an object containing r, g & b attributes
function isValidColorObject(color) {
if (typeof color !== 'object') {
return false
}
if (
!color.hasOwnProperty('r') ||
!color.hasOwnProperty('g') ||
!color.hasOwnProperty('b')
) {
return false
}
return true
}
module.exports = function (targetColor) {
if (!isValidColorObject(targetColor)) {
return null
}
let targetColorId = colorToId(targetColor)
if (targetColorId in lookupCache) {
return lookupCache[targetColorId]
}
let nearestDistance = null
let nearestName = null
// we're using a naive sorting algorithm,
// simply iterating over every color entry
for (let key in colorTable) {
if (colorTable.hasOwnProperty(key)) {
let currentDistance = getSquareDistance(targetColor, colorTable[key])
// perfect match? we're done
if (currentDistance === 0) {
return key
}
if (nearestDistance === null || currentDistance < nearestDistance) {
nearestDistance = currentDistance
nearestName = key
}
}
}
return nearestName
}