Compare commits

...

4 Commits

  1. 2
      HexGrid.pm
  2. 69
      HexGrid/Dynamic.pm
  3. 6
      HexGrid/Pin.pm
  4. 22
      HexGrid/Region.pm
  5. 72
      wiki-map.pl

@ -28,7 +28,7 @@ has width => (is => 'rw', default => 1000);
has height => (is => 'rw', default => 1000);
has defaults => (is => 'rw', default => sub { {} });
has make_popups => (is => 'rw', default => 1, alias => 'popups');
has popup_class => (is => 'rw', default => 'pin-popup');
has popup_class => (is => 'rw', default => 'popup');
has hidden_popups => (is => 'rw', default => 1, alias => 'popups_are_hidden');
has embed_images => (is => 'rw', default => 1);

@ -0,0 +1,69 @@
package HexGrid::Dynamic;
use v5.30;
use Carp;
use Data::Dumper;
use feature "signatures";
no warnings "experimental::signatures";
$HexGrid::Dynamic::click_pin = <<EOS;
function clickPin(pinId, event) {
event.stopPropagation();
let popup = document.getElementById(pinId + '-popup');
popup.style.visibility = popup.style.visibility == 'visible' ? 'hidden' : 'visible';
}
EOS
$HexGrid::Dynamic::click_region = <<EOS;
function clickRegion(regionId, x, y, event) {
event.stopPropagation();
let popup = document.getElementById(regionId + '-popup');
popup.style.visibility = popup.style.visibility == 'visible' ? 'hidden' : 'visible';
if (popup.style.visibility == 'visible')
{
popup.transform.baseVal.getItem(0).setTranslate(x, y);
}
}
EOS
$HexGrid::Dynamic::toggle_coords = <<EOS;
function toggleCoords(show) {
for (var elem of document.getElementsByClassName('coords')) {
elem.style.visibility = show ? 'visible' : 'hidden';
}
}
EOS
$HexGrid::Dynamic::coords_toggler = <<EOS;
<label for="show-coords-checkbox">Show coordinates</label>
<input type="checkbox" checked id="show-coords-checkbox" onclick="toggleCoords(event.srcElement.checked)" />
EOS
sub render_html($svg, $options = undef)
{
my $document = "<!DOCTYPE html>";
$document .= "\n<html>\n<body>";
if($options)
{
if (ref $options eq 'HASH')
{
$document .= "\n<script>\n";
$document .= $HexGrid::Dynamic::click_pin if $options->{pin_popups};
$document .= $HexGrid::Dynamic::click_region if $options->{region_popups};
$document .= $HexGrid::Dynamic::toggle_coords if $options->{toggle_coords};
$document .= "\n</script>\n";
$document .= $HexGrid::Dynamic::coords_toggler if $options->{toggle_coords};
}
else
{
carp("Options passed to HexGrid::Dynamic::render_html must be a hash ref");
return;
}
}
$document .= "\n" . $svg;
$document .= "\n</body>\n</html>";
return $document;
}
1;

@ -13,7 +13,7 @@ has link => (is => 'rw', alias => 'href');
has description => (is => 'rw', alias => 'desc');
has popup => (is => 'rw', default => 1, alias => 'use_popup');
has popup_class => (is => 'rw', default => 'pin-popup');
has popup_class => (is => 'rw', default => 'popup pin-popup');
sub render($this, $pin_container, $x, $y, $w, $h, $clip_path, $layers)
{
@ -21,7 +21,7 @@ sub render($this, $pin_container, $x, $y, $w, $h, $clip_path, $layers)
my $element = $group->use(href => "#$this->{icon}_symbol",
x => $x, y => $y, width => $w, height => $h);
$element->{id} = "$this->{id}-use";
$element->{onclick} = "clickPin('$this->{id}', '$pin_container->{id}');"
$element->{onclick} = "clickPin('$this->{id}', event);"
if $this->popup;
my $center_x = $x + $w/2;
my $center_y = $y + $h/2;
@ -36,7 +36,7 @@ sub render($this, $pin_container, $x, $y, $w, $h, $clip_path, $layers)
sub render_popup($this, $popup_container, $transform, $x_shift, $y_shift)
{
my $popup_scaler = $popup_container->
g(id => "$this->{id}-popup",transform => $transform, class => $this->{popup_class})->
g(id => "$this->{id}-popup", transform => $transform, class => $this->{popup_class})->
svg(id => "$this->{id}-scaler");
my $popup = new HexGrid::PopUp
(

@ -16,6 +16,9 @@ has name => (is => 'rw', required => 1);
has defaults => (is => 'rw', default => sub { {} });
has id_suffix => (is => 'rw', default => '_region');
has popup_class => (is => 'rw', default => 'popup region-popup');
has popup => (is => 'rw', default => undef);
# New region with same properties, but doesn't import tiles
sub clone($this)
{
@ -48,8 +51,9 @@ sub iter_tile($this, $code)
sub render($this, $svg, $grid, $layers)
{
my $base_id = HexGrid::to_id("$this->{name}$this->{id_suffix}");
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}"));
my $g = $svg->g(id => $base_id);
foreach my $nw (keys %{$this->{tiles}})
{
foreach my $sw (keys %{$this->{tiles}{$nw}})
@ -59,6 +63,12 @@ sub render($this, $svg, $grid, $layers)
{
my $tile_group = $this->{tiles}{$nw}{$sw}->render($g, $grid->tile_width, $grid->tile_height, $layers);
$tile_group->{transform} = "translate($x_translate, $y_translate)";
if ($this->popup)
{
my $popup_x = $x_translate + $grid->tile_width / 2;
my $popup_y = $y_translate - $this->{popup}{height} + $grid->tile_height / 2;
$tile_group->{onclick} = "clickRegion('$base_id', $popup_x, $popup_y, event);";
}
};
$min_x = $x_translate if $x_translate < $min_x;
@ -67,6 +77,16 @@ sub render($this, $svg, $grid, $layers)
$max_y = $y_translate if $y_translate > $max_y;
}
}
if ($this->popup)
{
push @{$layers->{popups}}, sub ($popup_container)
{
my $popup_scaler = $popup_container->
g(id => "$base_id-popup", class => $this->{popup_class}, transform => "translate(0,0)")
->svg(id => "$base_id-scaler");
$this->{popup}->render($popup_scaler);
};
}
return { min_x => $min_x,min_y => $min_y,max_x => $max_x,max_y => $max_y, group => $g };
}

@ -3,6 +3,8 @@ use rlib '.';
use HexGrid;
use HexGrid::Pin;
use HexGrid::PopUp;
use HexGrid::Dynamic;
use MWTemplate;
use MediaWiki::API;
@ -96,6 +98,15 @@ foreach my $page (values %{$region_query_results->{query}{pages}})
$region->{defaults}{colour} = $parsed_template->{named_params}{colour};
$region->{defaults}{coords_colour} = $parsed_template->{named_params}{coordinates_colour}
if $parsed_template->{named_params}{coordinates_colour};
if($html_document)
{
$region->{popup} = HexGrid::PopUp->new
(
name => $region->{name},
description => $parsed_template->{named_params}{abstract},
link => $page->{canonicalurl}
);
}
if($regiondir)
{
$regions_by_subregion{$region->{name}} = $region->{name};
@ -129,6 +140,15 @@ foreach my $page (values %{$subregion_query_results->{query}{pages}})
$subregion->{defaults}{colour} = $parsed_template->{named_params}{colour};
$subregion->{defaults}{coords_colour} = $parsed_template->{named_params}{coordinates_colour}
if $parsed_template->{named_params}{coordinates_colour};
if($html_document)
{
$subregion->{popup} = HexGrid::PopUp->new
(
name => $subregion->{name},
description => $parsed_template->{named_params}{abstract},
link => $page->{canonicalurl}
);
}
if($regiondir)
{
my $region_name = $parsed_template->{positional_params}[0];
@ -167,6 +187,15 @@ foreach my $page (values %{$location_query_results->{query}{pages}})
$location->{defaults}{coords_colour} = $parsed_template->{named_params}{coordinates_colour}
if $parsed_template->{named_params}{coordinates_colour};
push @{$background_pages{"File:$parsed_template->{named_params}{background}"}}, $location;
if($html_document)
{
$location->{popup} = HexGrid::PopUp->new
(
name => $location->{name},
description => $parsed_template->{named_params}{abstract},
link => $page->{canonicalurl}
);
}
my $region_name = $parsed_template->{positional_params}[1];
$regions_by_subregion{$location->{name}} = $region_name;
@ -410,7 +439,8 @@ foreach my $page (values %{$site_icon_query_results->{query}{pages}})
# Render and output
open (my $fh, "> $outfile") or croak "Couldn't open $outfile for writing: $!";
say $fh ($html_document ? wrap_in_html($grid) : $grid->render);
say $fh ($html_document ? HexGrid::Dynamic::render_html($grid->render,
{ toggle_coords => $show_coords, pin_popups => 1, region_popups => 1 }) : $grid->render);
close $fh;
if($regiondir)
@ -436,7 +466,8 @@ if($regiondir)
say STDERR "Rendering Region $region\'s grid";
open (my $region_fh, "> $region.$extension")
or croak "Couldn't open $region.extension for writing: $!";
say $region_fh ($html_document ? wrap_in_html($region_grid) : $region_grid->render);
say $region_fh ($html_document ? HexGrid::Dynamic::render_html($grid->render,
{ toggle_coords => $show_coords, pin_popups => 1, region_popups => 1 }) : $region_grid->render);
close $region_fh;
}
# TODO: Location grids need to import images
@ -445,41 +476,8 @@ if($regiondir)
say STDERR "Rendering Location $location_name\'s grid";
open (my $location_fh, "> $location_name.$extension")
or croak "Couldn't open $location_name.$extension for writing: $!";
say $location_fh ($html_document ? wrap_in_html($location_grid) : $location_grid->render);
say $location_fh ($html_document ? HexGrid::Dynamic::render_html($grid->render,
{ toggle_coords => $show_coords, pin_popups => 1, region_popups => 1 }) : $location_grid->render);
close $location_fh;
}
}
# Puts the rendered SVG inside an html document,
# along with a bit of javascript to show popups for sites and to toggle coordinates visibility
sub wrap_in_html($grid)
{
my $html_builder = "<!DOCTYPE html>";
$html_builder .= "\n<html>\n<body>";
$html_builder .= "\n" . <<EOS;
<script>
function clickPin(pinId, containerId) {
let popup = document.getElementById(pinId + '-popup');
popup.style.visibility = popup.style.visibility == 'visible' ? 'hidden' : 'visible';
}
</script>
EOS
if($show_coords)
{
$html_builder .= <<EOS;
<script>
function toggleCoords(show) {
for (var elem of document.getElementsByClassName('coords')) {
elem.style.visibility = show ? 'visible' : 'hidden';
}
}
</script>
<label for="show-coords-checkbox">Show coordinates</label>
<input type="checkbox" checked id="show-coords-checkbox" onclick="toggleCoords(event.srcElement.checked)" />
EOS
}
$html_builder .= "\n" . $grid->render;
$html_builder .= "\n</body>\n</html>";
return $html_builder;
}

Loading…
Cancel
Save