Skip to content

Instantly share code, notes, and snippets.

@andraz
Created August 8, 2024 11:43
Show Gist options
  • Save andraz/2825861d66e09d75ae9ff89134050810 to your computer and use it in GitHub Desktop.
Save andraz/2825861d66e09d75ae9ff89134050810 to your computer and use it in GitHub Desktop.
Honeycomb Blueprint background
<canvas id="canvas"></canvas>
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
canvas.height = window.innerHeight;
canvas.width = window.innerWidth;
const initialHexSize = 100; // Initial size of each hexagon
let hexSize = initialHexSize;
let hexWidth = hexSize * 2;
let hexHeight = Math.sqrt(3) * hexSize;
let outlineWidth = 0;
// Start with 2 screens of buffer area around
let offsetX = -2 * canvas.width;
let offsetY = -2 * canvas.height;
let isDragging = false;
let startX, startY;
let zoomLevel = 1;
// Function to draw a line of half of a single hexagon
function drawHexagon({ x, y, strokeColor = "#6a8ada", lineWidth = 0.15 }) {
ctx.beginPath();
// Draw bottom left half of hexagon
for (let i = 0; i < 4; i++) {
const angle = ((2 * Math.PI) / 6) * (i + 0.5);
const px = x + hexSize * Math.cos(angle);
const py = y + hexSize * Math.sin(angle);
ctx.lineTo(px, py);
}
// Stroke the line
if (strokeColor && lineWidth) {
ctx.strokeStyle = strokeColor;
ctx.lineWidth = lineWidth;
ctx.stroke();
}
}
// Function to draw the hexagon grid
function drawGrid() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
let hexHorizontalSpacing = hexWidth * 0.865;
let hexVerticalSpacing = hexHeight * 0.865 - Math.sqrt(3);
// Add 5 screens of extra clipped world outside the initial viewport
const rows = Math.ceil(canvas.height / hexVerticalSpacing) * 5;
const cols = Math.ceil(canvas.width / hexHorizontalSpacing) * 5;
for (let row = -1; row < rows; row++) {
for (let col = -1; col < cols; col++) {
const x =
col * hexHorizontalSpacing +
(row % 2 === 1 ? hexHorizontalSpacing / 2 : 0) +
offsetX;
const y = row * hexVerticalSpacing + offsetY;
drawHexagon({ x, y, lineWidth: zoomLevel });
}
}
}
// Function to convert mouse coordinates to axial coordinates
function getAxialCoordinates(mouseX, mouseY) {
const q = (mouseX * 2) / 3 / hexSize - offsetX / hexHorizontalSpacing;
const r =
(-mouseX / 3 + (Math.sqrt(3) / 3) * mouseY) / hexSize -
offsetY / hexVerticalSpacing;
return { q, r };
}
// Function to get the center coordinates of a hexagon
function getHexagonCenter(q, r) {
const x =
q * hexHorizontalSpacing +
(r % 2 === 1 ? hexHorizontalSpacing / 2 : 0) +
offsetX;
const y = r * hexVerticalSpacing + offsetY;
return { x, y };
}
// Event listeners for dragging
canvas.addEventListener("mousedown", (e) => {
isDragging = true;
startX = e.clientX - offsetX;
startY = e.clientY - offsetY;
});
canvas.addEventListener("mousemove", (e) => {
if (isDragging) {
offsetX = e.clientX - startX;
offsetY = e.clientY - startY;
}
drawGrid(); // Redraw the grid to move with cursor
});
canvas.addEventListener("mouseup", () => {
isDragging = false;
});
// Event listener for mouse wheel zoom
canvas.addEventListener("wheel", (e) => {
e.preventDefault();
const delta = Math.sign(e.deltaY);
zoomLevel += delta * 0.1;
zoomLevel = Math.max(0.1, Math.min(zoomLevel, 5));
hexSize = initialHexSize * zoomLevel;
hexWidth = hexSize * 2;
hexHeight = Math.sqrt(3) * hexSize;
hexHorizontalSpacing = hexWidth;
hexVerticalSpacing = hexHeight - 1 / Math.sqrt(3);
drawGrid();
});
// Initial grid drawing
drawGrid();
body {
margin: 0;
overflow: hidden;
}
#canvas {
background-color: hwb(222.86deg 34.81% 22.33%);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment