iOS动画iOS开发动画

Mask动画深入学习

2016-07-20  本文已影响549人  怪小喵

请下载Demo

CALayer有一个属性叫做mask(对应UIView中maskView属性,下文说的maskView和mask是一个东西)mask图层定义了父图层的部分可见区域,功能类似于PS 中的图层蒙版。
mask图层的Color属性是无关紧要的,真正重要的是图层的轮廓。mask属性就像是一个饼干切割机,mask图层实心的部分会被保留下来,其他的则会被抛弃。(如图1.1)。

也可以这样理解,maskView将每个point的alpha赋值给View的重叠部分相对应的point,这样view的重叠每个point都有个alpha值了,view重叠部分就可能显示多种透明色

就如图1.1 而言,由于maskView颜色的alpha为1.0,那么与view重叠部分的alpha也应该为1.0(即重叠部分没变化),与mask颜色没关系。

图1.1

还是云里雾里的也没关系。您可以下载demo对照学习,注释非常详细,一看就懂。
demo中前三个例子可有帮助更深刻的体会mask属性的基本原理。


CALayer蒙板图层真正厉害的地方在于蒙板图不局限于静态图。任何有图层构成的都可以作为mask属性,这意味着你的蒙板可以通过代码甚至是动画实时生成。

如图1.2 的图片切换效果,其实是使用了的alpha通道变化的maskView完成图片的切换。


图1.2
    // 在底层的 图片 background(最后要显示出来)
    UIImageView *background = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
    background.image        = [UIImage imageNamed:@"base"];
    background.center       = self.view.center;
    [self.view addSubview:background];
    
    // 在上层的 图片 upGround
    UIImageView *upGround = [[UIImageView alloc] initWithFrame:background.frame];
    upGround.image        = [UIImage imageNamed:@"background"];
    [self.view addSubview:upGround];
    
    
    // maskView 由两个分别加载 “mask1” “mask” 的imageView拼接而成。加在 上层图片上 , 注意 两张透明度渐变的图片是重点。是它们使 上层图片upGround 显示 或者隐藏
    UIView *mask      = [[UIView alloc] initWithFrame:upGround.bounds];
    upGround.maskView = mask;
    
    UIImageView *picOne = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 400)];
    picOne.image        = [UIImage imageNamed:@"mask1"];
    [mask addSubview:picOne];
    
    UIImageView *picTwo = [[UIImageView alloc] initWithFrame:CGRectMake(100, -200, 100, 400)];
    picTwo.image        = [UIImage imageNamed:@"mask"];
    [mask addSubview:picTwo];
    
    
    // 两个imageView的动画 使maskView的alpha通道由 1 变成 0 ,导致 上层图片消失, 达到切换的效果
    [UIView animateWithDuration:2.f delay:2.f options:0 animations:^{
        picOne.y -= 400;
        picTwo.y += 400;
    } completion:^(BOOL finished) {
        
    }];

这个例子实现了 iPhone的滑动解锁效果

1.首先构建一个 颜色渐变的layer,可以使用CAGradientLayer这个类,你也可以像上一个例子一样使用图片,看起来像图1.3.1就行。
关于CAGradientLayer的属性详细解析可参考CAGradientLayer的一些属性解析

CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    [self.view.layer addSublayer:gradientLayer];
    gradientLayer.frame = CGRectMake(0, 200, self.view.width, 64);
    gradientLayer.colors = @[
                             (__bridge id)[UIColor blackColor].CGColor,
                             (__bridge id)[UIColor whiteColor].CGColor,
                             (__bridge id)[UIColor blackColor].CGColor,
                             ];
    gradientLayer.locations = @[@0.25,@0.5,@0.75];
    gradientLayer.startPoint = CGPointMake(0, 0.5);
    gradientLayer.endPoint = CGPointMake(1, 0.5);
图1.3.1

2.让这个图层动起来,加个动画。

  // CAGradientLayer可用来处理颜色渐变,它的渐变色也可以做隐式动画
   CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"locations"];
   basicAnimation.fromValue = @[@0, @0, @0.25];
   basicAnimation.toValue = @[@0.75, @1, @1];
   basicAnimation.duration = 2.5;
   basicAnimation.repeatCount = HUGE;
   [gradientLayer addAnimation:basicAnimation forKey:nil];
图1.3.2

3.让UILabel上的文字成为CAGradientLayer的遮罩,完成。

   // 设置 gradientLayer  的 mask 为 unLock   有透明度的地方 就露出来了
    UILabel *unlock = [[UILabel alloc] initWithFrame:gradientLayer.bounds];
    self.unlock = unlock;
    unlock.alpha = 0.5;
    unlock.text = @"滑动来解锁 >>";
    unlock.textAlignment = NSTextAlignmentCenter;
    unlock.font = [UIFont boldSystemFontOfSize:30];
    gradientLayer.mask = unlock.layer;
图1.3.3

直接上代码,在图片层上 加一层毛玻璃层,在毛玻璃层上加一层圆形的mask。

图1.4.1
    // 最底层的view  显示图片
    UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
    imageView.image = [UIImage imageNamed:@"Slice"];
    [self.view addSubview:imageView];
   
    
    
    // 创建mask
    // 贝塞尔曲线(创建一个圆)
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(0, 0)
                                                        radius:100
                                                    startAngle:DEGREES(0)
                                                      endAngle:DEGREES(360)
                                                     clockwise:YES];

    _maskLayer = [CAShapeLayer layer];
    _maskLayer.path     = path.CGPath;
    _maskLayer.position = CGPointMake(_showView.bounds.size.width/2.f,
                                      _showView.bounds.size.height/2.f);
    _maskLayer.fillColor = [UIColor whiteColor].CGColor;
    _maskLayer.position = self.view.center;
    
    
    
    // 创建覆盖在最底层imageView上的模糊图片, 添加mask   注意mask为一个圆形(模糊图片只会显示一个圆,其他地方会变成透明)
    UIView *blurView = [[UIView alloc] initWithFrame:self.view.bounds];
    blurView.backgroundColor = [UIColor blackColor];
    [self.view addSubview:blurView];
    blurView.layer.mask = _maskLayer;
    blurView.layer.contents = (__bridge id)([[UIImage imageNamed:@"Slice"] imgWithBlur].CGImage);
    
    
    
    /*
     透明的View,用于maskView中的ShapeLayer的参考View(用于拖拽)
     */
    _showView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
    _showView.backgroundColor = [UIColor clearColor];
    _showView.center = self.view.center;
    [self.view addSubview:_showView];
    
    UIPanGestureRecognizer *recognizer =
    [[UIPanGestureRecognizer alloc] initWithTarget:self
                                            action:@selector(handlePan:)];
    [_showView addGestureRecognizer:recognizer];
}

- (void)handlePan:(UIPanGestureRecognizer *)recognizer
{
    // 拖拽
    CGPoint translation = [recognizer translationInView:self.view];
    recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x,
                                         recognizer.view.center.y + translation.y);
    [recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
    
    // 关闭CoreAnimation实时动画绘制(核心)
    [CATransaction setDisableActions:YES];
    _maskLayer.position = recognizer.view.center;
}

如图1.5.1 效果 ,如果你理解了mask的原理,这个和上一个类似,
在图片层上 加一层毛玻璃层,在毛玻璃层上加一层透明度渐变的mask,OK。


图1.5.1


  UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
    imageView.image = [UIImage imageNamed:@"Slice"];
    [self.view addSubview:imageView];
    
    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    [self.view.layer addSublayer:gradientLayer];
    gradientLayer.frame = self.view.bounds;
    // 颜色的透明度   alpha   0.0  全透过  1.0 不透明
    gradientLayer.colors = @[
                             (__bridge id)[UIColor colorWithWhite:1 alpha:0.0].CGColor,
                             (__bridge id)[UIColor colorWithWhite:1 alpha:1.0].CGColor,
                             ];
    gradientLayer.locations = @[@0.35,@0.55];
    _gradientLayer = gradientLayer;
    
    UIView *blurView = [[UIView alloc] initWithFrame:self.view.bounds];
    blurView.backgroundColor = [UIColor blackColor];
    [self.view addSubview:blurView];
    blurView.layer.mask = gradientLayer;
    blurView.layer.contents = (__bridge id)([[UIImage imageNamed:@"Slice"] imgWithBlur].CGImage);

以上例子的代码可以在这下载
另外推荐一个mask实现的动画效果,mask的实现方式非常巧妙。
https://github.com/andreamazz/BubbleTransition

上一篇下一篇

猜你喜欢

热点阅读