1

We are trying to create an animation after you press the camera button similar to Frontback app (frontback.me) and haven't been able to find a cocoa pod or the right terminology for the animation. The animation is similar to the old Iris shutter animation Apple used to use.

After you press the camera button, there is an animation. The animation is a circle overlaying the image captured. Inside the circle is the image captured and the outside is black. The circle gets smaller and smaller until it reaches the center and then the entire image captured is shown.

Please advise on where I can find this animation, custom create it and/or the correct terminology for this specific animation. Thank you!

Is this the animation I am looking for, I am quite new to Xcode: CAShapeLayer path animation -- shrinking a circle

Thanks again!

Community
  • 1
  • 1

1 Answers1

2

I'm actually Frontback co-founder and developer who made this. This is how I did it, it's in Rubymotion but it can easily be ported back to Obj-C (or even easier to Swift), you get the idea.

def setupCaptureAnimation
  w = view.bounds.size.width
  h = view.bounds.size.height
  location = CGPointMake(w/2, h/2)
  shapeLayer = CAShapeLayer.layer

  outerRadius = 0.5 * Math.sqrt(w**2 + h**2) # circle around the view bounds
  @animStartPath = makeCircleAtLocation(location, radius:outerRadius).CGPath
  @animEndPath = makeCircleAtLocation(location, radius:0).CGPath

  shapeLayer.path = @animStartPath
  shapeLayer.fillColor = UIColor.blackColor.CGColor

  @animLayer = shapeLayer
end

def playCaptureStartAnimation
  view.layer.addSublayer(@animLayer)
  pathAnimation = CABasicAnimation.animationWithKeyPath("path")
  pathAnimation.setValue("start", forKey:"id")
  pathAnimation.duration = 0.1
  pathAnimation.fromValue = @animStartPath
  pathAnimation.toValue = @animEndPath
  pathAnimation.delegate = self
  @animLayer.addAnimation(pathAnimation, forKey:nil)
  @animLayer.path = @animEndPath
end

def playCaptureEndAnimation
  pathAnimation = CABasicAnimation.animationWithKeyPath("path")
  pathAnimation.setValue("end", forKey:"id")
  pathAnimation.duration = 0.2
  pathAnimation.fromValue = @animEndPath
  pathAnimation.toValue = @animStartPath
  pathAnimation.delegate = self
  @animLayer.addAnimation(pathAnimation, forKey:nil)
  @animLayer.path = @animStartPath
end

def makeCircleAtLocation(location, radius:radius)
  path = UIBezierPath.bezierPath
  # fill rectangle
  rect = view.bounds
  path.moveToPoint(CGPointMake(CGRectGetMinX(rect), CGRectGetMinY(rect)))
  path.addLineToPoint(CGPointMake(CGRectGetMinX(rect), CGRectGetMaxY(rect)))
  path.addLineToPoint(CGPointMake(CGRectGetMaxX(rect), CGRectGetMaxY(rect)))
  path.addLineToPoint(CGPointMake(CGRectGetMaxX(rect), CGRectGetMinY(rect)))
  path.addLineToPoint(CGPointMake(CGRectGetMinX(rect), CGRectGetMinY(rect)))
  # remove circle
  path.addArcWithCenter(location, radius:radius, startAngle:0.0, endAngle:2 * Math::PI, clockwise:true)
  path.closePath

  path
end

def animationDidStop(anim, finished:finished)
  if anim.valueForKey("id") == "start"
    # trigger capture and after that playCaptureEndAnimation
  else
    @animLayer.removeFromSuperlayer
    # done
  end
end

The drawing trick resides in makeCircleAtLocation:radius:: when you draw a path, if you superimpose something (like a circle) on top of something else (like a rectangle), the intersection is actually removed from the path. So by drawing the circle in the rectangle, the circle is removed from the rectangle.

You first have to call setupCaptureAnimation at initialization. Then when the user taps the camera button you have to call playCaptureStartAnimation that will play the shrinking animation, then the delegate method animationDidStop:finished will be called. At that moment the screen is all black, you have to capture the image from the camera session. When it's taken, call playCaptureEndAnimation and it will play the reverse animation.

Melvyn Hills
  • 248
  • 2
  • 6