簡體   English   中英

如何制作線跡動畫CALayer?

[英]How to make line track animating CALayer?

我有許多動畫CALayers,並且我想在動畫時排成一行。

假設有兩個動畫圈CALayers。 我想用一條線跟蹤CALayers的中心。 我想出了兩種可能的解決方案。

1每當將什么動畫添加到圓形圖層時,就計算直線的相應動畫。

2使用受objc.io啟發的時間計算來控制整個動畫。 在每個步驟中,計算圓如何移動以及如何移動以及直線。

有一個問題,在解決方案一中,將有不良的代碼來控制太多的圓圈層,並且對於不同的圓圈動畫,應該有不同的對應關系。 如果有很多圈子和各種各樣的動畫,情況將會變得更糟,這正是我的情況。

在解決方案二中,我必須放棄Core Animation並從頭開始做,這會增加復雜性,並且將來很難進行調整。

有沒有一種更簡單,更優雅的方法來執行此操作,也許是核心動畫背后的一些技巧。 非常感謝。

更新:根據@Duncan C指出的,我正在嘗試使用具有相同時間功能的3層。

我根據圓圈創建了線條動畫。 為了處理多個動畫,需要添加動畫。 但是添加到CAShaperLayer行的動畫使整個視圖變黑。 哪里不對了?

這是一些代碼。 TIA。

- (void)startHorizontalAnimation:(int)duplicateNum {
    // circle animation
    const double distance = 30;
    int totalTime = 600;
    int timeEachDirection = 5;
    double zInterpolation = self.zPosition / duplicateNum;
    double position = distance * 2 * zInterpolation - distance;

    CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
    animation.keyPath = @"position.x";

    NSMutableArray *valueArr = [[NSMutableArray alloc] initWithObjects:@0, nil];
    for (int i = 0; i < totalTime / (timeEachDirection * 2); ++i) {
        [valueArr addObject:[NSNumber numberWithDouble:position]];
        [valueArr addObject:[NSNumber numberWithDouble:-position]];
    }
    [valueArr addObject:@0];
    animation.values = valueArr;


    animation.additive = YES;
    animation.duration = totalTime;

    NSMutableArray *animationArr = [[NSMutableArray alloc] init];
    for (int i = 0; i < [valueArr count] - 1; ++i) {
        [animationArr addObject:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
    }

    animation.timingFunctions = animationArr;

    animation.delegate = self.delegate;

    [self addAnimation:animation forKey:ANIMI_HORIZONTALD_DISPERSE];

    // line animation
    CAAnimation *startAnimation = [self copyPositionFrom:animation modifyStart:YES onDirectionX:YES];
    CAAnimation *endAnimation = [self copyPositionFrom:animation modifyStart:NO onDirectionX:YES];

    [self.lineFrom addAnimation:startAnimation forKey:nil];
    [self.lineTo addAnimation:endAnimation forKey:nil];

}

// create line animation according to the circle animation, changing the start point or end point on direction x or y.
- (CAAnimation *)copyPositionFrom:(CAKeyframeAnimation *)animation modifyStart:(BOOL)modifyStart onDirectionX:(BOOL)directionX {
    CAKeyframeAnimation *newAnimation = [CAKeyframeAnimation animationWithKeyPath:@"path"];
    newAnimation.additive = animation.additive;
    newAnimation.duration = animation.duration;
    newAnimation.timingFunction = animation.timingFunction;
    newAnimation.delegate = animation.delegate;


    CGPathRef lineCGPath = ((CAShapeLayer *)self.lineFrom).path;
    NSMutableArray *bezierPoints = [NSMutableArray array];
    // MyCGPathApplierFunc is according to http://stackoverflow.com/a/5714872/531966
    CGPathApply(lineCGPath, (__bridge void *)(bezierPoints), MyCGPathApplierFunc);

    __block NSMutableArray *pathArray = [NSMutableArray array];
    [animation.values enumerateObjectsUsingBlock:^(NSNumber *value, NSUInteger idx, BOOL *stop) {

        CGPoint startPoint = [[bezierPoints objectAtIndex:0] CGPointValue];
        CGPoint endPoint = [[bezierPoints objectAtIndex:1] CGPointValue];

        // modify the position additively
        if (modifyStart) {
            if (directionX) {
                startPoint.x += [value floatValue];
            } else {
                startPoint.y += [value floatValue];
            }
        } else {
            if (directionX) {
                endPoint.x += [value floatValue];
            } else {
                endPoint.y += [value floatValue];
            }
        }

        UIBezierPath *linePath = [UIBezierPath bezierPath];
        [linePath moveToPoint:startPoint];
        [linePath addLineToPoint:endPoint];

        [pathArray addObject:linePath];
    }];

    newAnimation.values = pathArray;
    return newAnimation;
}

@interface CircleShapeLayer : CAShapeLayer

@property (nonatomic, weak) CAShapeLayer *lineFrom; // the line goes from the circle
@property (nonatomic, weak) CAShapeLayer *lineTo; // the line goes to the circle

@end

我建議您以相同的時間在集合中創建動畫。

要為2個圓及其間的線設置動畫,請為每個圓層的position屬性設置為單獨的CABasicAnimation動畫,並為第三個CABasicAnimation設置線動畫(您可以使用CAShapeLayer進行動畫處理,在該動畫中設置路徑的起點和終點形狀層。)

或者,您可以對圓形和連接線使用單個形狀圖層,並同時對路徑進行所有動畫處理(路徑包含2個圓形和線,並創建一個動畫,以同時更改控制點3個。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM