32

贝塞尔曲线的动画运用

 5 years ago
source link: http://www.cocoachina.com/ios/20190315/26569.html?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

背景:因为公司需要做等级切换查看对应的权益,需要做一个曲线运动的一个动画形式,现决定用贝塞尔曲线的动画和CAKeyframeAnimation 动画的形式实现

上图
Yzay2iv.gif

grade.gif

制作曲线路径

  • 不想用 - (void)drawRect:(CGRect)rect 的形式画圆,我这里就直接用CAShapeLayer写了。

    首先绘制一个半圆形当背景,使用CAShapeLayer 和 UIBezierPath绘制曲线路径,声明圆的半径 radius 圆心所在的点centerPoint。

//懒加载
- (CAShapeLayer *)shapeLayer
{
    if (!_shapeLayer) {
        _shapeLayer = [CAShapeLayer layer];
        _shapeLayer.path = self.bezierPath.CGPath;
        _shapeLayer.lineWidth = 3;
        _shapeLayer.fillColor = [UIColor clearColor].CGColor;
        _shapeLayer.strokeColor = [UIColor colorWithWhite:1 alpha:0.6].CGColor;
    }
    return _shapeLayer;
}

-(UIBezierPath *)bezierPath
{
    UIBezierPath *bezierPath = [UIBezierPath bezierPathWithArcCenter:self.centerPoint
                                   radius:self.radius
                               startAngle:0
                                 endAngle:M_PI
                                clockwise:YES];
    return bezierPath;
}
  • 创建等级对应的数据模型,我这里使用的json本地数据进行建模了

   // 获取文件路径
    NSString *path = [[NSBundle mainBundle] pathForResource:@"grade" ofType:@"json"];
    // 将文件数据化
    NSData *data = [[NSData alloc] initWithContentsOfFile:path];
    // 对数据进行JSON格式化并返回字典形式
    NSDictionary *result = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
  • 这里的动画形式主要是通过贝塞尔的角度计算的

       double angle = gradeInfo.angle.doubleValue;
        CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
        animation.keyPath = @"position";
        animation.duration = 0.6;
        animation.removedOnCompletion = NO;
        animation.fillMode = kCAFillModeForwards;
        // 设置贝塞尔曲线路径
        UIBezierPath *circylePath = [[UIBezierPath alloc] init];
        [circylePath addArcWithCenter:self.centerPoint radius:self.radius startAngle:angle *M_PI endAngle:(angle +angleTrend)*M_PI clockwise:clockwise];
        animation.path = circylePath.CGPath;
  • 动画执行后真实的所在位置并不会发生改变,我们需要对动画完成后对当前的图片做位置修改

   //位置纠正
        CGFloat a = (gradeInfo.angle.floatValue + angleTrend) * M_PI;
        CGPoint point = CGPointMake(self.centerPoint.x + cos(a) *(self.radius), self.centerPoint.y + sin(a) *(self.radius));
        gradeInfo.iconImage.center = point;

好了,结束!

GitHub地址: https://github.com/zyaxuan/NTGrade

作者:只因为趁年轻
链接:https://www.jianshu.com/p/412dd8e33d13


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK