Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

226
Vistas
Draw grid with hexagons using canvas Html & JavaScript

I try to create a canvas with X * X of size, using hexagon shapes, currently I base on this reference, with some adaptations, my code until now look like this:

const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');

const shapeType = 6;
const angle = 2 * Math.PI / shapeType;
const radius = 20;

function init() {
    drawGrid(5);
}

init();

function drawGrid(size) {
    for (let y = radius, i = 0; i < size; i++) {
        y += radius * Math.sin(angle);
        for (let x = radius, j = 0;
             j < size;
             x += radius * (1 + Math.cos(angle)), y += (-1) ** j++ * radius * Math.sin(angle)) {
            drawHexagon(x, y);
        }
    }
}

function drawHexagon(x, y) {
    context.beginPath();
    for (let i = 0; i < shapeType; i++) {
        let xx = x + radius * Math.cos(angle * i);
        let yy = y + radius * Math.sin(angle * i);
        context.lineTo(xx, yy);
    }
    context.closePath();
    context.stroke();
}
<!DOCTYPE HTML>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>HexGrid</title>
    <style>
        .test {
            display: flex;
            justify-content: space-between;
        }

        .canvas {
            border: 1px solid #000000;
        }
    </style>
</head>
<body>
<canvas id="canvas" width="500" height="500" class="canvas"></canvas>
<script src="main.js"></script>
</body>
</html>

Until now, every thing is good, but just with odd size, but if the size is even, I get this:

even grid

As a beginner in JavaScript, I'm blocked in this, any one have any idea how can I solve this please?

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

Regular Hexagon Grid

A grid of hexagons has a regular spacing just like a grid of squares however every 2nd column if offset (down in this case) by half the hexagons height.

To get the x and y grid spacing, and the offset is half the y grid spacing.

    RADIUS = 20;
    EDGE_LEN = Math.sin(Math.PI / 6) * RADIUS * 2;
    GRID_Y_SPACE = Math.cos(Math.PI / 6) * RADIUS * 2;
    GRID_X_SPACE = RADIUS * 2 - EDGE_LEN * 0.5;
    GRID_Y_OFFSET = GRID_Y_SPACE * 0.5;

The hexagon's position can be calculated using (gx, gy are column, row positions)

    function gridToPixel(gx, gy, p = {}) {
        p.x = gx * GRID_X_SPACE;
        p.y = gy * GRID_Y_SPACE + (gx % 2 ? GRID_Y_OFFSET : 0);        
        return p;
    }

Example

Example fills canvas with hexagon grid.

const ctx = canvas.getContext('2d');

const P2 = (x, y) => ({x,y});
const EDGES = 6;
const RADIUS = 20;
const TAU = 2 * Math.PI;
const EDGE_LEN = Math.sin(Math.PI / EDGES) * RADIUS * 2;
const GRID_Y_SPACE = Math.cos(Math.PI / EDGES) * RADIUS * 2;
const GRID_X_SPACE = RADIUS * 2 - EDGE_LEN * 0.5;
const GRID_Y_OFFSET = GRID_Y_SPACE * 0.5;
const COLS = "=#3c2f18,#01335f,#3f0e77,#204a73,#511d94,#fe1f00,#0060fd,#fe7603,#f0ca1d,#b085e8,#e9cafa".split(",");
const rndItem = arr => arr[Math.random() * arr.length | 0];

drawGrid(1, 1, 15, 13, createPoly(EDGES));
function drawGrid(x, y, w, h, points) {
  const p = P2();
  var gy, gx;
  for (gy = y; gy < y + h; gy++) {
      for (gx = x; gx < x + w; gx++) {
          ctx.fillStyle = rndItem(COLS);
          drawPoly(gridToPixel(gx, gy, p), points);
      }
  }
}
function gridToPixel(gx, gy, p = {}) {
    p.x = gx * GRID_X_SPACE;
    p.y = gy * GRID_Y_SPACE + (gx % 2 ? GRID_Y_OFFSET : 0);       
    return p;
}
function drawPoly(p, points) { // p.x, p.y is center
    ctx.setTransform(1, 0, 0, 1, p.x, p.y);
    var i = 0;
    ctx.beginPath();
    while (i < points.length) {
        const p2 = points[i++];
        ctx.lineTo(p2.x, p2.y);
    }
    ctx.closePath();
    ctx.fill();
    ctx.stroke();
}
function createPoly(sides, points = []) {
    const step = TAU / sides;
    var ang = 0, i = sides;
    while (i--) {
        points.push(P2(RADIUS * Math.cos(ang), RADIUS * Math.sin(ang)));
        ang += step;
    }
    return points;
}
canvas { border: 1px solid #000000; }
<canvas id="canvas" width="500" height="500"></canvas>

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda