Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moving an object along a curve in iPhone development

I wanted to animate an image object by moving it along a particular curve. It is not a general or random curve but rather a curve which follows a particular path on screen.

Currently, Im manually specifying the list of x and y co-ordinates of the path along which i want the image object to move by setting its frame each time. This is a laborious process in the sense that im setting the specific x and y coordinates of the path and moving the image along it. Is there a more efficient way to do this?

Is there a way that i can specify,say, just about 15 - 20 points and have a curve traced along those to move the object? Any other way to acheive this? Any help would be much appreciated. Thanks.

like image 465
Nathan Avatar asked Dec 27 '10 11:12

Nathan


2 Answers

You could use a combination of UIBezierPath and CAKeyFrameAnimation. I found a very useful blog post dealing with this subject.

http://oleb.net/blog/2010/12/animating-drawing-of-cgpath-with-cashapelayer/

Here's a simplified version of what I used (it just animates the drawing of a square):

UIBezierPath *customPath = [UIBezierPath bezierPath];
[customPath moveToPoint:CGPointMake(100,100)];
[customPath addLineToPoint:CGPointMake(200,100)];
[customPath addLineToPoint:CGPointMake(200,200)];
[customPath addLineToPoint:CGPointMake(100,200)];
[customPath addLineToPoint:CGPointMake(100,100)];

UIImage *movingImage = [UIImage imageNamed:@"foo.png"];
CALayer *movingLayer = [CALayer layer];
movingLayer.contents = (id)movingImage.CGImage;
movingLayer.anchorPoint = CGPointZero;
movingLayer.frame = CGRectMake(0.0f, 0.0f, movingImage.size.width, movingImage.size.height);
[self.view.layer addSublayer:movingLayer];

CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
pathAnimation.duration = 4.0f;
pathAnimation.path = customPath.CGPath;
pathAnimation.calculationMode = kCAAnimationLinear;
[movingLayer addAnimation:pathAnimation forKey:@"movingAnimation"];
like image 123
Jilouc Avatar answered Nov 14 '22 10:11

Jilouc


In Swift-3 version of @Jilouc :-

    override func viewDidLoad() {
        super.viewDidLoad()
        addAdditiveAnimation()
        initiateAnimation()
     }

    //curve which follows a particular path  
    func pathToTrace() -> UIBezierPath {
            let path =  UIBezierPath(ovalIn: CGRect(x: 120  , y: 120, width: 100, height: 100))
            let shapeLayer = CAShapeLayer()
            shapeLayer.path = path.cgPath
            shapeLayer.strokeColor = UIColor.red.cgColor
            shapeLayer.lineWidth = 1.0
            self.view.layer.addSublayer(shapeLayer)
            return path
        }

func addAdditiveAnimation() {
        let movement = CAKeyframeAnimation(keyPath: "position")
        movement.path = pathToTrace().cgPath
        movement.duration = 5
        movement.repeatCount = HUGE
        movement.calculationMode = kCAAnimationPaced
        movement.timingFunctions = [CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)]
        self.movement = movement
}

func createLayer() -> CALayer {
        let layer = CALayer()
        let image = UIImage(named: "launch.png")
        layer.frame = CGRect(x: 0 , y: 0, width: (image?.size.width),height: (image?.size.height))
        layer.position = CGPoint(x: 5, y: 5)
        layer.contents = image?.cgImage
        layer.anchorPoint =  .zero
        layer.backgroundColor =  UIColor.red.cgColor
        //layer.cornerRadius =  5
        self.view.layer.addSublayer(layer)
        return layer
    }

func initiateAnimation() {
        let layer = createLayer()
        layer.add(self.movement, forKey: "Object Movement")
     }

Github Demo

like image 45
Shrawan Avatar answered Nov 14 '22 10:11

Shrawan