BUDAnimationTool.m 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. //
  2. // BUDAnimationTool.m
  3. // BUDemo
  4. //
  5. // Created by wangyanlin on 2020/6/18.
  6. // Copyright © 2020 bytedance. All rights reserved.
  7. //
  8. #import "BUDAnimationTool.h"
  9. @interface BUDAnimationTool()<CAAnimationDelegate>
  10. @property (nonatomic, weak) BUSplashAdView *splashView;
  11. @property (nonatomic, weak) BUSplashZoomOutView *zoomOutView;
  12. @property (nonatomic, assign) CGRect resultFrame;
  13. @property (nonatomic, assign) BOOL isAnimationStart;
  14. @end
  15. @implementation BUDAnimationTool
  16. + (instancetype)sharedInstance {
  17. static BUDAnimationTool *toolManager = nil;
  18. static dispatch_once_t onceToken;
  19. dispatch_once(&onceToken, ^{
  20. toolManager = [[BUDAnimationTool alloc] init];
  21. });
  22. return toolManager;
  23. }
  24. - (void)transitionFromView:(BUSplashAdView *)fromView toView:(BUSplashZoomOutView *)toView {
  25. if (self.isAnimationStart) {
  26. return;
  27. }else{
  28. self.isAnimationStart = YES;
  29. }
  30. self.splashView = fromView;
  31. self.zoomOutView = toView;
  32. CGSize size = self.zoomOutView.showSize;
  33. CGFloat screenW = [UIScreen mainScreen].bounds.size.width;
  34. CGFloat screenH = [UIScreen mainScreen].bounds.size.height;
  35. self.resultFrame = CGRectMake(screenW - size.width - 16, screenH - size.height - 100,size.width, size.height);
  36. CGRect tempFrame = CGRectMake(CGRectGetMidX(self.resultFrame) - size.width * 0.25, CGRectGetMidY(self.resultFrame) - size.height * 0.25, size.width * 0.5, size.height * 0.5);
  37. self.zoomOutView.frame = tempFrame;
  38. [self transitionFromFrame:fromView.frame toFrame:tempFrame animationView:fromView];
  39. }
  40. - (void)transitionFromFrame:(CGRect)fromFrame toFrame:(CGRect)toFrame animationView:(UIView *)animationView {
  41. CGFloat frameRadius = sqrtf(pow(fromFrame.size.width, 2) + pow(fromFrame.size.height, 2));
  42. UIBezierPath *startCircle = [UIBezierPath bezierPathWithArcCenter:CGPointMake(fromFrame.origin.x + fromFrame.size.width * 0.5, fromFrame.origin.y + fromFrame.size.height * 0.5) radius:frameRadius startAngle:0 endAngle:M_PI * 2 clockwise:YES];
  43. CGFloat radius = MIN(toFrame.size.width, toFrame.size.height) * 0.5;
  44. UIBezierPath *endCircle = [UIBezierPath bezierPathWithArcCenter:CGPointMake(toFrame.origin.x + toFrame.size.width * 0.5, toFrame.origin.y + toFrame.size.height * 0.5) radius:radius startAngle:0 endAngle:M_PI * 2 clockwise:YES];
  45. CAShapeLayer *maskLayer = [CAShapeLayer layer];
  46. maskLayer.path = endCircle.CGPath;
  47. animationView.layer.mask = maskLayer;
  48. CABasicAnimation * maskLayerAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
  49. maskLayerAnimation.delegate = self;
  50. maskLayerAnimation.fromValue = (__bridge id)(startCircle.CGPath);
  51. maskLayerAnimation.toValue = (__bridge id)((endCircle.CGPath));
  52. maskLayerAnimation.duration = 1.0f;
  53. maskLayerAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
  54. [maskLayer addAnimation:maskLayerAnimation forKey:@"path"];
  55. }
  56. - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
  57. self.isAnimationStart = NO;
  58. [self.splashView removeFromSuperview];
  59. [UIView beginAnimations:nil context:nil];
  60. [UIView setAnimationDuration:0.5];
  61. self.zoomOutView.frame = self.resultFrame;
  62. [UIView commitAnimations];
  63. }
  64. @end