From a758dabcf298f1fe3d49b44099a220b8d8e86a8a Mon Sep 17 00:00:00 2001 From: Daniel Asher Resnick Date: Sat, 29 Jul 2023 12:23:48 -0500 Subject: [PATCH] Cache images --- HexGrid.pm | 28 ++++++++++++++++++++++++++++ HexGrid/Image.pm | 27 +++++++++++++++++++++++++++ HexGrid/Tile.pm | 4 ++-- wiki-map.pl | 3 ++- 4 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 HexGrid/Image.pm diff --git a/HexGrid.pm b/HexGrid.pm index 7f45a1a..77bf7c9 100644 --- a/HexGrid.pm +++ b/HexGrid.pm @@ -9,6 +9,7 @@ use Hash::Merge qw(merge); use HexGrid::Tile; use HexGrid::Region; use HexGrid::PopUp; +use HexGrid::Image; use Carp; use Data::Dumper; @@ -16,6 +17,8 @@ use feature "signatures"; no warnings "experimental::signatures"; has regions => (is => 'rw', default => sub { {} }); +has images => (is => 'rw', default => sub{ {} }); + has sideLength => (is => 'rw', default => 100); has width => (is => 'rw', default => 1000); has height => (is => 'rw', default => 1000); @@ -36,6 +39,19 @@ sub make_region($this, $name, %defaults) $this->add_region(HexGrid::Region->new(name => $name, defaults => $tile_defaults)); } +sub add_image($this, $name, $source) +{ + # Height/width of the image within the symbol doesn't matter + # it will be scaled on use by matching the symbol viewbox to the declared image dimensions + $this->{images}{$name} = HexGrid::Image->new + ( + source => $source, + id => "${name}_img", + width => 1, + height => 1 + ); +} + sub get_tile_at($this, $nw, $sw) { foreach my $region (keys $this->{regions}->%*) @@ -54,6 +70,18 @@ sub render($this) $style_text .= ".$this->{popup_class} { visibility: hidden; }" if $this->{hidden_popups}; $root_style->cdata($style_text); + my $defs = $svg->defs(); + while (my ($key, $image) = each %{$this->{images}}) + { + my $symbol = $defs->symbol + ( + id => "${key}_symbol", + viewBox => "0 0 $image->{width} $image->{height}", + width => $image->{width}, + height => $image->{height}); + $image->render($symbol); + } + my $laters = []; foreach my $region (keys %{$this->{regions}}) { diff --git a/HexGrid/Image.pm b/HexGrid/Image.pm new file mode 100644 index 0000000..f655ba4 --- /dev/null +++ b/HexGrid/Image.pm @@ -0,0 +1,27 @@ +package HexGrid::Image; + +use v5.30; + +use Moo; +use MooX::Aliases; + +use feature "signatures"; +no warnings "experimental::signatures"; + + +has source => (is => 'rw', required => 1, alias => [qw(src url source_url)]); +has fetch => (is => 'rw', default => 0); +has id => (is => 'rw', required => 1); +has width => (is => 'rw', required => 1); +has height => (is => 'rw', required => 1); + +sub render($this, $container) +{ + # hard coded into external URL mode + my $image_element = $container->image(id => $this->{id}, href => $this->{source}); + $image_element->{width} = $this->{width} if defined($this->{width}); + $image_element->{height} = $this->{height} if defined($this->{height}); + return $image_element; +} + +1; diff --git a/HexGrid/Tile.pm b/HexGrid/Tile.pm index 11563b3..fb23fde 100644 --- a/HexGrid/Tile.pm +++ b/HexGrid/Tile.pm @@ -116,8 +116,8 @@ sub render($this, $container, $width, $height, $laters = undef) $this->{images} = [$this->{images}] if ref($this->{images}) ne 'ARRAY'; foreach my $image ($this->{images}->@*) { - my $image_element = $g->image(id => "$this->{nw}_$this->{sw}_${image}_img", - href => $image, width => $width, height => $height, + my $use_element = $g->use(id => "$this->{nw}_$this->{sw}_${image}_use", + href => "#${image}_symbol", width => $width, height => $height, "clip-path" => "url(#$clipPath->{id})"); } } diff --git a/wiki-map.pl b/wiki-map.pl index be7def4..03f4833 100644 --- a/wiki-map.pl +++ b/wiki-map.pl @@ -203,9 +203,10 @@ foreach my $page (values %{$background_query_results->{query}{pages}}) if($page->{imageinfo}) { say STDERR "Processing image: $page->{title}"; + $grid->add_image(HexGrid::to_id($page->{title}), $page->{imageinfo}[0]{url}); foreach my $region (@{$background_pages{$page->{title}}}) { - $region->{defaults}{image} = $page->{imageinfo}[0]{url}; + $region->{defaults}{image} = HexGrid::to_id($page->{title}); } } }