Использование canvas в javascript для создания объекта ромба из прямоугольников

#javascript #html #canvas #html5-canvas

#javascript #HTML #холст #html5-canvas

Вопрос:

Я новичок в теге canvas, и спецификация для моего проекта заключается в использовании canvas для построения в виде ромба с этими черными рамками, сделанными из прямоугольников (показано на рисунке ниже):

Ромб из проекта

Это то, что я получил до сих пор:

 var canvas=document.getElementById('cilim');
    var ctx=canvas.getContext('2d');

    for(let i=0;i<11;i  ){
        ctx.beginPath();
        ctx.rect(i*50,0,50,50);
        ctx.rect(0,i*50,50,50);
        ctx.rect(i*50,10*50,50,50);
        ctx.rect(10*50,i*50,50,50);
        ctx.lineWidth=1;
        ctx.strokeStyle="lightgrey";
        ctx.stroke();
    }
    for(let i=1;i<10;i  ){
        for(let j=1;j<10;j  ){
            if((i j===6) || Math.abs((i-j))===4 || (i j)===14){
                ctx.beginPath();
                ctx.rect(i*50,j*50,50,50);
                ctx.lineWidth=2;
                ctx.strokeStyle="black";
            }else{
                ctx.beginPath();
                ctx.rect(i*50,j*50,50,50);
                ctx.lineWidth=3;
                ctx.strokeStyle="lightgrey";

            }
            ctx.stroke();
        }
    } 
 <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Cilim</title>
</head>
<body>
<canvas id="cilim" width="550px" height="550px"></canvas>
</body>
</html> 

Есть ли какой-либо другой способ сделать эти черные границы, где я ошибся, или я могу использовать любой другой объект в canvas для создания ромба такого типа. Любые отзывы, предложения приветствуются. Заранее благодарю.

Ответ №1:

Используйте 2D-массив

Есть много способов сделать это. Самое простое — это еще и самое гибкое.

Создайте карту из строки. Использование символа для определения внутри ячеек. Преобразуйте строку в 2D-массив с шагом по каждой ячейке, если ячейка содержит внутренний символ, проверьте каждую ячейку слева, вверху, справа и внизу. Для каждого ребра, если в этой позиции в массиве нет внутреннего символа, вы знаете, что у него должно быть нарисовано ребро.

Пример.

 const ctx = canvas.getContext('2d'), size = 50;
const map = `..........,
.....#....,
....###...,
...#####..,
..#######.,
.#########,
..#######.,
...#####..,
....###...,
.....#....
`.split(",").map(row => [...row.trim()]);
createGrid();
outlineCells(map);
function outlineCells(map) {
    var x, y;
    ctx.lineWidth=3;
    ctx.strokeStyle = "#000";
    ctx.beginPath();
    for (y = 0; y < map.length; y  ) {
        const row = map[y];
        for (x = 0; x < row.length; x  ) {
            if (row[x] === "#") {
               const xx = x * size, yy = y * size;
               if (row[x - 1] !== "#") {  // left edge
                  ctx.moveTo(xx, yy   size);
                  ctx.lineTo(xx, yy);               
               }
               if (y === 0 || map[y - 1][x] !== "#") {  // top edge
                  ctx.moveTo(xx, yy);
                  ctx.lineTo(xx   size, yy);               
               }
               if (row[x   1] !== "#") {  // right edge
                  ctx.moveTo(xx   size, yy);
                  ctx.lineTo(xx   size, yy   size);               
               }
               if (y === map.length - 1 || map[y   1][x] !== "#") {  // top edge
                  ctx.moveTo(xx, yy   size);
                  ctx.lineTo(xx   size, yy   size);               
               }
           }
       }
    }
    ctx.stroke();
}
function createGrid() {
    ctx.strokeStyle = "lightgrey";
    ctx.beginPath();
    for(let i = 0; i < 11; i  ) {
        ctx.rect(0, i * size, 11 * size, size);
        ctx.rect(i * size, 0, size, 11 * size);
   }
    ctx.stroke();
} 
 <canvas id="canvas" width="550" height="550"></canvas> 

Комментарии:

1. Спасибо за ваш ответ, я только что попробовал что-то похожее на ваш ответ, для этих черных границ я использовал moveTo и lineTo, проверил диагонали, и это работает.