在 UIBezier 路径的某些部分上设置动画
Animating on some part of UIBezier path
我有两个 UIBezierPath...
第一条路径显示往返目的地的总路径,第二条路径是第一条路径的副本,但该副本应该是第一条路径的百分比,我无法做到。
基本上我希望飞机停在绿色 UIBezier 路径结束的部分,直到过去的绿色。
我在 hte link 中附加了一个视频,它将显示我想要获得的动画。 http://cl.ly/302I3O2f0S3Y
还有一个类似的问题是 Move CALayer via UIBezierPath
这里是相关代码
override func viewDidLoad() {
super.viewDidLoad()
let endPoint = CGPointMake(fullFlightLine.frame.origin.x + fullFlightLine.frame.size.width, fullFlightLine.frame.origin.y + 100)
self.layer = CALayer()
self.layer.contents = UIImage(named: "Plane")?.CGImage
self.layer.frame = CGRectMake(fullFlightLine.frame.origin.x - 10, fullFlightLine.frame.origin.y + 10, 120, 120)
self.path = UIBezierPath()
self.path.moveToPoint(CGPointMake(fullFlightLine.frame.origin.x, fullFlightLine.frame.origin.y + fullFlightLine.frame.size.height/4))
self.path.addQuadCurveToPoint(endPoint, controlPoint:CGPointMake(self.view.bounds.size.width/2, -200))
self.animationPath = self.path.copy() as! UIBezierPath
let w = (viewModel?.completePercentage) as CGFloat!
// let animationRectangle = UIBezierPath(rect: CGRectMake(fullFlightLine.frame.origin.x-20, fullFlightLine.frame.origin.y-270, fullFlightLine.frame.size.width*w, fullFlightLine.frame.size.height-20))
// let currentContext = UIGraphicsGetCurrentContext()
// CGContextSaveGState(currentContext)
// self.animationPath.appendPath(animationRectangle)
// self.animationPath.addClip()
// CGContextRestoreGState(currentContext)
self.shapeLayer = CAShapeLayer()
self.shapeLayer.path = path.CGPath
self.shapeLayer.strokeColor = UIColor.redColor().CGColor
self.shapeLayer.fillColor = UIColor.clearColor().CGColor
self.shapeLayer.lineWidth = 10
self.animationLayer = CAShapeLayer()
self.animationLayer.path = animationPath.CGPath
self.animationLayer.strokeColor = UIColor.greenColor().CGColor
self.animationLayer.strokeEnd = w
self.animationLayer.fillColor = UIColor.clearColor().CGColor
self.animationLayer.lineWidth = 3
fullFlightLine.layer.addSublayer(shapeLayer)
fullFlightLine.layer.addSublayer(animationLayer)
fullFlightLine.layer.addSublayer(self.layer)
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
updateAnimationForPath(self.animationLayer)
}
func updateAnimationForPath(pathLayer : CAShapeLayer) {
let animation : CAKeyframeAnimation = CAKeyframeAnimation(keyPath: "position")
animation.path = pathLayer.path
animation.calculationMode = kCAAnimationPaced
animation.delegate = self
animation.duration = 3.0
self.layer.addAnimation(animation, forKey: "bezierPathAnimation")
}
}
extension Int {
var degreesToRadians : CGFloat {
return CGFloat(self) * CGFloat(M_PI) / 180.0
}
}
您的行进路径动画非常正确。现在唯一的问题是您将关键路径动画的路径设置为 whole 贝塞尔曲线路径:
animation.path = pathLayer.path
如果您希望动画仅覆盖该路径的一部分,您有两种选择:
提供更短版本的贝塞尔曲线路径,而不是 pathLayer.path
。
或者,将整个动画包装在持续时间较短的 CAAnimationGroup 中。例如,如果您的三秒动画包裹在两秒动画组中,它会在播放到三分之二时停止。
我有两个 UIBezierPath...
第一条路径显示往返目的地的总路径,第二条路径是第一条路径的副本,但该副本应该是第一条路径的百分比,我无法做到。
基本上我希望飞机停在绿色 UIBezier 路径结束的部分,直到过去的绿色。
我在 hte link 中附加了一个视频,它将显示我想要获得的动画。 http://cl.ly/302I3O2f0S3Y
还有一个类似的问题是 Move CALayer via UIBezierPath
这里是相关代码
override func viewDidLoad() {
super.viewDidLoad()
let endPoint = CGPointMake(fullFlightLine.frame.origin.x + fullFlightLine.frame.size.width, fullFlightLine.frame.origin.y + 100)
self.layer = CALayer()
self.layer.contents = UIImage(named: "Plane")?.CGImage
self.layer.frame = CGRectMake(fullFlightLine.frame.origin.x - 10, fullFlightLine.frame.origin.y + 10, 120, 120)
self.path = UIBezierPath()
self.path.moveToPoint(CGPointMake(fullFlightLine.frame.origin.x, fullFlightLine.frame.origin.y + fullFlightLine.frame.size.height/4))
self.path.addQuadCurveToPoint(endPoint, controlPoint:CGPointMake(self.view.bounds.size.width/2, -200))
self.animationPath = self.path.copy() as! UIBezierPath
let w = (viewModel?.completePercentage) as CGFloat!
// let animationRectangle = UIBezierPath(rect: CGRectMake(fullFlightLine.frame.origin.x-20, fullFlightLine.frame.origin.y-270, fullFlightLine.frame.size.width*w, fullFlightLine.frame.size.height-20))
// let currentContext = UIGraphicsGetCurrentContext()
// CGContextSaveGState(currentContext)
// self.animationPath.appendPath(animationRectangle)
// self.animationPath.addClip()
// CGContextRestoreGState(currentContext)
self.shapeLayer = CAShapeLayer()
self.shapeLayer.path = path.CGPath
self.shapeLayer.strokeColor = UIColor.redColor().CGColor
self.shapeLayer.fillColor = UIColor.clearColor().CGColor
self.shapeLayer.lineWidth = 10
self.animationLayer = CAShapeLayer()
self.animationLayer.path = animationPath.CGPath
self.animationLayer.strokeColor = UIColor.greenColor().CGColor
self.animationLayer.strokeEnd = w
self.animationLayer.fillColor = UIColor.clearColor().CGColor
self.animationLayer.lineWidth = 3
fullFlightLine.layer.addSublayer(shapeLayer)
fullFlightLine.layer.addSublayer(animationLayer)
fullFlightLine.layer.addSublayer(self.layer)
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
updateAnimationForPath(self.animationLayer)
}
func updateAnimationForPath(pathLayer : CAShapeLayer) {
let animation : CAKeyframeAnimation = CAKeyframeAnimation(keyPath: "position")
animation.path = pathLayer.path
animation.calculationMode = kCAAnimationPaced
animation.delegate = self
animation.duration = 3.0
self.layer.addAnimation(animation, forKey: "bezierPathAnimation")
}
}
extension Int {
var degreesToRadians : CGFloat {
return CGFloat(self) * CGFloat(M_PI) / 180.0
}
}
您的行进路径动画非常正确。现在唯一的问题是您将关键路径动画的路径设置为 whole 贝塞尔曲线路径:
animation.path = pathLayer.path
如果您希望动画仅覆盖该路径的一部分,您有两种选择:
提供更短版本的贝塞尔曲线路径,而不是
pathLayer.path
。或者,将整个动画包装在持续时间较短的 CAAnimationGroup 中。例如,如果您的三秒动画包裹在两秒动画组中,它会在播放到三分之二时停止。