Скриншот из DOOM, отрендеренного с помощью нативных чекбоксов
Скриншот из DOOM, отрендеренного с помощью нативных чекбоксов

Дисклеймер: перевод статьи публикуется с одобрения оригинального автора

Поиграть можно тут (Chrome/Edge), исходный код здесь, текст статьи ниже.

На этой неделе я прочитал статью Брайана Брауна — "Я всё ещё продолжаю экспериментировать с чекбоксами". Там он рассказывал про свою библиотеку Checkboxland.

JavaScript-библиотека для отображения текста и анимаций на сетке из чекбоксов

Это довольно приятная библиотека. Её API и документация лучше некоторых библиотек, с которыми мне приходится иметь дело на работе. С её помощью можно рендерить текст, фигуры, изображения и видео. Есть низкоуровневое API. В ней есть всё, что надо. Брайан использовал Checkboxland для создания шикарных интерактивных анимаций.

Кто-то на Hacker News прокомментировал статью:

Я не думаю, что вы исчерпаете все возможности библиотеки, до тех пор пока не отренедерите с её помощью DOOM

После проверки, что Брайан ещё не взялся за реализацию этой идеи, я начал скрещивать Checkboxland и WebAssembly-порт DOOM Корнелиуса Дайкменна.

Корнелиус во всех деталях описывает процесс портирования DOOM в README. Я взял его порт за основу и написал glue-код для интеграции с Checkboxland.

В моём проекте DOOM запускается с помощью WebAssembly и рендерится в невидимый <canvas>. Я использую HTMLCanvasElement.captureStream() для его преобразования в MediaStream. Элемент <video> отображает MediaStream и передаётся методу renderVideo из Checkboxland. Я экспериментировал с разными пороговыми значениями, чтобы картинка получилась настолько чёткой, насколько это возможно. Одно из возможных улучшений — использовать что-то похожее на дизеринг.

Элемент <video> тоже можно было спрятать, но по моим наблюдениям пользователи не могли выйти из главного меню без посторонней помощи, если они не видели оригинальную картинку.

Наш экран — это сетка 160 на 100, состоящая из нативных чекбоксов. С более высоким разрешением FPS падал совсем низко. Изображение в начале статьи из ранней версии с разрешением 320x200.

const cbl = new Checkboxland({
  dimensions: "160x100",
  selector: "#checkboxes",
});

Стигматизированное CSS-свойство zoom используется для уменьшения размера чекбоксов. Использование transform: scale(x) приводило к худшей производительности и качеству картинки. К сожалению, это означает, что пользователи Firefox должны вручную уменьшить масштаб страницы.

Эта нестандартное свойство, и оно не находится в процессе стандартизации. Не используйте его на публичных сайтах — оно не будет работать у всех пользователей.

События нажатия клавиш форвардятся в скрытый <canvas>, чтобы избежать проблем с фокусом.

const forwardKey = (e, type) => {
  const ev = new KeyboardEvent(type, {
    key: e.key,
    keyCode: e.keyCode,
  });
  canvas.dispatchEvent(ev);
};

document.body.addEventListener("keydown", function (e) {
  forwardKey(e, "keydown");
});

document.body.addEventListener("keyup", function (e) {
  forwardKey(e, "keyup");
});

На время загрузки и компиляции WebAssembly-модуля на сетке отображается сообщение с помощью метода print:

Сообщение о загрузке WebAssembly, отрендеренное с помощью чекбоксов
Сообщение о загрузке WebAssembly, отрендеренное с помощью чекбоксов

После загрузки выводится сообщение о том, что нужно где-нибудь кликнуть, чтобы инициализировать <video>. После клика запускается игра!

Пока вы всё ещё тут, вы знали, что Билл Гейтс однажды поместил себя в DOOM, чтобы прорекламировать Windows 95?

Кадр из рекламы Windows 95, на котором изображён Билл Гейтс c ружьём внутри коридора DOOM
Кадр из рекламы Windows 95, на котором изображён Билл Гейтс c ружьём внутри коридора DOOM

Примечание переводчика: если вам понравися перевод, то вам скорее всего понравится мой телеграм-канал, где я публикую рецензии на статьи про веб-стандарты, производительность и т.п.

Комментарии (4)


  1. endlessnights
    19.11.2021 18:57
    +1

    Opera (webkit):

    image

    Не так контрастно, как я ожидал.


  1. chv
    20.11.2021 10:03
    +2

    Не очень понятно, что этим творением хотел сказать аффтар. Что любое изображение можно довольно тривиально представить в виде сетки темных и светлых квадратов? Ну это вроде и до этого было известно. Что отмеченный чекбокс — это квадрат более темный, а не отмеченный — более светлый? Это как-то не менее банальная мысль.

    В общем, как заголовок для поста может и весело, но по факту смотреть особенно не на что.


  1. namikiri
    20.11.2021 12:14
    +1

    desktop Chrome/Edge only

    Почему? Оригинальный Doom на WebAssembly прекрасно работает в Firefox (в нём же и тестировался), Checkboxland тоже ничего про зависимость от браузера не говорит. Остаётся только предположение, что автор что-то ниасилил.

    Ну и, вероятно, если бы Checkboxland не занимался придумыванием существующего (судя по виду чекбоксов, он их как-то сам переопределяет и стилизует), оно бы работало пошустрее.

    Update: перечитал и нашёл ответы на оба вопроса. В первом случае не работает нестандартное свойство, во втором чекбоксы реально так выглядят, оказывается, их стилизует сам Firefox. Упустил момент, когда он перестал использовать системный вид чекбоксов.


  1. TortIriska
    22.11.2021 03:55

    1000 посредников для вывода пикселя. Ок