Skip to content

Instantly share code, notes, and snippets.

@zackthehuman
Created February 20, 2012 03:46
Show Gist options
  • Star 37 You must be signed in to star a gist
  • Fork 20 You must be signed in to fork a gist
  • Save zackthehuman/1867663 to your computer and use it in GitHub Desktop.
Save zackthehuman/1867663 to your computer and use it in GitHub Desktop.
Drawing a hexagonal grid with HTML canvas
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Canvas Hexagonal Map</title>
<style type="text/css">
canvas {
border:0;
display:block;
margin:0 auto;
}
</style>
</head>
<body>
<canvas id="hexmap" width="660" height="624"></canvas>
<script src="hexagons.js"></script>
</body>
</html>
(function(){
var canvas = document.getElementById('hexmap');
var hexHeight,
hexRadius,
hexRectangleHeight,
hexRectangleWidth,
hexagonAngle = 0.523598776, // 30 degrees in radians
sideLength = 36,
boardWidth = 10,
boardHeight = 10;
hexHeight = Math.sin(hexagonAngle) * sideLength;
hexRadius = Math.cos(hexagonAngle) * sideLength;
hexRectangleHeight = sideLength + 2 * hexHeight;
hexRectangleWidth = 2 * hexRadius;
if (canvas.getContext){
var ctx = canvas.getContext('2d');
ctx.fillStyle = "#000000";
ctx.strokeStyle = "#CCCCCC";
ctx.lineWidth = 1;
drawBoard(ctx, boardWidth, boardHeight);
canvas.addEventListener("mousemove", function(eventInfo) {
var x,
y,
hexX,
hexY,
screenX,
screenY;
x = eventInfo.offsetX || eventInfo.layerX;
y = eventInfo.offsetY || eventInfo.layerY;
hexY = Math.floor(y / (hexHeight + sideLength));
hexX = Math.floor((x - (hexY % 2) * hexRadius) / hexRectangleWidth);
screenX = hexX * hexRectangleWidth + ((hexY % 2) * hexRadius);
screenY = hexY * (hexHeight + sideLength);
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBoard(ctx, boardWidth, boardHeight);
// Check if the mouse's coords are on the board
if(hexX >= 0 && hexX < boardWidth) {
if(hexY >= 0 && hexY < boardHeight) {
ctx.fillStyle = "#000000";
drawHexagon(ctx, screenX, screenY, true);
}
}
});
}
function drawBoard(canvasContext, width, height) {
var i,
j;
for(i = 0; i < width; ++i) {
for(j = 0; j < height; ++j) {
drawHexagon(
ctx,
i * hexRectangleWidth + ((j % 2) * hexRadius),
j * (sideLength + hexHeight),
false
);
}
}
}
function drawHexagon(canvasContext, x, y, fill) {
var fill = fill || false;
canvasContext.beginPath();
canvasContext.moveTo(x + hexRadius, y);
canvasContext.lineTo(x + hexRectangleWidth, y + hexHeight);
canvasContext.lineTo(x + hexRectangleWidth, y + hexHeight + sideLength);
canvasContext.lineTo(x + hexRadius, y + hexRectangleHeight);
canvasContext.lineTo(x, y + sideLength + hexHeight);
canvasContext.lineTo(x, y + hexHeight);
canvasContext.closePath();
if(fill) {
canvasContext.fill();
} else {
canvasContext.stroke();
}
}
})();
@zackthehuman
Copy link
Author

Works in Chrome but my mouse position gather is wrong for Firefox. Working on a fix...

@Apreche
Copy link

Apreche commented Nov 25, 2012

I'm thinking of making a version of this that scales with window size. Either more hexes will be visible with a larger window, or the map will have a fixed number of hexes that will get bigger and easier to see.

@matthewisabel
Copy link

Forked and added a few lines to fix the mouse positioning in FF. Using getBoundingClientRect(), I see the correct behavior in Chrome, FF, IE9, and Opera on Win 7.

@ArneBab
Copy link

ArneBab commented Mar 22, 2015

forked to experiment with conways life in hexagon. Would you allow me to use this under a license which is compatible with GPL?

@JohnRayson
Copy link

Great work: I've incorporated your core hex drawing logic into my own project here: https://github.com/JohnRayson/Hexagons_Rebooted
You are currently referenced in the MD file, is there a specific way you would like me to attribute the work to yourself?

@Krischeto
Copy link

Awesome

@Krischeto
Copy link

I search for rotated hexagon grid 1 hour

@skeltont
Copy link

skeltont commented Jul 3, 2018

Absolutely awesome, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment