Руководство по использованию
Полное API animated-fluent-emojis. Об установке и первом эмодзи читайте в
README.
- Frameworks
- Props
- Наведение и фокус
- Уменьшение анимации
- Fallback
- Воспроизведение
- Изображения и HD sprite sheets
- Предзагрузка
- Asset site
- Lookup
- Types
Приведённые ниже props общие для всех адаптеров; в разделе каждого фреймворка
указано, как prop записывается именно там. Компонент запрашивает небольшой
manifest у asset site при первом рендере эмодзи, а не во время импорта. Пока
manifest загружается, Emoji рендерит пустой плейсхолдер с aria-hidden
итогового размера, поэтому вёрстка не сдвигается. Если id неизвестен, компонент
рендерит ваш узел fallback или ничего. Если manifest не удалось загрузить,
компонент рендерит ваш узел fallback или ничего и повторяет попытку при
следующем монтировании, следующем вызове preloadEmojis или когда браузер снова
окажется онлайн.
Frameworks
Один пакет, один путь импорта на каждый фреймворк. configureEmojis и
preloadEmojis не зависят от фреймворков и остаются в animated-fluent-emojis;
см. Предзагрузка и Asset site. Все адаптеры
используют одно ядро воспроизведения и проходят один набор тестов на
соответствие, поэтому props везде ведут себя одинаково. См.
ADR 0014.
Адаптеры React, Vue и Svelte, а также createEmoji берут keyframes из
animated-fluent-emojis/style.css; импортируйте его один раз. <fluent-emoji>
и компонент Astro приносят свои стили.
React
Импортируйте Emoji из подпути React:
import { Emoji } from 'animated-fluent-emojis/react'
import 'animated-fluent-emojis/style.css'Миграция с версии 0.6 и ранее: экспорт Emoji из корня был объявлен устаревшим
в 0.6 и удалён в 0.7. Измените путь импорта, больше ничего: props и поведение
идентичны. Тип EmojiProps тоже переехал в animated-fluent-emojis/react.
configureEmojis и preloadEmojis остаются в animated-fluent-emojis.
Поддерживаются React 18 и 19, а react и react-dom являются необязательными
peer-зависимостями.
Vue
Vue 3.3 или новее. Emoji принимает приведённые ниже props в camelCase. Слот
fallback заменяет изображение, а события: load, error и playbackEnd.
Остальные атрибуты, такие как class, style и data-*, попадают на корневой
span.
<script setup lang="ts">import { Emoji } from 'animated-fluent-emojis/vue'
import 'animated-fluent-emojis/style.css'
const handlePlaybackEnd = () => { console.log('done')}</script>
<template> <Emoji id="1f44b_wavinghand" :size="64" play-on-hover @playback-end="handlePlaybackEnd" > <template #fallback><span>👋</span></template> </Emoji></template>На сервере и во время гидратации компонент рендерит пустой плейсхолдер итогового размера, поэтому он работает в Nuxt.
Svelte
Svelte 5. Emoji принимает приведённые ниже props; fallback является snippet,
а class, style и attributes попадают на корневой span. Колбэки: onLoad,
onError и onPlaybackEnd.
<script lang="ts"> import { Emoji } from 'animated-fluent-emojis/svelte'
import 'animated-fluent-emojis/style.css'</script>
<Emoji id="1f44b_wavinghand" size={64} playOnHover> {#snippet fallback()}<span>👋</span>{/snippet}</Emoji>На сервере он рендерит плейсхолдер, а эмодзи появляется после гидратации,
поэтому он работает в SvelteKit. В экспорте пакета есть условие svelte,
указывающее на исходный код компонента.
Astro
Astro 5 или новее. Компонент рендерит разметку эмодзи во время сборки, поэтому
спрайт оказывается в HTML ещё до запуска любого скрипта, а небольшой скрипт
запускает воспроизведение в браузере. Он приносит свои стили; импортировать
таблицу стилей не нужно. Именованный слот fallback рендерится, когда id
неизвестен или изображение не загрузилось.
---import Emoji from 'animated-fluent-emojis/astro'---
<Emoji id="1f44b_wavinghand" size={64} playOnHover> <span slot="fallback">👋</span></Emoji>Props те же, что описаны ниже, кроме колбэков, плюс class и style в виде
строки. Вместо колбэков корневой span отправляет emoji-load, emoji-error и
playback-end как всплывающие DOM-события. Скрипт в браузере также запускается
повторно при astro:page-load, поэтому view transitions продолжают работать.
Обычный HTML
Импорт animated-fluent-emojis/element регистрирует <fluent-emoji>. Таблица
стилей не нужна: keyframes находятся в его shadow root.
<script type="module"> import 'animated-fluent-emojis/element'</script>
<fluent-emoji id="1f44b_wavinghand" size="64" play-on-hover> <span slot="fallback">👋</span></fluent-emoji>Атрибуты повторяют props в kebab-case: id, size, play-on-hover,
animation-iterations, auto-play, playing, skin-tone и alt. Булев
атрибут включён, если его значение не равно false. Те же имена существуют как
camelCase-свойства элемента (element.playOnHover = true); установка свойства
не переписывает атрибут. Элемент с slot="fallback" является fallback. Элемент
отправляет emoji-load, emoji-error и playback-end как всплывающие
composed-события.
Пока элемент не определён, у него нет размера. Добавьте в CSS страницы
FLUENT_EMOJI_PRE_UPGRADE_CSS, экспортируемый из той же точки входа, чтобы
зарезервировать место по атрибуту size (в пикселях) и избежать сдвига вёрстки.
Angular, Solid и Preact
Они используют <fluent-emoji> через собственный синтаксис шаблонов; см. how-to
руководства для Angular,
Solid и Preact. То же
относится к Lit, Alpine и htmx: импортируйте animated-fluent-emojis/element и
пишите тег.
Без фреймворка
createEmoji рендерит в любой DOM-узел и возвращает контроллер. Это ядро
каждого адаптера, не зависящее от фреймворков. Его импорт не затрагивает DOM.
import { createEmoji } from 'animated-fluent-emojis'
import 'animated-fluent-emojis/style.css'
const controller = createEmoji(document.querySelector('#slot'), { id: '1f44b_wavinghand', size: 64, fallback: () => document.createTextNode('👋'),})
controller.update({ playing: false })controller.destroy()Его опции — это props, описанные ниже, плюс className, style и attributes
для корневого span, колбэки onLoad, onError и onPlaybackEnd и fallback,
который может быть узлом, функцией, возвращающей узел, или null.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| id | EmojiId or string |
- | Уникальный идентификатор эмодзи; известные id дополняются автоматически |
| size | number or string | 100 | Пиксели или любая CSS-длина, например 2rem или var(--size) |
| playOnHover | boolean | false | Воспроизводить ли анимацию при наведении и при фокусе с клавиатуры |
| animationIterations | number or ‘infinite’ | 2 | Сколько раз воспроизводить анимацию при загрузке |
| autoPlay | boolean | true | Запускать ли анимацию автоматически при монтировании |
| playing | boolean | - | Управляет воспроизведением; true запускает, false ставит на паузу, если не задан, действует значение по умолчанию |
| onPlaybackEnd | function | - | Вызывается один раз, когда завершается конечный запуск animationIterations |
| skinTone | SkinTone | ‘default’ | Оттенок кожи для эмодзи с вариантами (см. ниже) |
| alt | string | description | Доступный текст; по умолчанию описание эмодзи, "" помечает его как декоративное |
| className | string | - | Имя класса для корневого <span>, объединяется с собственным классом компонента |
| style | CSSProperties | - | Встроенный стиль для корневого <span>; width и height следуют за size |
| ref | Ref<HTMLSpanElement> |
- | Передаётся корневому <span>; работает в React 18 и 19 |
| fallback | ReactNode | glyph | Рендерится, если изображение или manifest не загрузились либо id неизвестен; null: ничего |
| onLoad | function | - | Вызывается, когда sprite sheet загружен |
| onError | function | - | Вызывается при сбое изображения, а при сбое manifest вызывается без события |
Любой другой атрибут <span> (data-*, aria-*, title, обработчики событий)
передаётся корневому элементу. Числовой size округляется; всё, кроме конечного
положительного числа, заменяется на 100. Строковый size передаётся в CSS как
есть, поэтому работают size="2rem" и size="var(--emoji-size)". Числовая
строка вроде "48" трактуется как число 48, а для остальных строк изображение
получает sizes="auto"; style с width или height приоритетнее size.
skinTone принимает одно из значений: 'default', 'light', 'medium-light',
'medium', 'medium-dark' или 'dark'. Он применяется только к эмодзи,
помеченным как diverse; для любого другого эмодзи или неизвестного значения
используется sheet по умолчанию. DiverseEmojiId перечисляет id, у которых есть
оттенки кожи, и skinTone типизируется по нему, когда id — один из них.
Наведение и фокус
С playOnHover анимация проигрывается после первоначального запуска, когда
указатель входит в область эмодзи, а также когда эмодзи находится внутри
<button> или <a>, получающего фокус с клавиатуры (:focus-visible).
Уменьшение анимации
Когда система пользователя просит уменьшить анимацию
(prefers-reduced-motion: reduce), autoPlay игнорируется, и эмодзи остаётся
на poster frame — первом кадре анимации. playOnHover по-прежнему проигрывается
при наведении и фокусе, потому что это явное действие пользователя.
Fallback
Если sprite sheet не удалось загрузить, Emoji показывает fallback glyph:
родной символ Unicode этого эмодзи с подписью из alt. Передайте fallback,
чтобы вместо этого отрендерить собственный узел, или fallback={null}, чтобы не
рендерить ничего:
<Emoji id="1f44b_wavinghand" fallback={<span>👋</span>} /><Emoji id="1f44b_wavinghand" fallback={null} />onError срабатывает при сбое изображения (с событием) и при сбое manifest (без
него). Fallback glyph зависит от manifest, поэтому, когда сам manifest не
загрузился, рендерится только явно заданный узел fallback. Неизвестный id
рендерит узел fallback или ничего; onError при этом не вызывается, а в
режиме разработки выводится одно предупреждение на каждый id. Запрос manifest
прекращается через 15 секунд и повторяется как любой другой сбой.
Воспроизведение
Автовоспроизведение ждёт, пока sprite sheet загрузится, эмодзи появится на
экране, а вкладка станет видимой, поэтому эмодзи вне экрана или в фоне не
анимируются. Скрытые вкладки ставят на паузу все эмодзи и возобновляют их, когда
вкладка возвращается. Смена id заново запускает первоначальный запуск нового
эмодзи. animationIterations, равный 0, отрицательному числу или NaN,
отключает автовоспроизведение; Infinity равнозначно 'infinite'. Пока
автовоспроизведение удерживается, эмодзи показывает poster frame.
Используйте playing, чтобы управлять воспроизведением самостоятельно. true
проигрывает animationIterations запусков, переопределяя autoPlay и reduced
motion (по-прежнему ожидая изображение, viewport и видимую вкладку); false
ставит на паузу на текущем кадре. Завершённый запуск не перезапускается
переключением, поэтому для повтора перемонтируйте с новым key. onPlaybackEnd
срабатывает один раз, когда завершается конечный запуск; он никогда не
срабатывает для 'infinite' или когда эмодзи размонтируется посреди запуска.
<Emoji id="1f389_partypopper" playing={isOpen} onPlaybackEnd={handleDone} />Изображения и HD sprite sheets
Sprite sheets загружаются с loading="lazy" и decoding="async". Эмодзи, у
которых есть HD sprite sheet (кадры 200px), также получают srcSet на основе
ширины (100w и 200w) с sizes, равным отрисованному размеру (auto для
строкового size), поэтому на экранах с высокой плотностью браузер выбирает
sheet @2x.
Предзагрузка
preloadEmojis начинает загрузку manifest до рендера любого Emoji и, если
переданы id, запрашивает их sprite sheets, когда он готов. Он никогда не
отклоняется:
import { preloadEmojis } from 'animated-fluent-emojis'
void preloadEmojis()void preloadEmojis(['1f44b_wavinghand', '1f525_fire'], { skinTone: 'medium' })skinTone выбирает вариант, который нужно прогреть, для эмодзи с оттенками
кожи.
Asset site
По умолчанию manifest и sprite sheets берутся с
https://animated-fluent-emojis-cdn.andryore.dev. Прежний адрес,
https://animated-fluent-emojis.pages.dev, продолжает работать. Чтобы отдавать
их из собственной копии, вызовите configureEmojis один раз, до первого рендера
Emoji:
import { configureEmojis } from 'animated-fluent-emojis'
configureEmojis({ assetSiteUrl: 'https://emojis.example.com' })Lookup
animated-fluent-emojis/lookup не зависит от React и использует тот же
manifest, что и Emoji, поэтому добавить его рядом дёшево. Каждая функция
загружает manifest и, если не может, возвращает undefined или пустой массив и
никогда не отклоняется:
import { extractEmojis, findEmojiByUnicode, searchEmojis,} from 'animated-fluent-emojis/lookup'
await findEmojiByUnicode('👍🏽') // { id: 'yes', skinTone: 'medium' }await extractEmojis('Hi 👋 there') // [{ id, text, index, length }]await searchEmojis('party', { limit: 5 }) // [{ id }]findEmojiByUnicode(text)находит один эмодзи и сопоставляет единичный модификатор оттенка кожи сskinTone; смешанные оттенки приводят к базовому эмодзи. Символам вроде©или™для совпадения нужен селектор вариантов эмодзи (U+FE0F), тогда как ZWJ-последовательности совпадают, даже если селектор вариантов отсутствует (minimally qualified).- Когда несколько записей каталога используют один глиф, lookup возвращает
канонический эмодзи: id с префиксом из кодовых точек глифа, иначе проверенное
переопределение, иначе первую запись в порядке каталога. Например,
❤️разрешается в сердце, а не в вариант, повторно использующий этот глиф. При заданном оттенке кожи используется соседняя запись, у которой есть оттенки. extractEmojis(text)находит в тексте каждый эмодзи каталога, сохраняя ZWJ-последовательности целыми, вместе с его смещением и длиной. БезIntl.Segmenterон переходит на группировку по кодовым точкам, и ни одна из функций никогда не отклоняется.searchEmojis(query, { limit })сопоставляет описания без учёта регистра;limitпо умолчанию равен 20;limit, не являющийся положительным числом, означает отсутствие ограничения, кроме0, который ничего не возвращает.
Types
Корень экспортирует configureEmojis, preloadEmojis и createEmoji, а также
типы SkinTone, EmojiId, DiverseEmojiId, EmojiController, EmojiOptions
и EmojiFallback. Компонент Emoji и EmojiProps были удалены из корня в
0.7.0; импортируйте их из /react. /react, /vue и /svelte экспортируют
каждый свои Emoji и EmojiProps; у /astro есть экспорт по умолчанию и тип
EmojiAstroProps; /element экспортирует тип FluentEmojiElement. EmojiId —
это объединение всех опубликованных id, оно генерируется из каталога; prop id
типизирован как EmojiId | (string & {}), поэтому известные id дополняются
автоматически, а id, добавленные в каталог после вашей установленной версии, всё
равно компилируются.