Skip to content

Instantly share code, notes, and snippets.

@Lokno
Last active July 30, 2023 01:02
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Lokno/df7c3bfdc9ad32558bb7 to your computer and use it in GitHub Desktop.
Save Lokno/df7c3bfdc9ad32558bb7 to your computer and use it in GitHub Desktop.
Color Blindness Matrices
// JSON of 3x3 matrices which transform RGB colors into colorspace which
// simulate the imparement of various color blindness deficiency.
//
// Used by Coblis: http://www.color-blindness.com/Coblis-color-blindness-simulator/
//
// The original website posting the matrices has been taken down:
// http://www.colorjack.com/labs/colormatrix/
//
// RGB transform matrices generated by Michael of www.colorjack.com
// Which were created using code by Matthew Wickline and the
// Human-Computer Interaction Resource Network ( http://hcirn.com/ )
//
// The original matrices were 5x5, for full homogeneous coordinates of RGBA
// They have been similified here to 3x3 matrices, because the additional
// dimensions were simple identity.
//
// These are very inaccurate so consider other methods. See comments on this gist.
var colorMats = {'Normal':[1,0,0,
0,1,0,
0,0,1],
// Red-Blind
'Protanopia': [0.567,0.433,0.000,
0.558,0.442,0.000,
0.000,0.242,0.758],
// Red-Weak
'Protanomaly': [0.817,0.183,0.000,
0.333,0.667,0.000,
0.000,0.125,0.875],
// Green-Blind
'Deuteranopia': [0.625,0.375,0.000,
0.700,0.300,0.000,
0.000,0.300,0.700],
// Green-Weak
'Deuteranomaly':[0.800,0.200,0.000,
0.258,0.742,0.000,
0.000,0.142,0.858],
// Blue-Blind
'Tritanopia': [0.950,0.050,0.000,
0.000,0.433,0.567,
0.000,0.475,0.525],
// Blue-Weak
'Tritanomaly': [0.967,0.033,0.00,
0.00,0.733,0.267,
0.00,0.183,0.817],
// Monochromacy
'Achromatopsia':[0.299,0.587,0.114,
0.299,0.587,0.114,
0.299,0.587,0.114],
// Blue Cone Monochromacy
'Achromatomaly':[0.618,0.320,0.062,
0.163,0.775,0.062,
0.163,0.320,0.516]};
@mikionakajima
Copy link

Thank you for providing these matrices. It makes me possible to create a html-js for selecting a color blind friendly color set. A power point file should be color blind friendly, yes absolutely. But, we have other problems.

  1. If we know that there are only normal and D-type, shall we consider about T-type?
  2. We have pre-selected color sets those are provided by several professors. Even though a student wants to change, he/she can not. They don't have enough knowledge.

I write a html-js for my studens.

<!DOCTYPE html>
<html lang="jp">
<head>
  <meta charset="utf-8">
  <style>
.content {
  max-width: 1500px;
  padding: 10px;
}
tr {height: 50px;}
td {width:  10%; border: 1px solid black;}
</style>
</head>
<body>
<div class="content">
  <table id="aTable">
    <thead id="aThead"></thead>
    <tbody id="aTbody"></tbody> 
  </table>
I removed all the Japanese sentences. It just explains how to use and something so on. You can see the Japanese version <a href="https://docs.0machi.com/CBF.html">here</a>. I included the link to this page in the HTML.
<script>
const CBOrder = ['Normal','Deuteranopia','Protanopia','Normal','Deuteranomaly','Protanomaly','Tritanopia','Tritanomaly','Achromatopsia','Achromatomaly'];
const InitialColor = ['#FF0000','#FFFF00','#0000FF','#FF0080','#00FF00'];

function CBColor(col, CB)
{
  let colorMats = 
{
// Normal
'Normal':
  [1,0,0,
  0,1,0,
  0,0,1],
// Green-Blind
'Deuteranopia': 
  [0.625,0.375,0.000,
  0.700,0.300,0.000,
  0.000,0.300,0.700],
// Red-Blind
'Protanopia':   
  [0.567,0.433,0.000,
  0.558,0.442,0.000,
  0.000,0.242,0.758],
// Green-Weak
'Deuteranomaly':
  [0.800,0.200,0.000,
  0.258,0.742,0.000,
  0.000,0.142,0.858],
// Red-Weak
'Protanomaly':  
  [0.817,0.183,0.000,
  0.333,0.667,0.000,
  0.000,0.125,0.875],
// Blue-Blind
'Tritanopia':   
  [0.950,0.050,0.000,
  0.000,0.433,0.567,
  0.000,0.475,0.525],
// Blue-Weak
'Tritanomaly':  
  [0.967,0.033,0.00,
  0.00,0.733,0.267,
  0.00,0.183,0.817],
// Monochromacy
'Achromatopsia':
  [0.299,0.587,0.114,
  0.299,0.587,0.114,
  0.299,0.587,0.114],
// Blue Cone Monochromacy
'Achromatomaly':
  [0.618,0.320,0.062,
  0.163,0.775,0.062,
  0.163,0.320,0.516]
};
  let r, g, b, r2, g2, b2;
  let mat = colorMats[CB];
  r = parseInt(col.substring(1,3), 16); 
  g = parseInt(col.substring(3,5), 16); 
  b = parseInt(col.substring(5,7), 16);
  r2 = Math.round(mat[0]*r+mat[1]*g+mat[2]*b);
  g2 = Math.round(mat[3]*r+mat[4]*g+mat[5]*b);
  b2 = Math.round(mat[6]*r+mat[7]*g+mat[8]*b);
  return(`#`+r2.toString(16).padStart(2, '0')+g2.toString(16).padStart(2, '0')+b.toString(16).padStart(2, '0'));
}
function paint1Line(line, col)
{
  let cells = line.cells;
  for (let i=1;i<cells.length;i++)
  {
      cells[i].style.backgroundColor=CBColor(col, CBOrder[i-1]);
  }
}
let thead = document.getElementById('aThead');
let tr = document.createElement('tr');
let td = document.createElement('td');
tr.appendChild(td);
for (const element of CBOrder) {
  let td = document.createElement('td');
  td.innerText = element;
  tr.appendChild(td);
}
thead.appendChild(tr);

let tbody = document.getElementById('aTbody');
for (const aColor of InitialColor) {
  let tr = document.createElement('tr');
  let td = document.createElement('td');
  let input = document.createElement('input');
  input.setAttribute("type", "color");
  td.appendChild(input);
  tr.appendChild(td);
  input.addEventListener("input", onColorBoxClick); 
  for (let j = 0; j < CBOrder.length; j++) {
    let td = document.createElement('td');
    tr.appendChild(td);
  }
  tbody.appendChild(tr);
  input.value = aColor;
  paint1Line(tr, aColor);
}

  function onColorBoxClick(){
  paint1Line(event.target.parentElement.parentElement, event.target.value)
}
</script>
</div>
</body>
</html>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment