.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.43) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Chart::Color 3pm" .TH Chart::Color 3pm "2022-10-21" "perl v5.36.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Chart::Color \- read only single color holding objects .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 6 \& my $red = Chart::Color\->new(\*(Aqred\*(Aq); \& say $red\->add(\*(Aqblue\*(Aq)\->name; # magenta, mixed in RGB space \& Chart::Color\->new( 0, 0, 255)\->hsl # 240, 100, 50 = blue \& $blue\->blend_with({H=> 0, S=> 0, L=> 80}, 0.1);# mix blue with a little grey \& $red\->gradient( \*(Aq#0000FF\*(Aq, 10); # 10 colors from red to blue \& $red\->complementary( 3 ); # get fitting red green and blue .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" This module is designed for internal usage. It handles also all color definitions done by users with method \*(L"$chart\->set(color => {...})\*(R". To see which formats are allowed there, read the next section and please note that \->\fBset()\fR handles only scalar values. .SH "CONSTRUCTOR" .IX Header "CONSTRUCTOR" There are many options to create a color objects. In short you can either use the name of a predefined constant or provide values in \s-1RGB\s0 or \s-1HSL\s0 color space. .SS "new( 'name' )" .IX Subsection "new( 'name' )" Get a color by providing a name from the X11 or \s-1HTML\s0 (\s-1SVG\s0) standard or a Pantone report. Upper/Camel case will be treated as lower case and inserted underscore letters ('_') will be ignored as perl does in numbers (1_000 == 1000) (see more under Chart::Color::Constant). .PP .Vb 2 \& my $color = Chart::Color\->new(\*(AqEmerald\*(Aq); \& my @names = Chart::Color::Constant::all_names(); # select from these .Ve .SS "new( 'standard:color' )" .IX Subsection "new( 'standard:color' )" Get a color by name from a specific standard as provided by an external module Graphics::ColorNames::* , which has to be installed separately. * is a placeholder for the pallet name, which might be: Crayola, \s-1CSS,\s0 EmergyC, GrayScale, \s-1HTML, IE, SVG,\s0 Werner, \s-1WWW\s0 or X. In ladder case Graphics::ColorNames::X has to be installed. .PP .Vb 2 \& my $color = Chart::Color\->new(\*(AqSVG:green\*(Aq); \& my @s = Graphics::ColorNames::all_schemes(); # installed pallets .Ve .SS "new( '#rgb' )" .IX Subsection "new( '#rgb' )" Color definitions in hexadecimal format as widely used in the web, are also acceptable. .PP .Vb 2 \& my $color = Chart::Color\->new(\*(Aq#FF0000\*(Aq); \& my $color = Chart::Color\->new(\*(Aq#f00\*(Aq); # works too .Ve .ie n .SS "new( [$r, $g, $b] )" .el .SS "new( [$r, \f(CW$g\fP, \f(CW$b\fP] )" .IX Subsection "new( [$r, $g, $b] )" Triplet of integer \s-1RGB\s0 values (\*(L"red\*(R", \*(L"green\*(R" and \*(L"blue\*(R" : 0 .. 255). Out of range values will be corrected to the closest value in range. .PP .Vb 2 \& my $red = Chart::Color\->new( 255, 0, 0 ); \& my $red = Chart::Color\->new([255, 0, 0]); # does the same .Ve .ie n .SS "new( {r => $r, g => $g, b => $b} )" .el .SS "new( {r => \f(CW$r\fP, g => \f(CW$g\fP, b => \f(CW$b\fP} )" .IX Subsection "new( {r => $r, g => $g, b => $b} )" Hash with the keys 'r', 'g' and 'b' does the same as previous paragraph, only more declarative. Casing of the keys will be normalised and only the first letter of each key is significant. .PP .Vb 3 \& my $red = Chart::Color\->new( r => 255, g => 0, b => 0 ); \& my $red = Chart::Color\->new({r => 255, g => 0, b => 0}); # works too \& ... Color\->new( Red => 255, Green => 0, Blue => 0); # also fine .Ve .ie n .SS "new( {h => $h, s => $s, l => $l} )" .el .SS "new( {h => \f(CW$h\fP, s => \f(CW$s\fP, l => \f(CW$l\fP} )" .IX Subsection "new( {h => $h, s => $s, l => $l} )" To define a color in \s-1HSL\s0 space, with values for \*(L"hue\*(R", \*(L"saturation\*(R" and \&\*(L"lightness\*(R", use the following keys, which will be normalized as decribed in previous paragraph. Out of range values will be corrected to the closest value in range. Since \*(L"hue\*(R" is a polar coordinate, it will be rotated into range, e.g. 361 = 1. .PP .Vb 3 \& my $red = Chart::Color\->new( h => 0, s => 100, b => 50 ); \& my $red = Chart::Color\->new({h => 0, s => 100, b => 50}); # good too \& ... \->new( Hue => 0, Saturation => 100, Lightness => 50 ); # also fine .Ve .SH "GETTER / ATTRIBUTES" .IX Header "GETTER / ATTRIBUTES" are all read only methods \- giving access to different parts of the objects data. .SS "name" .IX Subsection "name" Name of the color in the X11 or \s-1HTML\s0 (\s-1SVG\s0) standard or the Pantone report. The name will be found and filled in, even when the object is created with \s-1RGB\s0 or \s-1HSL\s0 values. If the color is not found in any of the mentioned standards, it returns an empty string. All names are at: \*(L"\s-1NAMES\*(R"\s0 in Chart::Color::Constant .SS "string" .IX Subsection "string" String to reproduce color object by: Chart::Color\->new (eval \f(CW$string\fR). It is either the name (if color has one) or the stringified triplet: \&\*(L"[ \f(CW$red\fR, \f(CW$green\fR, \f(CW$blue\fR ]\*(R". .SS "red" .IX Subsection "red" Integer between 0 .. 255 describing the red portion in \s-1RGB\s0 space. .SS "green" .IX Subsection "green" Integer between 0 .. 255 describing the green portion in \s-1RGB\s0 space. .SS "blue" .IX Subsection "blue" Integer between 0 .. 255 describing the blue portion in \s-1RGB\s0 space. .SS "rgb" .IX Subsection "rgb" Three values of red, green and blue (see above). .SS "rgb_hex" .IX Subsection "rgb_hex" String starting with '#', followed by six hexadecimal figures. Two digits for each of red, green and blue value \- the format used in \s-1CSS.\s0 .SS "hue" .IX Subsection "hue" Integer between 0 .. 359 describing the angle (in degrees) of the circular dimension in \s-1HSL\s0 space named hue. 0 approximates red, 30 \- orange, 60 \- yellow, 120 \- green, 180 \- cyan, 240 \- blue, 270 \- violet, 300 \- magenta, 330 \- pink. 0 and 360 point to the same coordinate, but this module only deals with 0. .SS "saturation" .IX Subsection "saturation" Integer between 0 .. 100 describing percentage of saturation in \s-1HSL\s0 space. 0 is grey and 100 the most colorful (except when lightness is 0 or 100). .SS "lightness" .IX Subsection "lightness" Integer between 0 .. 100 describing percentage of lightness in \s-1HSL\s0 space. 0 is always black, 100 is always white and 50 the most colorful (depending on hue value) (or grey \- if saturation = 0). .SS "hsl" .IX Subsection "hsl" Three values of hue, saturation and lightness (see above). .SH "METHODS" .IX Header "METHODS" create new, related color (objects) or compute similarity of colors .SS "distance_to" .IX Subsection "distance_to" A number that measures the distance (difference) between two colors: 1. the calling object (C1) and 2. a provided first argument C2 \- color object or scalar data that is acceptable by new method : name or #hex or [$r, \f(CW$g\fR, \f(CW$b\fR] or {...} (see chapter \s-1CONSTRUCTOR\s0). .PP If no second argument is provided, than the difference is the Euclidean distance in cylindric \s-1HSL\s0 space. If second argument is 'rgb' or '\s-1RGB\s0', then its the Euclidean distance in \s-1RGB\s0 space. But als subspaces of both are possible, as r, g, b, rg, rb, gb, h, s, l, hs, hl, and sl. .PP .Vb 6 \& my $d = $blue\->distance_to( \*(Aqlapisblue\*(Aq ); # how close to lapis color? \& # how different is my blue value to airy_blue \& $d = $blue\->distance_to( \*(Aqairyblue\*(Aq, \*(AqBlue\*(Aq); # same amount of blue? \& $d = $color\->distance_to( $c2, \*(AqHue\*(Aq ); # same hue ? \& $d = $color\->distance_to( [10, 32, 112 ], \*(Aqrgb\*(Aq ); \& $d = $color\->distance_to( { Hue => 222, Sat => 23, Light => 12 } ); .Ve .SS "add" .IX Subsection "add" Create a Chart::Color object, by adding any \s-1RGB\s0 or \s-1HSL\s0 values to current color. (Same rules apply for key names as in new \- values can be negative.) \&\s-1RGB\s0 and \s-1HSL\s0 can be combined, but please note that \s-1RGB\s0 are applied first. .PP If the first argument is a Chart::Color object, than \s-1RGB\s0 values will be added. In that case an optional second argument is a factor (default = 1), by which the \s-1RGB\s0 values will be multiplied before being added. Negative values of that factor lead to darkening of result colors, but its not subtractive color mixing, since this module does not support \s-1CMY\s0 color space. All \s-1RGB\s0 operations follow the logic of additive mixing, and the result will be rounded (trimmed), to keep it inside the defined \s-1RGB\s0 space. .PP .Vb 5 \& my $blue = Chart::Color\->new(\*(Aqblue\*(Aq); \& my $darkblue = $blue\->add( Lightness => \-25 ); \& my $blue2 = $blue\->add( blue => 10 ); \& $blue\->distance( $blue2 ); # == 0, can\*(Aqt get bluer than blue \& my $color = $blue\->add( $c2, \-1.2 ); # subtract color c2 with factor 1.2 .Ve .SS "blend_with" .IX Subsection "blend_with" Create Chart::Color object, that is the average of two colors in \s-1HSL\s0 space: 1. the calling object (C1) and 2. a provided argument C2 (object or a refrence to data that is acceptable definition). .PP The second argument is the blend ratio, which defaults to 0.5 ( 1:1 ). 0 represents here C1 and 1 C2. Numbers below 0 and above 1 are possible, and will be applied, as long the result is inside the finite \s-1HSL\s0 space. There is a slight overlap with the add method which mostly operates in \&\s-1RGB\s0 (unless told so), while this method always operates in \s-1HSL\s0 space. .PP .Vb 4 \& my $c = $color\->blend_with( Chart::Color\->new(\*(Aqsilver\*(Aq) ); \& $color\->blend_with( \*(Aqsilver\*(Aq ); # same thing \& $color\->blend_with( [192, 192, 192] ); # still same \& my $difference = $color\->blend_with( $c2, \-1 ); .Ve .SS "gradient_to" .IX Subsection "gradient_to" Creates a gradient (a list of colors that build a transition) between current (C1) and a second, given color (C2). .PP The first argument is C2. Either as an Chart::Color object or a scalar (name, hex or reference), which is acceptable to the method new. .PP Second argument is the number \f(CW$n\fR of colors, which make up the gradient (including C1 and C2). It defaults to 3. These 3 colors C1, C2 and a color in between, which is the same as the result of method blend_with. .PP Third argument is also a positive number \f(CW$p\fR, which defaults to one. It defines the dynamics of the transition between the two colors. If \f(CW$p\fR == 1 you get a linear transition \- meaning the distance in \s-1HSL\s0 space (distance_hsl) is equal from one color to the next. If \f(CW$p\fR != 1, the formula \f(CW$n\fR ** \f(CW$p\fR starts to create a parabola function, which defines a none linear mapping. For values \f(CW$n\fR > 1 the transition starts by sticking to C1 and slowly getting faster and faster toward C2. Values \f(CW$n\fR < 1 do the opposite: starting by moving fastest from C1 to C2 (big distances) and becoming slower and slower. .PP .Vb 2 \& my @colors = $c\->gradient_to( $grey, 5 ); # we turn to grey \& @colors = $c1\->gradient_to( [14,10,222], 10, 3 ); # none linear gradient .Ve .SS "complementary" .IX Subsection "complementary" Creates a set of complementary colors. It accepts 3 numerical arguments: n, delta_S and delta_L. .PP Imagine an horizontal circle in \s-1HSL\s0 space, whith a center in the (grey) center column. The saturation and lightness of all colors on that circle is the same, they differ only in hue. The color of the current color object ($self a.k.a C1) lies on that circle as well as C2, which is 180 degrees (half the circumference) apposed to C1. .PP This circle will be divided in \f(CW$n\fR (first argument) equal partitions, creating \f(CW$n\fR equally distanced colors. All of them will be returned, as objects, starting with C1. However, when \f(CW$n\fR is set to 1 (default), the result is only C2, which is \s-1THE\s0 complementary color to C1. .PP The second argument moves C2 along the S axis (both directions), so that the center of the circle is no longer in the \s-1HSL\s0 middle column and the complementary colors differ in saturation. (C1 stays unmoved. ) .PP The third argument moves C2 along the L axis (vertical), which gives the circle a tilt, so that the complementary colors will differ in lightness. .PP .Vb 1 \& my @colors = $c\->complementary( 3, +20, \-10 ); .Ve .SH "COPYRIGHT & LICENSE" .IX Header "COPYRIGHT & LICENSE" Copyright 2022 Herbert Breunung. .PP This program is free software; you can redistribute it and/or modify it under same terms as Perl itself. .SH "AUTHOR" .IX Header "AUTHOR" Herbert Breunung,