Как анимировать только процент полной анимации 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% пути и оживило его!