簡體   English   中英

如何更改CALayer動畫的方向

[英]How to change direction of CALayer animation

如何更改CALayer動畫的方向和起始位置?

例如,如果我使用以下代碼制作圓形動畫:

-(void)drawCircle {
    CAShapeLayer *circleShapeLayer = [[CAShapeLayer alloc] init];
    circleShapeLayer.path          = [self circleBezierPath].CGPath;
    circleShapeLayer.strokeColor   = [UIColor lightGrayColor].CGColor;
    circleShapeLayer.fillColor     = [UIColor clearColor].CGColor;
    circleShapeLayer.lineWidth     = 2;
    [self.view.layer addSublayer:circleShapeLayer];

    CABasicAnimation *circleShapeAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    circleShapeAnimation.timingFunction    = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    circleShapeAnimation.duration          = 1.0f;
    circleShapeAnimation.fromValue         = @(0.0f);
    circleShapeAnimation.toValue           = @(1.0f);
    [circleShapeLayer addAnimation:circleShapeAnimation forKey:@"strokeEnd"];
}

-(UIBezierPath *)circleBezierPath {
    UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 100, 100, 100)];
    return circlePath;
}

動畫總是從3點開始,並沿順時針方向進行動畫處理。

如何強制它從12點(或其他任何位置)開始並沿逆時針方向進行動畫處理?

怎么了

當您在矩形中創建橢圓(使用CGPath函數的UIBezierPath一起)時,它將創建一個適合指定矩形的橢圓或橢圓。 這意味着橢圓形的中心與矩形的原點不同:

矩形中的橢圓形

動畫始終從3點開始,並逆時針旋轉,因為在默認坐標系中,這是從0到2π的圓的圓弧路徑:

默認坐標系中的角度

這意味着您正在為筆畫設置動畫的路徑如下所示:

在此處輸入圖片說明

解決問題的錯誤方法

查看路徑,您可以通過旋轉視圖來移動起點。 不建議這樣做,因為它有副作用。 如果有任何子層,這些子層也將被旋轉。 可以通過翻轉視圖(沿一個軸縮放為負數)或通過將筆划的起點從1動畫化為0而不是動畫的終點來改變筆划方向。

所有這些解決方案都可以使用,但是有副作用,並且不清楚哪種方法更可取。

更好的解決方案

我喜歡看這樣的問題:動畫代碼做正確的事,使筆觸從無到有動畫化,但是路徑的起點和筆觸方向並不是所期望的。 這意味着“問題”在於道路。

代替使用bezierPathWithOvalInRect:您可以使用圓弧創建自己的完整圓,該圓弧可以沿順時針方向或逆時針方向從任意起始角度到任意終止角度。 所需要做的就是計算圓心(以及起始和終止角度)。 查看默認坐標系,我們可以看到起始角度為3π/ 2或-π/ 2。 然后,終止角度為起始角度的正負2π(取決於它是順時針還是逆時針)。

創建這樣的弧可能看起來像這樣:

- (UIBezierPath *)circleBezierPath
{
    CGRect boundingRect = CGRectMake(100, 100, 100, 100);
    CGPoint center      = CGPointMake(CGRectGetMidX(boundingRect), CGRectGetMidY(boundingRect));
    CGFloat radius      = MIN(CGRectGetWidth(boundingRect), CGRectGetHeight(boundingRect));

    CGFloat twelveOClockAngle = -M_PI_2;
    BOOL clockwise = NO; // NO for counter clockwise

    CGFloat startAngle = twelveOClockAngle;
    CGFloat endAngle = startAngle + (2.0*M_PI * (clockwise ? 1.0 : -1.0));

    return [UIBezierPath bezierPathWithArcCenter:center
                                          radius:radius
                                      startAngle:startAngle
                                        endAngle:endAngle
                                       clockwise:clockwise];
}

暫無
暫無

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

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