ol-games/examples/map.hexmap.html
2024-02-10 11:55:01 +01:00

269 lines
9.0 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<!--
Copyright (c) 2017 Jean-Marc VIGLINO,
released under CeCILL-B (french BSD like) licence: http://www.cecill.info/
-->
<title>ol-games: Hexmap</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="description" content="Hexagonal source for openlayers maps" />
<meta name="keywords" content="ol, game, hexagon, hexagonal, source, map" />
<link rel="stylesheet" href="style.css" />
<!-- jQuery -->
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
<!-- FontAwesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<!-- OpenLayers -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@latest/ol.css" />
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ol@latest/dist/ol.js"></script>
<!-- ol-ext -->
<link rel="stylesheet" href="https://rawgit.com/Viglino/ol-ext/master/dist/ol-ext.css" />
<script type="text/javascript" src="https://rawgit.com/Viglino/ol-ext/master/dist/ol-ext.js"></script>
<!-- ol-games -->
<link rel="stylesheet" href="../dist/ol-games.css" />
<script type="text/javascript" src="../dist/ol-games.js"></script>
<style>
#map
{ width:100%;
height: 600px;
margin: 0;
}
.options
{ position:absolute;
right: 1em;
}
</style>
</head>
<body >
<a href="https://github.com/Viglino/ol-games" class="icss-github-corner"><i></i></a>
<a href="../index.html">
<h1>ol-games: Hexmap</h1>
</a>
<div class="info">
<p>
hexagonal map or hex map is a game board design commonly used in wargames of all scales.
The map is subdivided into a hexagonal tiling, small regular hexagons of identical size.
<br />
<i>ol.source.HexMap</i> is an image source that render an hexagonal grid on a map.
The <i>ol.Hexgrid</i> object is used to convert from coordinate to hex or calculate lines beetween hexagons.
</p>
<p>
For more information on Hexagnol grid, I recommend this fabulous <a href="http://www.redblobgames.com/grids/hexagons/">Red Blob Games article</a>.
</p>
</div>
<!-- Map div -->
<div id="map"></div>
<div class="options" >
<h2>Options:</h2>
<div id="pattern"></div>
<ul>
<li>
layout:
<select id="layout" onchange="grid.setLayout(this.value); vector.getSource().clear();">
<option value="pointy">pointy</option>
<option value="flat">flat</option>
</select>
</li>
<li>
size:
<select id="size" onchange="grid.setSize(this.value)">
<option value="2000">small</option>
<option value="4000" selected="selected">standard</option>
<option value="6000">big</option>
</select>
</li>
<li>
actions:<br/>
<input type="radio" name="action" value="dist" /><label> distance</label>
<br/>
coords:<br/>
<input type="radio" name="action" value="axial" /><label> axial</label>
<br />
<input type="radio" name="action" value="offset" /><label> offset</label>
<br />
<input type="radio" name="action" value="cube" /><label> cube</label>
</li>
</ul>
</div>
<script type="text/javascript">
// Layers
var layers = [new ol.layer.Tile({ preload:Infinity, source: new ol.source.StadiaMaps({ layer: 'stamen_watercolor' }) })];
// Popup
var popup = new ol.Overlay.Popup (
{ popupClass: "tooltips",
positioning: 'auto'
});
// The map
var map = new ol.Map({
target: 'map',
view: new ol.View({
zoom: 11,
center: [260064, 6250762]
}),
layers: layers,
overlays: [popup]
});
var grid = new ol.HexGrid ({ size:4000, origin: map.getView().getCenter() });
var hex = new ol.source.HexMap({ hexGrid: grid });
map.addLayer ( new ol.layer.Image({ source: hex }) );
var text = false;
hex.set('text', text);
grid.setLayout($("#layout").val());
grid.setSize($("#size").val());
var vector = new ol.layer.Vector({
source: new ol.source.Vector(),
//style: new ol.style.Style ({ fill: new ol.style.Fill({ color:"red"} )})
});
map.addLayer(vector);
// Styles
var greenStyle = new ol.style.Style({
fill: new ol.style.Fill({ color: 'rgba(0,255,0,0.2)' }),
stroke: new ol.style.Stroke({ color: 'green', width: 1.25 })
});
var blueStyle = new ol.style.Style({
fill: new ol.style.Fill({ color: 'rgba(0,0,255,0.2)' }),
stroke: new ol.style.Stroke({ color: 'blue', width: 1.25 })
});
var redStyle = new ol.style.Style({
fill: new ol.style.Fill({ color: 'rgba(255,0,0,0.2)' }),
stroke: new ol.style.Stroke({ color: 'red', width: 1.25 })
});
// Pointer move
var current = [];
var start = false;
map.on(["pointermove", "click"], function(e)
{ // Coords
var h = grid.coord2hex(e.coordinate);
if (e.type!="click" && h[0]==current[0] && h[1]==current[1]) return;
current = h;
// Move
if (!text)
{ vector.getSource().clear();
var c = grid.hex2cube(grid.coord2hex(e.coordinate));
if (e.type=="click") start = c;
if (start)
{ var l = grid.cube_line(start, c);
for (var i=0; i<l.length; i++)
{ var ex = grid.getHexagon(grid.cube2hex(l[i]));
var f = new ol.Feature(new ol.geom.Polygon([ex]));
f.setStyle(redStyle);
vector.getSource().addFeature(f);
}
popup.show ( e.coordinate, "Move = "+(l.length-1)+" hexagon"+(l.length>2?"s":"") );
}
return;
}
//popup.hide();
vector.getSource().clear();
var ex = grid.getHexagon(h);
var f = new ol.Feature(new ol.geom.Polygon([ex]));
vector.getSource().addFeature(f);
var size = map.getSize();
size = Math.round( Math.max(size[0],size[1]) / grid.getSize() * map.getView().getResolution() / Math.sqrt(3) );
switch (text)
{ case 'cube':
var c = grid.hex2cube(h);
popup.show ( e.coordinate, "x: "+c[0]+", y: "+c[1]+", z: "+c[2]);
for (var x=-size; x<=size; x++)
{ if (x)
{ ex = grid.getHexagon (grid.cube2hex([c[0]+x,c[1]-x,c[2]]));
f = new ol.Feature(new ol.geom.Polygon([ex]));
f.setStyle(greenStyle);
vector.getSource().addFeature(f);
ex = grid.getHexagon (grid.cube2hex([c[0]+x,c[1],c[2]-x]));
f = new ol.Feature(new ol.geom.Polygon([ex]));
f.setStyle(blueStyle);
vector.getSource().addFeature(f);
ex = grid.getHexagon (grid.cube2hex([c[0],c[1]+x,c[2]-x]));
f = new ol.Feature(new ol.geom.Polygon([ex]));
f.setStyle(redStyle);
vector.getSource().addFeature(f);
}
}
break;
case 'axial':
popup.show ( e.coordinate, "x: "+h[0]+", y: "+h[1]);
for (var x=-size; x<=size; x++)
{ if (x)
{ ex = grid.getHexagon ([h[0]+x,h[1]]);
f = new ol.Feature(new ol.geom.Polygon([ex]));
f.setStyle(greenStyle);
vector.getSource().addFeature(f);
ex = grid.getHexagon ([h[0],h[1]+x]);
f = new ol.Feature(new ol.geom.Polygon([ex]));
f.setStyle(blueStyle);
vector.getSource().addFeature(f);
}
}
break;
case 'offset':
var o = grid.hex2offset(h);
popup.show ( e.coordinate, "x: "+o[0]+", y: "+o[1]);
for (var x=-size; x<=size; x++)
{ if (x)
{ ex = grid.getHexagon (grid.offset2hex([o[0]+x,o[1]]));
f = new ol.Feature(new ol.geom.Polygon([ex]));
f.setStyle(greenStyle);
vector.getSource().addFeature(f);
ex = grid.getHexagon (grid.offset2hex([o[0],o[1]+x]));
f = new ol.Feature(new ol.geom.Polygon([ex]));
f.setStyle(blueStyle);
vector.getSource().addFeature(f);
}
}
break;
default: break;
}
});
// Handle menu
$("label").click(function(){ $(this).prev().click(); });
$('input[name=action]').on('change', function()
{ var v = $('input[name=action]:checked').val();
vector.getSource().clear();
popup.hide();
start = false;
switch (v)
{ case 'axial':
case 'offset':
case 'cube':
text = v;
hex.showCoordiantes(v);
break;
default:
text = false;
hex.showCoordiantes(false);
break;
};
});
</script>
</body>
</html>