xref: /webtrees/app/ColorGenerator.php (revision 873953697c930fadbf3243d2b8c0029fd684da0e)
1<?php
2/**
3 * webtrees: online genealogy
4 * Copyright (C) 2018 webtrees development team
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16namespace Fisharebest\Webtrees;
17
18/**
19 * Generate a range of colurs for the lifespan chart.
20 */
21class ColorGenerator
22{
23    /** @var int Current hue */
24    private $hue;
25
26    /** @var int Initial hue */
27    private $basehue;
28
29    /** @var int Saturation */
30    private $saturation;
31
32    /** @var int Lightness */
33    private $lightness;
34
35    /** @var int Initial lightness */
36    private $baselightness;
37
38    /** @var int Alpha transparancy */
39    private $alpha;
40
41    /** @var int Clockwise or anticlockwise color wheel */
42    private $range;
43
44    /**
45     * Create a color generator.
46     *
47     * @param int $hue   (0Deg = Red, 120Deg = green, 240Deg = blue)
48     * @param int $saturation
49     * @param int $lightness
50     * @param int $alpha
51     * @param int $range (sign determines direction. positive = clockwise, negative = anticlockwise)
52     */
53    public function __construct($hue, $saturation, $lightness, $alpha, $range)
54    {
55        $this->hue           = $hue;
56        $this->basehue       = $hue;
57        $this->saturation    = $saturation;
58        $this->lightness     = $lightness;
59        $this->baselightness = $lightness;
60        $this->alpha         = $alpha;
61        $this->range         = $range;
62    }
63
64    /**
65     * Function getNextColor
66     *
67     * $lightness cycles between $baselightness and 100% in $lightnessStep steps
68     * $hue cycles on each complete $lightness cycle
69     * between $basehue and $basehue + $range degrees in $hueStep degrees
70     *
71     * @param int $lightnessStep
72     * @param int $hueStep
73     *
74     * @return string
75     */
76    public function getNextColor($lightnessStep = 10, $hueStep = 15): string
77    {
78        $lightness = $this->lightness + $lightnessStep;
79        $hue       = $this->hue;
80
81        if ($lightness >= 100) {
82            $lightness = $this->baselightness;
83            if ($this->range > 0) {
84                $hue += $hueStep;
85            } else {
86                $hue -= $hueStep;
87            }
88            if (($hue - $this->basehue) * ($hue - ($this->basehue + $this->range)) >= 0) {
89                $hue = $this->basehue;
90            }
91            $this->hue = $hue;
92        }
93        $this->lightness = $lightness;
94
95        return sprintf('hsla(%s, %s%%, %s%%, %s)', $this->hue, $this->saturation, $this->lightness, $this->alpha);
96    }
97}
98