Fork me on GitHub

iOS仿QQ消息动画

此次是通过CALayer和CoreGraphics结合实现了QQ消息列表中滑动使数字消失的动画。在滑动的过程中,中间会逐渐变瘦。效果如下图:
效果

实现思路

思路是通过两个圆加一个自己绘制的图形三部分组成,并且是在理想条件下的动画,然后再进行坐标的微调。

所谓的理想条件如下图1:两个圆大小是一样,同时AB和CD是平行的,AC和BD是两个圆的切线。

图1

图2
根据图1我们算出A、B、C、D、O、P这6个点的坐标(见图2)。O、P两个坐标稍微复杂点。这时候如果我们在AOC这三个点加一条弧线明显是不行的,没有弧度。
所以我们需要调整O、P点的坐标以实现弧度,O、P两个点向里移动,这时候我们在滑动的时候,中间会出现逐渐变瘦的效果。

1
2
3
4
CGFloat maxOffx = r1;
CGFloat maxOffy = r1;
CGFloat maxD = 8*r1;//滑动最大距离
CGFloat factor = MIN(maxD, d)/maxD;//这个factor就是需要便宜的百分比

这时候我们可以算出O、P偏移之后的坐标

1
2
pointOffO = CGPointMake(pointO.x+maxOffx*factor, pointO.y+maxOffy*factor);
pointOffP = CGPointMake(pointP.x-maxOffx*factor, pointP.y-maxOffy*factor);

由于我们滑动过程中会分为四个方向,所以会做如下处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
UIBezierPath *ovalPath = [UIBezierPath bezierPath];
[ovalPath moveToPoint:pointA];
CGPoint pointOffO;
CGPoint pointOffP;

if(x1>x2&&y1>y2){
pointOffO = CGPointMake(pointO.x+maxOffx*factor, pointO.y-maxOffy*factor);
pointOffP = CGPointMake(pointP.x-maxOffx*factor, pointP.y+maxOffy*factor);
}else if (x1<x2&&y2<y1){
pointOffO = CGPointMake(pointO.x+maxOffx*factor, pointO.y+maxOffy*factor);
pointOffP = CGPointMake(pointP.x-maxOffx*factor, pointP.y-maxOffy*factor);
}else if (x1>x2&&y1<y2) {
pointOffO = CGPointMake(pointO.x-maxOffx*factor, pointO.y-maxOffy*factor);
pointOffP = CGPointMake(pointP.x+maxOffx*factor, pointP.y+maxOffy*factor);
}else{
pointOffO = CGPointMake(pointO.x-maxOffx*factor, pointO.y+maxOffy*factor);
pointOffP = CGPointMake(pointP.x+maxOffx*factor, pointP.y-maxOffy*factor);
}

完整代码

Github完整代码

0%