两条Bézier路径形状之间的动画 [英] Animating between two bezier path shapes

查看:155
本文介绍了两条Bézier路径形状之间的动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我觉得棘手的动画一个的UIImageView 两者之间的状态:原来的矩形边框,并用创造了一个新的形状 UIBezierPath 。有提到很多不同的技术,其中大部分并没有为我工作。

I found it tricky to animate a UIImageView between two states: its original rectangle frame, and a new shape created with a UIBezierPath. There are many different techniques mentioned, most of which did not work for me.

首先是实现了使用的UIView动画块是行不通的;显然一个人不能在一个 animateWithDuration执行子层动画:块。 (请参见这里和的here

First was the realization that using UIView block animation would not work; evidently one can't perform sublayer animations in an animateWithDuration: block. (see here and here)

这让 CAAnimation ,像 CABasicAnimation 的具体子类。我很快意识到,一个人不能从没有一个 CAShapeLayer 一,它(请参阅<一个视图动画href=\"http://stackoverflow.com/questions/11463438/cabasicanimation-with-calayer-path-doesnt-animate\">here,例如)。

That left CAAnimation, with the concrete subclasses like CABasicAnimation. I soon realized that one can't animate from a view that doesn't have a CAShapeLayer to one that does (see here, for example).

他们不能只是任何两个形状图层路径,而是动画形状图层的路径,才能保证当您从动画一样喜欢的工作(见的here

And they can't be just any two shape layer paths, but rather "Animating the path of a shape layer is only guaranteed to work when you are animating from like to like" (see here)

通过在地方,来了更现实的问题,如怎样使用 fromValue toValue (应他们是一个 CAShapeLayer CGPath ?),有什么动画添加到(在屏蔽?)等。

With that in place, comes the more mundane problems, like what to use for fromValue and toValue (should they be a CAShapeLayer, or a CGPath?), what to add the animation to (the layer, or the mask?), etc.

似乎有这么多的变数;该组合会给我我一直在寻找的动画?

It seemed there were so many variables; which combination would give me the animation I was looking for?

推荐答案

首先重要的一点是相似的构造两个贝塞尔路径,所以矩形是一个(简单)模拟向更复杂的形状。

The first important point is to construct the two bezier paths similarly, so the rectangle is a (trivial) analogue to the more complex shape.

// the complex bezier path
let initialPoint = CGPoint(x: 0, y: 0)
let curveStart = CGPoint(x: 0, y: (rect.size.height) * (0.2))
let curveControl = CGPoint(x: (rect.size.width) * (0.6), y: (rect.size.height) * (0.5))
let curveEnd = CGPoint(x: 0, y: (rect.size.height) * (0.8))
let firstCorner = CGPoint(x: 0, y: rect.size.height)
let secondCorner = CGPoint(x: rect.size.width, y: rect.size.height)
let thirdCorner = CGPoint(x: rect.size.width, y: 0)

var myBezierArc = UIBezierPath()
myBezierArc.moveToPoint(initialPoint)
myBezierArc.addLineToPoint(curveStart)
myBezierArc.addQuadCurveToPoint(curveEnd, controlPoint: curveControl)
myBezierArc.addLineToPoint(firstCorner)
myBezierArc.addLineToPoint(secondCorner)
myBezierArc.addLineToPoint(thirdCorner)

在简单的'小事'贝塞尔路径,即创建一个矩形,是完全一样的,但的ControlPoint 设置,以便它似乎不应该存在:

The simpler 'trivial' bezier path, that creates a rectangle, is exactly the same but the controlPoint is set so that it appears to not be there:

let curveControl = CGPoint(x: 0, y: (rect.size.height) * (0.5))

(尝试删除 addQuadCurveToPoint 线得到一个很奇怪的动画!)

( Try removing the addQuadCurveToPoint line to get a very strange animation! )

最后,动画命令:

let myAnimation = CABasicAnimation(keyPath: "path")

if (isArcVisible == true) {
    myAnimation.fromValue = myBezierArc.CGPath
    myAnimation.toValue = myBezierTrivial.CGPath
} else {
    myAnimation.fromValue = myBezierTrivial.CGPath
    myAnimation.toValue = myBezierArc.CGPath
}       
myAnimation.duration = 0.4
myAnimation.fillMode = kCAFillModeForwards
myAnimation.removedOnCompletion = false

myImageView.layer.mask.addAnimation(myAnimation, forKey: "animatePath")

如果有人有兴趣,该项目是这里

If anyone is interested, the project is here.

这篇关于两条Bézier路径形状之间的动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆