Если вам нравятся мелочи (и конфетти) в UX и UI-дизайне, вы попали в нужное место.
Все дело в мелочах
Мелочи в пользовательском интерфейсе (UX) и дизайне пользовательского интерфейса (UI) очень важны. Они - то, что отличает вас от остальных. Они создают характер и личность. Они дополняют хорошо продуманный интерфейс и укрепляют тему.
Если вы находитесь на стадии разработки, позволяя сосредоточиться на более подробном пользовательском интерфейсе с помощью микровзаимодействий, предоставляя вашим пользователям дополнительный источник дофамина , демонстрируя умопомрачительные навыки веб-разработчиков (или просто импортируя библиотеку, которая делает за вас умопомрачительные вещи), а затем реализуя микровзаимодействия, например это то, что может оставить у вашего пользователя неизгладимое впечатление. Это может быть причиной того, что они помнят вас через море конкуренции.
Я помню, как впервые хлопнул в ладоши на Medium и увидел конфетти. Было нелепо поддаться на это влиянию. Но я подумал: «Как мне это сделать?».
Что ж, я тебе покажу.
В React есть библиотека для этих микровзаимодействий, называемых пользовательскими "вознаграждениями". Он называется react-rewards
и поддерживает набор конфетти, смайликов или мемфиса прямо из коробки. Я думал, вот оно что; что не было ничего похожего, что я мог бы легко использовать в Angular (изначально я нашел эту библиотеку в поисках причины хлопка конфетти).
В Angular нет библиотеки для этих маленьких "наград". НО пакет npm canvas-confetti
- это источник волшебства. Итак, мы установим этот пакет и будем использовать его для работы с конфетти внутри компонента Angular.
Давайте праздновать вместе с Angular
Установка полотна-конфетти
Сначала установите пакет canvas-confetti
из диспетчера пакетов узлов.
$ npm install canvas-confetti
Создайте компонент Angular - CelebrateComponent
Я собираюсь создать компонент с помощью Angular CLI, который будет взаимодействовать с Angular службой и распылять полноэкранное конфетти. в ответ на отпраздновать событие.
$ ng g c modules/shared/celebrate
Это также импортирует класс CelebrateComponent в SharedModule (структура модуля не важна, это просто пример).
Также обратите внимание, что по умолчанию я использую
ChangeDetectionStrategy.OnPush
.
Я делаю это из соображений производительности; чтобы избежать запуска слишком большого количества ненужных запусков обнаружения изменений.
Поскольку вы можете сообщить Angular вручную, когда ожидать изменений с помощью
this.changeDetectorRef.detectChanges();
(после внедренияprivate changeDetectorRef: ChangeDetectorRef
в конструктор).
Ваш класс CelebrateComponent будет начинаться следующим образом.
Объявить поля экземпляра
Нам нужно, чтобы в некоторых полях экземпляра сохранялся элемент холста для повторного использования, а также динамически импортируемая библиотека холста-конфетти в дополнение для создания некоторых наблюдаемых для прослушивания событий.
По сути мы хотим:
- Слушайте RXJS Observable (
celebrate$
), который поступает от CelebrateService (который мы создадим), чтобы мы могли программно запускать конфетти в ответ на пользовательское событие. - Будьте в курсе, когда компонент уничтожен, предоставляя уведомление об этом событии через Тема. Мы возложим на этого Субъекта ответственность за обеспечение отсутствия утечек памяти в наблюдаемых подписках на этот компонент (
destroy
).
Для этого будет создана тема
destroy
. Затем мы можем вызватьdestroy.next()
вNgOnDestroy
жизненном цикле. Наблюдаемый объект (destroy
) будет создан (destroy$
), что даст нам возможность прослушивать уничтоженное событие.
- Слушайте созданный
destroy$
Observable, предоставив его в качестве значения для оператора RXJStakeUntil
, чтобы мы в конечном итоге отказались от подписки наcelebrate$
Observable. - Сохраните библиотеку холста-конфетти в переменной экземпляра
confettiLib
, чтобы мы не импортируем ее дважды. Мы будем использовать динамический импорт ES6,import('canvas-confetti')
, чтобы впоследствии сохранить значение.
Это также гарантирует, что нам не придется импортировать его, если он не используется, поскольку он будет использоваться редко, если вы не используете его с кнопкой или аналогичным частым событием.
- Сохраните функцию холста конфетти (confettiCanvas), чтобы мы могли повторно использовать ее и создать только один раз.
Использование динамического импорта ES6 позволяет Angular распознавать библиотеку как собственный фрагмент, уменьшая размер пакета main.js.
Если вы не поддерживаете код ES6 в своем приложении, вы можете просто удалить код с помощью динамического импорта и разместить import * as canvasConfetti from 'canvas-confetti'
в верхней части файла компонента.
Создать CelebrateService
Прежде чем мы углубимся в CelebrateComponent, давайте создадим CelebrateService, который останется простым для этого примера.
Нам просто нужно предоставить способ включить празднование из любой точки приложения в ответ на поведение пользователя. Вот некоторые примеры такого поведения пользователя:
- О пользователе Регистрация.
- Нажмите кнопку (лайки, поделиться, создать).
- Завершенный профиль (если вы предоставите контрольный список, который необходимо заполнить).
- Учебное пособие / демонстрация / пошаговое руководство Завершение.
Итак, нам нужно использовать Angular CLI для создания службы:
$ ng g s services/celebrate
Это создаст службу в services/celebrate.service.ts
.
В CelebrateService мы создаем celebrate
тему RXJS, которая будет использоваться исключительно службой, и celebrate$
Observable, который позволит нам прослушивать выбросы, контролируемые этим Тема.
celebrate$
Observable будет подписан на CelebrateComponent, чтобы он мог реагировать на событие празднования.
Мы также определяем функцию startCelebrate()
, которая будет вызываться, когда вы хотите инициировать празднование.
Вот и все для CelebrateService. Теперь вернемся к компоненту…
Предоставление зависимостей через внедрение зависимостей
Нам нужно разрешить зависимости с помощью функции конструктора. Я введу токен PLATFORM_ID, который мы используем для проверки того, что этот компонент не инициализирован в среде SSR (поскольку мы не иметь доступ к HTMLCanvasElement).
Нам также необходимо динамически отобразить элемент холста с помощью Renderer2, используя элемент хоста (ElementRef), плюс нам понадобится CelebrateService зависимость (которую мы только что создали) для привязки к наблюдаемому celebrate$
, как обсуждалось.
Мы проверяем, что мы на стороне клиента, если используем SSR с isPlatformBrowser
, подписываемся на celebrate$
наблюдаемый, заботясь об объекте подписки, возвращенном из вызова subscribe()
, с takeUntil
.
Основная функция «праздновать»
Я оставил эту функцию последней, потому что именно здесь происходит волшебство.
С помощью функции celebrate
мы:
- Проверьте, что библиотеки конфетти холста еще не существует.
- Добавьте холст к основному элементу (ElementRef) с помощью Renderer2.
- Создайте холст с конфетти, если он еще не создан, предоставив холст, который мы создали.
- Создайте Интервал, чтобы конфетти вызывалось каждые 200 миллисекунд, с
setInterval
. - Установите таймер, чтобы мы могли в конечном итоге уничтожить конфетти с помощью
clearInterval()
. - Разожгите конфетти 🎉 🎊
Полноэкранный
Чтобы сделать холст полноэкранным с вашим собственным элементом холста, вам нужно стилизовать компонент. Позиционирование холста должно быть фиксированным и должно быть по всей ширине и высоте.
Вы можете сделать это внутри celebrate.component.scss
. Как только функция конфетти будет завершена, холст будет уничтожен и удален из модели DOM, поэтому использование фиксированного контекста не приведет к любые вопросы.
Конфетти Конфетти
Вы можете настроить количество частиц, начальную скорость, распространение, происхождение (откуда оно будет стрелять), shape (может дать вам эффект снега с помощью «круга») и многое другое! Просмотрите демонстрационную страницу ниже, чтобы узнать, что возможно!
- - - - - - - - - - - - - - Готово 🚀 - - - - - - - - - - - - -