Skip to content

Instantly share code, notes, and snippets.

@zackthehuman
Created February 20, 2012 03:46
Show Gist options
  • Select an option

  • Save zackthehuman/1867663 to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown
Author

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

@Apreche
Copy link
Copy Markdown

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
Copy Markdown

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
Copy Markdown

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
Copy Markdown

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
Copy Markdown

Awesome

@Krischeto
Copy link
Copy Markdown

I search for rotated hexagon grid 1 hour

@skeltont
Copy link
Copy Markdown

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