Я создаю терминальное приложение с 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>Не могли бы вы объяснить, что означает «насколько это возможно» в данном контексте? При каких обстоятельствах он не поместился бы на экране?
@AHaworth я обновил вопрос



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я изо всех сил пытаюсь понять вашу проблему, но я думаю, что вы пытаетесь разместить числа в сетке 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>когда #game изменяется, чтобы соответствовать размеру экрана, между символами «1» не должно появляться пустого места. я пытаюсь воспроизвести командную строку Windows
2 возможности: 1 - это означает, что количество строк не равно 25, количество столбцов не равно 100. Эти числа должны увеличиваться или уменьшаться в зависимости от размера #game. 2- строк 25, столбцов 100, шрифт внутри каждой ячейки должен заполнять размер 1 ячейки
вам нужно, чтобы игра была на 100% шире?
если экран пользователя шире, чем #game, #game должен располагаться по центру и масштабироваться так, чтобы он касался верхней и нижней части экрана. #игра должна подстраиваться под размер экрана. количество строк и столбцов должно оставаться одинаковым независимо от разрешения экрана.
Что касается вашего комментария, это означает, что размер шрифта увеличивается, чтобы заполнить ячейку. Но до какого размера? «экран шире, чем #game», значит, размер #game имеет ограничение?
Точное масштабирование 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>в целом работает очень хорошо, но нашел баг: обрезает одну строку и один столбец imgur.com/XOyTyjw imgur.com/A3W4U9p
@Nire Да, просто небольшие изменения, "alignment-baseline", а не "alignmentBaseline", и в ваших циклах было y = 0; y <= numRows; y++ вместо y = 0; y < numRows; y++, в других у вас будет 26 строк, а не 25.
Все элементы в элементе body центрированы как по вертикали, так и по горизонтали из-за
display: flex; justify-content: center; align-items: center;