CGAffineTransform与CABasicAnimation

来源:互联网 发布:百度云签到源码 编辑:程序博客网 时间:2024/06/08 16:38

- (id)translateAnimation:(NSDictionary *)translateInfo {

    CGFloat precent = translateInfo[@"percent"] ==nil ? 1 : [translateInfo[@"percent"]floatValue];

    NSString *beginPointString = translateInfo[@"beginPoint"];

    CGPoint begin = beginPointString == nil ? lastPoint : [[NSValuevalueWithCGPoint:CGPointFromString(beginPointString)]CGPointValue];

    NSString *endPointString = translateInfo[@"endPoint"];

    CGPoint endPoint = [[NSValuevalueWithCGPoint:CGPointFromString(endPointString)]CGPointValue];

    

    //endPoint = beginPointString == nil ? endPoint : CGPointMake(begin.x + precent * (endPoint.x - begin.x), begin.y + precent * (endPoint.y - begin.y));

    

    float duration = [translateInfo[@"duration"]floatValue];

    NSString *curve = translateInfo[@"curve"];

    BOOL animated = [translateInfo[@"animated"]boolValue];

    

    CABasicAnimation *animationX = [CABasicAnimationanimationWithKeyPath:@"transform.translation.x"];

    animationX.autoreverses = NO;

    animationX.removedOnCompletion = NO;

    animationX.repeatCount = 0;

    animationX.fromValue@(begin.x);

    animationX.toValue = @(endPoint.x);

    

    CABasicAnimation *animationY = [CABasicAnimationanimationWithKeyPath:@"transform.translation.y"];

    animationY.autoreverses = NO;

    animationY.removedOnCompletion = NO;

    animationY.repeatCount = 0;

    animationY.fromValue = @(begin.y);

    animationY.toValue = @(endPoint.y);

    

    CAAnimationGroup *animationGroup = [CAAnimationGroupanimation];

    animationGroup.removedOnCompletion = NO;

    animationGroup.delegate = self;

    animationGroup.duration = duration;

    animationGroup.timingFunction = [MRPageAttachmentcurve:curve];

    animationGroup.repeatCount = 0;

    animationGroup.fillMode =kCAFillModeForwards;

    animationGroup.animations = @[ animationX, animationY ];

    

    if (translateInfo[@"percent"] !=nil) {

        // 根据位移比例来计算transform

        CGAffineTransform newTransform1 =CGAffineTransformIdentity;

        newTransform1 = CGAffineTransformMakeTranslation((endPoint.x - begin.x) * precent + begin.x - (self.pageAttachment.frame.origin.x + self.pageAttachment.frame.size.width/2), (endPoint.y - begin.y) * precent + begin.y - (self.pageAttachment.frame.origin.y +self.pageAttachment.frame.size.height/2));

        self.transform = newTransform1;

        lastTransform = newTransform1;

        return nil;

    } else {

        lastPoint = endPoint;

        CGAffineTransform newTransform1 =CGAffineTransformIdentity;

        newTransform1 = CGAffineTransformMakeTranslation(endPoint.x - begin.x, endPoint.y - begin.y);


        newTransform = CGAffineTransformConcat(newTransform, newTransform1);

        if (!animated) {

            self.transform =newTransform;

            return nil;

        }


        return animationGroup;

    }

}


- (id)scaleAnimation:(NSDictionary *)scaleInfo {

    CGFloat precent = scaleInfo[@"percent"] ==nil ? 1 : [scaleInfo[@"percent"]floatValue];

    NSString *beginScaleString = scaleInfo[@"beginScale"];

    CGPoint beginScale = beginScaleString ==nil ? lastScale : [[NSValuevalueWithCGPoint:CGPointFromString(beginScaleString)]CGPointValue];

    NSString *endScaleString = scaleInfo[@"endScale"];

    CGPoint endScale = [[NSValuevalueWithCGPoint:CGPointFromString(endScaleString)]CGPointValue];

    endScale = beginScaleString == nil ? endScale :CGPointMake(beginScale.x + precent * (endScale.x - beginScale.x), beginScale.y + precent * (endScale.y - beginScale.y));

    float duration = [scaleInfo[@"duration"]floatValue];

    NSString *curve = scaleInfo[@"curve"];

    BOOL animated = [scaleInfo[@"animated"]boolValue];

   

    if (newTransform.b !=0 || newTransform.c !=0) {

        if (endScale.x != endScale.y) {

            return nil;

        }

    }


    CABasicAnimation *animationX = [CABasicAnimationanimationWithKeyPath:@"transform.scale.x"];

    animationX.timingFunction = [MRPageAttachmentcurve:curve];

    animationX.fromValue = [NSNumbernumberWithFloat:beginScale.x];

    animationX.toValue = [NSNumbernumberWithFloat:endScale.x];

    animationX.autoreverses = NO;

    animationX.cumulative = YES;

 

    CABasicAnimation *animationY = [CABasicAnimationanimationWithKeyPath:@"transform.scale.y"];

    animationY.timingFunction = [MRPageAttachmentcurve:curve];

    animationY.fromValue = [NSNumbernumberWithFloat:beginScale.y];

    animationY.toValue = [NSNumbernumberWithFloat:endScale.y];

    animationY.autoreverses = NO;

    animationY.cumulative = YES;


    CAAnimationGroup *animationGroup = [CAAnimationGroupanimation];

    animationGroup.removedOnCompletion = NO;

    animationGroup.delegate = self;

    animationGroup.duration = duration;

    animationGroup.timingFunction = [MRPageAttachmentcurve:curve];

    animationGroup.repeatCount = 0;

    animationGroup.fillMode =kCAFillModeForwards;

    animationGroup.animations = @[ animationX, animationY ];

    

    CGAffineTransform newTransform1 =CGAffineTransformIdentity;

    newTransform1 = CGAffineTransformMakeScale(endScale.x, endScale.y);

    

    CGAffineTransform newTransform2 =CGAffineTransformIdentity;

    newTransform2 = CGAffineTransformMakeScale(1 /lastScale.x, 1 /lastScale.y);

    

    // 恢复前一次放大状态

    if (newTransform.ty !=0 || newTransform.tx !=0) {

        CGFloat tx = newTransform.tx;

        CGFloat ty = newTransform.ty;

        newTransform = CGAffineTransformMake(newTransform.a,newTransform.b,newTransform.c,newTransform.d,0 * fabs(tx) ,0 * fabs(ty));

        newTransform = CGAffineTransformConcat(newTransform, newTransform2);

        newTransform = CGAffineTransformMake(newTransform.a,newTransform.b,newTransform.c,newTransform.d, tx, ty);

    } else {

        newTransform = CGAffineTransformConcat(newTransform, newTransform2);

    }


    if (newTransform.ty !=0 || newTransform.tx !=0) {

        CGFloat tx = newTransform.tx;

        CGFloat ty = newTransform.ty;

        newTransform = CGAffineTransformMake(newTransform.a,newTransform.b,newTransform.c,newTransform.d,0 * fabs(tx) ,0 * fabs(ty));

        newTransform = CGAffineTransformConcat(newTransform, newTransform1);

        newTransform = CGAffineTransformMake(newTransform.a,newTransform.b,newTransform.c,newTransform.d, tx, ty);

    } else {

        newTransform = CGAffineTransformConcat(newTransform, newTransform1);

    }

    

    lastScale = endScale;

    lastPoint = CGPointMake(newTransform.tx,newTransform.ty);

    if (!animated) {

        self.transform =newTransform;

        return nil;

    }


    return animationGroup;

}


- (id)rotateAnimation:(NSDictionary *)rotateInfo {

    CGFloat precent = rotateInfo[@"percent"] ==nil ? 1 : [rotateInfo[@"percent"]floatValue];

    float beginAngle = rotateInfo[@"beginAngle"] ==nil ? lastAngle : [rotateInfo[@"beginAngle"]floatValue];

    float endAngle = [rotateInfo[@"endAngle"]floatValue];

    endAngle = rotateInfo[@"beginAngle"] ==nil ? endAngle : beginAngle + precent * (endAngle - beginAngle);

    float duration = [rotateInfo[@"duration"]floatValue];

    NSString *curve = rotateInfo[@"curve"];

    BOOL animated = [rotateInfo[@"animated"]boolValue];

    

    

    CABasicAnimation* animation;

    animation = [CABasicAnimationanimationWithKeyPath:@"transform.rotation.z"];

    animation.timingFunction = [MRPageAttachmentcurve:curve];

    animation.fromValue@(beginAngle / 180 * M_PI);

    animation.toValue = @(endAngle /180 * M_PI);

    animation.duration = duration;

    animation.autoreverses = NO;

    animation.delegate = self;

    animation.removedOnCompletion =NO;

    animation.fillMode = kCAFillModeForwards;

   

    if (rotateInfo[@"percent"] !=nil) {

        // 换算出相对于初始0角度时的旋转的角度

        CGFloat angleOffset = (precent - (0 - beginAngle) / (endAngle - beginAngle)) * (endAngle - beginAngle);

        CGFloat rotateOffset = angleOffset *M_PI / 180;

        CGFloat newOffset = rotateOffset - self.transformBeginFloat;

        

        lastTransform = CGAffineTransformRotate(self.transform, newOffset);

        self.transform =lastTransform;

        self.transformBeginFloat = rotateOffset;

        self.transformFloat = rotateOffset;

        return nil;

    } else {

        

        CGAffineTransform newTransform1 =CGAffineTransformIdentity;

        newTransform1 = CGAffineTransformMakeRotation((endAngle - beginAngle) /180 * M_PI);

        

        if (newTransform.ty !=0 || newTransform.tx !=0) {

            CGFloat tx = newTransform.tx;

            CGFloat ty = newTransform.ty;

            newTransform =CGAffineTransformMake(newTransform.a,newTransform.b,newTransform.c,newTransform.d,0 * fabs(tx) ,0 * fabs(ty));

            newTransform = CGAffineTransformConcat(newTransform, newTransform1);

            newTransform =CGAffineTransformMake(newTransform.a,newTransform.b,newTransform.c,newTransform.d, tx, ty);

        } else {

            newTransform = CGAffineTransformConcat(newTransform, newTransform1);

        }

        

        lastAngle = endAngle;

        lastPoint = CGPointMake(newTransform.tx,newTransform.ty);

        if (!animated) {

            self.transform =newTransform;

            return nil;

        }

        

        return animation;

    }

}


#pragma mark - CAAnimation委托

- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag {

    self.finishedAnimation =YES;

    if ([theAnimation isKindOfClass:[CATransitionclass]]) {

        if (flag) {

            [self.pageViewremovePageAttachmentView:self];

        }

    } else {

        if (!CGAffineTransformEqualToTransform(newTransform,CGAffineTransformIdentity)) {

            self.transform =newTransform;

            [self.layerremoveAllAnimations];

        }

        [self.delegatepageAttachmentView:selffinishedEventAnimation:animationKey];

    }

}

重点,在动画结束后,设置transform的时候,要去掉之前存在的animation,否则会影响到下次变幻时的显示状态

原创粉丝点击