图片碎片化mask动画

效果

源码

https://github.com/YouXianMing/Animations

//
//  TransformFadeViewController.m
//  Animations
//
//  Created by YouXianMing on 15/11/17.
//  Copyright © 2015年 YouXianMing. All rights reserved.
//

#import "TransformFadeViewController.h"
#import "TranformFadeView.h"
#import "GCD.h"

typedef enum : NSUInteger {

    TYPE_ONE,
    TYPE_TWO,

} EType;

@interface TransformFadeViewController ()

@property (nonatomic, strong) TranformFadeView *tranformFadeViewOne;
@property (nonatomic, strong) TranformFadeView *tranformFadeViewTwo;

@property (nonatomic, strong) GCDTimer *timer;
@property (nonatomic)         EType     type;

@property (nonatomic, strong) NSArray   *images;
@property (nonatomic)         NSInteger  count;

@end

@implementation TransformFadeViewController

- (void)viewDidLoad {

    [super viewDidLoad];
}

- (void)setup {

    [super setup];

    self.images = @[[UIImage imageNamed:@"1"],
                    [UIImage imageNamed:@"2"],
                    [UIImage imageNamed:@"3"],
                    [UIImage imageNamed:@"4"],
                    [UIImage imageNamed:@"5"]];

    // 图片1
    self.tranformFadeViewOne                 = [[TranformFadeView alloc] initWithFrame:self.view.bounds];
    self.tranformFadeViewOne.contentMode     = UIViewContentModeScaleAspectFill;
    self.tranformFadeViewOne.image           = [self currentImage];
    self.tranformFadeViewOne.verticalCount   = 2;
    self.tranformFadeViewOne.horizontalCount = 12;
    self.tranformFadeViewOne.center          = self.view.center;
    [self.tranformFadeViewOne buildMaskView];

    self.tranformFadeViewOne.fadeDuradtion        = 1.f;
    self.tranformFadeViewOne.animationGapDuration = 0.1f;

    [self.view addSubview:self.tranformFadeViewOne];

    // 图片2
    self.tranformFadeViewTwo                 = [[TranformFadeView alloc] initWithFrame:self.view.bounds];
    self.tranformFadeViewTwo.contentMode     = UIViewContentModeScaleAspectFill;
    self.tranformFadeViewTwo.verticalCount   = 2;
    self.tranformFadeViewTwo.horizontalCount = 12;
    self.tranformFadeViewTwo.center          = self.view.center;
    [self.tranformFadeViewTwo buildMaskView];

    self.tranformFadeViewTwo.fadeDuradtion        = 1.f;
    self.tranformFadeViewTwo.animationGapDuration = 0.1f;

    [self.view addSubview:self.tranformFadeViewTwo];
    [self.tranformFadeViewTwo fadeAnimated:YES];

    // timer
    self.timer = [[GCDTimer alloc] initInQueue:[GCDQueue mainQueue]];
    [self.timer event:^{

        if (self.type == TYPE_ONE) {

            self.type = TYPE_TWO;

            [self.view sendSubviewToBack:self.tranformFadeViewTwo];
            self.tranformFadeViewTwo.image = [self currentImage];
            [self.tranformFadeViewTwo showAnimated:NO];
            [self.tranformFadeViewOne fadeAnimated:YES];

        } else {

            self.type = TYPE_ONE;

            [self.view sendSubviewToBack:self.tranformFadeViewOne];
            self.tranformFadeViewOne.image = [self currentImage];
            [self.tranformFadeViewOne showAnimated:NO];
            [self.tranformFadeViewTwo fadeAnimated:YES];
        }

    } timeIntervalWithSecs:6];
    [self.timer start];
}

- (UIImage *)currentImage {

    self.count = ++self.count % self.images.count;

    return self.images[self.count];
}

@end
//
//  TranformFadeView.h
//  TransformationFadeView
//
//  Created by XianMingYou on 15/4/16.
//  Copyright (c) 2015年 XianMingYou. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface TranformFadeView : UIView

/**
 *  Image显示方式
 */
@property (nonatomic) UIViewContentMode  contentMode;

/**
 *  要显示的相片
 */
@property (nonatomic, strong) UIImage   *image;

/**
 *  垂直方向方块的个数
 */
@property (nonatomic) NSInteger          verticalCount;

/**
 *  水平的个数
 */
@property (nonatomic) NSInteger          horizontalCount;

/**
 *  开始构造出作为mask用的view
 */
- (void)buildMaskView;

/**
 *  渐变动画的时间
 */
@property (nonatomic) NSTimeInterval     fadeDuradtion;

/**
 *  两个动画之间的时间间隔
 */
@property (nonatomic) NSTimeInterval     animationGapDuration;

/**
 *  开始隐藏动画
 *
 *  @param animated 是否执行动画
 */
- (void)fadeAnimated:(BOOL)animated;

/**
 *  开始显示动画
 *
 *  @param animated 时候执行动画
 */
- (void)showAnimated:(BOOL)animated;

@end
//
//  TranformFadeView.m
//  TransformationFadeView
//
//  Created by XianMingYou on 15/4/16.
//  Copyright (c) 2015年 XianMingYou. All rights reserved.
//

#import "TranformFadeView.h"

#define  STATR_TAG  0x19871220

@interface TranformFadeView ()

/**
 *  图片
 */
@property (nonatomic, strong) UIImageView    *imageView;

/**
 *  所有的maskView
 */
@property (nonatomic, strong) UIView         *allMaskView;

/**
 *  maskView的个数
 */
@property (nonatomic)         NSInteger       maskViewCount;

/**
 *  存储maskView的编号
 */
@property (nonatomic, strong) NSMutableArray *countArray;

@end

@implementation TranformFadeView

/**
 *  初始化并添加图片
 *
 *  @param frame frame值
 */
- (void)initImageViewWithFrame:(CGRect)frame {

    self.imageView                     = [[UIImageView alloc] initWithFrame:frame];
    self.imageView.layer.masksToBounds = YES;
    [self addSubview:self.imageView];
}

- (instancetype)initWithFrame:(CGRect)frame {

    if (self = [super initWithFrame:frame]) {

        [self initImageViewWithFrame:self.bounds];
    }

    return self;
}

- (void)buildMaskView {

    // 如果没有,就返回空
    if (self.horizontalCount < 1 || self.verticalCount < 1) {

        return;
    }

    // 承载所有的maskView
    self.allMaskView = [[UIView alloc] initWithFrame:self.bounds];
    self.maskView    = self.allMaskView;

    // 计算出每个view的尺寸
    CGFloat height         = self.frame.size.height;
    CGFloat width          = self.frame.size.width;
    CGFloat maskViewHeight = self.verticalCount   <= 1 ? height : (height / self.verticalCount);
    CGFloat maskViewWidth  = self.horizontalCount <= 1 ? width  : (width  / self.horizontalCount);

    // 用以计数
    int count = 0;

    // 先水平循环,再垂直循环
    for (int horizontal = 0; horizontal < self.horizontalCount; horizontal++) {

        for (int vertical = 0; vertical < self.verticalCount; vertical++) {

            CGRect frame = CGRectMake(maskViewWidth  * horizontal,
                                      maskViewHeight * vertical,
                                      maskViewWidth,
                                      maskViewHeight);

            UIView *maskView         = [[UIView alloc] initWithFrame:frame];
            maskView.frame           = frame;
            maskView.tag             = STATR_TAG + count;
            maskView.backgroundColor = [UIColor blackColor];

            [self.allMaskView addSubview:maskView];

            count++;
        }
    }

    self.maskViewCount = count;

    // 存储
    self.countArray  = [NSMutableArray array];
    for (int i = 0; i < self.maskViewCount; i++) {

        [self.countArray addObject:@(i)];
    }
}

/**
 *  策略模式一
 *
 *  @param inputNumber 输入
 *
 *  @return 输出
 */
- (NSInteger)strategyNormal:(NSInteger)inputNumber {

    NSNumber *number = self.countArray[inputNumber];
    return number.integerValue;
}

- (void)fadeAnimated:(BOOL)animated {

    if (animated == YES) {

        for (int i = 0; i < self.maskViewCount; i++) {

            UIView *tmpView = [self maskViewWithTag:[self strategyNormal:i]];
            [UIView animateWithDuration:(self.fadeDuradtion <= 0.f ? 1.f : self.fadeDuradtion)
                                  delay:i * (self.animationGapDuration <= 0.f ? 0.2f : self.animationGapDuration)
                                options:UIViewAnimationOptionCurveLinear
                             animations:^{

                                 tmpView.alpha = 0.f;

                             } completion:^(BOOL finished) {

                             }];
        }

    } else {

        for (int i = 0; i < self.maskViewCount; i++) {

            UIView *tmpView = [self maskViewWithTag:i];
            tmpView.alpha   = 0.f;
        }
    }
}

- (void)showAnimated:(BOOL)animated {

    if (animated == YES) {

        for (int i = 0; i < self.maskViewCount; i++) {

            UIView *tmpView = [self maskViewWithTag:[self strategyNormal:i]];

            [UIView animateWithDuration:(self.fadeDuradtion <= 0.f ? 1.f : self.fadeDuradtion)
                                  delay:i * (self.animationGapDuration <= 0.f ? 0.2f : self.animationGapDuration)
                                options:UIViewAnimationOptionCurveLinear
                             animations:^{

                                 tmpView.alpha = 1.f;
                             } completion:^(BOOL finished) {

                             }];
        }

    } else {

        for (int i = 0; i < self.maskViewCount; i++) {

            UIView *tmpView = [self maskViewWithTag:i];
            tmpView.alpha   = 1.f;
        }
    }
}

/**
 *  根据tag值获取maskView
 *
 *  @param tag maskView的tag值
 *
 *  @return tag值对应的maskView
 */
- (UIView *)maskViewWithTag:(NSInteger)tag {

    return [self.maskView viewWithTag:tag + STATR_TAG];
}

#pragma mark - setter & getter.
@synthesize contentMode = _contentMode;
- (void)setContentMode:(UIViewContentMode)contentMode {

    _contentMode               = contentMode;
    self.imageView.contentMode = contentMode;
}

- (UIViewContentMode)contentMode {

    return _contentMode;
}

@synthesize image = _image;
- (void)setImage:(UIImage *)image {

    _image               = image;
    self.imageView.image = image;
}

- (UIImage *)image {

    return _image;
}

@end

细节

使用的时候动态切换图片就可以了,实际上只需要创建出2个view.

时间: 2024-08-05 13:40:00

图片碎片化mask动画的相关文章

使用 Core Animation 实现图片的碎片化----

用 Core Animation 实现图片的碎片化 参考书籍: 效果如下: 原理其实非常简单哦:). 1. 创建一个CALayer,使用其 contents 属性来装载一张图片(获取图片的CGImage) 2. 根据frame值裁剪图片,然后将裁剪的图片赋给你创建的更小的CALayer 3. 实现这些更小的CALayer的动画 4. 剩下的该干嘛干嘛,比如使用 Core Image 滤镜什么的,就靠你创造了:) 核心代码: 源码(书中提供,并非本人所写): /*** * Excerpted fr

用 Core Animation 实现图片的碎片化

用 Core Animation 实现图片的碎片化 参考书籍: 效果如下: 原理其实非常简单哦:). 1. 创建一个CALayer,使用其 contents 属性来装载一张图片(获取图片的CGImage) 2. 根据frame值裁剪图片,然后将裁剪的图片赋给你创建的更小的CALayer 3. 实现这些更小的CALayer的动画 4. 剩下的该干嘛干嘛,比如使用 Core Image 滤镜什么的,就靠你创造了:) 核心代码: 源码(书中提供,并非本人所写): /*** * Excerpted fr

Android笔记:多分辨率适配及碎片化问题解决方案总结

一.适配多分辨率 1.官网介绍: http://developer.android.com/guide/practices/screens_support.html#qualifiers Screen characteristic Qualifier Description Size small Resources for small size screens. normal Resources for normal size screens. (This is the baseline siz

如何适应android碎片化的屏幕

在碎片化的Android设备中,设备的屏幕大小和密度也有很多类型,所以android帮我们定义了 四种大小类型:small,normal,large,xlarge 四种屏幕密度:ldpi(120dpi),mdpi(160dpi),hdpi(240dpi),xhdpi(320dpi) (屏幕密度可以理解成单位面积的区域上有多少像素点,像素点越多,屏幕密度越大,显示得越清晰) 我们一般会用dp来定义长度,用sp来定义文字大小. 为什么要用dp来定义长度呢?原因很简单,当不使用dp定义长度的时候,ui

碎片化阅读神器-MarginNote电子阅读利器

在这个信息碎片化时代,我们的初衷是想利用更多的碎片时间来吸收更多的信息资源,也在不断的尝试如何抗衡这个输入输出的平衡. https://www.macdown.com MarginNote,它是一款强大的学习者阅读工具.在一个学习应用程序里,你可以突出显示PDF和EPUB,记下,创建思维导图,审查闪存卡,并节省您在不同的应用程序之间无休止地切换. MarginNote作为阅读器使用,在MarginNote中,我可以: 对书籍按照类别做分类阅读书籍并做文字.语音笔记将知识点关联成为思维导图有疑问及

学技术无法碎片化

近期有一种声音,就是"学习要碎片化",主要考虑是现在人们的工作和生活节奏加快,很难有比较长的时间段来专门进行学习.为此有人高呼,将来图书会碎片化,视频课程也会碎片化,认为这样就可以充分利用吃饭前的几分钟,睡觉前的十几分钟,甚至上厕所的几分钟等一切可利用的时间来学习,并以期最终通过日积月累的方式达到全面学习的目的. 看似合情合理,也很符合时代特点,但笔者认为对于技术的学习是不能这样做.娱乐可以碎片化,休息可以碎片化,资讯获取也可碎片化,因为这些方面彼此没有太多关联.但学技术不可能碎片化,

源中瑞智慧城市工程建设,智慧城市碎片化管理系统开发

源中瑞智慧城市工程建设,智慧城市碎片化管理系统开发(ruiec_wangxuyan) 推进新型智慧城市建设是以习同志为核心的党中央在新时期为强化城市科学发展而做出的战略性决策,是破解城市发展难题的新途径,是以大数据为基础的城市治理新举措,是以信息流驱动的城市综合发展新模式. 当前智慧城市的风头正劲,据统计,全国有597个城市提出了与智慧城市相关的试点或规划.碎片化现象本来是智慧城市建设的必经之路,因为不同的智慧项目都是由不同的政府部门和企业去实现的.虽然智慧医疗.智慧交通.智慧家居是当前的主流智

为什么越学反而越蠢?碎片化学习是个骗局

来源于:https://news.cnblogs.com/n/558233/ 编者按:本文来自微信公众号"古典古少侠"(ID:gudian515),作者古典 先给你讲个故事,看你有没有中招: 有一天,你的朋友给你"知识装逼"了一个术语,牛!怎么知道的?--他推给你一个公众号. 你开始关注,觉得哇!大神!牛逼!长见识! 每天刷每天刷每天刷.很多问题也有了解决方法--按照这个进度,过 3 年就能理解宇宙终极奥义了. 慢慢你有了十多个类似的号,承包了你从专业.生活.工作.

程序员MM的自白:磨人小妖精之安卓碎片化

文/腾讯优测 章婉霞 除了crash问题,Android平台的碎片化越来越受到移动开发的关注,且不谈支持Android系统的移动设备早已过万款,屏幕.品牌以及传感器等方面的碎片化问题也困扰着开发者. 初级Android的开发人员经常关心的问题就是开发的应用能不能在需求的设备上正常运行.为什么我没有说所有设备呢?长期盘踞各Android设备市场份额或市场关注度榜单前十位,被大家熟知的品牌,它们ROM的个性化都足以让人眼花缭乱了,更何况在如今"乱世"里那些七零八落的机型了.想要做更全面的自