歌颂祖国!用OC简单的写了一个小demo。
步骤一、创建图片切片存储对象
@interface** KDSClipImageModel : NSObject
//保存切图位置
@property (nonatomic,assign) CGRect rect;
//切片image
@property (nonatomic,strong) UIImage * image;
//缩放宽度
@property (nonatomic,assign) CGFloat scaleW;
//缩放高度
@property (nonatomic,assign**) CGFloat scaleH;
//imageView
@property (nonatomic,strong) UIImageView * imageView;
@end
步骤二、管理类
1、管理类
//定时器,用来发射粒子
static dispatch_source_t timer;
//因为管理类用的是类方法,所以这里用static修饰了一个布尔值,来保存切片小图是否可以消失
static bool isCanDismiss = true;
@interface KDSClipImageTool : NSObject
2、一张整图生成切图
//将一张图片切成N个小图,imgae:原图,row:行数,column:列数,rect是要展示的view的rect,
这样可以根据image和rect的大小进行缩放。
+ (NSMutableArray *)clipAllCellImagesWithImage:(UIImage *)image row:(NSInteger)row column:(NSInteger)column rect:(CGRect)rect
{
NSMutableArray * saveCellImagesArr = @[].mutableCopy;
CGFloat imageWidth = image.size.width;
CGFloat imageHeight = image.size.height;
//小图的宽度
CGFloat width = (imageWidth / column);
//小图的高度
CGFloat height = (imageHeight / row);
//缩放宽度
CGFloat rw = (rect.size.width / imageWidth);
//缩放高度
CGFloat rh = (rect.size.height / imageHeight);
for (int i = 0; i < column; i++) {
for (int j = 0; j < row; j++) {
CGRect imageRect = CGRectMake(width * i, height * j, width, height);
//切小图
UIImage * cellImage = [self clipImageWithAllImage:image rect:imageRect];
//保存数据
KDSClipImageModel * model = [[KDSClipImageModel alloc] init];
model.image = cellImage;
model.scaleW = rw;
model.scaleH = rh;
//这里计算小切图实际的位置坐标
CGRect imageRRect = CGRectMake(width * rw * i, height * rh * j, width * rw, height * rh);
model.imageView = [[UIImageView alloc] initWithFrame:imageRRect];
model.imageView.image = cellImage;
model.rect = imageRRect;
[saveCellImagesArr addObject:model];
}
}
return saveCellImagesArr;
}
//切小图逻辑
+ (UIImage *)clipImageWithAllImage:(UIImage *)image rect:(CGRect)rect
{
CGImageRef imageRef = CGImageCreateWithImageInRect(image.CGImage, rect);
UIImage * imageResult = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return imageResult;
}
3、展示切图组无序排列
//展示大图片前将小图先随机打乱顺序,然后进行重排复原,最后进行粒子消失动画
+ (void)showImageModels:(NSMutableArray <KDSClipImageModel *>*)clipImageModels pushView:(UIView *)pushView canDismiss:(void(^)(void))dismissBlock
{
isCanDismiss = true;
//随机排序
NSArray *tempClipImageModels = [clipImageModels sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
return (arc4random_uniform(2) == 0);
}];
NSInteger index = 0;
//重置乱序下的小图
for (KDSClipImageModel * clipImageModel **in** tempClipImageModels) {
KDSClipImageModel * imageModel = clipImageModels[index];
clipImageModel.imageView.frame = imageModel.rect;
index ++;
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//图片复原
for (KDSClipImageModel * clipImageModel in tempClipImageModels) {
[UIView animateWithDuration:0.3 animations:^{
clipImageModel.imageView.frame = clipImageModel.rect;
} completion:^(BOOL finished) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//这里只进行一次消失动画,所以用static修饰isCanDismiss 来执行dismiss
if (isCanDismiss == true) {
if (dismissBlock) {
dismissBlock();
}
isCanDismiss = false;
}
});
}];
}
});
}
4、粒子消失
//定时器下定时创建粒子发射器发射粒子,粒子的CGImage为小切图的image内容
+ (void)setupEmitterWithClipImageModels:(NSMutableArray <KDSClipImageModel *>*)clipImageModels pushView:(UIView *)pushView{
//随机创建10个粒子发射器
NSInteger radomNum = 10;
dispatch_queue_t queue = dispatch_get_main_queue();
//初始化定时器
timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 0.05 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
dispatch_source_set_event_handler(timer, ^{
if (clipImageModels.count <= 0) {
dispatch_suspend(timer);
} else {
//随机获取 KDSClipImageModel 进行粒子释放
for (int i = 0; i < radomNum; i++) {
NSInteger index = arc4random() % clipImageModels.count;
KDSClipImageModel * model = clipImageModels[index];
[self createCAEmitterCellWithImage:model pushView:pushView];
//移除 KDSClipImageModel
[clipImageModels removeObject:model];
}
}
});
dispatch_resume(timer);
}
//创建粒子发射器
+ (void)createCAEmitterCellWithImage:(KDSClipImageModel *)model pushView:(UIView *)pushView
{
CAEmitterLayer *emitter = [[CAEmitterLayer alloc]init];
emitter.preservesDepth = YES;
CAEmitterCell *cell = [[CAEmitterCell alloc]init];
//因为是粒子性,所以一般是设置具体参数值及设置参数的波动范围。
cell.velocity = 150;
cell.velocityRange = 100;
cell.scale = 1 * model.scaleW;
cell.scaleRange = 1 * model.scaleW;
cell.emissionLongitude = -M_PI_2;
cell.emissionRange = M_PI_2 / 4;
cell.lifetime = 3;
cell.lifetimeRange = .5;
cell.spin = M_PI_2;
cell.spinRange = M_PI_2 / 2;
cell.birthRate = 1;
emitter.emitterPosition = CGPointMake(model.rect.origin.x, model.rect.origin.y);
//这里设置粒子的内容,即小切图的内容
cell.contents = ( __bridge id _Nullable )(model.image.CGImage);
emitter.emitterCells = @[cell];
//移除所有相关数据
[pushView.layer addSublayer:emitter];
[model.imageView removeFromSuperview];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[emitter removeFromSuperlayer];
});
}
步骤三、展示控件类
#import "KDSClipImageView.h"
#import "KDSClipImageTool.h"
#import "KDSClipImageModel.h"
@interface KDSClipImageView()
@property (nonatomic,strong) NSMutableArray * saveClipImages;
@end
@implementation** KDSClipImageView
- (void)clipImagesCanDismiss:(void(^)(void))disMissBlock
{
if (!self.image) {
return;
}
//获取self的rect
[self layoutIfNeeded];
//获取小切图数组 这里是30 * 45个
self.saveClipImages = [KDSClipImageTool clipAllCellImagesWithImage:self.image row:30 column:45 rect:self.bounds];
for (KDSClipImageModel * imageModel in self.saveClipImages) {
[self addSubview:imageModel.imageView];
}
[self showCanDismiss:disMissBlock];
}
- (void)showCanDismiss:(void(^)(void))disMissBlock
{
@weakify(self);
进行展示后进行消失动画
[KDSClipImageTool showImageModels:self.saveClipImages pushView:self canDismiss:^{
@strongify(self);
if (disMissBlock) {
disMissBlock();
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
@strongify(self);
[self dismiss];
});
}];
}
- (void)dismiss
{
//消失动画
[KDSClipImageTool setupEmitterWithClipImageModels:self.saveClipImages pushView:self];
}
步骤四、初始化
//国旗背景图
UIImageView * gqImageView = [[UIImageView alloc] init];
gqImageView.contentMode = UIViewContentModeScaleAspectFit;
gqImageView.hidden = YES;
gqImageView.image = [UIImage imageNamed:@"gq"];
//抗美援朝英雄图
UIImage * image = [UIImage imageNamed:@"kmyc"];
KDSClipImageView * imageBaseView = [[KDSClipImageView alloc] init];
[imageBaseView addSubview:gqImageView];
[gqImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(imageBaseView);
}];
imageBaseView.image = image;
[self addSubview:imageBaseView];
CGFloat imageViewWidth = image.size.width < self.width ?: self.width;
[imageBaseView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self).offset(0);
make.width.mas_equalTo(imageViewWidth);
make.height.mas_equalTo((imageViewWidth) * (image.size.height image.size.width));
}];
//开始显示,显示动画完后即将消失时将国旗背景图显示
[imageBaseView clipImagesCanDismiss:^{
gqImageView.hidden = NO;
}];
代码拙劣,大神勿喷。