Плеер для высокопроизводительного проигрывания Lottie-анимаций на веб-страницах. Использует WASM-версию библиотеки RLottie, которая запускается в отдельном процессе (Web Worker): это позволяет по-минимуму задействовать основной поток браузера.
Модуль устанавливается как обычный npm-пакет, но сначала необходимо добавить в файл .npmrc
проекта (если файла нет — нужно его создать) следующую строчку:
@tamtam-chat:registry=https://npm.pkg.github.com
Для установки используем команду npm install
:
npm install @tamtam-chat/lottie-player
Для воспроизведения Lottie-анимации делаем следующее:
import { createPlayer } from '@tamtam-chat/lottie-player';
// Создаём или получаем <canvas>-элемент, на котором будет
// воспроизводиться анимация
const canvas = document.createElement('canvas');
document.body.appendChild(canvas);
const player = createPlayer({
// Элемент, в котором отрисовывать анимацию
canvas,
// Lottie-анимация. Это может быть как URL на анимацию, так и сам
// JSON-файл анимации в виде объекта или строки
movie: '{...}',
// Воспроизводить анимацию в цикле
loop: true,
// Размер кадра анимации. Если не указано — будет взят
// из canvas-элемента
width: 100,
height: 100
});
setTimeout(() => {
// Завершение анимации и удаление плеера
player.dispose();
}, 1000);
Warning Стоит учитывать, что библиотека создаёт отдаёт отдельный Worker-процесс для отрисовки анимаций. Само содержимое воркера находится а отдельном файле
worker.js
, который подгружается по запросу как только будет создана первая анимация. При бандлинге проекта стоит это учитывать и, при необходимости, импортировать файл как отдельный чанк вашего бандла. Для этого нужно получить ссылку наworker.js
и передать её загрузчику до того, как будет создана анимация. Вот как это можно сделать при сборке через Vite:
// Получаем ссылку на файл воркера. Этот же вызов добавит новый чанк в сборку
import workerUrl from '@tamtam-chat/lottie-player/dist/worker?url';
import { createPlayer, updateConfig } from '@tamtam-chat/lottie-player';
// Указываем, откуда грузить воркер
updateConfig({ workerUrl });
// Теперь можно запускать анимации
const player = createPlayer({ ... });
По спецификации ссылка на код воркера должна соответствовать same-origin policy основной страницы. Если код располагается на отдельном хосте, можно обойти это ограничение, предварительно загрузив код как Blob:
import { updateConfig } from '@tamtam-chat/lottie-player';
updateConfig({
// В качестве workerUrl можно отдать функцию, которая вернёт URL
// или Promise c URL
workerUrl: async () => {
const resp = await fetch('https://static.host.com/worker.js', { mode: 'cors' });
const blob = await resp.blob();
return URL.createObjectURL(blob);
}
});
У созданного плеера доступны следующие свойства и методы:
paused
– воспроизведение плеера на паузе.loop
– воспроизводить анимацию в цикле.frame
– текущий кадр анимации.totalFrames
– всего кадров анимации.play()
— запустить воспроизведение анимации.pause()
— остановить воспроизведение анимации.toggle()
— переключение воспроизведения анимации (play/pause).resize(width, height, dpr?)
— поменять размер кадра анимации. Чем меньше размер, тем выше производительность.dispose()
— завершить анимацию и удалить плеер.on(event, callback)
— подписаться на событиеevent
плеераoff(event, callback)
— отписаться от событияevent
плеера
mount
— к плееру успешно добавлен воркер и загружена анимация, он готов к воспроизведению. В качестве аргумента коллбэка приходит количество кадров в анимации.play
— вызвали методplay
, начала воспроизводиться анимация.pause
— вызвали методpause
, анимация поставлена на паузу.end
— отрисовался последний кадр анимации. В зависимости от значенияloop
, анимация продолжит воспроизводиться с начала или остановится.rendered
— впервые отрисовался кадр анимации после монтирования плеера.resize
— у плеера поменялся размер после вызоваresize
. В качестве аргументов приходит новый размер и DPR.dispose
— плеер был удалён.
У самого модуля доступны следующие импортируемые методы для управления анимациями:
createPlayer(options: PlayerOptions): Player
— создаёт новый плеер с указанными опциями.dipsosePlayer(player: Player | HTMLCanvasElement | ID)
— универсальный механизм для удаления плеера анимации. Можно передать сам плеер,<canvas>
-элемент или ID анимации (об этом ниже).updateConfig(config)
— обновление конфига модуля. В основном используется для указания ссылки на файлworker.js
, но также можно поменять внутренние параметры создания воркеров.pause()
— поставить на паузу воспроизведение всех плееров.play()
— запустить воспроизведение всех плееров.
Часто бывают ситуации, когда нужно воспроизводить одну и ту же анимацию в нескольких местах страницы. Например, в мессенджере несколько человек могут отправить один и тот же стикер. Чтобы в таких случаях не создавать несколько разных роликов, которые будут тратить ресурсы на отрисовку одного и того же содержимого, можно объединить плееры в одну группу с помощью атрибута id
.
Если указан атрибут id
, для всех плееров с одинаковым атрибутом будет создан только один отрисовщик, который отрисует только один кадр и размножит его на все экземпляры. Причём, можно создавать плееры с разным размером: в этом случае отрисовщик нарисует самый большой кадр и сделает копии нужного размера для всех остальных плееров.
import { createPlayer } from '@tamtam-chat/lottie-player';
// Содежимое JSON-файла с анимацией
const movie = '{...}';
// Группирующий идентификатор
const id = 'my-animation';
const player1 = createAnimation({
id,
movie,
canvas: document.querySelector('canvas.movie1'),
width: 100,
height: 100
});
const player2 = createAnimation({
id,
movie,
canvas: document.querySelector('canvas.movie2'),
width: 200,
height: 200
});
Из примера выше будет создан только один процесс отрисовки для ролика, будет отрисовываться кадр размером 200×200 как самый большой из группы.