2015-10-05 3 views
8

Мне удалось анимировать 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") 

ответ

2

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

anim.repeatCount = 0.25  

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

Append:
1. Чтобы достичь того, чего вы хотите, ближайший способ состоит в том, чтобы иметь 25% -ную подпапку, вот helper method.

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

ticker.position = ticker.presentationLayer().position 
+1

Проблема заключается в том, что анимация не будет останавливаться на 1/4 пути через * путь *, только на 1/4 пути через * анимацию *. Поэтому с помощью функции времени «kCAMediaTimingFunctionEaseInEaseOut» и 0,25 для «repeatCount» анимация останавливается раньше, чем ожидалось. Кроме того, функция синхронизации будет по-прежнему применяться ко всей продолжительности анимации - и, следовательно, она будет ускоряться, а затем внезапно останавливаться, что может или не может быть тем, что хочет OP. – Hamish

+0

@ originaluser2, вы правы. Я обнаружил, что анимация останавливается не совсем так, как я думал, что так будет, поэтому это объясняет! Благодаря! Я ищу 1/4 пути, а не анимацию. –

0

Вы пытаетесь установить fromValue и toValue свойства? Он должен работать, если вы установите fromValue в 0,0 и toValue в 0,25

+1

'fromValue' и' toValue' введены в 'CABasicAnimation', который не является суперклассом для' CAKeyframeAnimation' –

0

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

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

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

RepeatCount

Как wj2061 упоминалось это his answer вас может настроить анимацию repeatCount. Против это будет живой 0,25 времени анимации, а не 0,25 траектории

CAShapeLayer

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

Clever RepeatCount

можно рассчитать такую ​​repeatCount значение, анимация остановится на 0.25 пути.

  • захватить некоторые Безье Lib
  • экстракта Безье из функции синхронизации с getControlPointAtIndex:
  • решить Безье, чтобы получить его «значение прогресса» (обычно называемый t), для которого «у» значения Безье будет соответствовать к вашему «требуется прогресс» 'х' значение (0.25)
  • CALCulate Безье для этого t - это точное значение repeatCount вам нужно

Anim живать с CAAnimation, все сами

родом передового

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

путь Split

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


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


Используемые материалы: Wiki on Cubic function, Great article about operations on beziers, Cubic equations solving method line-by-line

0

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

То, что я закончил, - это установить уровень strokeStart и strokeEnd слоя в то же значение с плавающей точкой, что и анимация.

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

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

+0

Я не помню точных причин, но это не сработало. (Я не тот, кто занижен) –

Смежные вопросы