mirror of
https://github.com/pebble-dev/clay.git
synced 2026-09-05 08:37:43 -04:00
When setting the value for the color picker, round it to the closest available value in the layout
This commit is contained in:
@@ -10,6 +10,8 @@ module.exports = {
|
|||||||
description: ''
|
description: ''
|
||||||
},
|
},
|
||||||
initialize: function(minified, clay) {
|
initialize: function(minified, clay) {
|
||||||
|
var HTML = minified.HTML;
|
||||||
|
var self = this;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string|boolean|number} color
|
* @param {string|boolean|number} color
|
||||||
@@ -22,13 +24,23 @@ module.exports = {
|
|||||||
return 'transparent';
|
return 'transparent';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
color = padColorString(color);
|
||||||
|
|
||||||
|
return '#' + (useSunlight ? sunlightColorMap[color] : color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} color
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
function padColorString(color) {
|
||||||
color = color.toLowerCase();
|
color = color.toLowerCase();
|
||||||
|
|
||||||
while (color.length < 6) {
|
while (color.length < 6) {
|
||||||
color = '0' + color;
|
color = '0' + color;
|
||||||
}
|
}
|
||||||
|
|
||||||
return '#' + (useSunlight ? sunlightColorMap[color] : color);
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,12 +49,66 @@ module.exports = {
|
|||||||
*/
|
*/
|
||||||
function normalizeColor(value) {
|
function normalizeColor(value) {
|
||||||
switch (typeof value) {
|
switch (typeof value) {
|
||||||
case 'number': return value.toString(16);
|
case 'number': return padColorString(value.toString(16));
|
||||||
case 'string': return value.replace(/^#|^0x/, '');
|
case 'string': return value.replace(/^#|^0x/, '');
|
||||||
default: return value;
|
default: return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Array.<Array>} layout
|
||||||
|
* @returns {Array}
|
||||||
|
*/
|
||||||
|
function flattenLayout(layout) {
|
||||||
|
return layout.reduce(function(a, b) {
|
||||||
|
return a.concat(b);
|
||||||
|
}, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert HEX color to LAB.
|
||||||
|
* Adapted from: https://github.com/antimatter15/rgb-lab
|
||||||
|
* @param {string} hex
|
||||||
|
* @returns {Array} - [l, a, b]
|
||||||
|
*/
|
||||||
|
function hex2lab(hex) {
|
||||||
|
hex = hex.replace(/^#|^0x/, '');
|
||||||
|
|
||||||
|
var r = parseInt(hex.slice(0, 2), 16) / 255;
|
||||||
|
var g = parseInt(hex.slice(2, 4), 16) / 255;
|
||||||
|
var b = parseInt(hex.slice(4), 16) / 255;
|
||||||
|
|
||||||
|
r = (r > 0.04045) ? Math.pow((r + 0.055) / 1.055, 2.4) : r / 12.92;
|
||||||
|
g = (g > 0.04045) ? Math.pow((g + 0.055) / 1.055, 2.4) : g / 12.92;
|
||||||
|
b = (b > 0.04045) ? Math.pow((b + 0.055) / 1.055, 2.4) : b / 12.92;
|
||||||
|
|
||||||
|
var x = (r * 0.4124 + g * 0.3576 + b * 0.1805) / 0.95047;
|
||||||
|
var y = (r * 0.2126 + g * 0.7152 + b * 0.0722) / 1.00000;
|
||||||
|
var z = (r * 0.0193 + g * 0.1192 + b * 0.9505) / 1.08883;
|
||||||
|
|
||||||
|
x = (x > 0.008856) ? Math.pow(x, 1 / 3) : (7.787 * x) + 16 / 116;
|
||||||
|
y = (y > 0.008856) ? Math.pow(y, 1 / 3) : (7.787 * y) + 16 / 116;
|
||||||
|
z = (z > 0.008856) ? Math.pow(z, 1 / 3) : (7.787 * z) + 16 / 116;
|
||||||
|
|
||||||
|
return [(116 * y) - 16, 500 * (x - y), 200 * (y - z)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the perceptual color distance between two LAB colors
|
||||||
|
* @param {Array} labA
|
||||||
|
* @param {Array} labB
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
function deltaE(labA, labB) {
|
||||||
|
var deltaL = labA[0] - labB[0];
|
||||||
|
var deltaA = labA[1] - labB[1];
|
||||||
|
var deltaB = labA[2] - labB[2];
|
||||||
|
|
||||||
|
return Math.sqrt(Math.pow(deltaL, 2) +
|
||||||
|
Math.pow(deltaA, 2) +
|
||||||
|
Math.pow(deltaB, 2));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the layout based on the connected watch
|
* Returns the layout based on the connected watch
|
||||||
* @returns {Array}
|
* @returns {Array}
|
||||||
@@ -62,8 +128,32 @@ module.exports = {
|
|||||||
return standardLayouts.COLOR;
|
return standardLayouts.COLOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
var HTML = minified.HTML;
|
/**
|
||||||
var self = this;
|
* @param {number|string} color
|
||||||
|
* @return {number}
|
||||||
|
*/
|
||||||
|
self.roundColorToLayout = function(color) {
|
||||||
|
var itemValue = normalizeColor(color);
|
||||||
|
|
||||||
|
// if the color is not in the layout we will need find the closest match
|
||||||
|
if (colorList.indexOf(itemValue) === -1) {
|
||||||
|
var itemValueLAB = hex2lab(itemValue);
|
||||||
|
var differenceArr = colorList.map(function(color) {
|
||||||
|
var colorLAB = hex2lab(normalizeColor(color));
|
||||||
|
return deltaE(itemValueLAB, colorLAB);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get the lowest number from the differenceArray
|
||||||
|
var lowest = Math.min.apply(Math, differenceArr);
|
||||||
|
|
||||||
|
// Get the index for that lowest number
|
||||||
|
var index = differenceArr.indexOf(lowest);
|
||||||
|
itemValue = colorList[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
return parseInt(itemValue, 16);
|
||||||
|
};
|
||||||
|
|
||||||
var useSunlight = self.config.sunlight !== false;
|
var useSunlight = self.config.sunlight !== false;
|
||||||
var sunlightColorMap = {
|
var sunlightColorMap = {
|
||||||
'000000': '000000', '000055': '001e41', '0000aa': '004387', '0000ff': '0068ca',
|
'000000': '000000', '000055': '001e41', '0000aa': '004387', '0000ff': '0068ca',
|
||||||
@@ -118,6 +208,12 @@ module.exports = {
|
|||||||
layout = [layout];
|
layout = [layout];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var colorList = flattenLayout(layout).map(function(item) {
|
||||||
|
return normalizeColor(item);
|
||||||
|
}).filter(function(item) {
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
|
||||||
var grid = '';
|
var grid = '';
|
||||||
var rows = layout.length;
|
var rows = layout.length;
|
||||||
var cols = 0;
|
var cols = 0;
|
||||||
|
|||||||
@@ -145,16 +145,12 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
color: {
|
color: {
|
||||||
get: function() {
|
get: function() {
|
||||||
return parseInt(this.$manipulatorTarget.get('value'), 16);
|
return parseInt(this.$manipulatorTarget.get('value'), 10) || 0;
|
||||||
},
|
},
|
||||||
set: function(value) {
|
set: function(value) {
|
||||||
switch (typeof value) {
|
value = this.roundColorToLayout(value || 0);
|
||||||
case 'number': value = value.toString(16); break;
|
|
||||||
case 'string': value = value.replace(/^#|^0x/, ''); break;
|
|
||||||
}
|
|
||||||
value = value || '000000';
|
|
||||||
|
|
||||||
if (this.get() === parseInt(value, 16)) { return this; }
|
if (this.get() === value) { return this; }
|
||||||
this.$manipulatorTarget.set('value', value);
|
this.$manipulatorTarget.set('value', value);
|
||||||
return this.trigger('change');
|
return this.trigger('change');
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -134,6 +134,39 @@ function testAutoLayout(platform, layout, allowGray, desc, activeWatchInfo) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number|string} input
|
||||||
|
* @param {number} expected
|
||||||
|
* @param {array|string} layout
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
function testClosestToLayout(input, expected, layout) {
|
||||||
|
it('rounds ' + input + ' to ' + expected.toString(16) +
|
||||||
|
' in layout: ' + JSON.stringify(layout),
|
||||||
|
function() {
|
||||||
|
var clayConfig;
|
||||||
|
var colorItem;
|
||||||
|
|
||||||
|
clayConfig = fixture.clayConfig([{
|
||||||
|
type: 'color',
|
||||||
|
sunlight: false,
|
||||||
|
layout: layout
|
||||||
|
}]);
|
||||||
|
colorItem = clayConfig.getItemsByType('color')[0];
|
||||||
|
colorItem.set(input);
|
||||||
|
assert.strictEqual(colorItem.get(), expected);
|
||||||
|
|
||||||
|
clayConfig = fixture.clayConfig([{
|
||||||
|
type: 'color',
|
||||||
|
sunlight: false,
|
||||||
|
layout: layout
|
||||||
|
}]);
|
||||||
|
colorItem = clayConfig.getItemsByType('color')[0];
|
||||||
|
colorItem.set(input);
|
||||||
|
assert.strictEqual(colorItem.get(), expected);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {boolean} sunlight
|
* @param {boolean} sunlight
|
||||||
* @param {Array|string} [layout=color]
|
* @param {Array|string} [layout=color]
|
||||||
@@ -291,6 +324,41 @@ describe('component - color', function() {
|
|||||||
assert.strictEqual($picker.get('classList').contains('show'), false);
|
assert.strictEqual($picker.get('classList').contains('show'), false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('color rounding', function() {
|
||||||
|
var layout = 'GRAY';
|
||||||
|
testClosestToLayout('000000', 0x000000, layout);
|
||||||
|
testClosestToLayout('005500', 0x000000, layout);
|
||||||
|
testClosestToLayout('55aa55', 0xaaaaaa, layout);
|
||||||
|
testClosestToLayout('ffaaff', 0xaaaaaa, layout);
|
||||||
|
testClosestToLayout('ffffaa', 0xffffff, layout);
|
||||||
|
testClosestToLayout('ffffff', 0xffffff, layout);
|
||||||
|
|
||||||
|
layout = 'BLACK_WHITE';
|
||||||
|
testClosestToLayout('000000', 0x000000, layout);
|
||||||
|
testClosestToLayout('005500', 0x000000, layout);
|
||||||
|
testClosestToLayout('55aa55', 0xffffff, layout);
|
||||||
|
testClosestToLayout('ffaaff', 0xffffff, layout);
|
||||||
|
testClosestToLayout('ffffaa', 0xffffff, layout);
|
||||||
|
testClosestToLayout('ffffff', 0xffffff, layout);
|
||||||
|
|
||||||
|
layout = 'COLOR';
|
||||||
|
testClosestToLayout('000000', 0x000000, layout);
|
||||||
|
testClosestToLayout('005500', 0x005500, layout);
|
||||||
|
testClosestToLayout('55bb55', 0x55aa55, layout);
|
||||||
|
testClosestToLayout('ff99ff', 0xffaaff, layout);
|
||||||
|
testClosestToLayout('ffffee', 0xffffff, layout);
|
||||||
|
testClosestToLayout('ffffff', 0xffffff, layout);
|
||||||
|
|
||||||
|
layout = ['ff0000', 'ff5500', 'ff00ff', '00ff00', '555555'];
|
||||||
|
testClosestToLayout('000000', 0x555555, layout);
|
||||||
|
testClosestToLayout('ff0000', 0xff0000, layout);
|
||||||
|
testClosestToLayout('ff1111', 0xff0000, layout);
|
||||||
|
testClosestToLayout('00aa00', 0x00ff00, layout);
|
||||||
|
testClosestToLayout('ff55ff', 0xff00ff, layout);
|
||||||
|
testClosestToLayout('aaaaaa', 0x555555, layout);
|
||||||
|
testClosestToLayout('ffffff', 0x555555, layout);
|
||||||
|
});
|
||||||
|
|
||||||
describe('layouts', function() {
|
describe('layouts', function() {
|
||||||
|
|
||||||
// allow gray does nothing for 2.x
|
// allow gray does nothing for 2.x
|
||||||
|
|||||||
Reference in New Issue
Block a user