Я создаю терминальное приложение с JS. Я хочу иметь возможность изменять цвет отдельных символов, поэтому я решил использовать много спанов для их отображения. Каждый диапазон содержит только один символ. Вот что у меня получилось . Он отлично работает, но я хочу, чтобы «промежуток экрана» (зеленый контур) максимально соответствовал экрану. Он должен масштабироваться, но сохранять соотношение сторон. Код выложил на CodePen.
Я попытался изменить размер div, содержащего спаны, но это не помогло. Затем я попытался изменить размер шрифта промежутков, но это тоже не помогло. Может быть, есть лучший способ добиться всего этого.
ОБНОВЛЕНИЕ: Вот так сейчас, и вот так должно быть.
Вот код:
document.addEventListener("DOMContentLoaded", draw);
function draw() {
game = document.getElementById("game");
for (y = 0; y <= 25; y++) {
for (x = 0; x <= 100; x++) {
cell = document.createElement("span");
cell.innerText = "1";
game.appendChild(cell);
}
game.appendChild(document.createElement("br"));
}
}
* {
margin: 0;
padding: 0;
border: 0;
}
html {
min-height: 100vh;
}
body {
min-height: 100vh;
box-shadow: 0px 0px 0px 10px red inset;
display: flex;
justify-content: center;
align-items: center;
}
#game {
box-shadow: 0px 0px 0px 10px green inset;
}
span {
font-family: Cascadia Code;
}
<div id='game'></div>
🤔 А знаете ли вы, что...
JavaScript поддерживает работу с различными форматами данных, такими как JSON и XML.
Я изо всех сил пытаюсь понять вашу проблему, но я думаю, что вы пытаетесь разместить числа в сетке 101 на 25 внутри контейнера неизвестной ширины. Если вы установите ширину каждого пролета на calc(100%/101)
, вы сможете это сделать.
#game {
box-shadow: 0px 0px 0px 10px green inset;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
span {
font-family: Cascadia Code;
width: calc(100%/101);
display: flex;
justify-content: center;
align-items: center;
}
Не могли бы вы использовать сетку? Если это игра, хорошо, когда вы можете обращаться к каждой ячейке по строке и столбцу.
let str = '';
for (let i = 0; i < 25; i++) {
for (let j = 0; j < 100; j++) {
str += '<div>1</div>';
}
}
document.querySelector('#game').innerHTML = str;
*,
*:before,
*:after {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
}
#gameWrapper {
position: relative;
width: 100vw;
height: 100vh;
}
#game {
position: absolute;
top: 50%;
transform: translateY(-50%);
display: grid;
grid-template-rows: repeat(25, auto);
grid-template-columns: repeat(100, 1fr);
gap: 0;
width: 100%;
}
#game {
box-shadow: 0px 0px 0px 10px green inset;
}
<div id = "gameWrapper">
<div id = "game">
</div>
</div>
Точное масштабирование HTML-элементов может быть непростой задачей.
Но SVG предназначены для масштабирования, поэтому, если вы создадите свой терминал внутри SVG, все станет намного проще.
Ниже приведен рабочий фрагмент, я настроил строки и столбцы, чтобы они лучше подходили внутри фрагмента SO. Вы также можете настроить масштаб SVG по осям X и Y с помощью атрибута preserveAspectRatio
. Щелкните SVG, чтобы увидеть разницу.
const tw = 10;
const th = 12;
const numCols = 40;
const numRows = 32;
function getNode(n, v) {
n = document.createElementNS("http://www.w3.org/2000/svg", n);
for (var p in v)
n.setAttributeNS(null, p, v[p]);
return n
}
function draw() {
const svg = getNode('svg', {
viewBox: `0 0 ${tw*numCols} ${th*numRows}`});
svg.style.display = 'block';
for (y = 0; y < numRows; y++) {
for (x = 0; x < numCols; x++) {
cell = getNode('text', {
"alignment-baseline":"hanging",
x: x * tw,
y: y * th,
class: 'cell',
});
cell.innerHTML = (x+y)%10;
svg.appendChild(cell);
}
}
game.appendChild(svg);
svg.addEventListener('click', () => {
const p = svg.getAttribute('preserveAspectRatio');
svg.setAttribute('preserveAspectRatio',
p === 'none' ? '' : 'none');
});
}
draw();
* {
margin: 0;
padding: 0;
border: 0;
}
html,
body {
height: 100%;
}
.cell {
font-family: courier;
}
#game {
height: 100%;
}
svg {
display: block;
width: 100%;
height: 100%;
}
<div id='game'>
</div>