貝塞爾曲線的動畫運用

背景:因為公司需要做等級切換查看對應(yīng)的權(quán)益,需要做一個曲線運動的一個動畫形式,現(xiàn)決定用貝塞爾曲線的動畫和CAKeyframeAnimation 動畫的形式實現(xiàn)

上圖
grade.gif

制作曲線路徑

  • 不想用 - (void)drawRect:(CGRect)rect 的形式畫圓,我這里就直接用CAShapeLayer寫了。
    首先繪制一個半圓形當(dāng)背景,使用CAShapeLayerUIBezierPath繪制曲線路徑,聲明圓的半徑 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;
}

  • 創(chuàng)建等級對應(yīng)的數(shù)據(jù)模型,我這里使用的json本地數(shù)據(jù)進(jìn)行建模了
    // 獲取文件路徑
    NSString *path = [[NSBundle mainBundle] pathForResource:@"grade" ofType:@"json"];
    // 將文件數(shù)據(jù)化
    NSData *data = [[NSData alloc] initWithContentsOfFile:path];
    // 對數(shù)據(jù)進(jìn)行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;
        // 設(shè)置貝塞爾曲線路徑
        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;
  • 動畫執(zhí)行后真實的所在位置并不會發(fā)生改變,我們需要對動畫完成后對當(dāng)前的圖片做位置修改
        //位置糾正
        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;

好了,結(jié)束!
GitHub地址: https://github.com/zyaxuan/NTGrade

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容