В последнее время мне не терпелось вернуться к созданию скринкастов и преподаванию, поэтому пару месяцев назад я собрал этот бесплатный мини-курс «Build UIs that don't suck». Людям вроде бы понравилось, и теперь я хочу заняться более масштабными видеопроектами, но тут возникла проблема.
Я — разработчик программного обеспечения.
И как разработчик ПО, точно так же, как мне нужно написать собственный генератор статических сайтов, прежде чем я смогу создать свой личный сайт, мне нужно было создать собственную платформу для курсов, прежде чем я вообще смог бы подумать о создании видеокурса.
Что ж, спустя шесть недель мы только что выпустили Compass — стартовый набор, который мы разработали с использованием Tailwind CSS и Next.js для публикации собственных онлайн-курсов.
Обязательно посмотрите интерактивное превью, чтобы оценить всё в полной мере.
Мы получили массу удовольствия от работы над этим проектом, поработали с кучей новых инструментов и технологий и решили несколько интересных задач.
Видео «картинка в картинке»
Возможно, вы раньше с этим не сталкивались, но большинство современных браузеров имеют встроенную поддержку режима «картинка в картинке». Эти API позволяют взять видео и вынести его в отдельное окно, которое пользователь может перемещать и изменять в размерах, продолжая просматривать сайт.
У нас была идея для Compass: если вы начинаете воспроизводить видео курса и прокручиваете страницу вниз, видео перемещается в правый нижний угол экрана, так что вы можете продолжать смотреть его во время чтения содержимого страницы.
Мы надеялись использовать для этого API «картинка в картинке», но оказалось, что нельзя пассивно запускать их при прокрутке (наверное, из соображений конфиденциальности и безопасности?) — пользователь должен реально на что-то кликнуть, аналогично API буфера обмена.
В итоге мы написали собственное простое решение, используя IntersectionObserver, события видео и немного состояния, чтобы определять, когда видео воспроизводится и находится вне экрана, а также добавили атрибуты данных к элементу <video>, чтобы к ним можно было применять утилитные классы:
video-player.tsx
Мне нравится использовать атрибуты данных для подобных вещей: код начинает читаться гораздо больше как стандартный Tailwind по сравнению с кучей тернарных операторов и условной логики в JavaScript.
Парсинг файлов VTT в транскрипты
В Compass есть раздел для интервью, каждое из которых включает видео в верхней части страницы, а также довольно нестандартный интерфейс транскрипта внизу:
Сначала мы не были до конца уверены, как к этому подступиться. Нашей первой идеей было просто написать несколько компонентов React для этих элементов и поместить контент прямо в файл MDX, но казалось как-то нереалистично ожидать, что кто-то когда-либо будет оформлять свои транскрипты в этом совершенно нестандартном формате.
Тогда у меня возникла идея использовать стандартный формат файлов субтитров, например SRT. Проблема заключалась в том, что для наших нужд нам нужно было кодировать текущего спикера (Тома или Энни на скриншоте выше), а в SRT нет стандартизированного способа кодирования этой информации в файле.
Я провел дополнительные исследования и в конце концов остановился на WebVTT, который похож на SRT, но поддерживает информацию о спикерах и удобно спроектирован для веб-среды.
annie-king.vtt
Поэтому мы настроили код для синтаксического анализа данных транскрипта из файла .vtt, а затем сопоставили эти данные для рендеринга в виде кастомного интерфейса с помощью React:
src/interview/[slug]/page.tsx
Получилось довольно круто — я легко могу представить, как кто-то просто генерирует транскрипт в формате VTT с помощью ИИ, забрасывает его в проект, и он автоматически отображается в красивом кастомном интерфейсе.
Расширение изображений Markdown для темного режима и предотвращения сдвига макета
Пример контента, который мы создали для Compass, включает в себя множество диаграмм, которые мы хотели адаптировать для светлого и темного режимов.
Этого можно добиться самыми разными способами (например, тег <picture> поддерживает это «из коробки»), но нам очень хотелось сделать так, чтобы файлы контента по ощущениям были максимально похожи на чистый Markdown.
Поэтому у нас появилась идея использовать плейсхолдер {scheme} в URL изображения, который мы динамически заменяем на light или dark, загружая правильное изображение в зависимости от цветовой схемы пользователя:
Теперь базовый компонент изображения будет автоматически отображать neuro-proof.light.png или neuro-proof.dark.png в зависимости от текущей цветовой схемы. А если вы просто хотите использовать одно и то же изображение в обоих режимах, просто не включайте {scheme} в URL вовсе.
Мы также хотели избежать сдвига макета в контенте, чего в наши дни можно добиться довольно легко, если убедиться, что вы указали для своих изображений атрибуты ширины и высоты, чтобы браузер мог вычислить соотношение сторон и зарезервировать место для изображения при его загрузке.
В синтаксисе изображений Markdown нет стандартного способа выразить это, но после небольшого исследования мы обнаружили прецедент в Obsidian.
Obsidian добавляет размеры изображения к альтернативному тексту вот так:
Поэтому мы использовали кастомный компонент MDX, чтобы извлечь размеры в том же формате и добавить их к изображению, гарантируя отсутствие сдвига макета при загрузке контента.
Вот и всё — это Compass! Как всегда, это бесплатное обновление для всех обладателей лицензии Tailwind Plus, так что бегите скачивать кодовую базу, изучайте её и получайте удовольствие.
Если у вас еще нет лицензии Tailwind Plus, подумайте о ее приобретении! Покупка лицензии — лучший способ поддержать нашу работу над Tailwind CSS, к тому же в ней содержится масса полезных вещей.
С нетерпением жду возможности использовать этот шаблон для некоторых своих предстоящих проектов в ближайшие пару месяцев!








