Bij elkaar passende kleuren generator
Met deze functie kun je een willekeurig aantal kleuren met zoveel mogelijk contrast genereren die toch mooi bij elkaar passen. Dit zou je bijvoorbeeld kunnen gebruiken voor het genereren van kleuren in een taart-grafiek. Deze functie maakt gebruik van deze door mij eerder geposte functie. De reden dat de kleuren bij elkaar lijken te passen (dat wil zeggen ze passen redelijk bij elkaar) is dat ze gebruik maken van het HSB/HSV kleurenspectrum. Dit spectrum is veel meer mens-intuïtief dan het RGB kleurenspectrum. Je kunt bijvoorbeeld de Saturation en Brightness van een kleurenset al vantevoren defineren, en dan worden de kleuren bepaald door de hue, wat erg constante kleuren oplevert. Ook kun je de Hue en Saturation of de Hue en Brightness defineren, en de kleuren laten bepalen door de overgebleven. Dit levert een reeks van kleuren respectievelijk van zwart naar kleur of van wit naar kleur op. Ook kun je een reeks van zwart naar wit maken door de Saturation op nul te zetten (de Hue maakt niet uit), en de Brightness variabel te houden. Het is zelfs mogelijk om twee of zelfs drie waardes variabel te maken. Dit kan er rare/bijzondere effecten opleveren. Ook kun je een start en stop defineren voor elke waarde. Je kunt dus bijvoorbeeld de Hue laten fluctueren van 30 tot 130. Ook kun je de kleurberekening omdraaien (dat wil zeggen dat als de Hue normaal van 30 tot 130 loopt, hij nu van 130 tot 30 loopt). Voor meer informatie zie de phpdoc in de functie. De function getPrecision() is wordt gebruikt in verband met het probleem dat hier in het rode waarschuwingsvak ik beschreven, net als de functie significantRound() die in mijn andere scriptp staat die hier voor nodig is. Ik zou zeggen experimenteer er even mee, en veel plezier. Met dank aan Jonathan Hogervorst is er nu een online voorbeeld beschikbaar
Voorbeeld (een van de vele mogelijkheden):<?php
echo '<pre>';
var_dump(getColors(10, null, 70, 80, 30, 170));
echo '</pre>';
?>De functies:<?php
/**
* This function calculates the precision of a float or integer. In other words, the number of digits in a number.
*
* @param int|float $number
* @return int
*/
function getPrecision($number) {
if (!is_numeric($number)) {
throw new InvalidArgumentException('Argument $number must be a number');
}
settype($number, 'string');
if ($dotPosition = strrpos($number, '.')) {
$number = substr($number, 0, $dotPosition) . substr($number, $dotPosition + 1);
}
$number = ltrim($number, '0');
if ($exponentPosition = strrpos($number, 'E')) {
$number = substr($number, 0, $exponentPosition);
}
return strlen($number);
}
/**
* This function creates a range of at each other appropriate colors with as many contrast as possible in RGB format.
*
* @uses hsbToRgb()
* @uses getPrecision()
* @uses significantRound()
* @param int $number The number of colors that needs to be created
* @param int|float|null $hue This parameter can be a int or float between 0 and 360. If you pass null through, the hue is used as a variable factor by calculating the colors.
* @param int|float|null $saturation This parameter can be a int or float between 0 and 100. If you pass null through, the saturation is used as a variable factor by calculating the colors.
* @param unknown_type $brightness This parameter can be a int or float between 0 and 100. If you pass null through, the brightness is used as a variable factor by calculating the colors.
* @param int|float $hueStart This parameter can be a int or float between 0 and 360. It specifies the starting point of the hue. This parameter has only effect when parameter $hue is set to null. It can be bigger then $hueStop.
* @param int|float $hueStop This parameter can be a int or float between 0 and 360. It specifies the ending point of the hue. This parameter has only effect when parameter $hue is set to null. It can be smaller then $hueStart.
* @param int|float $saturationStart This parameter can be a int or float between 0 and 100. It specifies the starting point of the saturation. This parameter has only effect when parameter $saturation is set to null. It can be bigger then $saturationStop.
* @param int|float $saturationStop This parameter can be a int or float between 0 and 100. It specifies the ending point of the saturation. This parameter has only effect when parameter $saturation is set to null. It can be smaller then $saturationStart.
* @param int|float $brightnessStart This parameter can be a int or float between 0 and 100. It specifies the starting point of the brightness. This parameter has only effect when parameter $brightness is set to null. It can be bigger then $brightnessStop.
* @param int|float $brightnessStop This parameter can be a int or float between 0 and 100. It specifies the ending point of the brightness. This parameter has only effect when parameter $brightness is set to null. It can be smaller then $brightnessStart.
* @param boolean $hueReverse When this parameter is set to true, the calculating of the hue value is reversed. This parameter has only effect when parameter $hue is set to null.
* @param boolean $saturationReverse When this parameter is set to true, the calculating of the saturation value is reversed. This parameter has only effect when parameter $saturation is set to null.
* @param boolean $brightnessReverse When this parameter is set to true, the calculating of the brightness value is reversed. This parameter has only effect when parameter $brightness is set to null.
* @return array The return value is a multidimesional array. Each top-level element has a array with elements 'red', 'green' and 'blue', holding integers from 0 to 255.
*/
function getColors(
$number,
$hue,
$saturation,
$brightness,
$hueStart = 0,
$hueStop = 360,
$saturationStart = 0,
$saturationStop = 100,
$brightnessStart = 0,
$brightnessStop = 100,
$hueReverse = false,
$saturationReverse = false,
$brightnessReverse = false
) {
$hueStart = significantRound($hueStart, getPrecision($hueStart));
if ($hueStart < 0 || $hueStart > 360) {
throw new LengthException('Argument $hueStart is not a number between 0 and 360.');
}
$hueStop = significantRound($hueStop, getPrecision($hueStop));
if ($hueStop < 0 || $hueStop > 360) {
throw new LengthException('Argument $hueStop is not a number between 0 and 360.');
}
$saturationStart = significantRound($saturationStart, getPrecision($saturationStart));
if ($saturationStart < 0 || $saturationStart > 100) {
throw new LengthException('Argument $saturaionStart is not a number between 0 and 100.');
}
$saturationStop = significantRound($saturationStop, getPrecision($saturationStop));
if ($saturationStop < 0 || $saturationStop > 100) {
throw new LengthException('Argument $saturaionStop is not a number between 0 and 100.');
}
$brightnessStart = significantRound($brightnessStart, getPrecision($brightnessStart));
if ($brightnessStart < 0 || $brightnessStart > 100) {
throw new LengthException('Argument $brightnessStart is not a number between 0 and 100.');
}
$brightnessStop = significantRound($brightnessStop, getPrecision($brightnessStop));
if ($brightnessStop < 0 || $brightnessStop > 100) {
throw new LengthException('Argument $brightnessStop is not a number between 0 and 100.');
}
if (!is_bool($hueReverse)) {
throw new InvalidArgumentException('Argument $hueReverse is not a boolean.');
}
if (!is_bool($saturationReverse)) {
throw new InvalidArgumentException('Argument $saturationReverse is not a boolean.');
}
if (!is_bool($brightnessReverse)) {
throw new InvalidArgumentException('Argument $brightnessReverse is not a boolean.');
}
$hueRange = max($hueStart, $hueStop) == $hueStop ? $hueStop - $hueStart : 360 - $hueStart + $hueStop;
$saturationRange = max($saturationStart, $saturationStop) == $saturationStop ? $saturationStop - $saturationStart : 100 - $saturationStart + $saturationStop;
$brightnessRange = max($brightnessStart, $brightnessStop) == $brightnessStop ? $brightnessStop - $brightnessStart : 100 - $brightnessStart + $brightnessStop;
$currentHue = $hue;
$currentSaturation = $saturation;
$currentBrightness = $brightness;
$hueBetween = 0;
$saturationBetween = 0;
$brightnessBetween = 0;
if (is_null($hue)) {
$hueBetween = $hueRange / $number;
$currentHue = $hueReverse ? $hueStop : $hueStart;
}
if (is_null($saturation)) {
$saturationBetween = $saturationRange / ($number - 1);
$currentSaturation = $saturationReverse ? $saturationStop : $saturationStart;
}
if (is_null($brightness)) {
$brightnessBetween = $brightnessRange / ($number - 1);
$currentBrightness = $brightnessReverse ? $brightnessStop : $brightnessStart;
}
$colors = array();
for ($i = 0; $i < $number; $i++) {
$colors[] = hsbToRgb($currentHue, $currentSaturation, $currentBrightness);
$currentHue += $hueReverse ? -$hueBetween : $hueBetween;
$currentSaturation += $saturationReverse ? -$saturationBetween : $saturationBetween;
$currentBrightness += $brightnessReverse ? -$brightnessBetween : $brightnessBetween;
$currentHue = significantRound($currentHue, 3) > 360 ? 0 : $currentHue;
$currentSaturation = significantRound($currentSaturation, 3) > 100 ? 0 : $currentSaturation;
$currentBrightness = significantRound($currentBrightness, 3) > 100 ? 0 : $currentBrightness;
$currentHue = significantRound($currentHue, 3) < 0 ? 360 : $currentHue;
$currentSaturation = significantRound($currentSaturation, 3) < 0 ? 100 : $currentSaturation;
$currentBrightness = significantRound($currentBrightness, 3) < 0 ? 100 : $currentBrightness;
}
return $colors;
}
?>
Reacties
0