From 8c2d5fc6c2bad54d8cd3188ef26609671a450cfd Mon Sep 17 00:00:00 2001 From: Daniel Asher Resnick Date: Thu, 25 Jul 2024 00:28:18 -0500 Subject: [PATCH] Layer-based rendering --- HexGrid.pm | 16 ++++++---------- HexGrid/Path.pm | 1 + HexGrid/Pin.pm | 12 +++++------- HexGrid/Region.pm | 9 ++++++--- HexGrid/Tile.pm | 12 ++++++------ 5 files changed, 24 insertions(+), 26 deletions(-) diff --git a/HexGrid.pm b/HexGrid.pm index 50ebedd..dbdb3d8 100644 --- a/HexGrid.pm +++ b/HexGrid.pm @@ -211,25 +211,21 @@ sub render($this) # Continuations to be performed after other renders have finished # Registered by subcomponents' render methods - my $laters = []; + my $layers = {}; foreach my $region (keys %{$this->{regions}}) { # $m contains the min/max extents of the region - my $m = $this->{regions}{$region}->render($svg, $laters, $this); + my $m = $this->{regions}{$region}->render($svg, $this, $layers); $min_x = $m->{min_x} if $m->{min_x} < $min_x; $min_y = $m->{min_y} if $m->{min_y} < $min_y; $max_x = $m->{max_x} if $m->{max_x} > $max_x; $max_y = $m->{max_y} if $m->{max_y} > $max_y; } - foreach my $path (keys %{$this->paths}) - { - $this->{paths}{$path}->render($this, $svg); - } - foreach my $later (@$laters) - { - $later->($svg); - } + foreach my $tile_callback (@{$layers->{tiles}}) { $tile_callback->(); } + foreach my $path (keys %{$this->paths}) { $this->{paths}{$path}->render($this, $svg); } + foreach my $pin_callback (@{$layers->{pins}}) { $pin_callback->(); } + foreach my $popup_callback (@{$layers->{popups}}) { $popup_callback->($svg); } # Max and min coordinates are all at the top-left corner of tiles, add one width/height to get full extent my $width = $max_x - $min_x + $this->tile_width; my $height = $max_y - $min_y + $this->tile_height; diff --git a/HexGrid/Path.pm b/HexGrid/Path.pm index 09780cf..a48b55e 100644 --- a/HexGrid/Path.pm +++ b/HexGrid/Path.pm @@ -4,6 +4,7 @@ use v5.30; use Moo; use MooX::Aliases; +use Carp; use Data::Dumper; use feature "signatures"; diff --git a/HexGrid/Pin.pm b/HexGrid/Pin.pm index 1e2207d..657a140 100644 --- a/HexGrid/Pin.pm +++ b/HexGrid/Pin.pm @@ -15,7 +15,7 @@ has popup => (is => 'rw', default => 1, alias => 'use_popup'); has popup_class => (is => 'rw', default => 'pin-popup'); -sub render($this, $pin_container, $x, $y, $w, $h, $laters = undef) +sub render($this, $pin_container, $x, $y, $w, $h, $clip_path, $layers) { my $group = $pin_container->g(); my $element = $group->use(href => "#$this->{icon}_symbol", @@ -26,12 +26,10 @@ sub render($this, $pin_container, $x, $y, $w, $h, $laters = undef) my $center_x = $x + $w/2; my $center_y = $y + $h/2; - if(defined $laters) - { - push @$laters, sub ($popup_container) { $this->render_popup($popup_container, - $pin_container->{transform}, $center_x, $center_y); } - if $this->popup; - } + push @{$layers->{popups}}, sub ($popup_container) { $this->render_popup($popup_container, + $pin_container->{transform}, $center_x, $center_y); } + if $this->popup; + $group->{"clip-path"} = "url(#$clip_path->{id})"; return $group; } diff --git a/HexGrid/Region.pm b/HexGrid/Region.pm index 3df1e23..1ee5501 100644 --- a/HexGrid/Region.pm +++ b/HexGrid/Region.pm @@ -46,7 +46,7 @@ sub iter_tile($this, $code) } } -sub render($this, $svg, $laters, $grid) +sub render($this, $svg, $grid, $layers) { my ($min_x,$min_y,$max_x,$max_y) = qw(Inf Inf -Inf -Inf); my $g = $svg->g(id => HexGrid::to_id("$this->{name}$this->{id_suffix}")); @@ -55,8 +55,11 @@ sub render($this, $svg, $laters, $grid) foreach my $sw (keys %{$this->{tiles}{$nw}}) { my ($x_translate, $y_translate) = $grid->translate_coords($nw, $sw); - my $tile_group = $this->{tiles}{$nw}{$sw}->render($g, $grid->tile_width, $grid->tile_height, $laters); - $tile_group->{transform} = "translate($x_translate, $y_translate)"; + push @{$layers->{tiles}}, sub + { + my $tile_group = $this->{tiles}{$nw}{$sw}->render($g, $grid->tile_width, $grid->tile_height, $layers); + $tile_group->{transform} = "translate($x_translate, $y_translate)"; + }; $min_x = $x_translate if $x_translate < $min_x; $min_y = $y_translate if $y_translate < $min_y; diff --git a/HexGrid/Tile.pm b/HexGrid/Tile.pm index 6d8b63f..955ffea 100644 --- a/HexGrid/Tile.pm +++ b/HexGrid/Tile.pm @@ -103,7 +103,7 @@ sub _do_pin($this, $pin, $dock = undef) } } -sub render($this, $container, $width, $height, $laters = undef) +sub render($this, $container, $width, $height, $layers) { my $g = $container->g ( @@ -112,8 +112,8 @@ sub render($this, $container, $width, $height, $laters = undef) my $hex = $g->polygon(points => hex_path($width, $height), id => "$this->{nw}_$this->{sw}_inner_hex", style => $this->style); # Have tile contents clip to the hexagon - my $clipPath = $g->clipPath(id => "$this->{nw}_$this->{sw}_clip"); - $clipPath->use(href => "#$hex->{id}"); + my $clip_path = $g->clipPath(id => "$this->{nw}_$this->{sw}_clip"); + $clip_path->use(href => "#$hex->{id}"); if($this->{colour}) { @@ -128,7 +128,7 @@ sub render($this, $container, $width, $height, $laters = undef) # The actual image is defined at the HexGrid level, here we reference it my $use_element = $g->use(id => "$this->{nw}_$this->{sw}_${image}_use", href => "#${image}_symbol", width => $width, height => $height, - "clip-path" => "url(#$clipPath->{id})"); + "clip-path" => "url(#$clip_path->{id})"); } } @@ -152,8 +152,8 @@ sub render($this, $container, $width, $height, $laters = undef) my $y = $height * $docks{$key}->{y}; my $h = $height * $docks{$key}->{h}; - my $pin_element = $this->{pins}{$key}->render($g, $x, $y, $w, $h, $laters); - $pin_element->{"clip-path"} = "url(#$clipPath->{id})"; + push @{$layers->{pins}}, + sub { $this->{pins}{$key}->render($g, $x, $y, $w, $h, $clip_path, $layers); }; } } return $g;