MediaWiki:Gadget-colortoggle.js
注意:在保存之后,您可能需要清除浏览器缓存才能看到所作出的变更的影响。
- Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5或Ctrl-R(Mac为⌘-R)
- Google Chrome:按Ctrl-Shift-R(Mac为⌘-Shift-R)
- Internet Explorer:按住Ctrl的同时单击刷新,或按Ctrl-F5
- Opera:前往菜单 → 设置(Mac为Opera → Preferences),然后隐私和安全 → 清除浏览数据 → 缓存的图片和文件。
var dropMenu = $('<div id="p-colorconv" role="navigation" class="vectorMenu" aria-labelledby="p-colorconv-label" style="background: linear-gradient(rgba(255,255,255,0),#fff);"><h3 id="p-colorconv-label" tabindex="0"><span data-color="yellow" style="padding:1px 3px;margin-left: 0.7em;margin-top: 1.375em;">颜表立</span><a href="#" tabindex="-1"></a></h3><div class="menu"><ul></ul></div></div>');
function cachedFactory(factory) {
var cache = {};
return function(key) {
if (!(key in cache)) {
cache[key] = factory(key);
}
return cache[key];
};
}
var colorToRgba = (function() {
var canvas = $('<canvas>')[0];
canvas.width = canvas.height = 1;
var ctx = canvas.getContext('2d');
return cachedFactory(function(col) {
ctx.clearRect(0, 0, 1, 1);
ctx.fillStyle = col;
ctx.fillRect(0, 0, 1, 1);
var ret = $.makeArray(ctx.getImageData(0, 0, 1, 1).data);
ret[3] /= 255;
return ret;
});
})();
function rgbaToColor(color) {
if (color.length === 3) {
return 'rgb(' + color[0] + ',' + color[1] + ',' + color[2] + ')';
} else {
return 'rgba(' + color[0] + ',' + color[1] + ',' + color[2] + ',' + color[3] + ')';
}
}
function luminance(color) {
var output = [];
for (var i = 0; i < 3; i++) {
var c = color[i] / 255;
if (c <= 0.03928) output[i] = c / 12.92;
else output[i] = Math.pow((c + 0.055) / 1.055, 2.4);
}
return 0.2126 * output[0] + 0.7152 * output[1] + 0.0722 * output[2];
}
function contrastRatio(c1, c2) {
var l1 = luminance(c1) + 0.05;
var l2 = luminance(c2) + 0.05;
if (l1 > l2) {
return l1 / l2;
} else {
return l2 / l1;
}
}
function hslToRgb(color) {
var h = color[0],
s = color[1],
l = color[2];
var r, g, b;
if (s === 0) {
r = g = b = l;
} else {
var hue2rgb = function hue2rgb(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;
};
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}
function rgbToHsl(color) {
var r = color[0] / 255,
g = color[1] / 255,
b = color[2] / 255;
var max = Math.max(r, g, b),
min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if (max == min) {
h = s = 0; // achromatic
} else {
var 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;
break;
}
h /= 6;
}
return [h, s, l];
}
var white = colorToRgba('#f6f6f6');
var lessBrightColor = cachedFactory(function(colortxt) {
var rgb = colorToRgba(colortxt);
var lum = contrastRatio(rgb, white);
if (lum >= 2) {
return colortxt;
}
var hsl = rgbToHsl(rgb);
do {
hsl[2] -= 0.02;
rgb = hslToRgb(hsl);
} while (contrastRatio(rgb, white) < 2);
return rgbaToColor(rgb);
});
var highContrastColor = cachedFactory(function(colortxt) {
var rgb = colorToRgba(colortxt);
var lum = contrastRatio(rgb, white);
if (lum >= 3) {
return colortxt;
}
var hsl = rgbToHsl(rgb);
do {
hsl[2] -= 0.02;
rgb = hslToRgb(hsl);
} while (contrastRatio(rgb, white) < 3);
return rgbaToColor(rgb);
});
function black(span) {
span.css('color', 'black');
span.css('background-color', '');
span.css('text-shadow', '');
}
function lowBrightness(span) {
var color = lessBrightColor(span.attr('data-color'));
span.css('color', color);
span.css('background-color', '');
span.css('text-shadow', '');
}
function highContrast(span) {
var color = highContrastColor(span.attr('data-color'));
span.css('color', color);
span.css('background-color', '');
span.css('text-shadow', '');
}
function original(span) {
span.css('color', span.attr('data-color'));
span.css('background-color', '');
span.css('text-shadow', '');
}
function originalWBackground(span) {
var color = span.attr('data-color');
span.css('color', color);
if (contrastRatio(white, colorToRgba(color)) < 3) {
span.css('background-color', '#3D3D3D');
} else {
span.css('background-color', '');
}
span.css('text-shadow', '');
}
function originalWShadow(span) {
var color = span.attr('data-color');
span.css('color', color);
if (contrastRatio(white, colorToRgba(color)) < 3) {
span.css('text-shadow', 'black 0 0 0.2em, black 0 0 0.2em, black 0 0 0.2em');
} else {
span.css('text-shadow', '');
}
span.css('background-color', '');
}
function makeOption(caption, style) {
var item = $('<li id="ca-colorconv-0"><a>' + caption + '</a></li>');
dropMenu.find('ul').append(item);
item.click(function() {
dropMenu.find('.selected').removeClass('selected');
item.addClass('selected');
localStorage.colorconv = style;
applyStyle(style);
});
}
function applyStyle(style) {
$('[data-color]').each(function(i, obj) {
var item = $(obj);
styles[style](item);
});
}
var styles = {
'black': black,
'lowBrightness': lowBrightness,
'highContrast': highContrast,
'original': original,
'originalWBackground': originalWBackground,
'originalWShadow': originalWShadow
};
makeOption('黑色', 'black');
makeOption('较高对比度', 'lowBrightness');
makeOption('高对比度', 'highContrast');
makeOption('原色', 'original');
makeOption('原色+背景', 'originalWBackground');
makeOption('原色+阴影', 'originalWShadow');
$(function() {
$('#left-navigation').append(dropMenu);
applyStyle(localStorage.colorconv || 'lowBrightness');
});