<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>https://mcbbs.wiki/index.php?action=history&amp;feed=atom&amp;title=%E5%BE%AE%E4%BB%B6%3ASaltContrastCalculator</id>
	<title>微件:SaltContrastCalculator - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="https://mcbbs.wiki/index.php?action=history&amp;feed=atom&amp;title=%E5%BE%AE%E4%BB%B6%3ASaltContrastCalculator"/>
	<link rel="alternate" type="text/html" href="https://mcbbs.wiki/index.php?title=%E5%BE%AE%E4%BB%B6:SaltContrastCalculator&amp;action=history"/>
	<updated>2026-05-14T13:47:21Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.40.3</generator>
	<entry>
		<id>https://mcbbs.wiki/index.php?title=%E5%BE%AE%E4%BB%B6:SaltContrastCalculator&amp;diff=30971&amp;oldid=prev</id>
		<title>Salt lovely：​网页版的文字对比度检测工具，ts写的，这是编译后的js代码所以看起来有些奇怪</title>
		<link rel="alternate" type="text/html" href="https://mcbbs.wiki/index.php?title=%E5%BE%AE%E4%BB%B6:SaltContrastCalculator&amp;diff=30971&amp;oldid=prev"/>
		<updated>2021-06-16T14:34:44Z</updated>

		<summary type="html">&lt;p&gt;网页版的文字对比度检测工具，ts写的，这是编译后的js代码所以看起来有些奇怪&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
一个页面只有一个对比度计算器生效（懒）。&lt;br /&gt;
&amp;lt;div id=&amp;quot;saltContrastCalculator&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
{{#Widget:SaltContrastCalculator}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&amp;lt;includeonly&amp;gt;&amp;lt;script&amp;gt;&lt;br /&gt;
&amp;quot;use strict&amp;quot;;&lt;br /&gt;
(function () {&lt;br /&gt;
    var generalProp = function (p, el) {&lt;br /&gt;
        if (p.id)&lt;br /&gt;
            el.id = p.id;&lt;br /&gt;
        if (p.className)&lt;br /&gt;
            el.className = p.className;&lt;br /&gt;
        if (p.title)&lt;br /&gt;
            el.title = p.title;&lt;br /&gt;
        if (p.textContent)&lt;br /&gt;
            el.textContent = p.textContent;&lt;br /&gt;
        if (p.children) {&lt;br /&gt;
            if (p.children instanceof Array) {&lt;br /&gt;
                for (var _i = 0, _a = p.children; _i &amp;lt; _a.length; _i++) {&lt;br /&gt;
                    var child = _a[_i];&lt;br /&gt;
                    if (child instanceof Node)&lt;br /&gt;
                        el.appendChild(child);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else if (p.children instanceof Node)&lt;br /&gt;
                el.appendChild(p.children);&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
    /** 带初始化地生成一个元素 */&lt;br /&gt;
    var newElement = function (tagName, p) {&lt;br /&gt;
        var el = document.createElement(tagName);&lt;br /&gt;
        if (p)&lt;br /&gt;
            generalProp(p, el);&lt;br /&gt;
        return el;&lt;br /&gt;
    };&lt;br /&gt;
    var log = function () {&lt;br /&gt;
        var argu = [];&lt;br /&gt;
        for (var _i = 0; _i &amp;lt; arguments.length; _i++) {&lt;br /&gt;
            argu[_i] = arguments[_i];&lt;br /&gt;
        }&lt;br /&gt;
        console.log.apply(console, argu);&lt;br /&gt;
    };&lt;br /&gt;
    var answer = {&lt;br /&gt;
        veryBad: [&lt;br /&gt;
            &amp;#039;对比度小于 3:1 , 难以阅读, 反对使用这种配色, 建议立即更改&amp;#039;,&lt;br /&gt;
            &amp;#039;文字ABCD 请勿使用于正文部分 ✗&amp;#039;,&lt;br /&gt;
            &amp;#039;文字AB 请勿使用于大号字体 ✗&amp;#039;,&lt;br /&gt;
        ],&lt;br /&gt;
        bad: [&lt;br /&gt;
            &amp;#039;对比度大于 3:1 但是小于 4.5:1 , 不适合阅读, 不推荐在任何情况下使用&amp;#039;,&lt;br /&gt;
            &amp;#039;文字ABCD 请勿使用于正文 ✗&amp;#039;,&lt;br /&gt;
            &amp;#039;文字AB 不推荐使用于大号字体 ✗&amp;#039;,&lt;br /&gt;
        ],&lt;br /&gt;
        pass: [&lt;br /&gt;
            &amp;#039;(AA级) 对比度大于 4.5:1 但是小于 7:1 , 较为适合阅读, 但仅建议用于大号字体部分&amp;#039;,&lt;br /&gt;
            &amp;#039;文字ABCD 不推荐使用于正文 ✗&amp;#039;,&lt;br /&gt;
            &amp;#039;文字AB 可以使用于大号字体 ✓&amp;#039;,&lt;br /&gt;
        ],&lt;br /&gt;
        good: [&lt;br /&gt;
            &amp;#039;(AAA级) 对比度大于 7:1 , 适合阅读, 此配色可以用于正文部分&amp;#039;,&lt;br /&gt;
            &amp;#039;文字ABCD 可以使用于正文 ✓&amp;#039;,&lt;br /&gt;
            &amp;#039;文字AB 可以使用于大号字体 ✓&amp;#039;,&lt;br /&gt;
        ],&lt;br /&gt;
    };&lt;br /&gt;
    /** rgb(255,255,255) 格式 */&lt;br /&gt;
    var RGBExpr = /rgba?\((\d+)[,;](\d+)[,;](\d+)[,;]?\d*\)/i;&lt;br /&gt;
    /** #ffffff 格式 */&lt;br /&gt;
    var HexExpr = /#([0-9a-f]{1,6})/i;&lt;br /&gt;
    /** #fff 格式 */&lt;br /&gt;
    var Hex3Expr = /#([0-9a-f]{3,4})([^0-9a-f]|$)/i;&lt;br /&gt;
    /** 将文字转为RGB8bit对象 */&lt;br /&gt;
    var calcColor = function (expr) {&lt;br /&gt;
        // 预处理&lt;br /&gt;
        expr = expr.replace(/\s+/g, &amp;#039;&amp;#039;);&lt;br /&gt;
        if (Hex3Expr.test(expr)) {&lt;br /&gt;
            // #fff 格式&lt;br /&gt;
            var hex = +(&amp;#039;0x&amp;#039; + expr.match(Hex3Expr)[1].slice(0, 3));&lt;br /&gt;
            return {&lt;br /&gt;
                R8bit: ((hex &amp;gt;&amp;gt; 8) % 16) * 17,&lt;br /&gt;
                G8bit: ((hex &amp;gt;&amp;gt; 4) % 16) * 17,&lt;br /&gt;
                B8bit: (hex % 16) * 17,&lt;br /&gt;
            };&lt;br /&gt;
        }&lt;br /&gt;
        else if (HexExpr.test(expr)) {&lt;br /&gt;
            // #ffffff 格式&lt;br /&gt;
            var hex = +(&amp;#039;0x&amp;#039; + expr.match(HexExpr)[1]);&lt;br /&gt;
            return {&lt;br /&gt;
                R8bit: (hex &amp;gt;&amp;gt; 16) % 256,&lt;br /&gt;
                G8bit: (hex &amp;gt;&amp;gt; 8) % 256,&lt;br /&gt;
                B8bit: hex % 256,&lt;br /&gt;
            };&lt;br /&gt;
        }&lt;br /&gt;
        else if (RGBExpr.test(expr)) {&lt;br /&gt;
            // rgb(255,255,255) 格式&lt;br /&gt;
            var _a = expr&lt;br /&gt;
                .match(RGBExpr)&lt;br /&gt;
                .splice(1, 3)&lt;br /&gt;
                .map(function (v) { return +v; }), sR = _a[0], sG = _a[1], sB = _a[2];&lt;br /&gt;
            return {&lt;br /&gt;
                R8bit: numFormat(sR),&lt;br /&gt;
                G8bit: numFormat(sG),&lt;br /&gt;
                B8bit: numFormat(sB),&lt;br /&gt;
            };&lt;br /&gt;
        }&lt;br /&gt;
        return {&lt;br /&gt;
            R8bit: 0,&lt;br /&gt;
            G8bit: 0,&lt;br /&gt;
            B8bit: 0,&lt;br /&gt;
        };&lt;br /&gt;
        function numFormat(num) {&lt;br /&gt;
            if (typeof num !== &amp;#039;number&amp;#039; || isNaN(num) || num &amp;lt; 0)&lt;br /&gt;
                return 0;&lt;br /&gt;
            else if (num &amp;gt; 255)&lt;br /&gt;
                return 255;&lt;br /&gt;
            return num;&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
    /** 用于计算相对明度 */&lt;br /&gt;
    var calcsRGB = function (c) {&lt;br /&gt;
        if (c &amp;lt; 0 || typeof c !== &amp;#039;number&amp;#039; || isNaN(c))&lt;br /&gt;
            return 0;&lt;br /&gt;
        else if (c &amp;gt; 255)&lt;br /&gt;
            return 1;&lt;br /&gt;
        var temp = c / 255;&lt;br /&gt;
        if (c &amp;lt;= 0.03928)&lt;br /&gt;
            return temp / 12.92;&lt;br /&gt;
        else&lt;br /&gt;
            return Math.pow(((temp + 0.055) / 1.055), 2.4);&lt;br /&gt;
    };&lt;br /&gt;
    /**&lt;br /&gt;
     * 计算相对明度&lt;br /&gt;
     * @param color 颜色&lt;br /&gt;
     * @returns 明度&lt;br /&gt;
     */&lt;br /&gt;
    var relativeLuminance = function (color) {&lt;br /&gt;
        if (typeof color !== &amp;#039;object&amp;#039;)&lt;br /&gt;
            return 0;&lt;br /&gt;
        var R = calcsRGB(color.R8bit), G = calcsRGB(color.G8bit), B = calcsRGB(color.B8bit);&lt;br /&gt;
        return 0.2126 * R + 0.7152 * G + 0.0722 * B;&lt;br /&gt;
    };&lt;br /&gt;
    /**&lt;br /&gt;
     * 返回两颜色的对比度&lt;br /&gt;
     * @param l1 较亮的颜色的明度&lt;br /&gt;
     * @param l2 较暗的颜色的明度&lt;br /&gt;
     * @returns 对比度&lt;br /&gt;
     */&lt;br /&gt;
    var contrastRatio = function (l1, l2) {&lt;br /&gt;
        if (typeof l1 !== &amp;#039;number&amp;#039; || isNaN(l1) || !isFinite(l1) || l1 &amp;lt; 0)&lt;br /&gt;
            l1 = 0;&lt;br /&gt;
        if (typeof l2 !== &amp;#039;number&amp;#039; || isNaN(l2) || !isFinite(l2) || l2 &amp;lt; 0)&lt;br /&gt;
            l2 = 0;&lt;br /&gt;
        if (l2 &amp;gt; l1) {&lt;br /&gt;
            var temp = l1;&lt;br /&gt;
            l1 = l2;&lt;br /&gt;
            l2 = temp;&lt;br /&gt;
        }&lt;br /&gt;
        return (l1 + 0.05) / (l2 + 0.05);&lt;br /&gt;
    };&lt;br /&gt;
    /**&lt;br /&gt;
     * 封装完毕，输入两个字符串格式的颜色代码&lt;br /&gt;
     *&lt;br /&gt;
     * 返回数字格式的对比度比值&lt;br /&gt;
     */&lt;br /&gt;
    var calcContrast = function (color1, color2) {&lt;br /&gt;
        return contrastRatio(relativeLuminance(calcColor(color1)), relativeLuminance(calcColor(color2)));&lt;br /&gt;
    };&lt;br /&gt;
    var formatRGB = function (rgb) {&lt;br /&gt;
        return &amp;quot;#&amp;quot; + hex(rgb.R8bit) + hex(rgb.G8bit) + hex(rgb.B8bit);&lt;br /&gt;
        function hex(c) {&lt;br /&gt;
            var h = c.toString(16);&lt;br /&gt;
            if (h.length &amp;lt; 2)&lt;br /&gt;
                h = &amp;#039;0&amp;#039; + h;&lt;br /&gt;
            return h;&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
    // 主过程&lt;br /&gt;
    function main() {&lt;br /&gt;
        var div = document.getElementById(&amp;#039;saltContrastCalculator&amp;#039;);&lt;br /&gt;
        if (!div)&lt;br /&gt;
            return;&lt;br /&gt;
        var frag = document.createDocumentFragment();&lt;br /&gt;
        // 添加两个输入框和其对应的预览&lt;br /&gt;
        // 文字色&lt;br /&gt;
        var color1Input = newElement(&amp;#039;input&amp;#039;);&lt;br /&gt;
        color1Input.placeholder = &amp;#039;请输入文字颜色，支持格式“#fff”“#ffffff”“rgb(255,255,255)”&amp;#039;;&lt;br /&gt;
        color1Input.maxLength = 20;&lt;br /&gt;
        var color1Show = newElement(&amp;#039;div&amp;#039;, { className: &amp;#039;color-show&amp;#039; });&lt;br /&gt;
        var color1 = newElement(&amp;#039;div&amp;#039;, { className: &amp;#039;color left&amp;#039;, children: [color1Input, color1Show] });&lt;br /&gt;
        // 背景色&lt;br /&gt;
        var color2Input = newElement(&amp;#039;input&amp;#039;);&lt;br /&gt;
        color2Input.placeholder = &amp;#039;请输入背景颜色，支持格式“#fff”“#ffffff”“rgb(255,255,255)”&amp;#039;;&lt;br /&gt;
        color2Input.maxLength = 20;&lt;br /&gt;
        var color2Show = newElement(&amp;#039;div&amp;#039;, { className: &amp;#039;color-show&amp;#039; });&lt;br /&gt;
        var color2 = newElement(&amp;#039;div&amp;#039;, { className: &amp;#039;color right&amp;#039;, children: [color2Input, color2Show] });&lt;br /&gt;
        // 添加结论框及其对应的预览&lt;br /&gt;
        var resShow = newElement(&amp;#039;div&amp;#039;, { className: &amp;#039;res-show&amp;#039;, textContent: &amp;#039;正文文字ABCD&amp;#039; });&lt;br /&gt;
        var resShowBig = newElement(&amp;#039;div&amp;#039;, { className: &amp;#039;res-show big&amp;#039;, textContent: &amp;#039;大号字体ABC&amp;#039; });&lt;br /&gt;
        var resText = newElement(&amp;#039;div&amp;#039;, { className: &amp;#039;res-text&amp;#039; });&lt;br /&gt;
        var res = newElement(&amp;#039;div&amp;#039;, { className: &amp;#039;res&amp;#039;, children: [resShow, resShowBig, resText] });&lt;br /&gt;
        // 绑定事件&lt;br /&gt;
        var renderColor = function () {&lt;br /&gt;
            var v1 = color1Input.value, v2 = color2Input.value;&lt;br /&gt;
            if (v1 &amp;amp;&amp;amp; v2) {&lt;br /&gt;
                var temp = Math.round(calcContrast(v1, v2) * 100) / 100, text = &amp;quot;\u5BF9\u6BD4\u5EA6: &amp;quot; + temp + &amp;quot;, \u8BC4\u4EF7: &amp;quot;;&lt;br /&gt;
                var tc = formatRGB(calcColor(v1)), bc = formatRGB(calcColor(v2));&lt;br /&gt;
                var evaluate = void 0;&lt;br /&gt;
                res.style.setProperty(&amp;#039;--color&amp;#039;, tc);&lt;br /&gt;
                res.style.setProperty(&amp;#039;--back-color&amp;#039;, bc);&lt;br /&gt;
                resShow.title = &amp;quot;\u6587\u5B57\u989C\u8272: &amp;quot; + tc + &amp;quot;; \u80CC\u666F\u989C\u8272: &amp;quot; + bc;&lt;br /&gt;
                resShowBig.title = &amp;quot;\u6587\u5B57\u989C\u8272: &amp;quot; + tc + &amp;quot;; \u80CC\u666F\u989C\u8272: &amp;quot; + bc;&lt;br /&gt;
                if (temp &amp;lt; 3) {&lt;br /&gt;
                    evaluate = answer.veryBad;&lt;br /&gt;
                }&lt;br /&gt;
                else if (temp &amp;lt; 4.5) {&lt;br /&gt;
                    evaluate = answer.bad;&lt;br /&gt;
                }&lt;br /&gt;
                else if (temp &amp;lt; 7) {&lt;br /&gt;
                    evaluate = answer.pass;&lt;br /&gt;
                }&lt;br /&gt;
                else {&lt;br /&gt;
                    evaluate = answer.good;&lt;br /&gt;
                }&lt;br /&gt;
                resText.textContent = text + evaluate[0];&lt;br /&gt;
                resShow.textContent = evaluate[1];&lt;br /&gt;
                resShowBig.textContent = evaluate[2];&lt;br /&gt;
            }&lt;br /&gt;
        };&lt;br /&gt;
        var renderColor1 = function () {&lt;br /&gt;
            var v = color1Input.value;&lt;br /&gt;
            if (v &amp;amp;&amp;amp; v.length &amp;gt; 1) {&lt;br /&gt;
                var temp = formatRGB(calcColor(v));&lt;br /&gt;
                color1Show.style.backgroundColor = temp;&lt;br /&gt;
                color1Show.title = &amp;#039;颜色: &amp;#039; + temp;&lt;br /&gt;
                renderColor();&lt;br /&gt;
            }&lt;br /&gt;
        };&lt;br /&gt;
        var renderColor2 = function () {&lt;br /&gt;
            var v = color2Input.value;&lt;br /&gt;
            if (v &amp;amp;&amp;amp; v.length &amp;gt; 1) {&lt;br /&gt;
                var temp = formatRGB(calcColor(v));&lt;br /&gt;
                color2Show.style.backgroundColor = temp;&lt;br /&gt;
                color2Show.title = &amp;#039;颜色: &amp;#039; + temp;&lt;br /&gt;
                renderColor();&lt;br /&gt;
            }&lt;br /&gt;
        };&lt;br /&gt;
        color1Input.addEventListener(&amp;#039;change&amp;#039;, renderColor1);&lt;br /&gt;
        color2Input.addEventListener(&amp;#039;change&amp;#039;, renderColor2);&lt;br /&gt;
        // 添加CSS&lt;br /&gt;
        var style = newElement(&amp;#039;style&amp;#039;, {&lt;br /&gt;
            textContent: &amp;quot;\n/**/\n#saltContrastCalculator * {\n    box-sizing: border-box;\n}\n#saltContrastCalculator .color,\n#saltContrastCalculator .res {\n    display: inline-block;\n    padding: 5px;\n    margin: 0 4px;\n    border: 4px solid #ccc6;\n    border-radius: 4px;\n    text-align: center;\n    vertical-align: middle;\n}\n#saltContrastCalculator .color {\n    width: calc(50% - 12px);\n}\n#saltContrastCalculator .color.left {\n    margin-right: 8px;\n}\n#saltContrastCalculator .color.right {\n    margin-left: 8px;\n}\n#saltContrastCalculator .res {\n    width: calc(100% - 8px);\n    margin-top: 4px;\n}\n#saltContrastCalculator input,\n#saltContrastCalculator .color-show,\n#saltContrastCalculator .res-show,\n#saltContrastCalculator .res-text {\n    width: 100%;\n    height: 3rem;\n    line-height: 3rem;\n    border-radius: 4px;\n    margin-top: 4px;\n    font-size: 1rem;\n    text-align: center;\n}\n#saltContrastCalculator .res-show {\n    color: var(--color);\n    background-color: var(--back-color);\n}\n#saltContrastCalculator .big {\n    font-size: 1.5rem;\n}\n#saltContrastCalculator .res-text {\n    height: 2rem;\n    line-height: 2rem;\n}\n&amp;quot;,&lt;br /&gt;
        });&lt;br /&gt;
        document.head.appendChild(style);&lt;br /&gt;
        // 渲染到DOM&lt;br /&gt;
        appendChildren(frag, color1, color2, res);&lt;br /&gt;
        div.appendChild(frag);&lt;br /&gt;
    }&lt;br /&gt;
    function appendChildren(parent) {&lt;br /&gt;
        var nodes = [];&lt;br /&gt;
        for (var _i = 1; _i &amp;lt; arguments.length; _i++) {&lt;br /&gt;
            nodes[_i - 1] = arguments[_i];&lt;br /&gt;
        }&lt;br /&gt;
        for (var _a = 0, nodes_1 = nodes; _a &amp;lt; nodes_1.length; _a++) {&lt;br /&gt;
            var n = nodes_1[_a];&lt;br /&gt;
            parent.appendChild(n);&lt;br /&gt;
        }&lt;br /&gt;
        return parent;&lt;br /&gt;
    }&lt;br /&gt;
    main();&lt;br /&gt;
})();&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>Salt lovely</name></author>
	</entry>
</feed>