美文网首页
加入购物车动画

加入购物车动画

作者: 羊妞麻麻 | 来源:发表于2019-03-12 18:12 被阅读0次

需求:

20161205170511736.png

点击商品列表中正在售卖的商品,通过坐标转换和动画的方式,完成类似点赞动画、加入购物车、查看头像大图等效果。

思路及问题点:

1)点击cell中的的添加+或者减号-来完成加入购物车的动画事件,需要清楚用户点击的是哪一个cell上面的button,更新购物车数量等操作。

__weak typeof(self) this = self;
        cell.addGoodBlock = ^(ShopListGoodsCell *cell) {
            [this goodAddOrMinusAction:YES cell:cell];
            [cell updateCount];
        };
        cell.minusGoodBlock = ^(ShopListGoodsCell *cell) {
            [this goodAddOrMinusAction:NO cell:cell];
            [cell updateCount];
        };

2)坐标系的转换
将像素point由point所在视图转换到目标视图view中,返回在目标视图view中的像素值
这里我们要将一个位置坐标传出去,但是传什么位置呢?如果是Lable的位置简单的传出去,那么很明显会出现一个问题:不管你点击那个cell的按钮,动画都是从同一个起点出发的,而且绝对不会是任何正确的起点。因为每个cell中Label的位置都是一样的,而我们实际需要的是这个坐标相对于TableView的位置,也就是说它在父视图中的位置,所以这里要将该点坐标转换。
右下角有一组图片和按钮,表示购物车,在tableView中有我们之前传过来的坐标,而我们希望让动画发生在view层级上,所以这里需要两次坐标转换,把右下角的控件集合中的按钮坐标(购物车是个按钮)和tableView中的传过来的起点坐标都转换到self.view中,具体做法是:


if (cell) {
        CGRect startRect = [cell convertRect:cell.countLab.frame toView:self.navigationController.view];
        [self joinCartAnimationWithRect:startRect];
    } else {
        CGRect startRect = [self.goodDesView convertRect:self.countLab.frame toView:self.navigationController.view];
        [self joinCartAnimationWithRect:startRect];
    }
[self updateCount];

3)Bezier曲线的应用
因为我们想产生一种类抛物线的动画,所以这里我们需要二阶Bezier曲线即可,所以要提供三个控制点,起始点和终止点都已经有了,关键就是中间的控制点。在计图实验中生成Bezier时,我们用的一种思路是以直代曲,用大量短线段来表示一条曲线,每一个n阶Bezier曲线(n+1个点)在生成时,总能在n个线段中按照一个比例各找出一个点,而这n个点又能生成一个n-1阶Bezier,我们的Bezier曲线上的点就是当只有一条线段以后按照那个比例找出的那个点。


UIView的动画是作用在layer层级的,所以我们可以生成一个CALayer,在这个layer上添加上自己的图片,然后将动画应用到这个layer中即可。

#pragma mark -加入购物车动画
-(void) joinCartAnimationWithRect:(CGRect)rect
{
//加入购物车结束点
    CGFloat endPoint_x = 35;
    CGFloat endPoint_y = SCREEN_HEIGHT - 35;
//加入购物车开始点
    CGFloat startX = rect.origin.x;
    CGFloat startY = rect.origin.y;// 和头部差值
//绘制贝塞尔曲线
    UIBezierPath *path= [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(startX, startY)];
    
    //三点曲线 让动画下滑的路线
    [path addCurveToPoint:CGPointMake(endPoint_x, endPoint_y)
            controlPoint1:CGPointMake(startX, startY)
            controlPoint2:CGPointMake(startX - 180, startY - 200)];
    CALayer *dotLayer = [CALayer layer];
    dotLayer.backgroundColor = [UIColor colorWithRed:244.0/255.0 green:80.0/255.0 blue:100.0/255.0 alpha:1].CGColor;
    dotLayer.frame = CGRectMake(0, 0, 16, 16);
    dotLayer.cornerRadius = 8;
    [self.view.layer addSublayer:dotLayer];
    [self groupAnimation:path.CGPath layer:dotLayer];
}
#pragma mark - 组合动画
-(void)groupAnimation:(CGPathRef)path layer:(CALayer*)layer;
{
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    animation.path = path;
    animation.rotationMode = kCAAnimationRotateAuto;
    
    CABasicAnimation *alphaAnimation = [CABasicAnimation animationWithKeyPath:@"alpha"];
    alphaAnimation.duration = 0.2f;
    alphaAnimation.fromValue = [NSNumber numberWithFloat:1.0];
    alphaAnimation.toValue = [NSNumber numberWithFloat:0.1];
    alphaAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
    
    CAAnimationGroup *groups = [CAAnimationGroup animation];
    groups.animations = @[animation,alphaAnimation];
    groups.duration = 0.5f;
    groups.removedOnCompletion = NO;
    
    groups.fillMode = kCAFillModeForwards;
    groups.delegate = self;
    [groups setValue:@"groupsAnimation" forKey:@"animationName"];
    [layer addAnimation:groups forKey:nil];
    [self performSelector:@selector(removeFromLayer:) withObject:layer afterDelay:0.5f];
}

- (void)removeFromLayer:(CALayer *)layerAnimation{
    
    [layerAnimation removeFromSuperlayer];
}

#pragma mark - CAAnimationDelegate
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    //[self performSelector:@selector(removeFromLayer:) withObject:dotLayer afterDelay:0.8f];
    if ([[anim valueForKey:@"animationName"]isEqualToString:@"groupsAnimation"]) {
        
        CABasicAnimation *shakeAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
        shakeAnimation.duration = 0.25f;
        shakeAnimation.fromValue = [NSNumber numberWithFloat:0.9];
        shakeAnimation.toValue = [NSNumber numberWithFloat:1];
        shakeAnimation.autoreverses = YES;
        //这个是下方的自定义View上面放的btn
        [self.cardView.cartBtn.layer addAnimation:shakeAnimation forKey:nil];
        
    }
    
}

相关文章

网友评论

      本文标题:加入购物车动画

      本文链接:https://www.haomeiwen.com/subject/rvwnpqtx.html