A Pen by Andraž Kos on CodePen.
Created
August 8, 2024 11:43
-
-
Save andraz/2825861d66e09d75ae9ff89134050810 to your computer and use it in GitHub Desktop.
Honeycomb Blueprint background
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<canvas id="canvas"></canvas> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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