|
@@ -5,6 +5,9 @@ const selectors = {
|
|
|
get clusterControl() {
|
|
|
return document.forms.clusterControl.elements;
|
|
|
},
|
|
|
+ get colorSpace() {
|
|
|
+ return selectors.colorSpace.value;
|
|
|
+ },
|
|
|
};
|
|
|
|
|
|
const onMetricChange = (elements) => {
|
|
@@ -17,7 +20,7 @@ const onMetricChange = (elements) => {
|
|
|
elements.statistic.disabled = kind !== "statistic";
|
|
|
elements.sortMetric.value = elements[kind].value;
|
|
|
|
|
|
- sortImages();
|
|
|
+ updateSort();
|
|
|
showResults(selectors.sortControl.resultsToDisplay.value);
|
|
|
};
|
|
|
|
|
@@ -38,16 +41,78 @@ const onColorChange = (inputValue) => {
|
|
|
selectors.sortControl.colorText.value = refomatted;
|
|
|
selectors.sortControl.colorPicker.value = refomatted;
|
|
|
|
|
|
- scoreImages();
|
|
|
- sortImages();
|
|
|
+ // TODO last color saver
|
|
|
+ // TODO bg + text color change
|
|
|
+
|
|
|
+ updateScores(rgb);
|
|
|
+ updateSort();
|
|
|
showResults(selectors.sortControl.resultsToDisplay.value);
|
|
|
};
|
|
|
|
|
|
-const scoreImages = () => {
|
|
|
- // TODO
|
|
|
+const calcScores = (data, target) => {
|
|
|
+ const sigma = Math.sqrt(
|
|
|
+ data.inertia - 2 * vectorDot(data.mu.vector, target.vector) + target.sqMag
|
|
|
+ );
|
|
|
+ const theta = rad2deg * Math.acos(vectorDot(data.mu.unit, target.unit));
|
|
|
+ const rawPhi = Math.abs(data.mu.hue - target.hue);
|
|
|
+ return {
|
|
|
+ sigma,
|
|
|
+ bigTheta: 1 - vectorDot(data.nu, target.unit),
|
|
|
+ alpha: sigma * Math.pow(bigTheta, target.chroma + target.lightness),
|
|
|
+
|
|
|
+ theta,
|
|
|
+ phi: Math.min(rawPhi, 360 - rawPhi),
|
|
|
+ delta: vectorMag(data.mu.vector.map((x, i) => x - target.vector[i])),
|
|
|
+ manhattan: data.mu.vector
|
|
|
+ .map((x, i) => Math.abs(x - target.vector[i]))
|
|
|
+ .reduce((x, y) => x + y),
|
|
|
+ ch: Math.max(...data.mu.vector.map((x, i) => Math.abs(x - target.vector[i]))),
|
|
|
+ lightnessDiff: Math.abs(data.mu.lightness - target.lightness),
|
|
|
+
|
|
|
+ inertia: data.inertia,
|
|
|
+ variance: data.inertia - data.mu.sqMag,
|
|
|
+ muNuAngle: data.muNuAngle,
|
|
|
+ size: data.size,
|
|
|
+ lightness: data.mu.lightness,
|
|
|
+ chroma: data.mu.chroma,
|
|
|
+ importance: data.importance,
|
|
|
+ };
|
|
|
+};
|
|
|
+
|
|
|
+const currentScores = {};
|
|
|
+const currentBestClusterIndices = {};
|
|
|
+let sortedData = pokemonData;
|
|
|
+
|
|
|
+const updateScores = (rgb) => {
|
|
|
+ const { J, a, b } = d3.jab(rgb);
|
|
|
+ const targetJab = buildVectorData([J, a, b], jab2hue, jab2lit, jab2chroma, jab2hex);
|
|
|
+ const targetRgb = buildVectorData(
|
|
|
+ [rgb.r, rgb.g, rgb.b],
|
|
|
+ rgb2hue,
|
|
|
+ rgb2lit,
|
|
|
+ rgb2chroma,
|
|
|
+ rgb2hex
|
|
|
+ );
|
|
|
+ pokemonData.forEach(({ name, jab, rgb }) => {
|
|
|
+ currentScores[name] = {
|
|
|
+ jab: {
|
|
|
+ total: calcScores(jab.total, targetJab),
|
|
|
+ clusters: jab.clusters.map((c) => calcScores(c, targetJab)),
|
|
|
+ },
|
|
|
+ rgb: {
|
|
|
+ total: calcScores(rgb.total, targetRgb),
|
|
|
+ clusters: rgb.clusters.map((c) => calcScores(c, targetRgb)),
|
|
|
+ },
|
|
|
+ };
|
|
|
+ currentBestClusterIndices[name] = {
|
|
|
+ // TODO
|
|
|
+ jab: 0,
|
|
|
+ rgb: 0,
|
|
|
+ };
|
|
|
+ });
|
|
|
};
|
|
|
|
|
|
-const sortImages = () => {
|
|
|
+const updateSort = () => {
|
|
|
// TODO
|
|
|
};
|
|
|
|