File: wcag.js

Recommend this page to a friend!
  Classes of Andrew Collington  >  PHP WCAG Color Compliance  >  wcag.js  >  Download  
File: wcag.js
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: PHP WCAG Color Compliance
Get the contrast ratio between two colors for WCAG
Author: By
Last change:
Date: 1 year ago
Size: 3,154 bytes
 

Contents

Class file image Download
class WCAG
{
    /**
     * Convert a hex colour string into an rgb array.
     *
     * Handles colour string in the following formats:
     *
     *     o #44FF55
     *     o 44FF55
     *     o #4F5
     *     o 4F5
     *
     * @param string hex
     * @return array<int>
     */
    hex2rgb(hex) {
        hex = hex.replace(/^#/, '');
        return hex.replace(/^([a-f\d])([a-f\d])([a-f\d])$/i, (m, r, g, b) => r + r + g + g + b + b)
            .match(/.{2}/g).map(x => parseInt(x, 16))
    }

    /**
     * Relative luminance of a colour.
     *
     * This calculates the relative luminance of a colour according to the
     * WCAG 2.0 specifications.
     *
     * Value returned is from 0 (no luminance/black) to 1 (full luminance/white).
     *
     * @param  string|array rgb
     * @return float
     * @see    https://www.w3.org/TR/WCAG20/#relativeluminancedef
     */
    luminance(rgb) {
        if (!Array.isArray(rgb)) {
            rgb = this.hex2rgb(rgb);
        }
        if (rgb.length != 3) {
            throw 'Colour value must be a hex string or an array of RGB values';
        }
        for (let c = 0; c < 3; c++) {
            if (rgb[c] < 0 || rgb[c] > 255) {
                throw 'RGB array values must range between 0 and 255, inclusive';
            }
            rgb[c] /= 255;
            rgb[c] = (rgb[c] <= 0.03928
                    ? rgb[c] / 12.92
                    : Math.pow(((rgb[c] + 0.055) / 1.055), 2.4)
            );
        }
        return ((0.2126 * rgb[0]) + (0.7152 * rgb[1]) + (0.0722 * rgb[2]));
    }


    /**
     * Calculate contrast ratio between two colours.
     *
     * @param string|array rgb1
     * @param string|array rgb2
     * @return float
     */
    contrastRatio(rgb1, rgb2) {
        if (!Array.isArray(rgb1)) {
            rgb1 = this.hex2rgb(rgb1);
        }
        if (!Array.isArray(rgb2)) {
            rgb2 = this.hex2rgb(rgb2);
        }
        if (rgb1.length != 3 || rgb2.length != 3) {
            throw 'Colour value must be a hex string or an array of RGB values';
        }
        for (let c = 0; c < 3; c++) {
            if ((rgb1[c] < 0 || rgb1[c] > 255) || (rgb2[c] < 0 || rgb2[c] > 255)) {
                throw 'RGB array values must range between 0 and 255, inclusive';
            }
        }

        let l1 = this.luminance(rgb1);
        let l2 = this.luminance(rgb2);
        return (l1 >= l2
                ? (l1 + .05) / (l2 + .05)
                : (l2 + .05) / (l1 + .05)
        );
    }

    /**
     * Get WCAG compliance information for the colours.
     *
     * Currently this will return the contrast ratio and the WCAG 2.0 pass/fail
     * states.
     *
     * @param  string|array fg
     * @param  string|array bg
     * @return {*}
     */
    accessibility(fg, bg) {
        let ratio = this.contrastRatio(fg, bg);
        return {
            ratio,
            "2.0": {
                "aa": (ratio >= 4.5),
                "aa-18pt": (ratio >= 3),
                "aaa": (ratio >= 7),
                "aaa-18pt": (ratio >= 4.5)
            }
        };
    }
}

const wcag = new WCAG();
module.exports = {
    wcag
};


For more information send a message to info at phpclasses dot org.