2015-10-05 11 views
8

私はUIBezierPathに沿ってCALayerをアニメーション化することができます。UIBezierPathに沿って完全なCALayerアニメーションの割合をアニメーション化する方法は?

私が達成しようとしているのは、パスの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

簡単な変更1プロパティ:ここ

anim.repeatCount = 0.25  

はあなたのアニメーションの上に、さらにきめ細かい制御を持ってする方法を学ぶことができ、 excellent article on animation timingです。

追加:
1.あなたが望むものを達成するには、最も近い方法は25%のsubPathを持つことです。ここにはある程度のhelper methodがあります。あなた2.Ifは

は、速度差をスタンド上記の方法を使用して、アニメーションが終了したときの位置をバックに設定することができます

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

この問題は、アニメーションが* path *の途中で停止せず、*アニメーション*の1/4だけ停止することです。したがって、 'kCAMediaTimingFunctionEaseInEaseOut'タイミング関数と' repeatCount'の0.25では、アニメーションは予想より早く停止します。さらに、タイミング機能はアニメーションの持続時間全体に適用されます。したがって、OPが望むものであってもなくても、スピードアップしてから突然停止するように見えます。 – Hamish

+0

@ originaluser2、あなたは正しいです。私はそれがそれを説明するので、私はそれが思ったどこに完全に停止アニメーションを見つけた!ありがとう!私は、アニメーションではなく、パスの1/4を探しています。 –

0

あなたは場合、fromValuetoValueのプロパティを設定しようとしましたか?それはつまり、後に開始(あなたが0.25

+1

'fromValue'と' toValue'は 'CAKeyframeAnimation'のスーパークラスではない' CABasicAnimation'に導入されました –

0

だけでなくCGPathにtoValueの0.0に場合、fromValueを設定した場合は不透明ですが、またCAAnimation継続的なアニメーションのための更新や通知をサポートしていません動作するはずですが、終了する前に)。関与するエンティティはアニメーションそのものと、それに適用されるCALayerです。

ので、オプションは次のとおりです。

(下記参照、いくつかのオプションがあまりにも怖い聞こえるかもしれないが、彼らはありませんので、私は、サンプルプロジェクトを作った)

のrepeatCount

言及wj2061がhis answerあなたであるためアニメーションのrepeatCountを微調整できます。短所それはそれは、セグメントのようになります。万が一、あなたがtickerCAShapeLayerとセグメントを表すことができ、場合、あなたはstrokeStartstrokeEndをアニメーション化することができない0.25パスの

CAShapeLayer、

をアニメーション時間の0.25をアニメーション化しますですパスに沿って移動さ

賢いrepeatCountに

あなたがアニメーションパスの0.25で停止するようrepeatCount値を計算することができます。

  • getControlPointAtIndex:
  • と機能からタイミング
  • エキスベジエlibにいくつかのベジエはベジエの「Y」の値は、あなたの「必要に一致する対象の(通常はt命名)その「進捗値」を取得するためにベジエを解決グラブ進歩」というt用(0.25)
  • 計算ベジエの 'x' の値が - これはrepeatCountの正確な値が必要である

のAnim CAAnimation、
  • libにいくつかのベジエはベジエから(のは、ベジェパスのrideProgress
  • アドオンを合成プロパティを言わせて、動的プロパティを持つカスタムのCALayerのサブクラスを作成
    • 高度なグラブのすべて自分で
  • 種類とating lib、CGPathではない)とサブレイヤ(例:rideLayer)をアニメーション化する

  • rideProgressキーの場合はneedsDisplayForKey:、導入プロパティの場合はinitWithLayer:ただし、drawInContext:の代わりにを使用してください。drawInContext:をコピーして、必要なものを描画してください。または(より良い)displaydisplayで現在のrideProgressの値をpresentationLayerから取得し、サブレイヤーを更新してからsuperを呼び出します。どちらにしても、値
  • rideProgressにCAAnimationまたは暗黙的なアニメーションの任意の種類を使用して、任意の層ついに
  • のいずれかの、アニメーション化プロパティを設定する前CATransaction.setDisableActions(true)に忘れないように、現在のrideProgressに応じて副層のための位置と回転を計算するためにLIBベジエ使用しますプロパティ
  • スプリットパス

    ここでも、wj2061によって提案されました。半分の1が元


    Hereの0.25を表しますので、あなたがパスを分割することができ、「スプリットパス」以外は、上記のすべての実装例です。私はこのコードでフィールドテストを実行していませんでした。これは単なる動作コンセプトです。 XCode 7.3.1、Swift。使用


    材料:Wiki on Cubic functionGreat article about operations on beziersCubic equations solving method line-by-line

    0

    私は同じ問題に実行していた、と私はパスの描画が、それの割合のみをアニメーション化したかったです。

    最後に、レイヤのstrokeStartとstrokeEndをアニメーションと同じ浮動小数点値に設定しました。

    あなたの例では、anim.fromValue = 0.0f、anim.toValue = 0.6f、さらにticker.strokeStart=0.0fticker.strokeEnd = 0.6fを設定してみてください。

    これで、パスの60%しか正常に描画されず、アニメーション化されました。

    +0

    私は正確な理由を覚えていませんが、これはうまくいきませんでした。 (私はダウン投票した人ではない) –

    関連する問題