Узнайте, как вращать объекты с опорной точкой
Compose прошел долгий путь, чтобы бросить вызов тому, как создавать декларативный пользовательский интерфейс. И анимационные объекты тоже не отстают. API предлагает унифицированный набор инструментов, который позволит вам отшлифовать ваши эффекты.
Сказав это, повторное открытие нового API может быть разочаровывающим. Вы столкнетесь с трудностями, пытаясь воспроизвести эффект, который вы знали, как выполнять с помощью прежнего API анимации. Вот что случилось со мной, когда я пытался раскачать предмет, как маятник. Вот чего я хотел добиться:
На первый взгляд анимация выглядит как бесконечное вращение вперед-назад от одного угла к другому. Ничего экстраординарного, правда? Посмотрим, как пойдет!
Создание компонуемого
Прежде чем добиться вышеуказанного эффекта, давайте создадим компонуемый объект, который мы хотим использовать. Ради примера я не буду останавливаться ни на стрелке, ни на внутренней части повернутой фигуры.
Для этого составного объекта нам нужны две вещи: форма, которую мы будем вращать, и гвоздь, закрепляющий ее. Учитывая его простоту, мы можем использовать Surface
для обоих компонентов — рисование на Canvas
тоже было бы прекрасно. Мы можем инкапсулировать составные объекты Panel
и Nail
в Box
с выравниванием TopCenter
для размещения гвоздя.
Результат должен выглядеть так:
Чтобы повернуть наш компонуемый Panel
, мы должны указать динамический угол. Поскольку мы хотим, чтобы фигура качалась бесконечно, мы можем использовать API перехода с помощью rememberInfiniteTransition
. Затем мы обновляем угол, изменяя его значение с начальной точки angleOffset
на его конечную точку назначения — я использовал его отрицательный аналог для целей симметрии, но вы можете выбрать иное.
Для самой части анимации я использовал интерполяцию tween
. Compose поставляется со множеством встроенных анимаций для достижения желаемого эффекта. Я настоятельно рекомендую вам взглянуть на их хорошо проработанную документацию.
Наконец, мы применяем этот угол к Modifier
Panel
, используя метод rotate
. Вот обновленный код Panel
:
И его вывод:
Не совсем то, что мы ожидали, верно? Гвоздь не выглядит так, как будто он правильно прикалывает панель. Этому есть простая причина: вращение закреплено в центре панели. Нам нужно переместить его начало в точку привязки: гвоздь.
Смещение источника трансформации
До Compose изменение точки привязки преобразования вращения не представляло большой проблемы. Например, RotateAnimation
позволяет изменить точку поворота непосредственно в его конструкторе:
public RotateAnimation ( float fromDegrees, float toDegrees, float pivotX, float pivotY )
В Compose метод rotate
не позволяет вам изменить свою точку поворота или любые другие, казалось бы, связанные модификаторы. Пока не найдешь: transformOrigin
.
Прежде всего важно понять, что все методы преобразования модификаторов оборачивают операции слоя в компонуемый объект. Метод rotate
не новичок в этом:
@Stable fun Modifier.rotate(degrees: Float) = if (degrees != 0f) graphicsLayer(rotationZ = degrees) else this
Он изменяет свойство слоя rotationZ
с заданным углом. Это намекает нам на то, что смещение опорной точки может быть вызвано изменением свойства graphicLayer
.
Модификатор graphicLayer
имеет свойство transformOrigin
, которое по умолчанию равно TransformOrigin.Center
. Если присмотреться к его реализации, он принимает два атрибута: pivotFractionX
и pivotFractionY
. Изменив начало координат, мы можем сориентировать его по местоположению нашего гвоздя.
Учитывая положение гвоздя, это означает, что центр находится горизонтально и почти в верхней части оси Y. Затем мы применяем наше вращение непосредственно к атрибуту rotationZ
.
Он производит следующий эффект:
Именно то, что мы хотели сделать! Что если элемент уже повернут, как мы могли видеть во вводной анимации.
Сначала нам нужно повернуть наш составной объект Swing
:
Обратите внимание, что выравнивание Box
изменилось на TopStart
.
Мы также скорректировали начало нашего преобразования, потому что мы изменили нашу ссылку, повернув Box
.
Это дает следующую анимацию:
Искусство трансформации
Изменение поворота анимации не распространяется исключительно на вращение. Все преобразования могут извлечь выгоду из этого свойства. Вы должны знать, что он существует и его полезность. Это может пригодиться для ваших будущих анимаций.
Повторное открытие нового API иногда может вызывать разочарование. Однако будьте уверены, что команда Compose поможет вам. Если вы чувствуете, что в Compose чего-то не хватает, я бы порекомендовал присоединиться к Kotlin Slack Channel. Участники поддерживают друг друга и способствуют росту сообщества. Для тем, связанных с Compose, существует специальная комната. Я пришел просить о помощи — спасибо Romain Guy за то, что он помог мне найти решение.
Наконец, все вышеперечисленное должно работать с Compose Multiplatform — в этом коде нет ничего специфичного для Android.
Больше статей на подходе! Удачного кодирования!