|
| 1 | +document.addEventListener("DOMContentLoaded", function () { |
| 2 | + const colorPicker = document.getElementById("colorPicker"); |
| 3 | + const protanopia = document.getElementById("protanopia"); |
| 4 | + const deuteranopia = document.getElementById("deuteranopia"); |
| 5 | + const tritanopia = document.getElementById("tritanopia"); |
| 6 | + |
| 7 | + colorPicker.addEventListener("input", updateSimulatedColors); |
| 8 | + |
| 9 | + function updateSimulatedColors() { |
| 10 | + const originalColor = colorPicker.value; |
| 11 | + const simulatedProtanopia = simulateColorBlindness( |
| 12 | + originalColor, |
| 13 | + "protanopia" |
| 14 | + ); |
| 15 | + const simulatedDeuteranopia = simulateColorBlindness( |
| 16 | + originalColor, |
| 17 | + "deuteranopia" |
| 18 | + ); |
| 19 | + const simulatedTritanopia = simulateColorBlindness( |
| 20 | + originalColor, |
| 21 | + "tritanopia" |
| 22 | + ); |
| 23 | + |
| 24 | + setSimulatedColor(protanopia, simulatedProtanopia); |
| 25 | + setSimulatedColor(deuteranopia, simulatedDeuteranopia); |
| 26 | + setSimulatedColor(tritanopia, simulatedTritanopia); |
| 27 | + } |
| 28 | + |
| 29 | + function setSimulatedColor(element, color) { |
| 30 | + element.style.backgroundColor = color; |
| 31 | + element.textContent = `Simulated Color: ${color}`; |
| 32 | + } |
| 33 | + |
| 34 | + function simulateColorBlindness(originalColor, type) { |
| 35 | + const color = parseHexColor(originalColor); |
| 36 | + |
| 37 | + switch (type) { |
| 38 | + case "protanopia": |
| 39 | + return rgbToHex(simulateProtanopia(color.r, color.g, color.b)); |
| 40 | + case "deuteranopia": |
| 41 | + return rgbToHex( |
| 42 | + simulateDeuteranopia(color.r, color.g, color.b) |
| 43 | + ); |
| 44 | + case "tritanopia": |
| 45 | + return rgbToHex(simulateTritanopia(color.r, color.g, color.b)); |
| 46 | + default: |
| 47 | + return originalColor; |
| 48 | + } |
| 49 | + } |
| 50 | + |
| 51 | + function parseHexColor(hex) { |
| 52 | + const bigint = parseInt(hex.substring(1), 16); |
| 53 | + const r = (bigint >> 16) & 255; |
| 54 | + const g = (bigint >> 8) & 255; |
| 55 | + const b = bigint & 255; |
| 56 | + |
| 57 | + return { r, g, b }; |
| 58 | + } |
| 59 | + |
| 60 | + function simulateProtanopia(r, g, b) { |
| 61 | + const luminance = 0.299 * r + 0.587 * g + 0.114 * b; |
| 62 | + const newR = 0; |
| 63 | + const newG = 0.9922 * g + 0.0078 * b; |
| 64 | + const newB = 0.9922 * b; |
| 65 | + |
| 66 | + return blendColors(luminance, newR, newG, newB); |
| 67 | + } |
| 68 | + |
| 69 | + function simulateDeuteranopia(r, g, b) { |
| 70 | + const luminance = 0.299 * r + 0.587 * g + 0.114 * b; |
| 71 | + const newR = 0.625 * r + 0.375 * b; |
| 72 | + const newG = 0.7 * g + 0.3 * b; |
| 73 | + const newB = 0; |
| 74 | + |
| 75 | + return blendColors(luminance, newR, newG, newB); |
| 76 | + } |
| 77 | + |
| 78 | + function simulateTritanopia(r, g, b) { |
| 79 | + const luminance = 0.299 * r + 0.587 * g + 0.114 * b; |
| 80 | + const newR = 0.9672 * r; |
| 81 | + const newG = 0.048 * r + 0.953 * g; |
| 82 | + const newB = 0.953 * b; |
| 83 | + |
| 84 | + return blendColors(luminance, newR, newG, newB); |
| 85 | + } |
| 86 | + |
| 87 | + function blendColors(luminance, newR, newG, newB) { |
| 88 | + const blendFactor = 0.7; // Adjust this value for blending intensity |
| 89 | + const resultR = Math.round( |
| 90 | + blendFactor * newR + (1 - blendFactor) * luminance |
| 91 | + ); |
| 92 | + const resultG = Math.round( |
| 93 | + blendFactor * newG + (1 - blendFactor) * luminance |
| 94 | + ); |
| 95 | + const resultB = Math.round( |
| 96 | + blendFactor * newB + (1 - blendFactor) * luminance |
| 97 | + ); |
| 98 | + |
| 99 | + return `rgb(${resultR}, ${resultG}, ${resultB})`; |
| 100 | + } |
| 101 | + |
| 102 | + function rgbToHex(r, g, b) { |
| 103 | + return `#${((1 << 24) | (r << 16) | (g << 8) | b) |
| 104 | + .toString(16) |
| 105 | + .slice(1)}`; |
| 106 | + } |
| 107 | +}); |
0 commit comments