Files
peko-ios/YuMi/Modules/YMRoom/View/AnimationView/XPRoomDatingAnimationView.m
2024-04-11 17:05:27 +08:00

372 lines
13 KiB
Objective-C

//
// YMRoomDatingAnimationView.m
// YUMI
//
// Created by YUMI on 2022/1/5.
//
#import "XPRoomDatingAnimationView.h"
///Third
#import <Masonry/Masonry.h>
#import <SVGA.h>
#import <SDWebImage/SDWebImage.h>
///Model
#import "YUMIMacroUitls.h"
#import "DJDKMIMOMColor.h"
#import "UIButton+EnlargeTouchArea.h"
///Model
#import "DatingInfoModel.h"
@interface XPRoomDatingAnimationView ()
///背景
@property (nonatomic,strong) UIView *backView;
///动画管理类
@property (strong, nonatomic) SVGAParser *parser;
///播放相亲结果的SVGA
@property (nonatomic, strong) SVGAImageView *datingSvgaImageView;
///倒计时的背景
@property (nonatomic,strong) UIView *cutTimeBackView;
///倒计时
@property (nonatomic,strong) UILabel *timeLabel;
///分割线
@property (nonatomic,strong) UIView *lineView;
///关闭的按钮
@property (nonatomic,strong) UIButton *closeButton;
///❤的动画
@property (nonatomic,strong) UIImageView *heartImageView;
///
@property (nonatomic,copy) void(^FinishBlock)(BOOL result);
/// 定时器
@property (nonatomic,strong) id timer;
@end
@implementation XPRoomDatingAnimationView
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self addSubview:self.backView];
[self addSubview:self.datingSvgaImageView];
[self addSubview:self.cutTimeBackView];
[self addSubview:self.heartImageView];
[self.cutTimeBackView addSubview:self.timeLabel];
[self.cutTimeBackView addSubview:self.lineView];
[self.cutTimeBackView addSubview:self.closeButton];
[self initContrations];
}
return self;
}
#pragma mark - Resonse
- (void)closetButtonAction:(UIButton *)sender {
if (self.FinishBlock) {
[NSObject cancelPreviousPerformRequestsWithTarget:self];
self.FinishBlock(YES);
}
}
#pragma mark - Pirvate Method
- (void)initContrations {
[self mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.mas_equalTo(KScreenWidth);
make.height.mas_equalTo(KScreenHeight);
}];
[self.backView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(self);
}];
[self.datingSvgaImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(self);
}];
[self.cutTimeBackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(70, 25));
make.trailing.mas_equalTo(self).offset(-12);
make.top.mas_equalTo(self).offset(41 + kSafeAreaTopHeight);
}];
[self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(self.cutTimeBackView).offset(13);
make.centerY.mas_equalTo(self.cutTimeBackView);
}];
[self.lineView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.mas_equalTo(self.cutTimeBackView);
make.size.mas_equalTo(CGSizeMake(0.5, 13));
}];
[self.closeButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(14, 14));
make.centerY.mas_equalTo(self.cutTimeBackView);
make.leading.mas_equalTo(self.lineView.mas_trailing).offset(8);
}];
}
- (void)stopAnimation {
if (self.FinishBlock) {
[NSObject cancelPreviousPerformRequestsWithTarget:self];
self.FinishBlock(YES);
}
}
- (UIImage *)setCornerWithRadius:(CGFloat)radius andSize:(CGSize)size image:(UIImage *)image {
//开启图形上下文
UIGraphicsBeginImageContext(size);
//绘制圆角矩形
CGRect rect = CGRectMake(0, 0, size.width, size.height);
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(radius, radius)];
//将Path添加到上下文中
CGContextAddPath(UIGraphicsGetCurrentContext(), path.CGPath);
//裁剪上下文
CGContextClip(UIGraphicsGetCurrentContext());
//将图片绘制到上下文中
[image drawInRect:rect];
//设置绘制模式
CGContextDrawPath(UIGraphicsGetCurrentContext(), kCGPathStroke);
//获取图片
UIImage *output = UIGraphicsGetImageFromCurrentImageContext();
//关闭上下文
UIGraphicsEndImageContext();
//返回裁剪好的图片
return output;
}
- (CAAnimationGroup *)createRoomDatingPickAnimatioOriginPoint:(CGPoint)orginPoint destinationPoint:(CGPoint)destinationPoint {
///刚出来的时候 进行慢慢放大的效果
CAKeyframeAnimation * scaleAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
scaleAnimation.duration = 0.5;
scaleAnimation.repeatCount = 1;
scaleAnimation.values = @[@(0),@(0.2),@(0.4), @(0.6), @(0.8), @(0.9), @(1)];
scaleAnimation.calculationMode = kCAAnimationCubic;
scaleAnimation.removedOnCompletion = NO;
scaleAnimation.fillMode = kCAFillModeForwards;
///
CAKeyframeAnimation * transformAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
transformAnimation.beginTime = 0.5;
transformAnimation.duration = 1;
transformAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];;
transformAnimation.values = @[[NSValue valueWithCGPoint:orginPoint],[NSValue valueWithCGPoint:destinationPoint]];
transformAnimation.repeatCount = 1;
transformAnimation.removedOnCompletion = NO;
transformAnimation.fillMode = kCAFillModeForwards;
CAKeyframeAnimation * desScaleformAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
desScaleformAnimation.beginTime = 1.5;
desScaleformAnimation.duration = 0.5;
desScaleformAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];;
desScaleformAnimation.values = @[@(1), @(1.2), @(1.4), @(1.6)];
desScaleformAnimation.repeatCount = 1;
desScaleformAnimation.removedOnCompletion = NO;
desScaleformAnimation.fillMode = kCAFillModeForwards;
CAKeyframeAnimation * opacityAnimation = [CAKeyframeAnimation animationWithKeyPath:@"opacity"];
opacityAnimation.beginTime = 1.5;
opacityAnimation.duration = 0.5;
opacityAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];;
opacityAnimation.values = @[@(1),@(0.8),@(0.6),@(0)];
opacityAnimation.repeatCount = 1;
opacityAnimation.removedOnCompletion = NO;
opacityAnimation.fillMode = kCAFillModeForwards;
CAAnimationGroup * group = [CAAnimationGroup animation];
group.animations = @[scaleAnimation, transformAnimation, desScaleformAnimation, opacityAnimation];
group.duration = 2;
group.removedOnCompletion = NO;
group.fillMode = kCAFillModeForwards;
return group;;
}
- (void)startBeginCutCountWithTotalTime:(int)time {
__block int totalTime = time;
dispatch_source_t times = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(0, 0));
_timer = times;
dispatch_source_set_timer(times, DISPATCH_TIME_NOW, 1* NSEC_PER_SEC, 0 * NSEC_PER_SEC);
dispatch_source_set_event_handler(times, ^{
dispatch_async(dispatch_get_main_queue(), ^{
if (totalTime <= 5 && totalTime >= 0) {
///开始显示倒计时
self.cutTimeBackView.hidden = NO;
self.timeLabel.text = [NSString stringWithFormat:@"%ds", totalTime];
}
if (totalTime <= 0) {
dispatch_source_cancel(times);
self.cutTimeBackView.hidden = YES;
}
totalTime--;
});
});
dispatch_resume(times);
}
- (void)startPickHeartPersonAnimationOriginPoint:(CGPoint)originPoint targetPoint:(CGPoint)targetPoint {
if (originPoint.x > 0 && targetPoint.x > 0) {
self.heartImageView.frame = CGRectMake(0, 0, 55, 55);
self.heartImageView.hidden = YES;
self.backView.hidden = YES;
self.heartImageView.hidden = NO;
self.heartImageView.center = originPoint;
CAAnimationGroup * group = [self createRoomDatingPickAnimatioOriginPoint:originPoint destinationPoint:targetPoint];
[self.heartImageView.layer addAnimation:group forKey:nil];
[self performSelector:@selector(aniationDidFinish:) withObject:self.heartImageView afterDelay:(2)];
}
}
- (void)aniationDidFinish:(UIImageView *)giftImageView{
[giftImageView.layer removeAllAnimations];
giftImageView.hidden = YES;
}
#pragma mark - Public Method
- (void)startAnimationWithModel:(DatingInfoModel *)model finishBlock:(void (^)(BOOL))finishBlock {
self.FinishBlock = finishBlock;
if (model.hasHeart) {
if (model.svgaUrl) {
[self startPalySVGAWithUrl:model];
} else {
///如果是心动选人的话 但是没有SVGA的话 直接结束
///播完之后直接结束这次
if (self.FinishBlock) {
self.FinishBlock(YES);
}
}
} else {
///不是心动选人的话 那就不用播两次 爱心的动画
[self startPickHeartPersonAnimationOriginPoint:model.originPoint targetPoint:model.targetPoint];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
///心动结束了 直接结束此次
if (self.FinishBlock) {
self.FinishBlock(YES);
}
});
}
}
///播放SVGA的时候 需要先播放选人的动画
- (void)startPalySVGAWithUrl:(DatingInfoModel *)model {
if (model.svgaUrl) {
self.backView.hidden = NO;
[[SDWebImageManager sharedManager] loadImageWithURL:[NSURL URLWithString:model.avatar] options:SDWebImageRetryFailed progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
if (image) {
image = [self setCornerWithRadius:200 andSize:CGSizeMake(400, 400) image:image];
[self.datingSvgaImageView setImage:image forKey:@"z_tx"];
}
}];
NSString * title = model.nickname ? model.nickname : @"";
if (title.length >= 5) {
title = [NSString stringWithFormat:@"%@…", [title substringToIndex:5]];
}
NSMutableAttributedString * rightAttribut = [[NSMutableAttributedString alloc] initWithString:title];
[rightAttribut addAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:28], NSForegroundColorAttributeName:[UIColor whiteColor]} range:NSMakeRange(0, title.length)];
[self.datingSvgaImageView setAttributedText:rightAttribut forKey:@"z_yhname"];
[[SDWebImageManager sharedManager] loadImageWithURL:[NSURL URLWithString:model.targetAvatar] options:SDWebImageRetryFailed progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
if (image) {
image = [self setCornerWithRadius:200 andSize:CGSizeMake(400, 400) image:image];
[self.datingSvgaImageView setImage:image forKey:@"y_tx"];
}
}];
NSString * leftTitle = model.targetNickname ? model.targetNickname : @"";
if (leftTitle.length >= 5) {
leftTitle = [NSString stringWithFormat:@"%@…", [leftTitle substringToIndex:5]];
}
NSMutableAttributedString * leftAttribut = [[NSMutableAttributedString alloc] initWithString:leftTitle];
[leftAttribut addAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:28], NSForegroundColorAttributeName:[UIColor whiteColor]} range:NSMakeRange(0, leftTitle.length)];
[self.datingSvgaImageView setAttributedText:leftAttribut forKey:@"y_yhname"];
@kWeakify(self);
NSString *url = [model.svgaUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
[self.parser parseWithURL:[NSURL URLWithString:url] completionBlock:^(SVGAVideoEntity * _Nonnull videoItem) {
@kStrongify(self);
self.datingSvgaImageView.hidden = NO;
self.datingSvgaImageView.videoItem = videoItem;
self.datingSvgaImageView.loops = 1;
self.datingSvgaImageView.alpha = 1;
self.datingSvgaImageView.clearsAfterStop = YES;
[ self.datingSvgaImageView startAnimation];
[self startBeginCutCountWithTotalTime:model.svgaSecond];
} failureBlock:^(NSError * _Nonnull error) {
}];
[self performSelector:@selector(stopAnimation) withObject:nil afterDelay:model.svgaSecond];
}
}
- (UIImageView *)heartImageView {
if (!_heartImageView) {
_heartImageView = [[UIImageView alloc] init];
_heartImageView.image = [UIImage imageNamed:@"room_mode_dating_pick_heart"];
_heartImageView.hidden = YES;
}
return _heartImageView;
}
- (UIView *)backView {
if (!_backView) {
_backView = [[UIView alloc] init];
_backView.backgroundColor = UIColorRGBAlpha(0x000000, 0.3);
_backView.hidden = YES;
}
return _backView;
}
- (UILabel *)timeLabel {
if (!_timeLabel) {
_timeLabel = [[UILabel alloc] init];
_timeLabel.text = @"5S";
_timeLabel.font = [UIFont systemFontOfSize:15];
_timeLabel.textColor = UIColorFromRGB(0xFFFEFE);
}
return _timeLabel;
}
- (UIView *)cutTimeBackView {
if (!_cutTimeBackView) {
_cutTimeBackView = [[UIView alloc] init];
_cutTimeBackView.backgroundColor = UIColorRGBAlpha(0x000000, 0.3);
_cutTimeBackView.layer.masksToBounds = YES;
_cutTimeBackView.layer.cornerRadius = 25/2;
_cutTimeBackView.hidden = YES;
}
return _cutTimeBackView;
}
- (UIButton *)closeButton {
if (!_closeButton) {
_closeButton = [UIButton buttonWithType: UIButtonTypeCustom];
[_closeButton setImage:[UIImage imageNamed:@"common_close_white"] forState:UIControlStateNormal];
[_closeButton addTarget:self action:@selector(closetButtonAction:) forControlEvents:UIControlEventTouchUpInside];
[_closeButton setEnlargeEdgeWithTop:10 right:10 bottom:10 left:10];
}
return _closeButton;
}
- (UIView *)lineView {
if (!_lineView) {
_lineView = [[UIView alloc] init];
_lineView.backgroundColor = UIColor.whiteColor;
}
return _lineView;
}
- (SVGAParser *)parser {
if (!_parser) {
_parser = [[SVGAParser alloc]init];
}
return _parser;
}
- (SVGAImageView *)datingSvgaImageView {
if (!_datingSvgaImageView) {
_datingSvgaImageView = [[SVGAImageView alloc]init];
_datingSvgaImageView.backgroundColor = [UIColor clearColor];
_datingSvgaImageView.frame = self.bounds;
_datingSvgaImageView.userInteractionEnabled = YES;
}
return _datingSvgaImageView;
}
@end