|
538 | 538 |
|
539 | 539 | /// Palette generation for charts |
540 | 540 | function generatePalette(numColors) { |
| 541 | + // oklch() does not work in firefox<=125 inside <canvas> element so we convert it back to rgb for now. |
| 542 | + // Based on https://github.com/color-js/color.js/blob/main/src/spaces/oklch.js |
| 543 | + const multiplyMatrices = (A, B) => { |
| 544 | + return [ |
| 545 | + A[0]*B[0] + A[1]*B[1] + A[2]*B[2], |
| 546 | + A[3]*B[0] + A[4]*B[1] + A[5]*B[2], |
| 547 | + A[6]*B[0] + A[7]*B[1] + A[8]*B[2] |
| 548 | + ]; |
| 549 | + } |
| 550 | + |
| 551 | + const oklch2oklab = ([l, c, h]) => [ |
| 552 | + l, |
| 553 | + isNaN(h) ? 0 : c * Math.cos(h * Math.PI / 180), |
| 554 | + isNaN(h) ? 0 : c * Math.sin(h * Math.PI / 180) |
| 555 | + ] |
| 556 | + |
| 557 | + const srgbLinear2rgb = rgb => rgb.map(c => |
| 558 | + Math.abs(c) > 0.0031308 ? |
| 559 | + (c < 0 ? -1 : 1) * (1.055 * (Math.abs(c) ** (1 / 2.4)) - 0.055) : |
| 560 | + 12.92 * c |
| 561 | + ) |
| 562 | + |
| 563 | + const oklab2xyz = lab => { |
| 564 | + const LMSg = multiplyMatrices([ |
| 565 | + 1, 0.3963377773761749, 0.2158037573099136, |
| 566 | + 1, -0.1055613458156586, -0.0638541728258133, |
| 567 | + 1, -0.0894841775298119, -1.2914855480194092, |
| 568 | + ], lab) |
| 569 | + const LMS = LMSg.map(val => val ** 3) |
| 570 | + return multiplyMatrices([ |
| 571 | + 1.2268798758459243, -0.5578149944602171, 0.2813910456659647, |
| 572 | + -0.0405757452148008, 1.1122868032803170, -0.0717110580655164, |
| 573 | + -0.0763729366746601, -0.4214933324022432, 1.5869240198367816 |
| 574 | + ], LMS) |
| 575 | + } |
| 576 | + |
| 577 | + const xyz2rgbLinear = xyz => { |
| 578 | + return multiplyMatrices([ |
| 579 | + 3.2409699419045226, -1.537383177570094, -0.4986107602930034, |
| 580 | + -0.9692436362808796, 1.8759675015077202, 0.04155505740717559, |
| 581 | + 0.05563007969699366, -0.20397695888897652, 1.0569715142428786 |
| 582 | + ], xyz) |
| 583 | + } |
| 584 | + |
| 585 | + const oklch2rgb = lch => srgbLinear2rgb(xyz2rgbLinear(oklab2xyz(oklch2oklab(lch)))) |
| 586 | + |
541 | 587 | palette = []; |
542 | 588 | for (let i = 0; i < numColors; i++) { |
543 | | - palette.push(`oklch(${theme != 'dark' ? 0.75 : 0.5}, 0.15, ${360 * i / numColors})`); |
| 589 | + //palette.push(`oklch(${theme != 'dark' ? 0.75 : 0.5}, 0.15, ${360 * i / numColors})`); |
| 590 | + let rgb = oklch2rgb([theme != 'dark' ? 0.75 : 0.5, 0.15, 360 * i / numColors]); |
| 591 | + palette.push(`rgb(${rgb[0] * 255}, ${rgb[1] * 255}, ${rgb[2] * 255})`); |
544 | 592 | } |
545 | 593 | return palette; |
546 | 594 | } |
|
0 commit comments