A TypeScript library for accurate color blindness simulation using the Brettel-Viénot-Mollon algorithm.
This library provides scientifically accurate simulation of how colors appear to individuals with different types of color vision deficiency (color blindness). The implementation is based on the research by Hans Brettel, Françoise Viénot, and John D. Mollon published in the Journal of the Optical Society of America A (1997).
Reference: "Computerized simulation of color appearance for dichromats"
Authors: Hans Brettel, Françoise Viénot, and John D. Mollon
Journal: Journal of the Optical Society of America A, Vol. 14, No. 10, pp. 2647-2655 (October 1997)
DOI: 10.1364/JOSAA.14.002647
The algorithm uses confusion lines in the CIE chromaticity diagram to accurately simulate color perception for different types of dichromacy and anomalous trichromacy.
npm install @cantoo/color-blindnessimport { protanopia, deuteranopia, simulate, ColorBlindnessType } from '@cantoo/color-blindness';
// Direct functions return hex colors
const protanopiaColor = protanopia('#FF0000');
console.log(protanopiaColor); // '#9C9C00'
// Works with different input formats
const deuteranopia1 = deuteranopia('#FF0000'); // Hex string
const deuteranopia2 = deuteranopia([255, 0, 0]); // RGB array
const deuteranopia3 = deuteranopia({ R: 255, G: 0, B: 0 }); // RGB object
// Use simulate() for custom options
const customResult = simulate('#FF0000', {
type: ColorBlindnessType.Deuteranomaly,
anomalize: true
});
console.log(customResult); // '#CB7B00'| Type | Description | Method |
|---|---|---|
| Protanopia | Complete absence of red photoreceptors | protanopia() |
| Protanomaly | Reduced sensitivity to red | protanomaly() |
| Deuteranopia | Complete absence of green photoreceptors | deuteranopia() |
| Deuteranomaly | Reduced sensitivity to green | deuteranomaly() |
| Tritanopia | Complete absence of blue photoreceptors | tritanopia() |
| Tritanomaly | Reduced sensitivity to blue | tritanomaly() |
| Achromatopsia | Complete color blindness (monochromacy) | achromatopsia() |
| Achromatomaly | Reduced color sensitivity | achromatomaly() |
import { protanopia, deuteranopia, tritanopia } from '@cantoo/color-blindness';
// Direct functions return hex colors - perfect for most use cases
const protanopiaColor = protanopia('#FF6B35'); // '#A86B00'
const deuteranopiaColor = deuteranopia('#FF6B35'); // '#C4B835'
const tritanopiaColor = tritanopia('#FF6B35'); // '#FF6B56'
// Works with all input formats
const fromHex = protanopia('#FF6B35');
const fromRGB = protanopia({ R: 255, G: 107, B: 53 });
const fromArray = protanopia([255, 107, 53]);import { simulate, ColorBlindnessType } from '@cantoo/color-blindness';
// Use simulate() for custom configurations
const customResult = simulate('#FF6B35', {
type: ColorBlindnessType.Protanomaly,
anomalize: true,
colorProfile: 'sRGB',
gammaCorrection: 2.2
});
console.log(customResult); // '#D4823A'import { protanopia, simulate, ColorBlindnessType } from '@cantoo/color-blindness';
const colors = ['#FF0000', '#00FF00', '#0000FF', '#FFFF00'];
// Simple batch processing
const protanopiaColors = colors.map(color => protanopia(color));
console.log(protanopiaColors); // ['#9C9C00', '#9C9C00', '#0000FF', '#9C9C00']
// Multiple types batch processing
const colorBlindnessTypes = [
ColorBlindnessType.Protanopia,
ColorBlindnessType.Deuteranopia,
ColorBlindnessType.Tritanopia
];
const results = colors.map(color =>
colorBlindnessTypes.map(type =>
simulate(color, { type })
)
);protanopia(input: ColorInput): stringprotanomaly(input: ColorInput): stringdeuteranopia(input: ColorInput): stringdeuteranomaly(input: ColorInput): stringtritanopia(input: ColorInput): stringtritanomaly(input: ColorInput): stringachromatopsia(input: ColorInput): stringachromatomaly(input: ColorInput): string
simulate(input: ColorInput, options: SimulationOptions): string
type ColorInput = string | RGBColor | [number, number, number];interface RGBColor {
R: number; // 0-255
G: number; // 0-255
B: number; // 0-255
}interface SimulationOptions {
type: ColorBlindnessType;
anomalize?: boolean; // Default: false
colorProfile?: 'sRGB' | 'generic'; // Default: 'sRGB'
gammaCorrection?: number; // Default: 2.2
}The library performs precise color space conversions:
- RGB → XYZ with gamma correction
- XYZ → xyY chromaticity coordinates
- Confusion line calculation using the Brettel-Viénot-Mollon algorithm
- Gamut mapping to ensure valid RGB output
- XYZ → RGB with inverse gamma correction
- sRGB Profile: Uses the standard sRGB gamma correction curve
- Generic Profile: Uses simple power law gamma correction (γ = 2.2 by default)
The algorithm ensures that simulated colors remain within the displayable RGB gamut by:
- Converting simulated colors to linear RGB
- Calculating the direction toward neutral gray (D65 white point)
- Applying proportional adjustment to bring out-of-gamut colors back into range
git clone <repository-url>
cd color-blindness
npm installnpm run build- Compile TypeScript to JavaScriptnpm run lint- Check code with ESLintnpm run lint:fix- Auto-fix ESLint errorsnpm test- Run Jest test suitenpm run release- Create a new release with release-it
Before each publication, the project automatically:
- ✅ Runs ESLint (code quality)
- ✅ Compiles TypeScript (build verification)
- ✅ Generates type definitions
To publish a new version:
npm run releaseThis will automatically:
- Run linting and build
- Increment version number
- Create git tag
- Publish to npm
- Create GitHub release
The library works in all modern browsers and Node.js environments that support:
- ES2020 features
- TypeScript (for development)
The simulation algorithms are optimized for real-time use:
- ⚡ Fast matrix operations
- 🎯 Efficient color space conversions
- 📐 Minimal computational overhead
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Hans Brettel, Françoise Viénot, and John D. Mollon for their groundbreaking research on color vision simulation
- The color science community for continued research in accessible color design
- All contributors to this open-source project
- Coblis - Online color blindness simulator
- Colorbrewer - Color schemes for maps and charts
- Accessible Colors - Color accessibility tools
Made with ❤️ for accessible design