xref: /webtrees/app/Statistics/Service/ColorService.php (revision 449b311ecf65f677a2595e1e29f712d11ef22f34)
193ccd686SRico Sonntag<?php
23976b470SGreg Roach
393ccd686SRico Sonntag/**
493ccd686SRico Sonntag * webtrees: online genealogy
5d11be702SGreg Roach * Copyright (C) 2023 webtrees development team
693ccd686SRico Sonntag * This program is free software: you can redistribute it and/or modify
793ccd686SRico Sonntag * it under the terms of the GNU General Public License as published by
893ccd686SRico Sonntag * the Free Software Foundation, either version 3 of the License, or
993ccd686SRico Sonntag * (at your option) any later version.
1093ccd686SRico Sonntag * This program is distributed in the hope that it will be useful,
1193ccd686SRico Sonntag * but WITHOUT ANY WARRANTY; without even the implied warranty of
1293ccd686SRico Sonntag * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1393ccd686SRico Sonntag * GNU General Public License for more details.
1493ccd686SRico Sonntag * You should have received a copy of the GNU General Public License
1589f7189bSGreg Roach * along with this program. If not, see <https://www.gnu.org/licenses/>.
1693ccd686SRico Sonntag */
17fcfa147eSGreg Roach
1893ccd686SRico Sonntagdeclare(strict_types=1);
1993ccd686SRico Sonntag
2093ccd686SRico Sonntagnamespace Fisharebest\Webtrees\Statistics\Service;
2193ccd686SRico Sonntag
225d4b7ec2SGreg Roachuse function array_map;
235d4b7ec2SGreg Roachuse function hexdec;
245d4b7ec2SGreg Roachuse function ltrim;
255d4b7ec2SGreg Roachuse function round;
265d4b7ec2SGreg Roachuse function sprintf;
275d4b7ec2SGreg Roach
2893ccd686SRico Sonntag/**
2993ccd686SRico Sonntag * Functions for managing and manipulating colors.
3093ccd686SRico Sonntag */
3193ccd686SRico Sonntagclass ColorService
3293ccd686SRico Sonntag{
3393ccd686SRico Sonntag    /**
3493ccd686SRico Sonntag     * Interpolates the number of color steps between a given start and end color.
3593ccd686SRico Sonntag     *
3693ccd686SRico Sonntag     * @param string $startColor The start color
3793ccd686SRico Sonntag     * @param string $endColor   The end color
3893ccd686SRico Sonntag     * @param int    $steps      The number of steps to interpolate
3993ccd686SRico Sonntag     *
405d4b7ec2SGreg Roach     * @return array<string>
4193ccd686SRico Sonntag     */
4293ccd686SRico Sonntag    public function interpolateRgb(string $startColor, string $endColor, int $steps): array
4393ccd686SRico Sonntag    {
44ef475b14SGreg Roach        if ($steps === 0) {
4593ccd686SRico Sonntag            return [];
4693ccd686SRico Sonntag        }
4793ccd686SRico Sonntag
4893ccd686SRico Sonntag        $s       = $this->hexToRgb($startColor);
4993ccd686SRico Sonntag        $e       = $this->hexToRgb($endColor);
5093ccd686SRico Sonntag        $colors  = [];
5193ccd686SRico Sonntag        $factorR = ($e[0] - $s[0]) / $steps;
5293ccd686SRico Sonntag        $factorG = ($e[1] - $s[1]) / $steps;
5393ccd686SRico Sonntag        $factorB = ($e[2] - $s[2]) / $steps;
5493ccd686SRico Sonntag
5593ccd686SRico Sonntag        for ($x = 1; $x < $steps; ++$x) {
5693ccd686SRico Sonntag            $colors[] = $this->rgbToHex(
57f78da678SGreg Roach                (int) round($s[0] + $factorR * $x),
58f78da678SGreg Roach                (int) round($s[1] + $factorG * $x),
59f78da678SGreg Roach                (int) round($s[2] + $factorB * $x)
6093ccd686SRico Sonntag            );
6193ccd686SRico Sonntag        }
6293ccd686SRico Sonntag
6393ccd686SRico Sonntag        $colors[] = $this->rgbToHex($e[0], $e[1], $e[2]);
6493ccd686SRico Sonntag
6593ccd686SRico Sonntag        return $colors;
6693ccd686SRico Sonntag    }
6793ccd686SRico Sonntag
6893ccd686SRico Sonntag    /**
6993ccd686SRico Sonntag     * Converts the color values to the HTML hex representation.
7093ccd686SRico Sonntag     *
7193ccd686SRico Sonntag     * @param int $r The red color value
7293ccd686SRico Sonntag     * @param int $g The green color value
7393ccd686SRico Sonntag     * @param int $b The blue color value
7493ccd686SRico Sonntag     *
7593ccd686SRico Sonntag     * @return string
7693ccd686SRico Sonntag     */
7793ccd686SRico Sonntag    private function rgbToHex(int $r, int $g, int $b): string
7893ccd686SRico Sonntag    {
7993ccd686SRico Sonntag        return sprintf('#%02x%02x%02x', $r, $g, $b);
8093ccd686SRico Sonntag    }
8193ccd686SRico Sonntag
8293ccd686SRico Sonntag    /**
8393ccd686SRico Sonntag     * Converts the HTML color hex representation to an array of color values.
8493ccd686SRico Sonntag     *
8593ccd686SRico Sonntag     * @param string $hex The HTML hex color code
8693ccd686SRico Sonntag     *
875d4b7ec2SGreg Roach     * @return array<int>
8893ccd686SRico Sonntag     */
8993ccd686SRico Sonntag    private function hexToRgb(string $hex): array
9093ccd686SRico Sonntag    {
91*f25fc0f9SGreg Roach        return array_map(static fn (string $hex): int => (int) hexdec($hex), str_split(ltrim($hex, '#'), 2));
9293ccd686SRico Sonntag    }
9393ccd686SRico Sonntag}
94