问题描述
所以我想为给定的一对 foregroundRGBA
和 backgroundRGBA
颜色编写一个颜色对比度计算器,使用 Advanced Perpetual Contrast Algorithm (APCA)(阅读 Google WebDev's mini-article on APCA)。
虽然上述网站有一些代码示例可以做同样的事情,但它们是:
- 当任一颜色具有透明度时无效 (0 ≤ α
- 写的很奇怪
- 无法读取
点号1 是这里最大的问题,因为前景色和/或背景色可能是半透明的。在这种情况下就会出现问题。而我对此真的无能为力。例如,该站点上的 RGBColor.toY
函数仅适用于 sRGB 颜色,而不适用于具有 alpha 透明度的 RGB 颜色。
这是我需要帮助的地方。
如何使用 APCA 为给定的一对 foregroundRGBA
和 backgroundRGBA
RGBA
颜色对象编写颜色对比度计算器?
我已经复制了站点中使用的常量,并为一些函数编写了一些代码,以及 RGBA
颜色类(其对象将作为参数传递给即将编写的 APCA 颜色对比度计算器,可以使用 RGBA
对象及其属性来简化计算和可读性)。
站点中给出和使用的常量
const sRGBtrc = 2.218; // Gamma for sRGB linearization. 2.223 could be used instead
// 2.218 sets unity with the piecewise sRGB at #777
const Rco = 0.2126; // sRGB Red Coefficient
const Gco = 0.7156; // sRGB Green Coefficient
const Bco = 0.0722; // sRGB Blue Coefficient
const scaleBoW = 161.8; // Scaling for dark text on light (phi * 100)
const scaleWoB = 161.8; // Scaling for light text on dark — same as BoW,but
// this is separate for possible future use.
const normBGExp = 0.38; // Constants for Power Curve Exponents.
const normTXTExp = 0.43; // One pair for normal text,and one for REVERSE
const revBGExp = 0.5; // FUTURE: These will eventually be dynamic
const revTXTExp = 0.43; // as a function of light adaptation and context
const blkThrs = 0.02; // Level that triggers the soft black clamp
const blkClmp = 1.75; // Exponent for the soft black clamp curve
杂项。功能
// Clamps a value between a given range [minimum,maximum]
const clamp = (value,minimum=0,maximum=1) => {
if (value < minimum) return minimum;
if (value > maximum) return maximum;
return value;
}
// Modified clamp to clamp an RGBA color value in [0,255]
const clampColor = (value=0) => clamp(Math.round(value),255);
RGBA
颜色类
// An RGBA color class to be used by `foregroundRGBA` and `backgroundRGBA`
class RGBA {
constructor(red=0,green=0,blue=0,alpha=1) {
// Clamp the given r,g,b arguments between 0 and 255
this._red = clampColor(red);
this._green = clampColor(green);
this._blue = clampColor(blue);
// Clamp a between 0 and 1 since it is alpha
this._alpha = clamp(alpha);
}
get r() {
return this._red;
}
set r(value) {
this._red = clampColor(value);
}
get linearizedR() {
return (this._red / 255) ^ sRGBtrc;
}
get g() {
return this._green;
}
set g(value) {
this._green = clampColor(value);
}
get linearizedG() {
return (this._green / 255) ^ sRGBtrc;
}
get b() {
return this._blue;
}
set b(value) {
this._blue = clampColor(value);
}
get linearizedB() {
return (this._blue / 255) ^ sRGBtrc;
}
get a() {
return this._alpha;
}
set a(value) {
this._alpha = clamp(value);
}
// Not given in the site (since the site is using RGB and not RGBA)
// Written based on assumption (since this._alpha is already betwen 0 and 1 unlike the others)
get linearizedA() {
return this._alpha ^ sRGBtrc;
}
// Relative Luminance (Y) property of a given RGBA color
// Works only for RGB and not RGBA (since the formula makes no use of this._alpha and purely returns the value based on RGB and not RGBA)
get Y() {
return (
Math.pow(this._red/255,sRGBtrc) * Rco
+ Math.pow(this._green/255,sRGBtrc) * Gco
+ Math.pow(this._blue/255,sRGBtrc) * Bco
// Assumption again
// Also,if there exists an `Aco`,its value is unknown (part of my question)
// + Math.pow(this._alpha,sRGBtrc) * Aco
);
}
// Modified `toString` to return a CSS-compatible RGBA color
toString() {
return `rgba(${this._red},${this._green},${this._blue},${this._alpha})`;
}
}
要编写的基于 APCA 的颜色对比度计算器
const getAPCAColorContrast = (foregroundRGBA=new RGBA(),backgroundRGBA=new RGBA(255,255,255)) => {
// Code to be written according to the algorithm using passed RGBA objects and their properties
// WHICH MUST BE COMPATIBLE WITH RGBA COLORS AND NOT JUST RGB COLORS
return colorContrast; // Calculated APCA-based color contrast
}
我尝试寻找一种可以计算任何地方的 RGBA 颜色的 APCA,但失败了。
我会尽力回答您的任何问题,以帮助您更好地回答。
如果我需要进行任何编辑以提出更好的问题,请告诉我。
如果您找到一种使用 APCA 计算 RGBA(不仅仅是 RGB)颜色的对比度的方法,我将不胜感激。
编辑 1:请注意,我不需要代码来填充函数 (getAPCAColorContrast
)。我所需要的只是一个不仅兼容 RGB 还兼容 RGBA 的 APCA 算法。一旦我知道并理解了用于 RGBA 前景色和背景色的修改后的 APCA 算法,我就可以自己编写代码。 (此免责声明已写在此处,以便问题不会因违反规则而被删除(如果有)。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)