Skip to content

Instantly share code, notes, and snippets.

@dantleech
Created March 18, 2021 11:07
Show Gist options
  • Save dantleech/7d7dbcf8d8ef29df89c62ed30a06c723 to your computer and use it in GitHub Desktop.
Save dantleech/7d7dbcf8d8ef29df89c62ed30a06c723 to your computer and use it in GitHub Desktop.
PHPBench Color/Gradient V/O / Collections
<?php
namespace PhpBench\Expression\ColorMap\Util;
use RuntimeException;
final class Color
{
/**
* @var int
*/
private $red;
/**
* @var int
*/
private $green;
/**
* @var int
*/
private $blue;
public function __construct(int $red, int $green, int $blue)
{
$this->red = $red;
$this->green = $green;
$this->blue = $blue;
}
public static function fromHex(string $hex): self
{
$hexRgb = sscanf(ltrim($hex, '#'), '%02s%02s%02s');
if (!is_array($hexRgb)) {
throw new RuntimeException(sprintf(
'Could not parse hex color "%s"', $hex
));
}
/** @phpstan-ignore-next-line */
return new self(...array_map('hexdec', $hexRgb));
}
/**
* @return array{int,int,int}
*/
public function toTuple(): array
{
return [
$this->red,
$this->green,
$this->blue
];
}
public function toHex(): string
{
return implode('', array_map(function (int $number) {
return sprintf('%02s', dechex($number));
}, $this->toTuple()));
}
}
<?php
namespace PhpBench\Expression\ColorMap\Util;
use RuntimeException;
use function array_fill;
use function array_key_first;
use function array_key_last;
use function array_unshift;
use function dechex;
use function sscanf;
final class Gradient
{
/**
* @var Color[]
*/
private $colors;
private function __construct(Color ...$colors)
{
$this->colors = $colors;
}
/**
* @return Color[]
*/
public function toArray(): array
{
return $this->colors;
}
public static function start(Color $start): self
{
return new self($start);
}
public function end(): Color
{
return $this->colors[array_key_last($this->colors)];
}
public function to(Color $end, int $steps): self
{
if ($steps <= 0) {
throw new RuntimeException(sprintf(
'Number of steps must be more than zero, got "%s"', $steps
));
}
$gradient = [];
$start = $this->end()->toTuple();
$end= $end->toTuple();
for ($i = 0; $i <= 2; $i++) {
$cStart = $start[$i];
$cEnd = $end[$i];
$step = abs($cStart - $cEnd) / $steps;
if ($step === 0) {
$gradient[$i] = array_fill(0, $steps + 1, $cStart);
continue;
}
$gradient[$i] = range($cStart, $cEnd, $step);
}
$colors = array_merge($this->colors, array_map(function (int $r, int $g, int $b) {
return new Color($r,$g,$b);
}, ...$gradient));
// remove the start color as it's already present
array_shift($colors);
return new self(...$colors);
}
public function colorAtIndex(int $index): Color
{
if (!isset($this->colors[$index])) {
throw new RuntimeException(sprintf(
'Color index is out of range "%s" (%s:%s)',
$index, array_key_first($this->colors), array_key_last($this->colors)
));
}
return $this->colors[$index];
}
}
<?php
$color = Gradient::start(
Color::fromHex(self::GREEN)
)->to(
Color::fromHex(self::BASE2), 100
)->to(
Color::fromHex(self::RED), 100
)->colorAtIndex($value + 100)->toHex();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment