Как анимировать только процент полной анимации CALayer вдоль UIBezierPath?

Мне удается анимировать CALayer вдоль UIBezierPath.

То, что я пытаюсь сделать, это анимировать только часть пути, например, только 25% пути, при этом слой остается в этой позиции (на 25%).

Как это сделать? Вот мой код, он всегда оживляет полный путь.

let aPath = UIBizierPath(CGPath: somePath)
let anim = CAKeyframeAnimation(keyPath: "position")
anim.path = aPath.CGPath
anim.rotationMode = kCAAnimationRotateAuto
anim.repeatCount = 1
anim.fillMode = kCAFillModeForwards
anim.removedOnCompletion = false
anim.duration = 3.0
anim.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)

ticker.addAnimation(anim, forKey: "animate_ticker")

4 ответа

Просто измените одно свойство:

anim.repeatCount = 0.25    

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

Append:
1. Чтобы достичь того, что вы хотите, самый близкий способ - это иметь 25% subPath, вот некоторый вспомогательный метод.

2.Если вы можете выдержать разницу в скорости, используйте метод, описанный выше, и установите положение назад, когда анимация заканчивается:

ticker.position = ticker.presentationLayer().position

Не только CGPath непрозрачный, но также CAAnimation не поддерживает обновления или уведомления для текущих анимаций (т.е. после запуска, но до окончания). Единственные вовлеченные объекты - это сама анимация и CALayer-с это применяется к.

Итак, варианты:

(некоторые варианты могут показаться слишком страшными, но это не так, поэтому я сделал пример проекта, см. ниже)

RepeatCount

Поскольку wj2061 упомянул его ответ, вы можете настроить анимацию repeatCount, Минусы в том, что он будет анимировать 0,25 времени анимации, а не 0,25 пути

CAShapeLayer

Если, случайно, вы можете представлять ticker с CAShapeLayer сегмент, то вы можете анимировать strokeStart а также strokeEnd так будет выглядеть сегмент, движущийся по пути

Умный повторитьСчет

Вы можете рассчитать такой repeatCount значение этой анимации остановится на 0,25 пути.

  • захватить немного безье lib
  • извлечь Безье из функции синхронизации с getControlPointAtIndex:
  • решить Безье, чтобы получить его "значение прогресса" (обычно называется t) для которого значение 'y' Безье будет соответствовать вашему "требуемому прогрессу" (0,25)
  • рассчитать значение Безье 'х' для этого t - это точное значение repeatCount тебе нужно

Анимация с CAAnimation, все самостоятельно

отчасти продвинутый

  • захватить немного безье lib
  • создать собственный подкласс CALayer с динамическим свойством, скажем rideProgress
  • добавить синтезированные свойства для пути Безье (из библиотеки Безье, а не из CGPath) и подслоя (скажем, rideLayer) оживить
  • переопределение needsDisplayForKey: за rideProgress ключ и initWithLayer: для всех введенных свойств НО использовать self.rideLayer?.presentationLayer() вместо копирования rideLayer
  • переопределить один из них: drawInContext: и нарисуйте, что вам нужно в нем; или лучше) display, в display получить текущий rideProgress значение от presentationLayer и обновить подслой, затем вызвать супер. В любом случае, используйте Bezier lib для расчета положения и поворота подслоя в соответствии с текущим rideProgress значение
  • не забудь CATransaction.setDisableActions(true) перед установкой любого анимируемого свойства любого слоя
  • наконец, используйте любой вид CAAnimation или неявную анимацию на rideProgress имущество

Сплит путь

Опять же, предложено wj2061. Вы можете разделить путь так, чтобы одна из половинок представляла 0.25 оригинала


Вот пример реализации всего вышеперечисленного, КРОМЕ "Split path". Я не запускал полевых тестов для этого кода, это просто рабочая концепция. XCode 7.3.1, Swift.


Использованные материалы: вики о кубической функции, отличная статья об операциях на Безье, метод решения кубических уравнений построчно

Вы пытались установить свойства fromValue и toValue? Это должно работать, если вы установите fromValue в 0.0 и toValue в 0.25

Я столкнулся с той же проблемой, и я хотел анимировать рисунок пути, но только процент от него.

В итоге я установил параметры strokeStart и strokeEnd слоя на те же значения с плавающей запятой, что и для анимации.

Так что в вашем примере попробуйте установить anim.fromValue = 0.0f, anim.toValue = 0.6f, а также ticker.strokeStart=0.0f а также ticker.strokeEnd = 0.6f,

Это успешно нарисовало только 60% пути и оживило его!

Другие вопросы по тегам