Raster bars

As there is no reference implementation, and rather sketchy task instructions, this may or may not fulfill the original task authors intent.

Not really sure what is meant by "swaying".

Generate random colored bars and display them. (They ended up looking more plastic than metallic; ah well.)

use SDL2::Raw;
use Cairo;

my $width  = 800;
my $height = 800;

SDL_Init(VIDEO);

my $window = SDL_CreateWindow(
    'Raster Bars - Perl 6',
    SDL_WINDOWPOS_CENTERED_MASK,
    SDL_WINDOWPOS_CENTERED_MASK,
    $width, $height, RESIZABLE
);

my $render = SDL_CreateRenderer($window, -1, ACCELERATED +| PRESENTVSYNC);

my @bars = (^256).map: { gen-bar( rand xx 3 ) };

my $event = SDL_Event.new;

enum KEY_CODES (
    K_UP     => 82,
    K_DOWN   => 81,
    K_LEFT   => 80,
    K_RIGHT  => 79,
    K_SPACE  => 44,
    K_PGUP   => 75,
    K_PGDN   => 78,
    K_LCTRL  => 224,
    K_Z      => 29,
    K_X      => 27,
    K_Q      => 20,
);

my $dir   = -1;
my $step  = 5;
my $incr  = 1;
my $gap   = 100;
my $bh    = 64;
$height  += 32;
my $port  = +@bars * $gap;
my $y     = $dir > 0 ?? $height - $port !! $height;
my $angle = 0;

main: loop {
    handle-event($event) while SDL_PollEvent($event);

    $y = $step * $dir + $y;

    if $dir > 0 {
        $y = $height - $port if $y > 0
    } else {
        $y = 0 if $y < $height - $port
    }

    for ^@bars {
        my $offset = $gap / cos(π * $angle / 180);
        SDL_RenderCopyEx( $render, @bars[$_], Nil,
          SDL_Rect.new( -$gap, $y + $offset * $_, $width * 2, $bh),
          $angle.Num, SDL_Point.new(:x(0),:y(0)), 0
        )
    }

    SDL_RenderPresent($render);

    SDL_RenderClear($render);
}

SDL_Quit();

sub gen-bar (@color) {
    my $bar = Cairo::Image.create( Cairo::FORMAT_ARGB32, 1, 32 );
    given Cairo::Context.new($bar) {
        my Cairo::Pattern::Gradient::Linear $lpat .= create(0.0, 0.0,  0.0, 32.0);
        $lpat.add_color_stop_rgba(  1, |(@color »*» .3), 1);
        $lpat.add_color_stop_rgba( .2, |(@color),        1);
        $lpat.add_color_stop_rgba( .8, |(@color),        1);
        $lpat.add_color_stop_rgba(  0, |(@color »+» .8), 1);
        .rectangle(0, 0, 1, 32);
        .pattern($lpat);
        .fill;
        $lpat.destroy;
    }

    my $bar_texture = SDL_CreateTexture(
        $render, %PIXELFORMAT<ARGB8888>,
        STATIC, 1, 32
    );

    SDL_UpdateTexture(
        $bar_texture,
        SDL_Rect.new(:x(0), :y(0), :w(1), :h(32)),
        $bar.data, $bar.stride // 1
    );

    $bar_texture
}

sub handle-event ($event) {
    my $casted_event = SDL_CastEvent($event);
    given $casted_event {
        when *.type == QUIT    { last main }
        when *.type == KEYDOWN {
            if KEY_CODES(.scancode) -> $comm {
                given $comm {
                    when 'K_UP'     { $step += $incr }
                    when 'K_DOWN'   { $step -= $incr if $step > $incr }
                    when 'K_LEFT'   { $gap = $gap < 32 ?? $gap !! $gap - 1; $port = +@bars * $gap; }
                    when 'K_RIGHT'  { $gap++; $port += +@bars; }
                    when 'K_PGUP'   { $bh += 2 }
                    when 'K_PGDN'   { $bh = $bh >= 34 ?? $bh - 2!! $bh }
                    when 'K_SPACE'  { $step = $step ?? 0 !! $incr }
                    when 'K_LCTRL'  { $dir  *= -1 }
                    when 'K_Z'      { $angle = $angle > -45 ?? $angle - 1 !! $angle }
                    when 'K_X'      { $angle = $angle <  45 ?? $angle + 1 !! $angle }
                    when 'K_Q'      { last main }
                }
            }
        }
        when *.type == WINDOWEVENT {
            if .event == 5 {
                $width  = .data1;
                $height = .data2 + 32;
            }
        }
    }
}

Screenshot still of typical run: (offsite .png image)