「利用者:Waiesu/ContrastChecker.js」の版間の差分

削除された内容 追加された内容
Waiesu (会話 | 投稿記録)
バージョンアップしたつもり
Waiesu (会話 | 投稿記録)
HSLに対応させてみる
39行目:
var CCcolor = function (color) {
if (!(this instanceof CCcolor)) throw new TypeError('Call constructor with "new": CCcolor');
if (typeof color != 'string') throw new TypeError('The argument should be string.');
var type, rgba;
if (color && color.match('rgb')) {
function convertPercentage(number, limit) {
type = 'rgb';
for (var i = 0; i < 4; i++) {
} else if (color && color.charAt(0) == '#') {
var matches = number[i].match(/([0-9].+)(%)?/);
type = color.length > 6 ? 'hex6' : 'hex3';
if (!matches) {
throw new TypeError('The number in argument "' + number[i] + '" is incorrect format.');
} else if (matches[2]) {
number[i] = limit[i] * matches[1] / 100;
} else {
number[i] = Number(matches[1]);
}
}
return number;
}
var type, rgba, hsla;
if (color.match('hsl')) {
hsla = color.match(/[0-9.%]+/g);
if (hsla.length == 3) hsla[3] = 1;
hsla = convertPercentage(hsla, [360, 1, 1, 1]);
var max, min;
if (hsla[2] < 0.5) {
max = 255 * (hsla[2] + hsla[1] * hsla[2]);
min = 255 * (hsla[2] - hsla[1] * hsla[2]);
} else {
max = 255 * (hsla[2] + hsla[1] * (1 - hsla[2]));
min = 255 * (hsla[2] - hsla[1] * (1 - hsla[2]));
}
if (hsla[0] < 60) {
rgba = [max, hsla[0] / 60 * (max - min) + min, min];
} else if (hsla[0] < 120) {
rgba = [(120 - hsla[0]) / 60 * (max - min) + min, max, min];
} else if (hsla[0] < 180) {
rgba = [min, max, (hsla[0] - 120) / 60 * (max - min) + min];
} else if (hsla[0] < 240) {
rgba = [min, (240 - hsla[0]) / 60 * (max - min) + min, max];
} else if (hsla[0] < 300) {
rgba = [(hsla[0] - 240) / 60 * (max - min) + min, min, max];
} else {
rgba = [max, min, (360 - hsla[0]) / 60 * (max - min) + min];
}
rgba[3] = hsla[3];
} else if (color.match('rgb')) {
rgba = color.match(/[0-9.%]+/g);
if (rgba.length == 3) rgba[3] = 1;
rgba = convertPercentage(rgba, [255, 255, 255, 1]);
} else if (color.charAt(0) == '#') {
if (color.length < 6) {
rgba = color.match(/[0-9A-F]/gi);
for (var i = 0; i < 4; i++) rgba[i] = Number('0x' + (rgba[i] || 'F') + (rgba[i] || 'F'));
} else {
rgba = color.match(/[0-9A-F]{2}/gi);
for (var j = 0; j < 4; j++) rgba[j] = Number('0x' + (rgba[j] || 'FF'));
}
} else if (color == 'transparent') {
rgba = [0, 0, 0, 0];
51 ⟶ 102行目:
} else {
throw new TypeError('The argument "' + color + '" is incorrect format.');
}
 
// For RGB, HEX
var regex, format;
if (type) {
switch (type) {
case 'rgb': regex = /\d+/g; format = '${n}'; break;
case 'hex6': regex = /[0-9A-F]{2}/gi; format = '0x${n}'; break;
case 'hex3': regex = /[0-9A-F]/gi; format = '0x${n}${n}'; break;
}
rgba = color.match(regex);
rgba[3] = Number(rgba[3] || 1);
}
 
73 ⟶ 112行目:
B: [76.245, 149.685, 29.07],
};
for (var i = 0; i < 3; i++) {
for (var k = 0; k < 3; k++) {
// For RGB, HEX
if (format) rgba[i] = Number(format.replace(/\$\{n\}/g, rgba[i]));
// RGBA
if (rgba[i] < 0 || 255 < rgba[i]) {
throw new Error('RGB'[i] + ' value "' + rgba[i] +'" is not in correct range (0 - 255).');
}
// sRGB
srgb[ik] = rgba[ik] / 255;
 
// 輝度
luminance += COEFFICIENT.L[ik] * (srgb[ik] <= 0.03928 ? srgb[ik] / 12.92 : Math.pow(((srgb[ik] + 0.055) / 1.055), 2.4));
 
// 明度(参考値)
brightness += COEFFICIENT.B[ik] * srgb[ik];
}
// HSL
if (!hsla) {
var _max = Math.max.apply(null, srgb), _min = Math.min.apply(null, srgb);
hsla[2] = (_max + _min) / 2;
if (_max == _min) {
hsla[0] = 0;
} else {
for (var l = 0; l < 3; l++) {
if (_max == srgb[l]) {
hsla[0] = 60 * ((srgb[l + 1] || srgb[l - 2] || 0) - (srgb[l - 1] || srgb[l + 2] || 0)) / (_max - _min) + 120 * l;
}
}
}
if (hsla[2] < 0.5) {
hsla[1] = (hsla[2] - _min) / hsla[2];
} else {
hsla[1] = (_max - hsla[2]) / (1 - hsla[2]);
}
hsla[3] == rgba[3];
}
this.alpha = rgba[3];
this.RGB = rgba.slice(0, 3);
this.RGBA = rgba;
this.sRGB = srgb;
this.HSL = hsla.slice(0, 3);
this.HSLA = hsla;
this.luminance = luminance;
this.brightness = brightness;