Path アニメーション　その１


pathを使ったアニメーションを試してみました。

作ったのは読み込み中などに動くアニメーションのようなもの。

ちょっとgifはかくかくしてますが、実際は滑らかに上からぐるぐると延々と回ります。

![iphonePlay_2014112901.gif](https://qiita-image-store.s3.amazonaws.com/0/40693/d983cba8-9481-2947-75a9-2d36ee180490.gif "iphonePlay_2014112901.gif")

大雑把な作り方として

1. 背景として円を描写

```
   func backViewImage() -> UIImage {
        var size = CGSize(width: self.view.bounds.width, height: self.view.bounds.height)
        UIGraphicsBeginImageContext(size)

        var context = UIGraphicsGetCurrentContext()
        CGContextSaveGState(context)

        var cyclePath : CGMutablePathRef = CGPathCreateMutable()
        var cyclePath2 : CGMutablePathRef = CGPathCreateMutable()
        
        var x : CGFloat = self.view.frame.size.width/2
        var y : CGFloat = self.view.frame.size.height/2
        var radius : CGFloat = 100.0

        CGContextSetFillColorWithColor(context, UIColor.whiteColor().CGColor)
        
        CGPathAddArc(cyclePath, nil, x, y, radius, CGFloat(0), CGFloat(M_PI*2), false)
        
        CGContextSetLineWidth(context, 20);
        CGContextSetStrokeColorWithColor(context, UIColor.grayColor().CGColor)
        CGContextAddPath(context, cyclePath)
        
        CGContextDrawPath(context, kCGPathStroke)

        var image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        CGContextRestoreGState(context)
        
        return image
    }

```

作ったイメージをCALayerに追加するなりします。

1. 動かす図を描写

```
    /*
    * 描画領域より大きい円を描いてその一部を描写する
    */
    func cycleImage() -> UIImage {
        var size : CGSize = CGSizeMake(20, 20)
        var radius : CGFloat = 100
        UIGraphicsBeginImageContext(size)
        var context = UIGraphicsGetCurrentContext()
        
        var path : CGMutablePathRef = CGPathCreateMutable()
        CGPathAddArc(path, nil, size.width/2, radius+size.height/2, radius, CGFloat(M_PI), CGFloat(M_PI*2), false)
        CGContextAddPath(context, path)
        CGContextSetLineWidth(context, 20);
        CGContextSetStrokeColorWithColor(context, UIColor.darkGrayColor().CGColor)
        CGContextDrawPath(context, kCGPathStroke)
        
        var image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }

```

作った円を回る図を作り、それをUIImageViewにセットします。
作る図は背景の円の一部を切り取った形にしたい為、描画域の外に円の中心を求めて描いた円の-10〜10度あたりを切り取るような感じで描きます。
このテクニックは以下を参考

[Core Graphics Tutorial: Arcs and Paths](http://www.raywenderlich.com/33193/core-graphics-tutorial-arcs-and-paths)

以前は日本語のページもあったのですが、何故か無くなっています。分かりやすく色んなテクニックを教えてくれるいいサイトなんですが・・・。


3. 作った図をパスで動かす

```
    func animationPath(){
        //パスでイメージを動かす
        var animation = CAKeyframeAnimation(keyPath: "position")
        animation.fillMode = kCAFillModeForwards
        animation.removedOnCompletion = false
        animation.duration = 10.0
        animation.repeatCount = Float.infinity
        
        var x : CGFloat = self.view.frame.size.width/2
        var y : CGFloat = self.view.frame.size.height/2
        var radius : CGFloat = 100.0
        
        var cyclePath : CGMutablePathRef = CGPathCreateMutable()
        CGPathAddArc(cyclePath, nil, x, y, radius, CGFloat(M_PI*(3/2)), CGFloat(-M_PI/2), false)
        
        animation.path = cyclePath
        imageView?.layer.addAnimation(animation, forKey: nil)
        
        //イメージ自体を回転させる
        var animation2 : CABasicAnimation = CABasicAnimation(keyPath: "transform")
        animation2.delegate = self
        animation2.fromValue = NSNumber(double: 0)
        animation2.toValue = NSNumber(double: M_PI*2)
        animation2.valueFunction = CAValueFunction(name: kCAValueFunctionRotateZ)
        animation2.duration = 10
        animation2.removedOnCompletion = false
        animation2.fillMode = kCAFillModeForwards
        animation2.repeatCount = Float.infinity
     
        imageView?.layer.addAnimation(animation2, forKey: nil)
    
    }

```

作った図を動かすパスを作成。そのパスを図をセットしたUIImageViewのレイヤーに追加。
さらに今回は動かす図をパスの動く時間に合わせて回転するようにします。これを追加しないとひっくり返ったお椀型の図が単に回る形になってしますので。