| 261 | } |
| 262 | |
| 263 | function parseCssColorChannels(colorText) { |
| 264 | const text = String(colorText || '').trim().toLowerCase(); |
| 265 | if (!text || text === 'transparent' || text === 'inherit' || text === 'initial' || text === 'unset') { |
| 266 | return null; |
| 267 | } |
| 268 | |
| 269 | if (text.startsWith('#')) { |
| 270 | const hex = text.slice(1); |
| 271 | if (hex.length === 3 || hex.length === 4) { |
| 272 | const expanded = hex.split('').map((part) => part + part); |
| 273 | const [r, g, b, a = 'ff'] = expanded; |
| 274 | return { |
| 275 | r: Number.parseInt(r, 16), |
| 276 | g: Number.parseInt(g, 16), |
| 277 | b: Number.parseInt(b, 16), |
| 278 | a: Number.parseInt(a, 16) / 255, |
| 279 | }; |
| 280 | } |
| 281 | if (hex.length === 6 || hex.length === 8) { |
| 282 | const parts = hex.match(/.{1,2}/g) || []; |
| 283 | const [r, g, b, a = 'ff'] = parts; |
| 284 | return { |
| 285 | r: Number.parseInt(r, 16), |
| 286 | g: Number.parseInt(g, 16), |
| 287 | b: Number.parseInt(b, 16), |
| 288 | a: Number.parseInt(a, 16) / 255, |
| 289 | }; |
| 290 | } |
| 291 | } |
| 292 | |
| 293 | if (text.startsWith('rgb')) { |
| 294 | const numericParts = text.match(/[\d.]+/g) || []; |
| 295 | if (numericParts.length >= 3) { |
| 296 | const [r, g, b, a = '1'] = numericParts.map(Number); |
| 297 | return { r, g, b, a }; |
| 298 | } |
| 299 | } |
| 300 | |
| 301 | return null; |
| 302 | } |
| 303 | |
| 304 | function isReddishColor(colorText) { |
| 305 | const channels = parseCssColorChannels(colorText); |