3

Меня заинтересовала работа участника @CbIPoK2513, где он создал координатную сетку с помощью технологии CSS, используя абсолютную единицу измерения - пиксель(px).

Вот его первая часть ответа на вопрос Как сделать адаптивную координатную сетку:

body {

--wM: 1px; /* Толщина линии / --xM: 10px; / Отступ по ширине / --yM: 10px; / Отступ по высоте / --cM: #ccc; / Цвет линии */

--wB: 1px; /* Толщина линии / --xB: 100px; / Отступ по ширине / --yB: 100px; / Отступ по высоте / --cB: #333; / Цвет линии */

background-position: -1px 0; background-image: linear-gradient(90deg, var(--cB) var(--wB), transparent var(--wB)), linear-gradient(0deg, var(--cB) var(--wB), transparent var(--wB)), linear-gradient(90deg, var(--cM) var(--wM), transparent var(--wM)), linear-gradient(0deg, var(--cM) var(--wM), transparent var(--wM)); background-size: var(--xB) 100%, 100% var(--yB), var(--xM) 100%, 100% var(--yM); }

#block { width: 150px; height: 150px; border: 1px solid red; box-sizing: border-box; position: absolute; left: 100px; top: 50px; }

<div id="block"></div> <!-- Для примера -->

Автор: @CbIPoK2513

Такая координатная сетка для удобства работы используется как фон (подложка) при отладке и вёрстке различных элементов дизайна web-страниц, а также демонстрации прозрачности этих элементов. Например, участник @UModeL использует в своей работе (ответах) изображение, которое он самостоятельно нарисовал в растровом редакторе. Вот пример такого использования:

* {
  margin: 0;
  padding: 0;
}

body { width: 100%; height: 100vh; background: url("https://i.stack.imgur.com/m9NKc.png") 0% 0% no-repeat #eee; }

Вопрос: Возможны ли иные варианты создать подобную координатную сетку, используя любые другие средства и технологии, указанные в метках вопроса?

Sevastopol'
  • 28,195

3 Answers3

4

Такую координатную сетку я попытался создать с помощью HTML+CSS и JavaScript. Вот, что у меня получилось:

// Ширина окна
document.getElementById('width').innerHTML = window.innerWidth;
// Высота окна
document.getElementById('height').innerHTML = window.innerHeight;

// Ширину окна делим на 10 пикселей (размер ячейки) и получаем количество ячеек по горизонтали var num_w = innerWidth / 10; // Высоту окна делим на 10 пикселей (размер ячейки) и получаем количество ячеек по вертикали var num_h = innerHeight / 10;

// Выводим результаты в консоль console.log('Ш:',num_w,'~','В:',num_h);

// Выводим общее количество ячеек на экран document.getElementById('pixel').innerHTML = ("<div class='row'>" + "<div class='cell'></div>".repeat(num_w) + "</div>").repeat(num_h);

/*Общие стили*/
* {box-sizing: border-box; margin: 0; padding: 0;}
body {width: 100%; height: 100vh; overflow: hidden;}

/*Координатная сетка*/
#pixel {display: table;}
.row {display: table-row; height: 10px;}
.cell {display: table-cell; border-right: 1px solid black; border-bottom: 1px solid black; width: 10px; height: 10px;}

/*Окно с размерами*/
.info {position: fixed; top: 50px; left: 0; border: none; background: black; color: white; width: 200px; height: 100px;}
.info p {padding: 7px 7px 0 7px; font-size: 12px; font-family: monospace;}
<!--Координатная сетка-->
<div id="pixel"></div>

<!--Окно с размерами-->
<div class="info">
<p>Ширина окна: <b id="width"></b>px</p>
<p>Высота окна: <b id="height"></b>px</p>
<p></p>
<p>Ширина этого блока - <b>200</b>px</p>
<p>Высота этого блока - <b>100</b>px</p>
</div>

Однако, у такого решения имеются два минуса:

  1. В случае, если ширина окна не кратна десяти, то сетка полностью не заполняет всю его рабочую область (как по горизонтали, так и по вертикали) и не выходит за его пределы, а обрезается, оставляя по правой и нижней сторонам пустое пространство. По всей видимости, необходимо каким-то образом округлять размеры экрана всегда в большую сторону.
  2. При изменении (масштабировании, risize) размера окна координатная сетка не перерисовывается.

Предлагаю доработать это решение и дать самостоятельный ответ. А также приветствуются любые другие индивидуальные варианты ответов.

Sevastopol'
  • 28,195
4

JavaScript + Canvas:

function createBackgroundGrid() {
    let context = document.getElementById("background-grid").getContext("2d");
    const LINE_TYPES = 3;
    const beginPos = [0.5, 50.5, 0.5];
    const step     = [10,  100,  100];
    const style    = ["rgb(210,210,210)", "rgb(150,150,150)", "rgb(0,0,0)"];
function handler() {
    context.canvas.width  = document.documentElement.clientWidth;
    context.canvas.height = document.documentElement.clientHeight;

    context.fillStyle = "rgb(245, 245, 245)";
    context.fillRect(0, 0, context.canvas.width, context.canvas.height);

    for (let lineType = 0; lineType &lt; LINE_TYPES; ++lineType)
        for (let dir = 0; dir &lt; 2; ++dir) {
            context.beginPath()
            context.strokeStyle = style[lineType];
            let index = beginPos[lineType];
            if (dir == 0)
                while (index &lt; context.canvas.width) {
                    context.moveTo(index, 0);
                    context.lineTo(index, context.canvas.height);
                    index += step[lineType];
                }
            else
                while (index &lt; context.canvas.height) {
                    context.moveTo(0, index);
                    context.lineTo(context.canvas.width, index);
                    index += step[lineType];
                }
            context.stroke();
        }

    const colShift = 5, rowShift = 10;

    context.fillStyle = "blue";
    let col = 0;
    while (col + colShift &lt; context.canvas.width) {
        context.fillText(col, col + colShift, 0 + rowShift);
        col += step[step.length - 1];
    }

    context.fillStyle = "red";
    let row = 0 + step[step.length - 1];
    while (row + rowShift &lt; context.canvas.height) {
        context.fillText(row, 0 + colShift, row + rowShift);
        row += step[step.length - 1];
    }
}
handler();
window.addEventListener("resize", () =&gt; requestAnimationFrame(handler));

}

createBackgroundGrid();

#background-grid {
    position: fixed;
    left: 0px;
    top: 0px;
}
<canvas id = "background-grid"></canvas>
wololo
  • 6,221
2

Хочу дополнить ответ @Sevastopol':

Я бы отметил тут ещё третий минус - каждая ячейка секции это элемент и их много, это нагружает страницу, что но есть хорошо.


Так же хочу дополнить, что в данную сетку можно добавить "ориентиры" в виде нумирации, допустим каждого 100го пикселя, средствами CSS:

// Ширину окна делим на 10 пикселей (размер ячейки) и получаем количество ячеек по горизонтали
var num_w = innerWidth / 10;
// Высоту окна делим на 10 пикселей (размер ячейки) и получаем количество ячеек по вертикали
var num_h = innerHeight / 10;

// Выводим общее количество ячеек на экран document.getElementById('pixel').innerHTML = ("<div class='row'>" + "<div class='cell'></div>".repeat(num_w) + "</div>").repeat(num_h);

/*Общие стили*/
* {box-sizing: border-box; margin: 0; padding: 0;}
body {width: 100%; height: 100vh; overflow: hidden;}


/*Координатная сетка*/
#pixel {
  display: flex;
  flex-direction: column;
  counter-reset: X, Y;
}

.row {
  display: flex;
  flex-direction: row;
  height: 10px;
}

.cell {
  display: block;
  border-right: 1px solid #ccc;
  border-bottom: 1px solid #ccc;
  width: 10px;
  height: 10px;
}


/* "Ориентиры" по высоте */
.row:nth-child(10n+10) {
  counter-increment: Y;
  position: relative;
}

.row:nth-child(10n+10) .cell {
  border-bottom-color: #333;
}

.row:nth-child(10n+10)::before {
  content: counter(Y)'00';
  display: inline-block;
  position: absolute;
  left: 0;
  top: 100%;
}

/* "Ориентиры" по ширине */
.row .cell:nth-child(10n+10) {
  border-right-color: #333;
}

.row:first-child .cell:nth-child(10n+10) {
  counter-increment: X;
  position: relative;
}

.row:first-child .cell:nth-child(10n+10)::before {
  content: counter(X)'00';
  display: inline-block;
  position: absolute;
  left: 100%;
  top: 0;
}

/* блок для теста */
#test {
  width: 150px;
  height: 100px;
  border: 2px solid red;
  position: absolute;
  left: 50px;
  top: 50px;
  box-sizing: border-box;
}
<!--Координатная сетка-->
<div id="pixel"></div>

<!--Блок для теста--->
<div id="test"></div>

А минус:

При изменении (масштабировании, risize) размера окна координатная сетка не перерисовывается.

можно и решить:

function Render() {
  var num_w = innerWidth / 10;
  var num_h = innerHeight / 10;

document.getElementById('pixel').innerHTML = ('<div class="row">'+'<div class="cell"></div>'.repeat(num_w)+'</div>').repeat(num_h); } Render();

window.addEventListener('resize', Render);

/*Общие стили*/
* {box-sizing: border-box; margin: 0; padding: 0;}
body {width: 100%; height: 100vh; overflow: hidden;}


/*Координатная сетка*/
#pixel {
  display: flex;
  flex-direction: column;
  counter-reset: X, Y;
}

.row {
  display: flex;
  flex-direction: row;
  height: 10px;
}

.cell {
  display: block;
  border-right: 1px solid #ccc;
  border-bottom: 1px solid #ccc;
  width: 10px;
  height: 10px;
}


/* "Ориентиры" по высоте */
.row:nth-child(10n+10) {
  counter-increment: Y;
  position: relative;
}

.row:nth-child(10n+10) .cell {
  border-bottom-color: #333;
}

.row:nth-child(10n+10)::before {
  content: counter(Y)'00';
  display: inline-block;
  position: absolute;
  left: 0;
  top: 100%;
}

/* "Ориентиры" по ширине */
.row .cell:nth-child(10n+10) {
  border-right-color: #333;
}

.row:first-child .cell:nth-child(10n+10) {
  counter-increment: X;
  position: relative;
}

.row:first-child .cell:nth-child(10n+10)::before {
  content: counter(X)'00';
  display: inline-block;
  position: absolute;
  left: 100%;
  top: 0;
}

/* блок для теста */
#test {
  width: 150px;
  height: 100px;
  border: 2px solid red;
  position: absolute;
  left: 50px;
  top: 50px;
  box-sizing: border-box;
}
<!--Координатная сетка-->
<div id="pixel"></div>

<!--Блок для теста--->
<div id="test"></div>
De.Minov
  • 24,026
  • 1
    Sevastopol', спасибо, на галочку не претендую, этот ответ всего лишь дополнение :) – De.Minov Mar 09 '21 at 09:59
  • Спасибо, воспользовался. Имеет место быть полезной при размещении блоков некоторых модификаций модов в играх. Как такой код реализовать вне браузера? – Тём Тёмыч May 02 '23 at 09:29
  • @ТёмТёмыч, тут речь конкретно про веб, если же речь идёт об игровых движках - то там своя координатная плоскость, да и свой подход для реализации, либо такое изначально уже может быть где-то в дев-тулсах движка. – De.Minov May 03 '23 at 07:01