Сердечная анимация, которая порадует ваших пользователей

Если вам что-то нравится и вы хотите показать это другим, вам нужно, чтобы это было похоже. Если вы хотите сделать это красиво, вам понадобится подобный вид со взрывной анимацией!

Сначала посмотрим на анимацию.

Если вы не хотите читать статью полностью, вы можете найти исходный код в моем репозитории GitHub.

Чтобы понять, что такое анимация, давайте посмотрим на анимацию в замедленном темпе.

Как видите, он состоит из четырех элементов:

  • Сердце (пустое в начале и полное в конце анимации)
  • Красный круг, который растет.
  • Белый круг, переходящий в красный круг.
  • Фейерверк.

Анимация состоит из нескольких этапов:

  1. Исчезнет сердце.
  2. Вырастите красный кружок.
  3. Вырастите белый круг.
  4. Исчезают в сердце взгляда.
  5. Взрывайте салют.

Чтобы создать эти элементы и добиться этой анимации, мы будем использовать Core Animation.

Вам нужно знать, что такое CALayer, CAShapeLayer, CAReplicatorLayer, _4 _, _ 5_ и CAAnimationGroup. Я не буду объяснять эти слои и анимацию. Если вы хотите узнать больше, прочтите несколько статей и документации и вернитесь к этой статье, когда закончите.

Теперь давайте создадим наши слои. Во-первых, нам нужно создать полный и пустой значок лайка (сердечка). Чтобы создать эти лайки, нам нужно добавить значки в наши активы.

После этого мы можем создать подобный слой.

Как видите, мы пишем метод changeLikeState(isFilled:). В зависимости от параметра isFilled это либо добавляет к слою подобие с заливкой, либо нет. Обратите внимание, что мы используем свойство маски, поэтому мы можем изменить цвет значка.

Давайте двигаться дальше. Теперь создадим круги.

Сначала мы пишем метод createCircleLayer(with:) . Это создает CAShapeLayer и круг с использованием UIBezierPath, который добавляется к свойству path слоя. В конце концов, мы используем этот метод для создания redCircleLayer и whiteCircleLayer.

Мы сделали самую простую часть. Теперь нам нужно создать фейерверк. Давай посмотрим на это.

Фейерверк состоит из больших и малых кругов. Чтобы создать круг, напишем метод createDotLayer(radius:) . Этот метод имеет параметр радиуса, который определяет размер круга.

Далее нам нужно создать массив кругов. Этот массив состоит из двух кружков: малого и большого. Затем мы умножим их на CAReplicatorLayer.

Итак, свойство movableDotShapeLayers содержит два круга: маленький и большой. Далее нам нужно создать CAReplicatorLayer. Для этого мы пишем метод createDotsLayer.

Итак, мы создали CAReplicatorLayer и добавили маленькие и большие круги в качестве подслоя. Затем мы используем свойство instanceCount, чтобы определить, сколько кругов будет в слое. Мы вычисляем расстояние между ними и сохраняем его в переменной angle. Чтобы растянуть круги, мы используем свойство слоя instanceTransform. Чтобы дать кружкам разные цвета, мы используем свойство instanceBlueOffset. Есть еще два свойства, которые мы можем использовать, instanceRedOffset и instanceGreenOffset ,, но я использую только instanceBlueOffset.

Давайте посмотрим, что у нас есть.

Теперь наши круги находятся друг под другом (маленькие кружки под большими). Давай исправим это. Для этого мы добавляем преобразование для CAReplicatorLayer. Это очень просто.

Результат будет таким.

Сначала наши круги должны быть скрыты. Итак, добавьте isHidden = true для CAReplicatorLayers и двигайтесь дальше.

На данный момент мы создали все слои. Все, что нам нужно сделать, это добавить жесты касания и немного анимации.

Если подобное представление заполнено, мы останавливаем анимацию, а если нет - запускаем анимацию. Довольно просто, не правда ли?

Чтобы остановить анимацию, напишем метод stopAnimations() .

Итак, чтобы остановить анимацию, все, что нам нужно сделать, это удалить все анимации со всех слоев, которые можно анимировать. Также скрываем ненужные слои (красные и белые круги и фейерверк).

Перейдем к первому этапу анимации. Наша первая анимация затмевает похожий вид. Чтобы добиться этого эффекта, мы анимируем непрозрачность слоя от 1 до 0.

Обратите внимание, что мы устанавливаем новое значение и используем свойство делегата. Мы делаем это, чтобы понять, когда анимация остановлена. Нам нужно, чтобы он перезапустился на следующем шаге анимации.

Давайте забегаем вперед и посмотрим на последовательность вызова анимации.

animationDidStart(_:) - метод делегата, который вызывается перед запуском анимации. Мы используем этот метод делегата, чтобы сделать необходимый слой видимым.

animationDidStop(_:, finished:) - это метод делегата, который вызывается после завершения анимации. Мы используем этот метод делегата, чтобы начать следующий шаг нашей взрывной анимации и скрыть ненужные слои.

Как видим, последовательность анимаций такова:

  1. Исчезнуть, как вид
  2. Исчезнуть в красном круге
  3. Исчезнуть в белом круге
  4. Исчезнуть на подобном просмотре
  5. Сделайте фейерверк

Наша последняя задача - реализовать эти методы. Мы уже реализовали метод fadeOutLikeView() . Давайте реализуем метод fadeInRedCircle().

Создать красный круг очень просто - мы просто увеличиваем масштаб круга с 0 до 1. То же самое касается белого круга и подобного вида.

Мы сделали самую простую часть. Реализуем последнюю анимацию.

Он состоит из трех шагов:

  • Изменение непрозрачности с 1 на 0.
  • Изменение шкалы от 1 до 0.
  • Изменение позиции с текущей позиции.

Непрозрачность и масштабная анимация выглядят так же, как и раньше. Чтобы реализовать анимацию положения, мы вычисляем смещение и определяем nextPosition. Затем мы объединяем эти анимации с помощью CAAnimationGroup.

Обратите внимание, что анимация применяется к маленькому и большому кругу, но не к слою репликатора.

Это все на сегодня. Мы реализовали красивую анимацию, которую вы можете использовать в своих проектах. Вы можете найти полный код в этом репозитории.

Спасибо за прочтение! 😉