Figma Perspective
Плагин для Figma, который помогает работать с перспективой фотографий прямо в макете — без лишних переключений между инструментами.
2026 / npmjs.com
TypeScript-библиотека для создания и чтения GIF в браузере. Кодирование кадров выполняется в Web Worker, чтобы тяжёлая обработка не блокировала интерфейс.
GIF — формат старый, знакомый и на первый взгляд довольно простой. Но стоит попробовать собрать анимацию прямо в браузере, как появляются нюансы: нужно подготовить кадры, подобрать палитру цветов, настроить задержки, разобраться с прозрачностью и получить готовый файл. И всё это желательно сделать так, чтобы страница продолжала нормально работать, а пользователь не смотрел на зависший интерфейс.
Для таких задач мы сделали @la-moore/gif — небольшую TypeScript-библиотеку, которая умеет создавать GIF из изображений и данных пикселей, а также читать уже готовые анимации.
При создании GIF недостаточно просто склеить несколько картинок. Кадры нужно обработать и подготовить к кодированию, в том числе подобрать цветовую палитру. На больших изображениях и длинных анимациях эта работа может оказаться достаточно тяжёлой.
Если выполнять её целиком в основном потоке браузера, пользователь рискует заметить задержки: интерфейс хуже реагирует на действия, анимации подтормаживают, страница кажется зависшей.
Поэтому в @la-moore/gif тяжёлая часть подготовки кадров вынесена в Web Worker. Для этого используется пул воркеров, а их количество можно настроить при создании GifWriter. Основной поток остаётся свободнее для интерфейса, пока библиотека занимается обработкой изображения.
При этом разработчику не нужно самостоятельно организовывать обмен данными с воркерами или собирать результат из отдельных частей. Библиотека скрывает эту механику за обычным API.
Мы старались сделать работу с библиотекой прямолинейной. Создаём GifWriter, задаём размеры будущей анимации, добавляем кадры и получаем готовый файл.
В качестве кадров можно использовать HTMLCanvasElement и HTMLImageElement. Если изображения уже подготовлены, например в процессе рендеринга через WebGL или OffscreenCanvas, их можно передать как ImageData.
После добавления кадров результат можно получить в виде Blob или Data URL с base64-кодированием. Первый вариант удобно использовать для создания объектного URL и отображения готовой анимации, второй позволяет получить представление GIF в виде строки.
Не нужно вручную заниматься сборкой файла или писать собственный конвейер обработки кадров — достаточно описать, какую анимацию мы хотим получить.
У анимаций бывают разные сценарии воспроизведения. Иногда достаточно стандартного зацикливания, но в других случаях хочется, чтобы последовательность проигрывалась в обратном порядке или двигалась туда-обратно.
В библиотеке предусмотрены три режима: loop, reverse и bounce. Последний добавляет обратный проход кадров, не дублируя крайние кадры последовательности.
Также можно управлять задержкой между кадрами и количеством повторов. Для отдельных кадров доступны собственные настройки, включая задержку, параметры палитры, дизеринг, прозрачность и способ обработки предыдущего кадра.
Это позволяет использовать один инструмент и для простой короткой анимации, и для более тонкой настройки результата.
Если GIF создаётся из большого количества кадров, пользователю полезно понимать, что происходит. Поэтому в библиотеке есть onRenderProgress, который сообщает о ходе обработки.
На основе этого значения можно показать индикатор прогресса, обновить состояние кнопки или сообщить, что файл готов. Вместо непрозрачной операции, которая заканчивается в неизвестный момент, приложение получает возможность объяснить пользователю, что сейчас происходит.
Для управления ресурсами предусмотрены и методы жизненного цикла. reset() очищает кадры и состояние рендеринга, позволяя использовать экземпляр повторно, а destroy() завершает работу воркеров, когда экземпляр больше не нужен.
Работа с GIF не всегда заканчивается экспортом. Иногда нужно загрузить существующую анимацию, узнать её размеры, количество кадров и длительность или получить пиксельные данные каждого кадра.
Для этого в библиотеке есть GifReader. Он умеет загружать GIF из Uint8Array, ArrayBuffer и Blob, предоставляет метаданные анимации и позволяет последовательно обходить кадры с декодированными RGBA-данными.
Так библиотека закрывает обе стороны задачи: создание анимации и чтение уже существующего файла.
@la-moore/gif написана на TypeScript и поставляется с типами. При этом она не привязана к React, Vue или другому UI-фреймворку: её можно использовать в обычном браузерном JavaScript-приложении, независимо от того, как устроен интерфейс.
Отдельного внимания требует сборка. Библиотека создаёт Web Worker через new Worker(new URL('./gif.worker.js', import.meta.url), { type: 'module' }). Vite умеет обрабатывать такой сценарий автоматически, а в Webpack и Next.js нужно учитывать поддержку сборки воркеров. Поскольку кодирование опирается на браузерные API, GifWriter следует создавать на клиенте, а не во время серверного рендеринга.
Это небольшие интеграционные нюансы, которые проще учитывать заранее, чем искать причину ошибки уже после подключения пакета.
@la-moore/gif — это попытка собрать всю необходимую работу с GIF в одном понятном инструменте: от добавления кадров до получения готового файла, с возможностью контролировать воспроизведение и отслеживать прогресс.
Библиотека доступна в npm и устанавливается привычным способом:
npm i @la-moore/gif
Её можно подключить к существующему проекту и использовать там, где нужно создавать GIF из изображений или читать кадры готовой анимации.
Плагин для Figma, который помогает работать с перспективой фотографий прямо в макете — без лишних переключений между инструментами.
Образовательное приложение для подготовки к экзаменам по математике: короткие ежедневные тренировки и персональные задания.