Skip to content

Instantly share code, notes, and snippets.

@chandeeland
Forked from KWKdesign/schemaverse-svg.pl
Created March 4, 2014 20:39
Show Gist options
  • Save chandeeland/9355140 to your computer and use it in GitHub Desktop.
Save chandeeland/9355140 to your computer and use it in GitHub Desktop.
#! /usr/bin/perl
use 5.010;
use strict;
use warnings;
# use Data::Dump qw/dump/;
use DBI;
use SVG;
use List::Util qw/max min/;
# https://dl.dropboxusercontent.com/u/94229093/Schemaverse/animate-paths12.svg
my $luma_threshold = 5;
sub get_luma {
my $rgb = uc shift;
return 0 unless $rgb =~ /[[:xdigit:]]{6}/;
my ( $r,$g,$b ) = $rgb =~ m/[[:xdigit:]]{2}/g;
no warnings 'uninitialized';
return ( 0.2126 * hex $r ) + ( 0.7152 * hex $g ) + ( 0.0722 * hex $b ); # luma objective
}
my $h = 750;
my $w = $h;
my $legend_w = 200;
my $svg = SVG->new( width => $w+$legend_w, height => $h );
my $map = $svg->group( id => 'map' );
$map->rect( id => 'map-bg', x => 1, y => 1, width => $w, height => $h );
my $legend = $svg->group( id => 'legend' );
$legend->rect(
id => 'legend-bg',
x => $w+1, y => 1,
width => $legend_w, height => $h,
);
$legend->line(
id => 'legend-border',
x1 => $w+1, x2 => $w+1,
y1 => 1, y2 => $h,
stroke => 'white',
'stroke-width' => 1,
);
$legend->image(
x => $w+1, y => $h-100,
width => 200, height => 73,
'-href' => 'https://schemaverse.com/images/schemaverse-logo.png',
id=> 'logo',
);
my $pass = '';
my $user = '';
my $host = 'db.schemaverse.com';
my $dbh = DBI->connect('dbi:Pg:host='.$host.';database=schemaverse',$user,$pass) or die "$!";
my $colors = [qw/1f77b4 aec7e8 ff7f0e ffbb78 2ca02c 98df8a d62728 ff9896 9467bd c5b0d5 8c564b c49c94 e377c2 f7b6d2 7f7f7f c7c7c7 bcbd22 dbdb8d 17becf 9edae5/];
my $dur = .1;
my $max_tic = $dbh->selectcol_arrayref(q/select last_value from tic_seq;/)->[0];
my $round = $dbh->selectcol_arrayref(q/select last_value from round_seq;/)->[0];
my $players = $dbh->selectcol_arrayref(q/
select player_id from (
select count(ship_id),ship_id,player_id
from ship_flight_recorder
group by ship_id,player_id
having count(ship_id) > 1
)a
group by player_id;
/);
$svg->title(id=>'document-title')->cdata('Schemaverse | Round '.$round.' | Max Tic '.$max_tic);
my $reload = $svg->script(-type=>"text/ecmascript");
$reload->CDATA(qq|
setTimeout(function(){
document.location.reload(true);
}, |.(1000*($max_tic*$dur)).qq| );
|);
my $clock_g = $svg->group( id => 'clock' );
$clock_g->text(
id => 'round',
x => $w+$legend_w-111, y => $h-12,
style => {
fill => 'white',
'font-size' => '1.4em',
},
)->cdata(sprintf('Rd: %5s',$round));
for( 0 .. $max_tic ) {
my $clock = $clock_g->text(
id => 'clock'.$_,
x => $w+10,
y => $h-12,
visibility => 'hidden',
style => {
fill => 'white',
'font-size' => '2em',
},
)->cdata(sprintf('%4s',( $_ > $max_tic ? $max_tic : $_ )));
$clock->animate(
-method => 'attribute',
attributeName => 'visibility',
to => 'visible',
begin => ( $_ * $dur ),
dur => $dur,
fill => ( $_ == $max_tic ? 'freeze' : 'remove' ),
);
}
my $paths_sth = $dbh->prepare(q\
select ship_id s, min(tic) start_tic, max(tic) end_tic,
string_agg( tic::text, ';') t,
string_agg( x, ';' ) x, string_agg( y , ';' ) y
from (
select ship_id, tic,
round( ( ? / ( 2e7 / ( (location[0]+1) + 1e7 ) ) )::numeric, 4 )::text x,
round( ( ? / ( 2e7 / ( (location[1]+1) + 1e7 ) ) )::numeric, 4 )::text y
from ship_flight_recorder
where player_id = ?
order by ship_id,tic
)a
group by ship_id
having count(*) > 1
;
\);
my $i = 0;
for my $player (@$players) {
$paths_sth->execute( $w, $h, $player );
my $ships = $paths_sth->fetchall_arrayref({});
my $p = $dbh->selectcol_arrayref(q/select get_player_username(?);/, undef, $player)->[0];
my $player_rgb = $dbh->selectcol_arrayref(q/select get_player_rgb(?::int);/, undef, $player )->[0];
my $new_color = 0;
# if ( defined $player_rgb ) {
# dump ( $p, $player_rgb, get_luma($player_rgb) );
# }
unless ( defined $player_rgb ) {
$new_color = 1;
}
elsif ( get_luma($player_rgb) < $luma_threshold ) {
$new_color = 1;
}
if ( $new_color ) {
my $scaled = $player % scalar @$colors;
$player_rgb = $colors->[ $scaled ];
}
$legend->text(
x => $w+5, y => ( ++$i * 32 ),
style => {
fill => '#'.$player_rgb,
'font-size' => '1.8em',
},
)->cdata($p);
my $svgg = $svg->group( id => 'p'.$player );
for(@$ships) {
my $ship = $svgg->circle(
id => 's'.$_->{s},
r => 1.125,
style => {
'fill' => '#'.$player_rgb,
}
);
my $begin = ( $dur * $_->{start_tic} );
my $ship_dur = ( $dur * ( $_->{end_tic} - $_->{start_tic} ) );
$ship->animate(
-method => 'attribute',
attributeName => 'cx',
values => $_->{x},
begin=> $begin.'s',
dur => $ship_dur.'s',
calcMode => 'linear',
);
$ship->animate(
-method => 'attribute',
attributeName => 'cy',
values => $_->{y},
begin=> $begin.'s',
dur => $ship_dur.'s',
calcMode => 'linear',
);
}
}
say $svg->render();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment