A fruit market, a metro map and test plates as dichromats see them.
Each generated scene is decoded to linear sRGB and taken into LMS cone space. A dichromat lacks one cone type, so Brettel's method projects every color along that missing axis onto two half-planes through white, anchored on monochromatic lights computed from CIE color matching functions (Vienot's single-plane variant is one click away), and achromatopsia keeps only luminance. The chain collapses to two 3x3 matrices and a sign test per pixel, and a severity slider blends toward the projection. The plate generator runs the math backwards: dart-thrown dots are colored by shifting the ground's colors along a single cone axis, so each plate's big digit vanishes for exactly one kind of dichromat.
Try it. Drag the lens around (or anywhere on the scene). Pick a scene with the top chips or the left and right arrow keys, and a type of vision with the bottom chips or keys 1 to 5. Drag the severity slider (or use up and down), switch between the lens and a full view with L, toggle Brettel and Vienot with V, and press N or Space for new plates.
Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.
Build a color vision deficiency simulator with JavaScript and the HTML canvas element: a colorful scene with a draggable lens that shows how people with protanopia, deuteranopia or tritanopia see it. Put everything in a single index.html file with no libraries or build step, so I can open it directly in a browser.
Start simple:
- Make a canvas that fills the window and draw a colorful scene into an offscreen canvas: a grid of fruit crates (red apples, green apples, oranges, limes, strawberries, blueberries) made of shaded circles.
- Read its pixels with getImageData. For each pixel, decode sRGB to linear light, convert to LMS cone space (sRGB to XYZ, then the Hunt-Pointer-Estevez matrix, normalized so white has equal L, M and S), and simulate a dichromat with the Vienot method: replace the missing cone's response with a combination of the other two chosen so that white and the sRGB blue primary are unchanged. Convert back and gamma encode into a second canvas.
- Precompute the whole chain as one 3x3 matrix in linear RGB for each deficiency, and use lookup tables for the sRGB curves so it runs fast.
- Draw the original scene, then the simulated one clipped to a circle that follows the pointer.
Once that works, make it beautiful:
- Add buttons for typical vision, protanopia, deuteranopia, tritanopia and achromatopsia, and a severity slider that blends between the original and the simulation in linear light.
- Give the lens a dark rim, a glassy highlight and a label.
- Add a second scene, such as a metro map with eight colored lines.
Explain the color science in short code comments. When you're done, tell me how to open it and suggest three directions I could take it next, such as Brettel's two half-plane method (better for tritanopia), Ishihara-style plates whose numbers vanish for one kind of dichromat, or comparing a rainbow colormap with viridis.