-
Notifications
You must be signed in to change notification settings - Fork 0
Documentation for PHP (English)
- How to use colori.php
- Create a color
- Color properties
- Express a color in different formats
- Modify a color
- Mix colors together
- Compare two colors
- Other functions
(Note: colori means colors in Italian. The singular is colore.)
You need to download the file colori.php, then just import it into your JavaScript code like this:
require_once 'colori.php';
The colori.php file starts with class Couleur
. You can replace Couleur
by any other name you want to give to the class. In this documentation, we will be using Colore
.
To be able to use functions from colori.js, you need to create a Colore
-cass object:
$rosso = new Colore('red');
// Which results in:
$rosso == object(Colore)[1]
public 'r' => float 1,
public 'g' => float 0,
public 'b' => float 0,
public 'a' => float 1,
public 'h' => float 0,
public 's' => float 1,
public 'l' => float 0.5,
public 'w' => float 0,
public 'b' => float 0,
public 'c' => float 0.54291,
public 'c' => float 80.815,
public 'c' => float 69.893,
public 'c' => float 106.85,
public 'c' => float 0.11349
The parameter in new Colore(parameter)
must be a string in a supported format according to the CSS specification about color formats.
Let's create two Colore
-class objects – $rosso
, representing the color red, and $rossoTrasparente
, representing the color red with opacity 0.6 – from their expressions in all formats supported by CSS.
// Creates the color from its name:
$rosso = new Colore('red');
// Creates the color from its hexadecimal expression:
$rosso = new Colore('#FF0000');
$rossoTrasparente = new Colore('#FF000099');
// or
$rosso = new Colore('#F00');
$rossoTrasparente = new Colore('#F009');
// Creates the color from its RGB expression:
$rosso = new Colore('rgb(255, 0, 0)');
$rossoTrasparente = new Colore('rgb(255, 0, 0, 0.6)');
// or
$rosso = new Colore('rgb(255 0 0)');
$rossoTrasparente = new Colore('rgb(255 0 0 / 0.6)');
Replacing
rgb
byrgba
works too.
// Creates the color from its HSL expression:
$rosso = new Colore('hsl(0, 100%, 50%)');
$rossoTrasparente = new Colore('hsl(0, 100%, 50%, 0.6)');
// or
$rosso = new Colore('hsl(0 100% 50%)');
$rossoTrasparente = new Colore('hsl(0 100% 50% / 0.6)');
Replacing
hsl
byhsla
works too.
// Creates the color from its HWB expression:
$rosso = new Colore('hwb(0 0% 0%)');
$rossoTrasparente = new Colore('hwb(0 0% 0% / 0.6)');
// Creates the color from its LAB expression:
$rosso = new Colore('lab(54% 81 70)');
$rossoTrasparente = new Colore('lab(54% 81 70 / 0.6)');
// Creates the color from its LCH expression:
$rosso = new Colore('lch(54% 107 41)');
$rossoTrasparente = new Colore('lch(54% 107 41 / 0.6)');
The CIELAB color space (used in LAB and LCH formats) contains colors which are not in the sRGB color space (used in RGB, HSL and HWB formats). Since CSS doesn't natively support LAB or LCH colors yet, using such a color in
new Colore()
will convert it into the closest color in sRGB space.For that reason, you could notice some inconsistencies, for example:
$a = new Colore('lab(50% 118 43)'); $a->rgb == 'rgb(232, 0, 78)' // but: $b = new Colore('rgb(232, 0, 78)') $b->lab == 'lab(50% 76 28)'$a = new Colore('lch(50% 125 20)'); $a->rgb == 'rgb(232, 0, 78)' // but: $b = new Colore('rgb(232, 0, 78)') $b->lch == 'lch(50% 81 20)'
When a Colore
-class object is created by using new Colore(expression)
, 14 different color properties are calculated. They correspond to every parameter from the different supported color formats:
-
The
r
,g
andb
properties are the red, green and blue values of the color when it's expressed inrgb(r, g, b)
format. These values are usually given between 0 and 255 or as percentages. -
The
h
property is the hue value of the color when it's expressed inhsl(h, s, l)
orhwb(h, w, bk)
format. This value is an angle, usually given in degrees (from 0 to 360), gradians (from 0 to 400), radians (from 0 to 2π) or turns (from 0 to 1). -
The
s
andl
properties are the saturation and luminosity values of the color when it's expressed inhsl(h, s, l)
format. These values are percentages. -
The
w
andbk
properties are the whiteness and blackness values of the color when it's given inhwb(h w bk)
format. These values are percentages. -
The
ciel
property is the luminosity of the color in CIELAB color space, when it's expressed inlab(ciel ciea cieb)
orlch(ciel ciec cieh)
format. This value is a percentage. The specification allows values over 100% for compatibility with the HDR standard. -
The
ciea
andcieb
properties are the values of the color on the "a" and "b" axes of CIELAB color space, when it's expressed inlab(ciel ciea cieb)
format. They can be any numerical value, but they are generally in the [-160, 160] interval. -
The
ciec
property is the chroma value of the color when it's expressed inlch(ciel ciec cieh)
format. It can be any numerical value, but it's generally in the [0, 230] interval. -
The
cieh
property is the hue value of the color when it's expressed inlch(ciel ciec cieh)
format. This value is an angle, usually given in degrees (from 0 to 360), gradians (from 0 to 400), radians (from 0 to 2π) or turns (from 0 to 1). It is similar to theh
property in HSL format, but its value is calculated in a slightly different way. -
The
a
property is the opacity of the color. It's the 4th optional parameter in every previous color format. This value is usually given in the [0, 1] interval or as a percentage.
Some colors have a name in the CSS specification. For these colors, the name
parameter gives their name:
(new Colore('red'))->name() == 'red'
Note: if a color isn't exactly equal to a named color (for example because of a rounded value in a calculation), the name
property will still recognize it as the named color it's close to:
(new Colore('red'))->rgb() == 'rgb(255, 0, 0)'
(new Colore('rgb(255, 0.1, 0.1)'))->name() == 'red'
The exactName
property only gives the name when the color is exactly equal to it:
(new Colore('red'))->rgb() == 'rgb(255, 0, 0)'
(new Colore('rgb(255, 0.1, 0.1)'))->exactName() == null
The luminance
property gives the luminance of the color, as defined by W3C.
rosso.luminance == 0.2126
The hex
, rgb
, hsl
, hwb
, lab
and lch
properties give the expression of the color in the corresponding format:
$rosso = new Colore('red');
$rosso->hex() == '#ff0000'
$rosso->rgb() == 'rgb(255, 0, 0)'
$rosso->hsl() == 'hsl(0, 100%, 50%)'
$rosso->hwb() == 'hwb(0 0% 0%)'
$rosso->lab() == 'lab(54% 81 70)'
$rosso->lch() == 'lch(54% 107 41)'
Transparent colors (a < 1
) are supported:
$rossoTrasparente = new Colore('rgb(255, 0, 0, 0.6)');
$rossoTrasparente->hex() == '#ff000099'
$rossoTrasparente->rgb() == 'rgb(255, 0, 0, 0.6)'
$rossoTrasparente->hsl() == 'hsl(0, 100%, 50%, 0.6)'
$rossoTrasparente->hwb() == 'hwb(0 0% 0% / 0.6)'
$rossoTrasparente->lab() == 'lab(54% 81 70 / 0.6)'
$rossoTrasparente->lch() == 'lch(54% 107 41 / 0.6)'
These properties hide opacity when it's equal to 1. The hexa
, rgba
, hsla
, hwba
, laba
and lcha
properties will display opacity in any case:
$rosso = new Colore('red');
$rosso->hexa() == '#ff0000ff'
$rosso->rgba() == 'rgb(255, 0, 0, 1)'
$rosso->hsla() == 'hsl(0, 100%, 50%, 1)'
$rosso->hwba() == 'hwb(0 0% 0% / 1)'
$rosso->laba() == 'lab(54% 81 70 / 1)'
$rosso->lcha() == 'lch(54% 107 41 / 1)'
The change
method lets you modify any property of a color, and returns a new Colore
-class object of which all properties have been recalculated following the change.
$result = $color->change($prop, $val, $options = (object)['replace' => <Boolean>, 'scale' => <Boolean>]);
It applies to a Colore
-class object – $color
here.
It takes these arguments:
-
$prop
: a string which contains the name of the property you want to change, for example'r'
,'g'
,'b'
, etc. -
$val
: a number or percentage used as the value which will be added to the previous value of the property. -
$options
: an object containing the following properties:-
replace
(default =false
): a boolean. Iftrue
, the value of$val
will replace the previous value of the property, instead of being added to it. -
scale
(default =false
): a boolean. Iftrue
, the value of$val
will be multiplied to the previous value of the property, instead of being added to it.
-
It returns a Colore
-class object – result
here – which is a copy of $color
with a modified $prop
property.
// Let's reduce the luminosity of red by 10%:
$rosso = new Colore('red');
$nuovoColore = $rosso->change('l', '-10%');
// which gives:
$rosso->hsl() == 'hsl(0, 100%, 50%)'
$nuovoColore->hsl() == 'hsl(0, 100%, 40%)'
// Let's replace the luminosity of red by 10%:
$rosso = new Colore('red');
$nuovoColore = $rosso->change('l', '10%', (object)['replace' => true ]);
// which gives:
$rosso->hsl() == 'hsl(0, 100%, 50%)'
$nuovoColore->hsl() == 'hsl(0, 100%, 10%)';
// Let's raise the luminosity of red by 50% of its current value:
$rosso->hsl() == 'hsl(0, 100%, 50%)'
$nuovoColore = $rosso->change('l', '150%', (object)['scale' => true]);
// which gives:
$rosso->hsl() == 'hsl(0, 100%, 50%)'
$nuovoColore->hsl() == 'hsl(0, 100%, 75%)';
The replace
method is equivalent to change
with option { replace: true }
.
$result = $color->replace($prop, $val);
It applies to a Colore
-class object – $color
here.
It takes these arguments:
-
$prop
: a string containing the name of the property you want to change, for example'r'
,'g'
,'b'
, etc. -
$val
: a number or percentage used as the value that will replace the previous value of the property.
It returns a Colore
-class object – $result
here – which is a copy of $color
with a modified $prop
property.
// Let's replace the luminosity of red by 10%:
$rosso = new Colore('red');
$nuovoColore = $rosso->replace('l', '10%');
// which gives:
$nuovoColore->hsl() == 'hsl(0, 100%, 10%)';
The scale
method is equivalent to change
with option (object)["scale" => true]
.
$result = $color->scale($prop, $val);
It applies to a Colore
-class object – $color
here.
It takes these arguments:
-
$prop
: a string containing the name of the property you want to change, for example'r'
,'g'
,'b'
, etc. -
$val
: a number or percentage used as the value that will be multiplied to the previous value of the property.
It returns a Colore
-class object – $result
here – which is a copy of $color
with a modified $prop
property.
// Let's raise the luminosity of red by 50% of its current value:
$rosso = new Colore('red');
$nuovoColore = $rosso->scale('l', '150%');
// which gives:
$rosso->hsl() == 'hsl(0, 100%, 50%)'
$nuovoColore->hsl() == 'hsl(0, 100%, 75%)'
The greyscale
(or grayscale
) method transforms a color into the shade of grey with the same luminosity.
$result = $color->greyscale();
It applies to a Colore
-class object – $color
here.
It takes no argument.
It returns a Colore
-class object – $result
here – which is a copy of $color
with its saturation reduced to 0.
// Let's take some blue
$blu = new Colore('blue');
$blu->hsl() == 'hsl(240, 100%, 50%)'
// Let's apply greyscale to that blue
$grigio = $blu->greyscale();
$grigio->hsl() == 'hsl(240, 0%, 50%)'
The sepia
method transforms a color into its sepia tone.
$result = $color->sepia();
It applies to a Colore
-class object – $color
here.
It takes no argument.
It returns a Colore
-class object – $result
here – which is a modification of $color
towards sepia tones.
// Let's take some blue
$blu = new Colore('blue');
$blu->rgb() == 'rgb(0, 0, 255)'
// Let's apply sepia to that blue
$seppia = $blu->sepia();
$seppia->rgb() == 'rgb(48, 43, 33)'
The complement
method calculates the complementary.
$result = $color->complement();
It applies to a Colore
-class object – $color
here.
It takes no argument.
It returns a Colore
-class object – $result
here – which is the complementary color to $color
.
// The complementary color to red is cyan / aqua
$rosso = new Colore('red');
$rosso->complement()->name() == 'aqua'
// The complementary color to white is white itself
$bianco = new Couleur('white');
$bianco->complement()->name() == 'white'
The negative
(or invert
) calculates the inverse color.
$result = $color->negative();
It applies to a Colore
-class object – $color
here.
It takes no argument.
It returns a Colore
-class object – $result
here – qui est la couleur négative de $color
.
// The negative color of white is black
$bianco = new Colore('white');
$bianco->negative()->name() == 'black'
// The negative color of red is cyan / aqua
$rosso = new Colore('red');
$rosso->negative()->name() == 'aqua'
The static method blend
can blend multiple colors. In other words, it calculates the color you would see on the screen if you displayed multiple colors over each other.
$result = Colore::blend($color1, $color2, $color3, ...);
It takes these arguments:
- an arbitrary number of
Colore
-class objects or strings in a format compatible withnew Colore()
. Each color will be overlayed over the previous one.
It returns a Colore
-class object which is the color you see after overlaying every color it took as arguments one by one.
Note: if you overlay an opaque color (such that
color.a == 1
) over another color, then the result will be that same opaque color ; since it's not transparent, it doesn't let you see the color below at all.blend
is thus mainly useful to blend transparent colors (such thatcolor.a < 1
).
// Let's take some red and blend some blue with opacity 0.5 over it
$bluTrasparente = (new Colore('blue'))->replace('a', .5);
$result = Colore::blend('red', $bluTrasparente);
// The result is purple, as we would expect
$result->name() == 'purple'
// Let's blend some red and blue again, but let's
// also add some green with opacity 0.4
$verdeTrasparente = (new Colore('green'))->replace('a', .4);
$result = Colore::blend('red', $bluTrasparente, $verdeTrasparente);
// The result is a desaturated purple, almost grey
$result->rgb() == 'rgb(77, 51, 77)'
The blend
method solved the following equality to calculate result
:
$result = Colore::blend($background, $overlay);
The static method unblend
, on the other hand, solves the same equation when it's $background
you want to calculate. In other words, it takes a color $result
and unblends $overlay
from it.
$background = Colore::unblend($result, $overlay);
$result = Colore::unblend($color1, $color2, $color3, ...);
It takes these arguments:
- an arbitrary number of
Colore
-class objects or strings in a format compatible withnew Colore()
. Each color will be overlayed over the previous one.
It returns a Colore
-class object which is the color you obtain after unmixing every color it took as arguments one by one.
// With blend, we saw that blending red and transparent blue
// made purple. So we would expect that unblending that same
// transparent blue from purple would make red again.
$bluTrasparente = (new Colore('blue'))->replace('a', .5);
$result = Colore::unblend('purple', $bluTrasparente);
// It works!
$result->name() == 'red'
The blend
method solved the following equality to calculate $result
:
$result = Colore::blend($background, $overlay)
The static method whatToBlend
, on the other hand, solves the same equation when it's $overlay
you want to calculate. In other words, it takes two colors $background
and $result
and calculates which color $overlay
should be blended with $background
to obtain the color $result
.
$overlay = Colore::whatToBlend($background, $result)
$overlay = Colore::whatToBlend($background, $result, $alpha, $alphaStep);
It takes these arguments:
-
$background
and$result
: twoColore
-class objects or strings in a format compatible withnew Colore()
. -
$alpha
: a number, the (optional) opacity value you want$overlay
to have. Indeed, multiple colors can be solutions to that equation. If that is the case, choosing an$alpha
value lets you find a unique solution. -
$alphaStep
(default =0.1
): a number, the (optional) value of the opacity difference between the different solutions returned bywhatToBlend
, when multiple solutions exist.
// whatToBlend returns the list of colors that can be
// blended with red to make purple:
$result = Colore::whatToBlend('red', 'purple');
array_map($result, fn($c) => $c->rgb()) == [
'rgb(0, 0, 255, 0.5)',
'rgb(43, 0, 213, 0.6)',
'rgb(74, 0, 183, 0.7)',
'rgb(96, 0, 160, 0.8)',
'rgb(114, 0, 142, 0.9)',
'purple'
];
// If we ask for a solution with opacity 0.5, it returns
// blue with opacity 0.5. That's the actual value
// bluTrasparente had in the blend and unblend examples!
$result = Colore::whatToBlend('red', 'purple', 0.5);
$result->rgb() == 'rgb(0, 0, 255, 0.5)'
The static method contrast
calculates the contrast between two colors.
$result = Colore::contrast($color1, $color2);
It takes these arguments:
-
$color1
and$color2
: twoColore
-class objects or strings in a format compatible withnew Colore()
.
It returns a number between 1 and 21.
Colore::contrast('white', 'black') == 21
Colore::contrast('skyblue', 'darkblue') == 8.7835
For a text to be easily readable on a colored surface, the contrast between the colors of that surface and the text must be high enough. The contrast
method can for example be used to check if two colors meet the WCAG recommandations.
The contrastedText
method determines if black or white text would be more readable on a colored surface.
$result = $color->contrastedText();
It applies to a Colore
-type object –$color
here.
It takes no argument.
It returns the string 'white'
or 'black'
.
// On a sky blue surface, black text is
// more readable than white text
$bluCielo = new Colore('skyblue');
$bluCielo->contrastedText() == 'black'
// On a dark blue surface, white text is
// more readable than black text
$bluScuro = new Colore('darkblue');
$bluScuro->contrastedText() == 'white'
The improveContrast
method changes the color it's applied to, more specifically its CIE luminosity ciel
, to give it better contrast with another color.
$result = $color->improveContrast($referenceColor, $desiredContrast, $step, $options = (object)["lower" => <Boolean>, "towards" => <Boolean>, "maxIterations" => <Boolean>]);
It applies to a Colore
-class object – $color
here.
It takes these arguments:
-
referenceColor
: aColore
-class object or a string in a format compatible withnew Colore()
, used as a reference color: the method is trying to improve the value ofColore::contrast($color, $referenceColor)
. -
$desiredContrast
: a number used as the value you want to contrast to be. -
$step
(default =2
): a number used as the quantity that will be added or removed from the CIE luminosity of$color
; in other words, at each step of the contrast optimization,$color->ciel
grows or decreases by$step
%. -
$options
: an object containing the following properties:-
lower
(default =false
): can take the following values:-
false
:improveContrast
will not do anything ifColore::contrast($color, $referenceColor) > $desiredContrast
. -
true
: whenColore::contrast($color, $referenceColor) > $desiredContrast
,$color
will be modified to reduce contrast so that it gets as close as possible todesiredContrast
.
-
-
towards
(default =null
): determines ifimproveContrast
should improve the contrast by making the color lighter or darker. It can take the following values:-
'black'
:improveContrast
will only try to improve the contrast by making$color
darker. -
'white'
:improveContrast
will only try to improve the contrast by making$color
lighter. -
null
:improveContrast
will try to guess if makingcolor
darker or lighter would lead to a better contrast. If it can't guess, it will default to the value'black'
.
-
-
maxIterations
(default =100
): the maximum number of timesimproveContrast
will change the color to improve contrast.
-
It returns a Colore
-class object – $result
here – which is a copy of $color
to which the needed modifications of its ciel
property have been applied so that Colore::contrast($result, $referenceColor) > $desiredContrast
.
// Let's take the example of a light blue background,
// over which we want to display some sky blue text.
$bluChiaro = new Couleur('lightblue');
$bluCielo = new Couleur('skyblue');
Colore::contrast($bluChiaro, $bluCielo) == 1.1396
// The contrast between sky blue and light blue is
// too low for the text to be readable. WCAG recommends
// a contrast of at least 4.5. Let's change the sky blue
// color to reach that value.
$nuovoBlue = $bluCielo->improveContrast($bluChiaro, 4.5);
// The new blue is darker than the sky blue we started with.
$bluCielo->hsl() == 'hsl(197, 71%, 73%)'
$nuovoBlu->hsl() == 'hsl(193, 100%, 24%)'
// The desired contrast has been reached!
Colore::contrast($bluChiaro, $nuovoBlue) == 4.6554
The static method distance
measures how much difference there is between two colors.
$result = Colore::distance($color1, $color2, $format, $tolerance);
It takes these arguments:
-
$color1
and$color2
: twoColore
-class objects or strings in a format compatible withnew Colore()
. -
$format
: a string, determines which color format will be used to calculate their distance. It can take the following values:-
'rgb'
,'hsl'
,'hwb'
,'lab'
or'lch'
: the distance between the two colors will be calculated by adding the difference in value between each property of the chosen format. -
null
(default): the calculated distance will be the average of the distance for each color format.
-
-
$tolerance
(default =0.02
): a number, used as a tolerance value to ignore certain color properties when they have no effect on the color. For example, in HSL format, when L = 0, the color is black no matter the value of H or S. To account for that even when some rounding errors made L slightly superior to 0, thedistance
method ignores H and S when$color1->l < $tolerance && $color2->l < $tolerance
.
It returns a positive number.
// Red and red are identical colors
Colore::distance('red', 'red') == 0
// Red and blue are different colors
Colore::distance('red', 'blue') == 1.3467999999999998
// Both colors are black despite different H and S values
Colore::distance('hsl(200, 50%, 0%)', 'hsl(50, 35%, 0%)') == 0
The static method same
determines if two colors are the same.
$result = Colore::same($color1, $color2, $tolerance);
It takes these arguments:
-
$color1
and$color2
: twoColore
-class objects or strings in a format compatible withnew Colore()
. -
$tolerance
(default =0.02
): a number, represents the minimal distance between two colors for them to be considered different.
It returns true
if the colors are considered identical, false
if they are not.
// Red and red are identical colors
Colore::same('red', 'red') == true
// Red and blue are different colors
Colore::same('red', 'blue') == false
// Both colors are black despite different H and S values
Colore::same('hsl(200, 50%, 0%)', 'hsl(50, 35%, 0%)') == true
// These two colors are so close that
// they're considered identical
Colore::same('rgb(0, 0, 255)', 'rgb(0, 0, 254)') == true
The static method gradient
generates a gradient between two colors that avoids going through a desaturated zone (see this article).
$result = Colore::gradient($start, $end, $steps, $format);
It takes these arguments:
-
$start
and$end
: twoColore
-class objects or strings in a format compatible withnew Colore()
. -
$steps
(default =5
): the number of steps – meaning the number of calculated colors – to go from$start
to$end
. The higher this number, the smoother the gradient and the more it avoids the desaturated zone. -
$format
(default ='lch'
): a string containing the name of the format whose properties will be used to compute the gradient. The supported values are'rgb'
,'hsl'
,'hwb'
,'lab'
and'lch'
.
It returns an Array
of length $steps + 1
containing Colore
-class objects: [$start, $color2, $color3, ..., $end]
.
$colori = Colore::gradient('indigo', 'orange');
// To use this gradient in CSS, let's use the calculated colors in the linear-gradient CSS function
$gradiente = `linear-gradient(to right, ${colori.map(c => c->name() || c->rgb()).join(', ')})`;
// By using this as a background-image in CSS, the gradient would be displayed
$$gradiente == 'linear-gradient(to right, indigo, rgb(137, 0, 116), rgb(192, 0, 105), rgb(238, 42, 80), rgb(255, 109, 52), orange)'
// Let's compute a gradient between the same colors, but using the HSL format
$colori = Colore::gradient('orchid', 'palegreen', 5, 'hsl');
// To use this gradient in CSS, let's use the calculated colors in the linear-gradient CSS function
$gradiente = 'linear-gradient(to right, ' . implode(', ', array_map(function($c) { return $c->name() ?? $c->rgb() })) . ')';
// By using this as a background-image in CSS, the gradient would be displayed
$gradiente == 'linear-gradient(to right, orchid, rgb(227, 118, 158), darksalmon, rgb(241, 221, 133), rgb(204, 246, 142), palegreen)'