В последнее время мне безумно хотелось снова заняться созданием скринкастов и преподаванием, поэтому пару месяцев назад я собрал этот бесплатный мини-курс Build UIs that don't suck. Людям вроде бы зашло, и теперь я хочу сделать несколько более масштабных видеопроектов, но тут возникла проблема.
Я — разработчик ПО.
А как разработчик ПО, примерно так же, как мне нужно написать собственный генератор статических сайтов, прежде чем я смогу создать свой личный сайт, мне нужно было построить собственную платформу для курсов, прежде чем я вообще смогу думать о создании видеокурса.
Ну что же, перенесемся на шесть недель вперед — мы только что выпустили Compass, стартовый набор, разработанный с использованием Tailwind CSS и Next.js для публикации собственных онлайн-курсов.
Как всегда, посмотрите живое превью, чтобы прочувствовать все в полной мере.
Мы отлично провели время, работая над этим проектом, поработали с кучей новых инструментов и технологий и решили несколько интересных задач.
Видео в режиме «картинка в картинке»
Возможно, вы раньше с этим не сталкивались, но большинство современных браузеров имеют встроенную поддержку режима «картинка в картинке». Эти API позволяют взять видео и вынести его в отдельное окно, которое пользователь может перемещать и изменять в размере, продолжая просматривать сайт.
У нас была такая идея для Compass: если вы начинали воспроизводить видео курса и прокручивали страницу вниз, видео перемещалось в правый нижний угол экрана, чтобы вы могли продолжать смотреть его, читая содержимое страницы.
Мы надеялись использовать для этого API Picture-in-Picture, но оказалось, что их нельзя пассивно запускать при прокрутке (предполагаю, из соображений конфиденциальности и безопасности?) — пользователь должен реально на что-то кликнуть, аналогично 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, к тому же в ней содержится масса полезных вещей.
С нетерпением жду возможности сам использовать этот шаблон для предстоящих проектов в ближайшие пару месяцев!
