LoginSignup
18
15

More than 5 years have passed since last update.

Path アニメーション その1

Last updated at Posted at 2014-11-30

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

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

ちょっと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

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

  1. 作った図をパスで動かす
    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のレイヤーに追加。
さらに今回は動かす図をパスの動く時間に合わせて回転するようにします。これを追加しないとひっくり返ったお椀型の図が単に回る形になってしますので。

18
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
15