Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(492)

Side by Side Diff: ui/accessibility/extensions/colorenhancer/src/cvd.js

Issue 984833004: Add color enhancer as a chromium accessibility extensions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: More docs. Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5
6 // ======= Global state =======
7
8 var storedDelta = 0;
9 var storedSeverity = 0;
10 var storedType = 'PROTANOMALY';
11 var storedSimulate = false;
12 var curFilter = 0;
13
14
15 // ======= 3x3 matrix ops =======
16
17 var identityMatrix3x3 = [
18 [1, 0, 0],
19 [0, 1, 0],
20 [0, 0, 1]
21 ];
22
23
24 /**
25 * TODO(mustaq): JsDoc
26 */
27 function add3x3(m1, m2) {
28 var result = [];
29 for (var i = 0; i < 3; i++) {
30 result[i] = [];
31 for (var j = 0; j < 3; j++) {
32 result[i].push(m1[i][j] + m2[i][j]);
33 }
34 }
35 return result;
36 }
37
38
39 /**
40 * TODO(mustaq): JsDoc
41 */
42 function sub3x3(m1, m2) {
43 var result = [];
44 for (var i = 0; i < 3; i++) {
45 result[i] = [];
46 for (var j = 0; j < 3; j++) {
47 result[i].push(m1[i][j] - m2[i][j]);
48 }
49 }
50 return result;
51 }
52
53
54 /**
55 * TODO(mustaq): JsDoc
56 */
57 function mul3x3(m1, m2) {
58 var result = [];
59 for (var i = 0; i < 3; i++) {
60 result[i] = [];
61 for (var j = 0; j < 3; j++) {
62 var sum = 0;
63 for (var k = 0; k < 3; k++) {
64 sum += m1[i][k] * m2[k][j];
65 }
66 result[i].push(sum);
67 }
68 }
69 return result;
70 }
71
72
73 /**
74 * TODO(mustaq): JsDoc
75 */
76 function mul3x3Scalar(m, k) {
77 var result = [];
78 for (var i = 0; i < 3; i++) {
79 result[i] = [];
80 for (var j = 0; j < 3; j++) {
81 result[i].push(k * m[i][j]);
82 }
83 }
84 return result;
85 }
86
87
88 // ======= CVD parameters =======
89 /**
90 * Parameters for simulating color vision deficiency.
91 * Source:
92 * http://www.inf.ufrgs.br/~oliveira/pubs_files/CVD_Simulation/CVD_Simulatio n.html
93 * Original Research Paper:
94 * http://www.inf.ufrgs.br/~oliveira/pubs_files/CVD_Simulation/Machado_Olive ira_Fernandes_CVD_Vis2009_final.pdf
95 *
96 * @enum {string}
97 */
98 var cvdSimulationParams = {
99 PROTANOMALY: [
100 [0.4720, -1.2946, 0.9857],
101 [-0.6128, 1.6326, 0.0187],
102 [0.1407, -0.3380, -0.0044],
103 [-0.1420, 0.2488, 0.0044],
104 [0.1872, -0.3908, 0.9942],
105 [-0.0451, 0.1420, 0.0013],
106 [0.0222, -0.0253, -0.0004],
107 [-0.0290, -0.0201, 0.0006],
108 [0.0068, 0.0454, 0.9990]
109 ],
110 DEUTERANOMALY: [
111 [0.5442, -1.1454, 0.9818],
112 [-0.7091, 1.5287, 0.0238],
113 [0.1650, -0.3833, -0.0055],
114 [-0.1664, 0.4368, 0.0056],
115 [0.2178, -0.5327, 0.9927],
116 [-0.0514, 0.0958, 0.0017],
117 [0.0180, -0.0288, -0.0006],
118 [-0.0232, -0.0649, 0.0007],
119 [0.0052, 0.0360, 0.9998]
120 ],
121 TRITANOMALY: [
122 [0.4275, -0.0181, 0.9307],
123 [-0.2454, 0.0013, 0.0827],
124 [-0.1821, 0.0168, -0.0134],
125 [-0.1280, 0.0047, 0.0202],
126 [0.0233, -0.0398, 0.9728],
127 [0.1048, 0.0352, 0.0070],
128 [-0.0156, 0.0061, 0.0071],
129 [0.3841, 0.2947, 0.0151],
130 [-0.3685, -0.3008, 0.9778]
131 ]
132 };
133
134
135 // TODO(mustaq): A common matrix for all types? E.g. Kevin's experiment
136 // suggested: Mx[1][0] = 0.7+0.3*delta and Mx[2][0] = 0.7-0.3*delta
137 /**
138 * TODO(mustaq): JsDoc
139 *
140 * @enum {string}
141 */
142 var cvdCorrectionParams = {
143 PROTANOMALY: {
144 addendum: [
145 [-1.0, 0.0, 0.0],
146 [0.5, 1.0, 0.0],
147 [1.5, 0.0, 1.0]
148 ],
149 delta_factor: [
150 [0.0, 0.0, 0.0],
151 [1.0, 0.0, 0.0],
152 [-1.0, 0.0, 0.0]
153 ]
154 },
155 DEUTERANOMALY: {
156 addendum: [
157 [1.0, 0.5, 0.0],
158 [0.5, -1.0, 0.0],
159 [1.5, 1.5, 1.0]
160 ],
161 delta_factor: [
162 [0.0, 1.0, 0.0],
163 [0.0, 0.0, 0.0],
164 [0.0, -1.0, 0.0]
165 ]
166 },
167 TRITANOMALY: {
168 addendum: [
169 [1.0, 0.0, 1.5],
170 [0.0, 1.0, 0.5],
171 [0.0, 0.0, -1.0]
172 ],
173 delta_factor: [
174 [0.0, 0.0, -1.0],
175 [0.0, 0.0, 1.0],
176 [0.0, 0.0, 0.0]
177 ]
178 }
179 };
180
181
182 // ======= CVD matrix builders =======
183
184 /**
185 * TODO(mustaq): JsDoc
186 */
187 function getCvdSimulationMatrix(cvdType, severity) {
188 var cvdSimulationParam = cvdSimulationParams[cvdType];
189 var severity2 = severity * severity;
190 var matrix = [];
191 for (var i = 0; i < 3; i++) {
192 var row = [];
193 for (var j = 0; j < 3; j++) {
194 var paramRow = i*3+j;
195 var val = cvdSimulationParam[paramRow][0] * severity2
196 + cvdSimulationParam[paramRow][1] * severity
197 + cvdSimulationParam[paramRow][2];
198 row.push(val);
199 }
200 matrix.push(row);
201 }
202 return matrix;
203 }
204
205
206 /**
207 * TODO(mustaq): JsDoc
208 */
209 function getCvdCorrectionMatrix(cvdType, delta) {
210 cvdCorrectionParam = cvdCorrectionParams[cvdType];
211 // TODO(mustaq): Perhaps nuke full-matrix operations after experiment.
212 return add3x3(cvdCorrectionParam['addendum'],
213 mul3x3Scalar(cvdCorrectionParam['delta_factor'], delta));
214 }
215
216
217 /**
218 * TODO(mustaq): JsDoc
219 */
220 function getCvdMatrixAsString(cvdType, severity, delta, simulate) {
221 var effectiveMatrix = getCvdSimulationMatrix(cvdType, severity);
222
223 if (!simulate) {
224 var cvdCorrectionMatrix = getCvdCorrectionMatrix(cvdType, delta);
225 var tmpProduct = mul3x3(cvdCorrectionMatrix, effectiveMatrix);
226
227 effectiveMatrix = sub3x3(
228 add3x3(identityMatrix3x3, cvdCorrectionMatrix),
229 tmpProduct);
230 }
231
232 var outputRows = [];
233 for (var i = 0; i < 3; i++) {
234 outputRows.push(effectiveMatrix[i].join(' ') + ' 0 0');
235 }
236 // Add the alpha row
237 outputRows.push('0 0 0 1 0');
238 return outputRows.join(' ');
239 }
240
241
242 // ======= Page linker =======
243
244 var svgDefaultMatrix =
245 '1 0 0 0 0 ' +
246 '0 1 0 0 0 ' +
247 '0 0 1 0 0 ' +
248 '0 0 0 1 0';
249
250 var svgContent =
251 '<svg xmlns='http://www.w3.org/2000/svg' version='1.1'>' +
252 ' <defs>' +
253 ' <filter id='cvd_extension_0'>' +
254 ' <feColorMatrix id='cvd_filter_matrix_0' type='matrix' values='' +
255 svgDefaultMatrix + ''/>' +
256 ' </filter>' +
257 ' <filter id='cvd_extension_1'>' +
258 ' <feColorMatrix id='cvd_filter_matrix_1' type='matrix' values='' +
259 svgDefaultMatrix + ''/>' +
260 ' </filter>' +
261 ' </defs>' +
262 '</svg>';
263
264 /**
265 * Checks for svg filter matrix presence and append to DOM if not present.
266 */
267 function addSvgIfMissing() {
268 var wrap = document.getElementById('cvd_extension_svg_filter');
269 if (!wrap) {
270 wrap = document.createElement('span');
271 wrap.id = 'cvd_extension_svg_filter';
272 wrap.setAttribute('hidden', '');
273 wrap.innerHTML = svgContent;
274 document.body.appendChild(wrap);
275 }
276 }
277
278
279 /**
280 * Update matrix when config values change.
281 */
282 function update() {
283 if (!document.body) {
284 document.addEventListener('DOMContentLoaded', update);
285 return;
286 }
287 addSvgIfMissing();
288 var next = 1 - curFilter;
289
290 debugPrint(
291 'Setting matrix#' + next + ' to ' +
292 getCvdMatrixAsString(
293 storedType, storedSeverity, storedDelta, storedSimulate));
294
295 var matrix = document.getElementById('cvd_filter_matrix_' + next);
296 matrix.setAttribute(
297 'values', getCvdMatrixAsString(
298 storedType, storedSeverity, storedDelta, storedSimulate));
299
300 var html = document.documentElement;
301 html.classList.remove('filter' + curFilter);
302 html.offsetTop;
303 html.classList.add('filter' + next);
304
305 curFilter = next;
306
307 // TODO(wnwen): Figure out whether this hack is still necessary.
308 window.scrollBy(0, 1);
309 window.scrollBy(0, -1);
310 }
311
312
313 /**
314 * Process request from background page.
315 */
316 function onExtensionMessage(request) {
317 var changed = false;
318
319 if (request['delta'] !== undefined) {
320 var delta = request.delta;
321 if (storedDelta != delta) {
322 storedDelta = delta;
323 changed = true;
324 }
325 }
326
327 if (request['severity'] !== undefined) {
328 var severity = request.severity;
329 if (storedSeverity != severity) {
330 storedSeverity = severity;
331 changed = true;
332 }
333 }
334
335 if (request['type'] !== undefined) {
336 var type = request.type;
337 if (storedType != type) {
338 storedType = type;
339 changed = true;
340 }
341 }
342
343 if (request['simulate'] !== undefined) {
344 var simulate = request.simulate;
345 if (storedSimulate != simulate) {
346 storedSimulate = simulate;
347 changed = true;
348 }
349 }
350
351 if (changed)
352 update();
353 }
354
355
356 /**
357 * Prepare to process background messages and let it know to send initial
358 * values.
359 */
360 (function initialize() {
361 chrome.extension.onRequest.addListener(onExtensionMessage);
362 chrome.extension.sendRequest({'init': true}, onExtensionMessage);
363 })();
OLDNEW
« no previous file with comments | « ui/accessibility/extensions/colorenhancer/src/common.js ('k') | ui/accessibility/extensions/colorenhancer/src/popup.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698