1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

simplify vibrant

This commit is contained in:
Luke Pulverenti 2016-10-20 15:34:32 -04:00
parent dc66936c08
commit 353dd8d067

View file

@ -504,380 +504,377 @@ module.exports = MMCQ.quantize
Google - Palette support library in Android
*/
(function() {
var CanvasImage, Swatch, Vibrant,
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
slice = [].slice;
var CanvasImage, Swatch, Vibrant,
bind = function (fn, me) { return function () { return fn.apply(me, arguments); }; },
slice = [].slice;
window.Swatch = Swatch = (function() {
Swatch.prototype.hsl = void 0;
window.Swatch = Swatch = (function () {
Swatch.prototype.hsl = void 0;
Swatch.prototype.rgb = void 0;
Swatch.prototype.rgb = void 0;
Swatch.prototype.population = 1;
Swatch.prototype.population = 1;
Swatch.yiq = 0;
Swatch.yiq = 0;
function Swatch(rgb, population) {
this.rgb = rgb;
this.population = population;
}
function Swatch(rgb, population) {
this.rgb = rgb;
this.population = population;
}
Swatch.prototype.getHsl = function() {
if (!this.hsl) {
return this.hsl = Vibrant.rgbToHsl(this.rgb[0], this.rgb[1], this.rgb[2]);
} else {
return this.hsl;
}
};
Swatch.prototype.getPopulation = function() {
return this.population;
};
Swatch.prototype.getRgb = function() {
return this.rgb;
};
Swatch.prototype.getHex = function() {
return "#" + ((1 << 24) + (this.rgb[0] << 16) + (this.rgb[1] << 8) + this.rgb[2]).toString(16).slice(1, 7);
};
Swatch.prototype.getTitleTextColor = function() {
this._ensureTextColors();
if (this.yiq < 200) {
return "#fff";
} else {
return "#000";
}
};
Swatch.prototype.getBodyTextColor = function() {
this._ensureTextColors();
if (this.yiq < 150) {
return "#fff";
} else {
return "#000";
}
};
Swatch.prototype._ensureTextColors = function() {
if (!this.yiq) {
return this.yiq = (this.rgb[0] * 299 + this.rgb[1] * 587 + this.rgb[2] * 114) / 1000;
}
};
return Swatch;
})();
window.Vibrant = Vibrant = (function() {
Vibrant.prototype.quantize = require('quantize');
Vibrant.prototype._swatches = [];
Vibrant.prototype.TARGET_DARK_LUMA = 0.26;
Vibrant.prototype.MAX_DARK_LUMA = 0.45;
Vibrant.prototype.MIN_LIGHT_LUMA = 0.55;
Vibrant.prototype.TARGET_LIGHT_LUMA = 0.74;
Vibrant.prototype.MIN_NORMAL_LUMA = 0.3;
Vibrant.prototype.TARGET_NORMAL_LUMA = 0.5;
Vibrant.prototype.MAX_NORMAL_LUMA = 0.7;
Vibrant.prototype.TARGET_MUTED_SATURATION = 0.3;
Vibrant.prototype.MAX_MUTED_SATURATION = 0.4;
Vibrant.prototype.TARGET_VIBRANT_SATURATION = 1;
Vibrant.prototype.MIN_VIBRANT_SATURATION = 0.35;
Vibrant.prototype.WEIGHT_SATURATION = 3;
Vibrant.prototype.WEIGHT_LUMA = 6;
Vibrant.prototype.WEIGHT_POPULATION = 1;
Vibrant.prototype.VibrantSwatch = void 0;
Vibrant.prototype.MutedSwatch = void 0;
Vibrant.prototype.DarkVibrantSwatch = void 0;
Vibrant.prototype.DarkMutedSwatch = void 0;
Vibrant.prototype.LightVibrantSwatch = void 0;
Vibrant.prototype.LightMutedSwatch = void 0;
Vibrant.prototype.HighestPopulation = 0;
function Vibrant(sourceImage, colorCount, quality) {
this.swatches = bind(this.swatches, this);
var a, allPixels, b, cmap, g, i, image, imageData, offset, pixelCount, pixels, r;
if (typeof colorCount === 'undefined') {
colorCount = 16;
}
if (typeof quality === 'undefined') {
quality = 5;
}
image = new CanvasImage(sourceImage);
try {
imageData = image.getImageData();
pixels = imageData.data;
pixelCount = image.getPixelCount();
allPixels = [];
i = 0;
while (i < pixelCount) {
offset = i * 4;
r = pixels[offset + 0];
g = pixels[offset + 1];
b = pixels[offset + 2];
a = pixels[offset + 3];
if (a >= 125) {
if (!(r > 250 && g > 250 && b > 250)) {
allPixels.push([r, g, b]);
Swatch.prototype.getHsl = function () {
if (!this.hsl) {
return this.hsl = Vibrant.rgbToHsl(this.rgb[0], this.rgb[1], this.rgb[2]);
} else {
return this.hsl;
}
};
Swatch.prototype.getPopulation = function () {
return this.population;
};
Swatch.prototype.getRgb = function () {
return this.rgb;
};
Swatch.prototype.getHex = function () {
return "#" + ((1 << 24) + (this.rgb[0] << 16) + (this.rgb[1] << 8) + this.rgb[2]).toString(16).slice(1, 7);
};
Swatch.prototype.getTitleTextColor = function () {
this._ensureTextColors();
if (this.yiq < 200) {
return "#fff";
} else {
return "#000";
}
};
Swatch.prototype.getBodyTextColor = function () {
this._ensureTextColors();
if (this.yiq < 150) {
return "#fff";
} else {
return "#000";
}
};
Swatch.prototype._ensureTextColors = function () {
if (!this.yiq) {
return this.yiq = (this.rgb[0] * 299 + this.rgb[1] * 587 + this.rgb[2] * 114) / 1000;
}
};
return Swatch;
})();
window.Vibrant = Vibrant = (function () {
Vibrant.prototype.quantize = require('quantize');
Vibrant.prototype._swatches = [];
Vibrant.prototype.TARGET_DARK_LUMA = 0.26;
Vibrant.prototype.MAX_DARK_LUMA = 0.45;
Vibrant.prototype.MIN_LIGHT_LUMA = 0.55;
Vibrant.prototype.TARGET_LIGHT_LUMA = 0.74;
Vibrant.prototype.MIN_NORMAL_LUMA = 0.3;
Vibrant.prototype.TARGET_NORMAL_LUMA = 0.5;
Vibrant.prototype.MAX_NORMAL_LUMA = 0.7;
Vibrant.prototype.TARGET_MUTED_SATURATION = 0.3;
Vibrant.prototype.MAX_MUTED_SATURATION = 0.4;
Vibrant.prototype.TARGET_VIBRANT_SATURATION = 1;
Vibrant.prototype.MIN_VIBRANT_SATURATION = 0.35;
Vibrant.prototype.WEIGHT_SATURATION = 3;
Vibrant.prototype.WEIGHT_LUMA = 6;
Vibrant.prototype.WEIGHT_POPULATION = 1;
Vibrant.prototype.VibrantSwatch = void 0;
Vibrant.prototype.MutedSwatch = void 0;
Vibrant.prototype.DarkVibrantSwatch = void 0;
Vibrant.prototype.DarkMutedSwatch = void 0;
Vibrant.prototype.LightVibrantSwatch = void 0;
Vibrant.prototype.LightMutedSwatch = void 0;
Vibrant.prototype.HighestPopulation = 0;
function Vibrant(sourceImage, colorCount, quality) {
this.swatches = bind(this.swatches, this);
var a, allPixels, b, cmap, g, i, image, imageData, offset, pixelCount, pixels, r;
if (typeof colorCount === 'undefined') {
colorCount = 16;
}
if (typeof quality === 'undefined') {
quality = 5;
}
image = new CanvasImage(sourceImage);
try {
imageData = image.getImageData();
pixels = imageData.data;
pixelCount = image.getPixelCount();
allPixels = [];
i = 0;
while (i < pixelCount) {
offset = i * 4;
r = pixels[offset + 0];
g = pixels[offset + 1];
b = pixels[offset + 2];
a = pixels[offset + 3];
if (a >= 125) {
if (!(r > 250 && g > 250 && b > 250)) {
allPixels.push([r, g, b]);
}
}
i = i + quality;
}
cmap = this.quantize(allPixels, colorCount);
this._swatches = cmap.vboxes.map((function (_this) {
return function (vbox) {
return new Swatch(vbox.color, vbox.vbox.count());
};
})(this));
this.maxPopulation = this.findMaxPopulation;
this.generateVarationColors();
this.generateEmptySwatches();
} finally {
image.removeCanvas();
}
}
i = i + quality;
}
cmap = this.quantize(allPixels, colorCount);
this._swatches = cmap.vboxes.map((function(_this) {
return function(vbox) {
return new Swatch(vbox.color, vbox.vbox.count());
};
})(this));
this.maxPopulation = this.findMaxPopulation;
this.generateVarationColors();
this.generateEmptySwatches();
} finally {
image.removeCanvas();
}
}
Vibrant.prototype.generateVarationColors = function() {
this.VibrantSwatch = this.findColorVariation(this.TARGET_NORMAL_LUMA, this.MIN_NORMAL_LUMA, this.MAX_NORMAL_LUMA, this.TARGET_VIBRANT_SATURATION, this.MIN_VIBRANT_SATURATION, 1);
this.LightVibrantSwatch = this.findColorVariation(this.TARGET_LIGHT_LUMA, this.MIN_LIGHT_LUMA, 1, this.TARGET_VIBRANT_SATURATION, this.MIN_VIBRANT_SATURATION, 1);
this.DarkVibrantSwatch = this.findColorVariation(this.TARGET_DARK_LUMA, 0, this.MAX_DARK_LUMA, this.TARGET_VIBRANT_SATURATION, this.MIN_VIBRANT_SATURATION, 1);
this.MutedSwatch = this.findColorVariation(this.TARGET_NORMAL_LUMA, this.MIN_NORMAL_LUMA, this.MAX_NORMAL_LUMA, this.TARGET_MUTED_SATURATION, 0, this.MAX_MUTED_SATURATION);
this.LightMutedSwatch = this.findColorVariation(this.TARGET_LIGHT_LUMA, this.MIN_LIGHT_LUMA, 1, this.TARGET_MUTED_SATURATION, 0, this.MAX_MUTED_SATURATION);
return this.DarkMutedSwatch = this.findColorVariation(this.TARGET_DARK_LUMA, 0, this.MAX_DARK_LUMA, this.TARGET_MUTED_SATURATION, 0, this.MAX_MUTED_SATURATION);
};
Vibrant.prototype.generateVarationColors = function () {
this.VibrantSwatch = this.findColorVariation(this.TARGET_NORMAL_LUMA, this.MIN_NORMAL_LUMA, this.MAX_NORMAL_LUMA, this.TARGET_VIBRANT_SATURATION, this.MIN_VIBRANT_SATURATION, 1);
this.LightVibrantSwatch = this.findColorVariation(this.TARGET_LIGHT_LUMA, this.MIN_LIGHT_LUMA, 1, this.TARGET_VIBRANT_SATURATION, this.MIN_VIBRANT_SATURATION, 1);
this.DarkVibrantSwatch = this.findColorVariation(this.TARGET_DARK_LUMA, 0, this.MAX_DARK_LUMA, this.TARGET_VIBRANT_SATURATION, this.MIN_VIBRANT_SATURATION, 1);
this.MutedSwatch = this.findColorVariation(this.TARGET_NORMAL_LUMA, this.MIN_NORMAL_LUMA, this.MAX_NORMAL_LUMA, this.TARGET_MUTED_SATURATION, 0, this.MAX_MUTED_SATURATION);
this.LightMutedSwatch = this.findColorVariation(this.TARGET_LIGHT_LUMA, this.MIN_LIGHT_LUMA, 1, this.TARGET_MUTED_SATURATION, 0, this.MAX_MUTED_SATURATION);
return this.DarkMutedSwatch = this.findColorVariation(this.TARGET_DARK_LUMA, 0, this.MAX_DARK_LUMA, this.TARGET_MUTED_SATURATION, 0, this.MAX_MUTED_SATURATION);
};
Vibrant.prototype.generateEmptySwatches = function() {
var hsl;
if (this.VibrantSwatch === void 0) {
if (this.DarkVibrantSwatch !== void 0) {
hsl = this.DarkVibrantSwatch.getHsl();
hsl[2] = this.TARGET_NORMAL_LUMA;
this.VibrantSwatch = new Swatch(Vibrant.hslToRgb(hsl[0], hsl[1], hsl[2]), 0);
Vibrant.prototype.generateEmptySwatches = function () {
var hsl;
if (this.VibrantSwatch === void 0) {
if (this.DarkVibrantSwatch !== void 0) {
hsl = this.DarkVibrantSwatch.getHsl();
hsl[2] = this.TARGET_NORMAL_LUMA;
this.VibrantSwatch = new Swatch(Vibrant.hslToRgb(hsl[0], hsl[1], hsl[2]), 0);
}
}
if (this.DarkVibrantSwatch === void 0) {
if (this.VibrantSwatch !== void 0) {
hsl = this.VibrantSwatch.getHsl();
hsl[2] = this.TARGET_DARK_LUMA;
return this.DarkVibrantSwatch = new Swatch(Vibrant.hslToRgb(hsl[0], hsl[1], hsl[2]), 0);
}
}
};
Vibrant.prototype.findMaxPopulation = function () {
var j, len, population, ref, swatch;
population = 0;
ref = this._swatches;
for (j = 0, len = ref.length; j < len; j++) {
swatch = ref[j];
population = Math.max(population, swatch.getPopulation());
}
return population;
};
Vibrant.prototype.findColorVariation = function (targetLuma, minLuma, maxLuma, targetSaturation, minSaturation, maxSaturation) {
var j, len, luma, max, maxValue, ref, sat, swatch, value;
max = void 0;
maxValue = 0;
ref = this._swatches;
for (j = 0, len = ref.length; j < len; j++) {
swatch = ref[j];
sat = swatch.getHsl()[1];
luma = swatch.getHsl()[2];
if (sat >= minSaturation && sat <= maxSaturation && luma >= minLuma && luma <= maxLuma && !this.isAlreadySelected(swatch)) {
value = this.createComparisonValue(sat, targetSaturation, luma, targetLuma, swatch.getPopulation(), this.HighestPopulation);
if (max === void 0 || value > maxValue) {
max = swatch;
maxValue = value;
}
}
}
return max;
};
Vibrant.prototype.createComparisonValue = function (saturation, targetSaturation, luma, targetLuma, population, maxPopulation) {
return this.weightedMean(this.invertDiff(saturation, targetSaturation), this.WEIGHT_SATURATION, this.invertDiff(luma, targetLuma), this.WEIGHT_LUMA, population / maxPopulation, this.WEIGHT_POPULATION);
};
Vibrant.prototype.invertDiff = function (value, targetValue) {
return 1 - Math.abs(value - targetValue);
};
Vibrant.prototype.weightedMean = function () {
var i, sum, sumWeight, value, values, weight;
values = 1 <= arguments.length ? slice.call(arguments, 0) : [];
sum = 0;
sumWeight = 0;
i = 0;
while (i < values.length) {
value = values[i];
weight = values[i + 1];
sum += value * weight;
sumWeight += weight;
i += 2;
}
return sum / sumWeight;
};
Vibrant.prototype.swatches = function () {
return {
Vibrant: this.VibrantSwatch,
Muted: this.MutedSwatch,
DarkVibrant: this.DarkVibrantSwatch,
DarkMuted: this.DarkMutedSwatch,
LightVibrant: this.LightVibrantSwatch,
LightMuted: this.LightMuted
};
};
Vibrant.prototype.isAlreadySelected = function (swatch) {
return this.VibrantSwatch === swatch || this.DarkVibrantSwatch === swatch || this.LightVibrantSwatch === swatch || this.MutedSwatch === swatch || this.DarkMutedSwatch === swatch || this.LightMutedSwatch === swatch;
};
Vibrant.rgbToHsl = function (r, g, b) {
var d, h, l, max, min, s;
r /= 255;
g /= 255;
b /= 255;
max = Math.max(r, g, b);
min = Math.min(r, g, b);
h = void 0;
s = void 0;
l = (max + min) / 2;
if (max === min) {
h = s = 0;
} else {
d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
}
h /= 6;
}
return [h, s, l];
};
Vibrant.hslToRgb = function (h, s, l) {
var b, g, hue2rgb, p, q, r;
r = void 0;
g = void 0;
b = void 0;
hue2rgb = function (p, q, t) {
if (t < 0) {
t += 1;
}
if (t > 1) {
t -= 1;
}
if (t < 1 / 6) {
return p + (q - p) * 6 * t;
}
if (t < 1 / 2) {
return q;
}
if (t < 2 / 3) {
return p + (q - p) * (2 / 3 - t) * 6;
}
return p;
};
if (s === 0) {
r = g = b = l;
} else {
q = l < 0.5 ? l * (1 + s) : l + s - (l * s);
p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - (1 / 3));
}
return [r * 255, g * 255, b * 255];
};
return Vibrant;
})();
/*
CanvasImage Class
Class that wraps the html image element and canvas.
It also simplifies some of the canvas context manipulation
with a set of helper functions.
Stolen from https://github.com/lokesh/color-thief
*/
window.CanvasImage = CanvasImage = (function () {
function CanvasImage(image) {
this.canvas = document.createElement('canvas');
this.context = this.canvas.getContext('2d');
var originalWidth = image.width;
var originalHeight = image.height;
var maxArea = 300 * 300;
var bitmapArea = originalWidth * originalHeight;
var scaleRatio = 1;
if (bitmapArea > maxArea) {
scaleRatio = maxArea / bitmapArea;
}
//console.log(scaleRatio);
this.width = this.canvas.width = originalWidth * scaleRatio;
this.height = this.canvas.height = originalHeight * scaleRatio;
this.context.drawImage(image, 0, 0, originalWidth, originalHeight, 0, 0, this.width, this.height);
}
}
if (this.DarkVibrantSwatch === void 0) {
if (this.VibrantSwatch !== void 0) {
hsl = this.VibrantSwatch.getHsl();
hsl[2] = this.TARGET_DARK_LUMA;
return this.DarkVibrantSwatch = new Swatch(Vibrant.hslToRgb(hsl[0], hsl[1], hsl[2]), 0);
}
}
};
Vibrant.prototype.findMaxPopulation = function() {
var j, len, population, ref, swatch;
population = 0;
ref = this._swatches;
for (j = 0, len = ref.length; j < len; j++) {
swatch = ref[j];
population = Math.max(population, swatch.getPopulation());
}
return population;
};
CanvasImage.prototype.getPixelCount = function () {
return this.width * this.height;
};
Vibrant.prototype.findColorVariation = function(targetLuma, minLuma, maxLuma, targetSaturation, minSaturation, maxSaturation) {
var j, len, luma, max, maxValue, ref, sat, swatch, value;
max = void 0;
maxValue = 0;
ref = this._swatches;
for (j = 0, len = ref.length; j < len; j++) {
swatch = ref[j];
sat = swatch.getHsl()[1];
luma = swatch.getHsl()[2];
if (sat >= minSaturation && sat <= maxSaturation && luma >= minLuma && luma <= maxLuma && !this.isAlreadySelected(swatch)) {
value = this.createComparisonValue(sat, targetSaturation, luma, targetLuma, swatch.getPopulation(), this.HighestPopulation);
if (max === void 0 || value > maxValue) {
max = swatch;
maxValue = value;
}
}
}
return max;
};
CanvasImage.prototype.getImageData = function () {
return this.context.getImageData(0, 0, this.width, this.height);
};
Vibrant.prototype.createComparisonValue = function(saturation, targetSaturation, luma, targetLuma, population, maxPopulation) {
return this.weightedMean(this.invertDiff(saturation, targetSaturation), this.WEIGHT_SATURATION, this.invertDiff(luma, targetLuma), this.WEIGHT_LUMA, population / maxPopulation, this.WEIGHT_POPULATION);
};
CanvasImage.prototype.removeCanvas = function () {
this.context = null;
this.canvas = null;
};
Vibrant.prototype.invertDiff = function(value, targetValue) {
return 1 - Math.abs(value - targetValue);
};
return CanvasImage;
Vibrant.prototype.weightedMean = function() {
var i, sum, sumWeight, value, values, weight;
values = 1 <= arguments.length ? slice.call(arguments, 0) : [];
sum = 0;
sumWeight = 0;
i = 0;
while (i < values.length) {
value = values[i];
weight = values[i + 1];
sum += value * weight;
sumWeight += weight;
i += 2;
}
return sum / sumWeight;
};
Vibrant.prototype.swatches = function() {
return {
Vibrant: this.VibrantSwatch,
Muted: this.MutedSwatch,
DarkVibrant: this.DarkVibrantSwatch,
DarkMuted: this.DarkMutedSwatch,
LightVibrant: this.LightVibrantSwatch,
LightMuted: this.LightMuted
};
};
Vibrant.prototype.isAlreadySelected = function(swatch) {
return this.VibrantSwatch === swatch || this.DarkVibrantSwatch === swatch || this.LightVibrantSwatch === swatch || this.MutedSwatch === swatch || this.DarkMutedSwatch === swatch || this.LightMutedSwatch === swatch;
};
Vibrant.rgbToHsl = function(r, g, b) {
var d, h, l, max, min, s;
r /= 255;
g /= 255;
b /= 255;
max = Math.max(r, g, b);
min = Math.min(r, g, b);
h = void 0;
s = void 0;
l = (max + min) / 2;
if (max === min) {
h = s = 0;
} else {
d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
}
h /= 6;
}
return [h, s, l];
};
Vibrant.hslToRgb = function(h, s, l) {
var b, g, hue2rgb, p, q, r;
r = void 0;
g = void 0;
b = void 0;
hue2rgb = function(p, q, t) {
if (t < 0) {
t += 1;
}
if (t > 1) {
t -= 1;
}
if (t < 1 / 6) {
return p + (q - p) * 6 * t;
}
if (t < 1 / 2) {
return q;
}
if (t < 2 / 3) {
return p + (q - p) * (2 / 3 - t) * 6;
}
return p;
};
if (s === 0) {
r = g = b = l;
} else {
q = l < 0.5 ? l * (1 + s) : l + s - (l * s);
p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - (1 / 3));
}
return [r * 255, g * 255, b * 255];
};
return Vibrant;
})();
/*
CanvasImage Class
Class that wraps the html image element and canvas.
It also simplifies some of the canvas context manipulation
with a set of helper functions.
Stolen from https://github.com/lokesh/color-thief
*/
window.CanvasImage = CanvasImage = (function() {
function CanvasImage(image) {
this.canvas = document.createElement('canvas');
this.context = this.canvas.getContext('2d');
var originalWidth = image.width;
var originalHeight = image.height;
var maxArea = 300 * 300;
var bitmapArea = originalWidth * originalHeight;
var scaleRatio = 1;
if (bitmapArea > maxArea) {
scaleRatio = maxArea / bitmapArea;
}
//console.log(scaleRatio);
this.width = this.canvas.width = originalWidth * scaleRatio;
this.height = this.canvas.height = originalHeight * scaleRatio;
this.context.drawImage(image, 0, 0, originalWidth, originalHeight, 0, 0, this.width, this.height);
}
CanvasImage.prototype.getPixelCount = function() {
return this.width * this.height;
};
CanvasImage.prototype.getImageData = function () {
return this.context.getImageData(0, 0, this.width, this.height);
};
CanvasImage.prototype.removeCanvas = function() {
this.context = null;
this.canvas = null;
};
return CanvasImage;
})();
}).call(this);
})();
},{"quantize":1}]},{},[2]);