=encoding utf8

=for HTML <a href="https://travis-ci.org/zoffixznet/perl6-Color"><img src="https://travis-ci.org/zoffixznet/perl6-Color.svg?branch=master"></a>

=head1 NAME

Color - Format conversion, manipulation, and math operations on colours

=head1 SYNOPSIS

    use Color;
    my $white        = Color.new(255, 255, 255);
    my $almost_black = Color.new('#111');
    say Color.new(:hsv<152 80 50>).hex; # convert HSV to HEX
    say "$white is way lighter than $almost_black";

    my $lighter_pink = Color.new('#ED60A2').lighten(20);
    my $lighter_pink = Color.new('#ED60A2') ◐ 20; # same as above

    my $saturated_pink = Color.new('#ED60A2').saturate(20);
    my $saturated_pink = Color.new('#ED60A2') 🞉 20; # same as above

    # Create an inverted colour scheme:
    $_ = .invert for @colours_in_my_colourscheme;

    use Color::Operators; # this gives us some ops to use on Color objects
    my $gray = $white / 2;
    say $gray.hex; # prints "#808080"
    say $almost_black + 25; # prints "42, 42, 42"

=head1 DESCRIPTION

This module allows you to perform mathematical operations on RGB colour tuples,
as well as convert them into other colour formats, like hex, and manipulate
them by, for example, making them lighter, darker, or more or less saturated.

=head1 OPERATORS

    use Color;
    use Color::Operators;

Note: as of this writing (Nov 17, 2015), merely importing the operators
made Rakudo compile 20 seconds slower, hence the operators are in a
separate module that you'll need to import.

=head1 CONSTRUCTOR

=head2 C<new>

    my $rgb = Color.new('abc');
    Color.new('#abc');
    Color.new('face');
    Color.new('#face');
    Color.new('abcdef');
    Color.new('#abcdef');
    Color.new('abcdefaa');
    Color.new('#abcdefaa');
    Color.new(:hex<abc>); # same applies to all other hex varians
    Color.new( 255, 100, 25 ); # RGB
    Color.new( .5, .1, .3, .4 ); # CMYK
    Color.new( rgb => [ 255, 100, 25 ] );
    Color.new(:rgb<255 100 25>); # same works on other formats
    Color.new( rgbd => [.086, .165, .282] ); # decimal RGB
    Color.new( rgba => [ 22, 42, 72, 88 ] );
    Color.new( rgbad => [ .086, .165, .282, .345 ] );
    Color.new( cmyk => [.55, .25, .85, .12] );
    Color.new( hsl => [ 72, 78, 65] );
    Color.new( hsv => [ 90, 60, 70] );

Creates new C<Color> object. All of the above formats are supported.
B<Note:> internally, the color will be converted to RGBA, which might
incurr slight precision loss when converting from other formats.

=head1 ATTRIBUTES

=head2 C<alpha-math>

    my $c = Color.new('abc');
    $c.alpha-math = True;

    my $c = Color.new('abca');
    $c.alpha-math = False;

Boolean. Specifies whether operator math from C<Color::Operators> should affect
the alpha channel. Colours contructed from RGBA automatically get this
attribute set to C<True>, rest of formats have it set as C<False>.

=head1 MANIPULATION METHODS

=head2 C<darken>

    say $c.darken(10).cmyk; # darken by 10%

Creates a new C<Color> object that is darkened by the percetange given as the
argument.

=head2 C<desaturate>

    say $c.desaturate(20).cmyk;

Creates a new C<Color> object that is desaturated by the percetange given as
the argument.

=head2 C<invert>

    say $c.invert.cmyk;

Creates a new C<Color> object that is inverted (black becomes white, etc).

=head2 C<lighten>

say $c.lighten(10).cmyk; # lighten by 10%

Creates a new C<Color> object that is lightened by the percetange given as the
argument.

=head2 C<saturate>

    say $c.saturate(20).cmyk;

Creates a new C<Color> object that is saturated by the percetange given as
the argument.

=head1 CONVERSION METHODS

=head2 C<to-string>

    $c.to-string('cmyk'); #   cmyk(0.954955, 0.153153, 0, 0.129412)
    $c.to-string('hsl');  #   hsl(189.622642, 91.379310, 45.490196)
    $c.to-string('hsv');  #   hsv(189.622642, 95.495495, 87.058824)
    $c.to-string('rgb');  #   rgb(10, 188, 222)
    $c.to-string('rgba'); #   rgba(10, 188, 222, 255)
    $c.to-string('rgbd'); #   rgb(0.039216, 0.737255, 0.870588)
    $c.to-string('rgbad');#   rgba(0.039216, 0.737255, 0.870588, 1)
    $c.to-string('hex');  #   #0ABCDE
    $c.to-string('hex3'); #   #1CE
    $c.to-string('hex8'); #   #0ABCDEFF

Converts the color to the format given by the argument and returns a string
representation of it. See above for the format of the tring for each
color format.

B<Note:> the C<.gist> and C<.Str> methods of the C<Color> object
are equivalent to C<.to-string('hex')>.

=head2 C<cmyk>

    say $c.cmyk; # (<106/111>, <17/111>, 0.0, <11/85>)

Converts the color to CMYK format and returns a list containing each color
(ranging `0`..`1`).

=head2 C<hex>

    say $c.hex; #  (0A BC DE);

Returns a list of 3 2-digit hex numbers representing the color.

=head2 C<hex3>

    say $c.hex3; #  (1 C E);

Returns a list of 3 1-digit hex numbers representing the color. They will
be rounded and they need to be doubled (i.e. the above would be C<11CCEE>)
to get the actual value.

=head2 C<hex4>

    say $c.hex4; #  (1 C E F);

Returns a list of 4 1-digit hex numbers representing the color. They will
be rounded and they need to be doubled (i.e. the above would be C<11CCEEFF>)
to get the actual value.

=head2 C<hex8>

    say $c.hex8; #  (0A BC DE FF);

Returns a list of 4 2-digit hex numbers representing the color, including
the Alpha space.

=head2 C<hsl>

    say $c.hsl; # (<10050/53>, <10600/111>, <1480/17>),

Converts the colour to HSL format and returns the three values
(hue, saturation, lightness). The S/L are returned as percentages, not decimals,
so 50% saturation is returned as C<50>, not C<.5>.

=head2 C<hsv>

    say $c.hsv; # (<10050/53>, <10600/111>, <1480/17>),

Converts the colour to HSV format and returns the three values
(hue, saturation, value). The S/V are returned as percentages, not decimals,
so 50% saturation is returned as C<50>, not C<.5>.

=head2 C<rgb>

    say $c.rgb; # (10, 188, 222)

Converts the color to RGB format and returns a list of the three colours.

=head2 C<rgba>

    say $c.rgba; # (10, 188, 222, 255);

Converts the color to RGBA format and returns a list of the three colours,
and alpha channel.

=head2 C<rgbd>

    say $c.rgbd; # (<2/51>, <188/255>, <74/85>)

Converts the color to RGB format ranging C<0>..C<1> and returns a list of
the three colours.

=head2 C<rgbad>

    say $c.rgbad; # (<2/51>, <188/255>, <74/85>, 1.0)

Converts the color to RGBA format ranging C<0>..C<1> and returns a list of
the three colours, and alpha channel.

=head1 CUSTOM OPERATORS

To get these, you need to C<use Color::Operators> along with C<use Color>.

=head2 C<+>

    Color.new('424') + 10;
    10 + Color.new('424');
    Color.new('424') + Color.new('424');

Add individual RGB values of each color. Plain numbers are added to each
value. If L</alpha-math> is turned on, alpha channel is affected as well.
The operation returns a new C<Color> object.

=head2 C<->

    Color.new('424') - 10;
    10 - Color.new('424');
    Color.new('424') - Color.new('666');

Subtract individual RGB values of each color. Plain numbers are subtracted
from each value. If L</alpha-math> is turned on, alpha channel is affected
as well. The operation returns a new C<Color> object.

=head2 C<*>

    Color.new('424') * 10;
    10 * Color.new('424');
    Color.new('424') * Color.new('424');

Multiply individual RGB values of each color. Plain numbers are multiplied
with each value. If L</alpha-math> is turned on, alpha channel is affected
as well. The operation returns a new C<Color> object.

=head2 C</>

    Color.new('424') / 10;
    Color.new('424') / 0; # doesn't die; sets values to 0
    10 / Color.new('424');
    Color.new('424') / Color.new('424');

Divide individual RGB values of each color. Plain numbers are divided
with each value. If L</alpha-math> is turned on, alpha channel is affected
as well. The operation returns a new C<Color> object. Illegal operation
of division by zero, doesn't die and simply sets the value to C<0>.

=head2 C<◐>

    say $c ◐ 20; # lighten by 20%

C<U+25D0 (e2 97 90): CIRCLE WITH LEFT HALF BLACK [◐]>. Same as C</lighten>

=head2 C<◑>

    say $c ◑ 20; # darken by 20%

C<U+25D1 (e2 97 91): CIRCLE WITH RIGHT HALF BLACK [◑]>. Same as C</darken>

=head2 C<🞉>

    say $c 🞉 20; # saturate by 20%

C<U+1F789 (f0 9f 9e 89): EXTREMELY HEAVY WHITE CIRCLE [🞉]>.
Same as C</desaturate>

=head2 C<¡>

    say $c¡; # invert colour

C<U+00A1 (c2 a1): INVERTED EXCLAMATION MARK [¡]>. Same as C</invert>

=head1 STRINGIFICATION

    say $c;
    say "$c";

The C<Color> object overrides C<.Str> and C<.gist> methods to be
equivalent to C<.to-string('hex')>.

=head1 REPOSITORY

Fork this module on GitHub:
L<https://github.com/zoffixznet/perl6-Color>

=head1 BUGS

To report bugs or request features, please use
L<https://github.com/zoffixznet/perl6-Color/issues>

=head1 AUTHOR

Zoffix Znet L<http://zoffix.com/>

=head1 CONTRIBUTORS

Thanks to timotimo++, jnthn++, psch++, RabidGravy++, ab5tract++, moritz++,
and anyone else who I forgot who helped me with questions on IRC.

=head1 LICENSE

You can use and distribute this module under the same terms as Perl 6
itself. See the C<LICENSE> file included in this distribution for complete
details.

=cut
