├── .DS_Store
├── README.md
├── YYPhotoBrowserLikeWX.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── yuyou.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
└── xcuserdata
│ └── yuyou.xcuserdatad
│ ├── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ └── xcschememanagement.plist
├── YYPhotoBrowserLikeWX
├── .DS_Store
├── Classes
│ ├── .DS_Store
│ ├── Main
│ │ ├── .DS_Store
│ │ ├── Appdelegate
│ │ │ ├── AppDelegate.h
│ │ │ └── AppDelegate.m
│ │ ├── PhotoBrowser
│ │ │ ├── .DS_Store
│ │ │ ├── PhotoBrowser(图片浏览控制器)
│ │ │ │ ├── YYPhotoBrowserMainScrollView.h
│ │ │ │ ├── YYPhotoBrowserMainScrollView.m
│ │ │ │ ├── YYPhotoBrowserSubScrollView.h
│ │ │ │ ├── YYPhotoBrowserSubScrollView.m
│ │ │ │ ├── YYPhotoBrowserViewController.h
│ │ │ │ └── YYPhotoBrowserViewController.m
│ │ │ └── Translation(转场动画管理者)
│ │ │ │ ├── YYPhotoBrowserTranslation.h
│ │ │ │ └── YYPhotoBrowserTranslation.m
│ │ └── TestVc
│ │ │ ├── TestViewController.h
│ │ │ └── TestViewController.m
│ ├── Other
│ │ ├── PrefixHeader.pch
│ │ └── main.m
│ └── Utils
│ │ ├── UIView+YYExtension
│ │ ├── UIView+YYExtension.h
│ │ └── UIView+YYExtension.m
│ │ └── pop
│ │ ├── POP.h
│ │ ├── POPAction.h
│ │ ├── POPAnimatableProperty.h
│ │ ├── POPAnimatableProperty.mm
│ │ ├── POPAnimation.h
│ │ ├── POPAnimation.mm
│ │ ├── POPAnimationEvent.h
│ │ ├── POPAnimationEvent.mm
│ │ ├── POPAnimationEventInternal.h
│ │ ├── POPAnimationExtras.h
│ │ ├── POPAnimationExtras.mm
│ │ ├── POPAnimationInternal.h
│ │ ├── POPAnimationPrivate.h
│ │ ├── POPAnimationRuntime.h
│ │ ├── POPAnimationRuntime.mm
│ │ ├── POPAnimationTracer.h
│ │ ├── POPAnimationTracer.mm
│ │ ├── POPAnimationTracerInternal.h
│ │ ├── POPAnimator.h
│ │ ├── POPAnimator.mm
│ │ ├── POPAnimatorPrivate.h
│ │ ├── POPBasicAnimation.h
│ │ ├── POPBasicAnimation.mm
│ │ ├── POPBasicAnimationInternal.h
│ │ ├── POPCGUtils.h
│ │ ├── POPCGUtils.mm
│ │ ├── POPCustomAnimation.h
│ │ ├── POPCustomAnimation.mm
│ │ ├── POPDecayAnimation.h
│ │ ├── POPDecayAnimation.mm
│ │ ├── POPDecayAnimationInternal.h
│ │ ├── POPDefines.h
│ │ ├── POPGeometry.h
│ │ ├── POPGeometry.mm
│ │ ├── POPLayerExtras.h
│ │ ├── POPLayerExtras.mm
│ │ ├── POPMath.h
│ │ ├── POPMath.mm
│ │ ├── POPPropertyAnimation.h
│ │ ├── POPPropertyAnimation.mm
│ │ ├── POPPropertyAnimationInternal.h
│ │ ├── POPSpringAnimation.h
│ │ ├── POPSpringAnimation.mm
│ │ ├── POPSpringAnimationInternal.h
│ │ ├── POPSpringSolver.h
│ │ ├── POPVector.h
│ │ ├── POPVector.mm
│ │ ├── WebCore
│ │ ├── FloatConversion.h
│ │ ├── TransformationMatrix.h
│ │ ├── TransformationMatrix.mm
│ │ └── UnitBezier.h
│ │ ├── module.modulemap
│ │ ├── pop-ios-Info.plist
│ │ ├── pop-osx-Info.plist
│ │ └── pop-tvos-Info.plist
└── Supporting Files
│ ├── .DS_Store
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Contents.json
│ └── LaunchImage.launchimage
│ │ └── Contents.json
│ ├── Images
│ ├── 01.jpg
│ ├── 02.jpg
│ ├── 03.jpg
│ ├── 04.jpg
│ ├── 05.jpg
│ └── 06.jpg
│ ├── Info.plist
│ └── Launch Screen.storyboard
├── YYPhotoBrowserLikeWXTests
├── Info.plist
└── YYPhotoBrowserLikeWXTests.m
└── YYPhotoBrowserLikeWXUITests
├── Info.plist
└── YYPhotoBrowserLikeWXUITests.m
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YYProgrammer/YYPhotoBrowserLikeWX/50506d404b1607ea14947d5740fbc30ed3659547/.DS_Store
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 仿微信图片浏览交互的实现(向下拖拽图片退出图片浏览器)
2 |
3 | - 实现图片组的浏览,包含捏合缩放、双击缩放、单击退出、向下拖拽退出等。
4 | - 重点是“向下拖拽退出”的实现。
5 | - 简书上有实现过程的介绍:http://www.jianshu.com/p/a62d1546f648
6 |
7 | 
8 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX.xcodeproj/project.xcworkspace/xcuserdata/yuyou.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YYProgrammer/YYPhotoBrowserLikeWX/50506d404b1607ea14947d5740fbc30ed3659547/YYPhotoBrowserLikeWX.xcodeproj/project.xcworkspace/xcuserdata/yuyou.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX.xcodeproj/xcuserdata/yuyou.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX.xcodeproj/xcuserdata/yuyou.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | YYPhotoBrowserLikeWX.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YYProgrammer/YYPhotoBrowserLikeWX/50506d404b1607ea14947d5740fbc30ed3659547/YYPhotoBrowserLikeWX/.DS_Store
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YYProgrammer/YYPhotoBrowserLikeWX/50506d404b1607ea14947d5740fbc30ed3659547/YYPhotoBrowserLikeWX/Classes/.DS_Store
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Main/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YYProgrammer/YYPhotoBrowserLikeWX/50506d404b1607ea14947d5740fbc30ed3659547/YYPhotoBrowserLikeWX/Classes/Main/.DS_Store
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Main/Appdelegate/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // YYPhotoBrowserLikeWX
4 | //
5 | // Created by yuyou on 2017/12/5.
6 | // Copyright © 2017年 yy. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Main/Appdelegate/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // YYPhotoBrowserLikeWX
4 | //
5 | // Created by yuyou on 2017/12/5.
6 | // Copyright © 2017年 yy. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 | #import "TestViewController.h"
11 |
12 | @interface AppDelegate ()
13 |
14 | @end
15 |
16 | @implementation AppDelegate
17 |
18 |
19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
20 | {
21 | self.window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
22 | self.window.rootViewController = [[TestViewController alloc] init];
23 | [self.window makeKeyAndVisible];
24 |
25 | return YES;
26 | }
27 |
28 |
29 | - (void)applicationWillResignActive:(UIApplication *)application {
30 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
31 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
32 | }
33 |
34 |
35 | - (void)applicationDidEnterBackground:(UIApplication *)application {
36 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
37 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
38 | }
39 |
40 |
41 | - (void)applicationWillEnterForeground:(UIApplication *)application {
42 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
43 | }
44 |
45 |
46 | - (void)applicationDidBecomeActive:(UIApplication *)application {
47 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
48 | }
49 |
50 |
51 | - (void)applicationWillTerminate:(UIApplication *)application {
52 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
53 | }
54 |
55 |
56 | @end
57 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Main/PhotoBrowser/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YYProgrammer/YYPhotoBrowserLikeWX/50506d404b1607ea14947d5740fbc30ed3659547/YYPhotoBrowserLikeWX/Classes/Main/PhotoBrowser/.DS_Store
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Main/PhotoBrowser/PhotoBrowser(图片浏览控制器)/YYPhotoBrowserMainScrollView.h:
--------------------------------------------------------------------------------
1 | //
2 | // YYPhotoBrowserMainScrollView.h
3 | // YYPhotoBrowserLikeWX
4 | //
5 | // Created by yuyou on 2017/12/5.
6 | // Copyright © 2017年 yy. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | /**
12 | * 这个控件的核心是:把所有图片的包装进一个大的scrollview,
13 | * 这样才能实现左右滑动查看图片
14 | */
15 |
16 | @protocol YYPhotoBrowserMainScrollViewDelegate
17 |
18 | /** 单击 */
19 | - (void)YYPhotoBrowserMainScrollViewDoSingleTapWithImageFrame:(CGRect)imageFrame;
20 | /** 翻页 */
21 | - (void)YYPhotoBrowserMainScrollViewChangeCurrentIndex:(int)currentIndex;
22 | /** 向下拖拽 */
23 | - (void)YYPhotoBrowserMainScrollViewDoingDownDrag:(CGFloat)dragProportion;
24 | /** 需要退回页面 */
25 | - (void)YYPhotoBrowserMainScrollViewNeedBackWithImageFrame:(CGRect)imageFrame;
26 |
27 | @end
28 |
29 | @interface YYPhotoBrowserMainScrollView : UIView
30 |
31 | @property (nonatomic,weak) id delegate;
32 |
33 | - (instancetype)initWithFrame:(CGRect)frame imageNameArray:(NSArray *)imageNameArray currentImageIndex:(int)index;
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Main/PhotoBrowser/PhotoBrowser(图片浏览控制器)/YYPhotoBrowserMainScrollView.m:
--------------------------------------------------------------------------------
1 | //
2 | // YYPhotoBrowserMainScrollView.m
3 | // YYPhotoBrowserLikeWX
4 | //
5 | // Created by yuyou on 2017/12/5.
6 | // Copyright © 2017年 yy. All rights reserved.
7 | //
8 |
9 | #import "YYPhotoBrowserMainScrollView.h"
10 | #import "YYPhotoBrowserSubScrollView.h"
11 |
12 | //图片间的间距
13 | #define MARGIN_BETWEEN_IMAGE 20
14 |
15 | @interface YYPhotoBrowserMainScrollView ()
16 |
17 | @property (nonatomic,strong) NSArray *imageNameArray;//图片名数组
18 | @property (nonatomic,assign) int currentIndex;//当前的图片索引
19 | @property (nonatomic,strong) UIScrollView *mainScrollView;//主滚动控件
20 |
21 | @property (nonatomic,assign) BOOL scrollDoEvent;
22 | @property (nonatomic,assign) CGPoint currentPoint;
23 | @property (nonatomic,strong) UIEvent *currentEvent;
24 |
25 | @end
26 |
27 | @implementation YYPhotoBrowserMainScrollView
28 |
29 | - (instancetype)initWithFrame:(CGRect)frame imageNameArray:(NSArray *)imageNameArray currentImageIndex:(int)index
30 | {
31 | if (self = [super initWithFrame:frame])
32 | {
33 | self.imageNameArray = [imageNameArray copy];
34 | self.currentIndex = index;
35 |
36 | [self createUI];
37 | }
38 | return self;
39 | }
40 |
41 | - (void)createUI
42 | {
43 | self.backgroundColor = [UIColor clearColor];//注意,背景是clearcolor
44 |
45 | /**
46 | * 滚动控件,包含所有图片,每一页是一张图片(但其实每个图片本身还包装了个scrollview用于缩放)
47 | */
48 | UIScrollView *mainScrollView = [[UIScrollView alloc] init];
49 | [self addSubview:mainScrollView];
50 | self.mainScrollView = mainScrollView;
51 | mainScrollView.frame = CGRectMake(0, 0, self.yy_width + MARGIN_BETWEEN_IMAGE, self.yy_height);// frame中的size指UIScrollView的可视范围
52 | mainScrollView.layer.masksToBounds = NO;
53 | mainScrollView.contentSize = CGSizeMake(self.imageNameArray.count * (self.yy_width + MARGIN_BETWEEN_IMAGE), 0);// 设置UIScrollView的滚动范围(内容大小)
54 | mainScrollView.delegate = self;
55 | mainScrollView.backgroundColor = [UIColor clearColor];//注意,背景是clearcolor
56 | mainScrollView.showsHorizontalScrollIndicator = NO;
57 | mainScrollView.pagingEnabled = YES;//分页
58 | if (@available(iOS 11.0, *))//表示只在ios11以上的版本执行
59 | {
60 | mainScrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
61 | }
62 |
63 | //添加图片
64 | for (int i = 0; i < self.imageNameArray.count; i++)
65 | {
66 | YYPhotoBrowserSubScrollView *subScrollView = [[YYPhotoBrowserSubScrollView alloc] initWithFrame:CGRectMake(i * (self.yy_width + MARGIN_BETWEEN_IMAGE), 0, self.yy_width, self.yy_height) imageNamed:self.imageNameArray[i]];
67 | [mainScrollView addSubview:subScrollView];
68 | subScrollView.delegate = self;
69 | subScrollView.tag = i + 1;
70 | }
71 |
72 | //设置偏移量,即滚到当前用户选择的图片
73 | mainScrollView.contentOffset = CGPointMake(self.currentIndex * (self.yy_width + MARGIN_BETWEEN_IMAGE), 0);
74 |
75 | }
76 |
77 | #pragma mark - uiscrollview代理
78 | /** 减速完毕 */
79 | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
80 | {
81 | //计算当前滚到了哪个index
82 | self.currentIndex = scrollView.contentOffset.x / self.mainScrollView.yy_width;
83 |
84 | //通知代理
85 | if (self.delegate && [self.delegate respondsToSelector:@selector(YYPhotoBrowserMainScrollViewChangeCurrentIndex:)])
86 | {
87 | [self.delegate YYPhotoBrowserMainScrollViewChangeCurrentIndex:self.currentIndex];
88 | }
89 | }
90 |
91 | #pragma mark - 单个图片的控件的代理
92 | - (void)YYPhotoBrowserSubScrollViewDoSingleTapWithImageFrame:(CGRect)imageFrame
93 | {
94 | //继续向下通知代理
95 | if (self.delegate && [self.delegate respondsToSelector:@selector(YYPhotoBrowserMainScrollViewDoSingleTapWithImageFrame:)])
96 | {
97 | [self.delegate YYPhotoBrowserMainScrollViewDoSingleTapWithImageFrame:imageFrame];
98 | }
99 | }
100 |
101 | - (void)YYPhotoBrowserSubScrollViewDoDownDrag:(BOOL)isBegin view:(YYPhotoBrowserSubScrollView *)subScrollView needBack:(BOOL)needBack imageFrame:(CGRect)imageFrame
102 | {
103 | if (needBack)//需要退回页面时,向下通知代理
104 | {
105 | if (self.delegate && [self.delegate respondsToSelector:@selector(YYPhotoBrowserMainScrollViewNeedBackWithImageFrame:)])
106 | {
107 | [self.delegate YYPhotoBrowserMainScrollViewNeedBackWithImageFrame:imageFrame];
108 | }
109 | }
110 | else
111 | {
112 | for (UIView *subView in self.mainScrollView.subviews)
113 | {
114 | if ([subView isKindOfClass:[YYPhotoBrowserSubScrollView class]])
115 | {
116 | if (subView.tag == subScrollView.tag)
117 | {
118 | continue;
119 | }
120 | subView.hidden = isBegin;
121 | }
122 | }
123 | }
124 |
125 | }
126 |
127 | - (void)YYPhotoBrowserSubScrollViewDoingDownDrag:(CGFloat)dragProportion
128 | {
129 | if (self.delegate && [self.delegate respondsToSelector:@selector(YYPhotoBrowserMainScrollViewDoingDownDrag:)])
130 | {
131 | [self.delegate YYPhotoBrowserMainScrollViewDoingDownDrag:dragProportion];
132 | }
133 | }
134 |
135 | @end
136 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Main/PhotoBrowser/PhotoBrowser(图片浏览控制器)/YYPhotoBrowserSubScrollView.h:
--------------------------------------------------------------------------------
1 | //
2 | // YYPhotoBrowserSubScrollView.h
3 | // YYPhotoBrowserLikeWX
4 | //
5 | // Created by yuyou on 2017/12/5.
6 | // Copyright © 2017年 yy. All rights reserved.
7 | //
8 |
9 |
10 | /**
11 | * 这个控件的核心是:把每一张图片包装进一个scrollview,
12 | * 这样才能实现图片的放大等功能。
13 | */
14 |
15 | #import
16 | @class YYPhotoBrowserSubScrollView;
17 |
18 | @protocol YYPhotoBrowserSubScrollViewDelegate
19 |
20 | /** 单击回调 */
21 | - (void)YYPhotoBrowserSubScrollViewDoSingleTapWithImageFrame:(CGRect)imageFrame;
22 | /** 开始或结束向下拖拽(外部需要隐藏其它图片,否则左右滑时会看到),needBack页面是否需要退回,imageFrame退回时用来做动画,不退回时可以不传 */
23 | - (void)YYPhotoBrowserSubScrollViewDoDownDrag:(BOOL)isBegin view:(YYPhotoBrowserSubScrollView *)subScrollView needBack:(BOOL)needBack imageFrame:(CGRect)imageFrame;
24 | /** 拖拽进行中额回调,把拖拽进度发下去,以设置透明度 */
25 | - (void)YYPhotoBrowserSubScrollViewDoingDownDrag:(CGFloat)dragProportion;
26 |
27 | @end
28 |
29 | @interface YYPhotoBrowserSubScrollView : UIView
30 |
31 | @property (nonatomic,weak) id delegate;
32 |
33 | - (instancetype)initWithFrame:(CGRect)frame imageNamed:(NSString *)imageNamed;
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Main/PhotoBrowser/PhotoBrowser(图片浏览控制器)/YYPhotoBrowserViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // YYPhotoBrowserViewController.h
3 | // YYPhotoBrowserLikeWX
4 | //
5 | // Created by yuyou on 2017/12/5.
6 | // Copyright © 2017年 yy. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface YYPhotoBrowserViewController : UIViewController
12 |
13 | /**
14 | * 初始化方法
15 | * imageNameArray:图片名数组
16 | * currentImageIndex:当前点击的第几个
17 | * imageViewArray:页面里图片控件数组,这里需要是因为,转场时,要隐藏对应的
18 | * imageViewFrameArray:页面里图片控件在window中的frame,包装成数组传进来,转场时需要
19 | */
20 | - (instancetype)initWithImageNameArray:(NSArray *)imageNameArray currentImageIndex:(int)currentImageIndex imageViewArray:(NSMutableArray *)imageViewArray imageViewFrameArray:(NSMutableArray *)imageViewFrameArray;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Main/PhotoBrowser/PhotoBrowser(图片浏览控制器)/YYPhotoBrowserViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // YYPhotoBrowserViewController.m
3 | // YYPhotoBrowserLikeWX
4 | //
5 | // Created by yuyou on 2017/12/5.
6 | // Copyright © 2017年 yy. All rights reserved.
7 | //
8 |
9 | #import "YYPhotoBrowserViewController.h"
10 | #import "YYPhotoBrowserMainScrollView.h"
11 | #import "YYPhotoBrowserTranslation.h"
12 |
13 | @interface YYPhotoBrowserViewController ()
14 |
15 | @property (nonatomic,strong) NSArray *imageNameArray;//图片名字数组
16 | @property (nonatomic,assign) int currentImageIndex;//当前图片索引
17 | @property (nonatomic,strong) NSMutableArray *imageViewArray;//外部的图片控件数组
18 | @property (nonatomic,strong) NSMutableArray *imageViewFrameArray;//外部图片在window中的frame数组
19 | @property (nonatomic,strong) YYPhotoBrowserMainScrollView *mainScrollView;//主控件
20 | @property (nonatomic,strong) YYPhotoBrowserTranslation *translation;//转场动画管理者
21 |
22 | @end
23 |
24 | @implementation YYPhotoBrowserViewController
25 |
26 | #pragma mark - 生命周期
27 | - (instancetype)initWithImageNameArray:(NSArray *)imageNameArray currentImageIndex:(int)currentImageIndex imageViewArray:(NSMutableArray *)imageViewArray imageViewFrameArray:(NSMutableArray *)imageViewFrameArray
28 | {
29 | if (self = [self init])
30 | {
31 | self.modalPresentationStyle = UIModalPresentationOverCurrentContext;//设置modal的方式,这样背后的控制器的view不会消失
32 | self.transitioningDelegate = self;//转场管理者
33 | self.imageNameArray = [imageNameArray copy];
34 | self.currentImageIndex = currentImageIndex;
35 | self.imageViewArray = imageViewArray;
36 | self.imageViewFrameArray = imageViewFrameArray;
37 | }
38 | return self;
39 | }
40 |
41 | - (void)viewDidLoad
42 | {
43 | [super viewDidLoad];
44 |
45 | [self setUIComponent];
46 | }
47 |
48 | - (void)dealloc
49 | {
50 | NSLog(@"图片浏览器死亡");
51 | }
52 |
53 | #pragma mark - UI相关
54 | - (void)setUIComponent
55 | {
56 | self.view.backgroundColor = UIAlphaColorFromRGB(0x000000, 1.0);
57 |
58 | self.mainScrollView.hidden = YES;
59 | }
60 |
61 | #pragma mark - 图片scrollview控件的代理
62 | - (void)YYPhotoBrowserMainScrollViewDoSingleTapWithImageFrame:(CGRect)imageFrame
63 | {
64 | self.translation.backImageFrame = imageFrame;//赋值给转场管理对象做动画
65 | //需要退回页面
66 | [self dismissViewControllerAnimated:YES completion:nil];
67 | }
68 |
69 | - (void)YYPhotoBrowserMainScrollViewChangeCurrentIndex:(int)currentIndex
70 | {
71 | self.currentImageIndex = currentIndex;
72 | self.translation.currentIndex = self.currentImageIndex;//传值给转场管理对象
73 |
74 | //隐藏或显示对应的外部imageView
75 | for (int i = 0; i < self.imageViewArray.count; i++)
76 | {
77 | ((UIImageView *)self.imageViewArray[i]).hidden = (i == self.currentImageIndex);
78 | }
79 | }
80 |
81 | - (void)YYPhotoBrowserMainScrollViewDoingDownDrag:(CGFloat)dragProportion
82 | {
83 | self.view.backgroundColor = UIAlphaColorFromRGB(0x000000, (1 - dragProportion));
84 | }
85 |
86 | - (void)YYPhotoBrowserMainScrollViewNeedBackWithImageFrame:(CGRect)imageFrame
87 | {
88 | self.translation.backImageFrame = imageFrame;//赋值给转场管理对象做动画
89 | [self dismissViewControllerAnimated:YES completion:nil];
90 | }
91 |
92 | #pragma mark UIViewControllerTransitioningDelegate(转场动画代理)
93 | - (id)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
94 | {
95 | self.translation.photoBrowserShow = YES;
96 | return self.translation;
97 | }
98 |
99 | - (id)animationControllerForDismissedController:(UIViewController *)dismissed
100 | {
101 | self.translation.photoBrowserShow = NO;
102 | return self.translation;
103 | }
104 |
105 | #pragma mark - 懒加载
106 | - (YYPhotoBrowserTranslation *)translation
107 | {
108 | if (!_translation)
109 | {
110 | _translation = [[YYPhotoBrowserTranslation alloc] init];
111 | // _translation.endBlock = ^{
112 | // NSLog(@"end");
113 | // };
114 | _translation.photoBrowserMainScrollView = (UIView *)self.mainScrollView;
115 | _translation.imageViewArray = self.imageViewArray;
116 | _translation.imageViewFrameArray = self.imageViewFrameArray;
117 | _translation.imageNameArray = self.imageNameArray;
118 | _translation.currentIndex = self.currentImageIndex;//这个参数要最后赋值,因为他的setter中用到了上面的参数
119 | }
120 | return _translation;
121 | }
122 |
123 | - (YYPhotoBrowserMainScrollView *)mainScrollView
124 | {
125 | if (!_mainScrollView)
126 | {
127 | _mainScrollView = [[YYPhotoBrowserMainScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.yy_width, self.view.yy_height) imageNameArray:self.imageNameArray currentImageIndex:self.currentImageIndex];
128 | [self.view addSubview:self.mainScrollView];
129 | _mainScrollView.delegate = self;
130 | _mainScrollView.hidden = YES;
131 | }
132 | return _mainScrollView;
133 | }
134 |
135 | @end
136 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Main/PhotoBrowser/Translation(转场动画管理者)/YYPhotoBrowserTranslation.h:
--------------------------------------------------------------------------------
1 | //
2 | // YYPhotoBrowserTranslation.h
3 | // YYPhotoBrowserLikeWX
4 | //
5 | // Created by yuyou on 2017/12/5.
6 | // Copyright © 2017年 yy. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //typedef void(^EndBlock)(void);
12 |
13 | @interface YYPhotoBrowserTranslation : NSObject
14 |
15 | @property (nonatomic,assign) BOOL photoBrowserShow;//图片浏览器是显示还是隐藏
16 | //@property (nonatomic,strong) EndBlock endBlock;
17 | @property (nonatomic,strong) UIView *photoBrowserMainScrollView;//图片浏览页主控件,转场时要隐藏它
18 | @property (nonatomic,strong) NSArray *imageNameArray;//图片名称数组
19 | @property (nonatomic,strong) NSMutableArray *imageViewArray;//外部的图片控件数组,转场时隐藏对应的
20 | @property (nonatomic,strong) NSMutableArray *imageViewFrameArray;//外部图片控件的frame数组,转场时需要
21 | @property (nonatomic,assign) CGRect backImageFrame;//退回时的image的frame
22 | /** 这个参数请最后设置,因为它的setter方法中用到了以上参数 */
23 | @property (nonatomic,assign) int currentIndex;//当前是从在哪个图片返回
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Main/PhotoBrowser/Translation(转场动画管理者)/YYPhotoBrowserTranslation.m:
--------------------------------------------------------------------------------
1 | //
2 | // YYPhotoBrowserTranslation.m
3 | // YYPhotoBrowserLikeWX
4 | //
5 | // Created by yuyou on 2017/12/5.
6 | // Copyright © 2017年 yy. All rights reserved.
7 | //
8 |
9 | #import "YYPhotoBrowserTranslation.h"
10 | #import "POP.h"
11 |
12 | //弹簧系数
13 | #define popSpringBounciness 4.0
14 | //速度
15 | #define popSpringSpeed 10.0
16 |
17 | @interface YYPhotoBrowserTranslation ()
18 |
19 | @property (nonatomic,strong) UIImageView *showImageView;
20 |
21 | @end
22 |
23 | @implementation YYPhotoBrowserTranslation
24 |
25 | - (void)dealloc
26 | {
27 | NSLog(@"图片浏览器转场管理死亡");
28 | }
29 |
30 | - (NSTimeInterval)transitionDuration:(id)transitionContext
31 | {
32 | return 0.5;
33 | }
34 |
35 | - (void)animateTransition:(id)transitionContext
36 | {
37 | if (self.photoBrowserShow)//显示出来
38 | {
39 | //transitionContext:转场上下文
40 | //转场过程中显示的view,所有动画控件都应该加在这上面
41 | __block UIView *containerView = [transitionContext containerView];
42 | //转场的来源控制器
43 | UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
44 | //转场去往的控制器
45 | UIViewController *toVc = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
46 |
47 | //隐藏photoBrowser里面的图片
48 | self.photoBrowserMainScrollView.hidden = YES;
49 |
50 | //添加目标控制器view
51 | toVc.view.alpha = 0;
52 | [containerView addSubview:toVc.view];
53 | [UIView animateWithDuration:0.2 animations:^{
54 | toVc.view.alpha = 1;
55 | }];
56 |
57 | //添加imageView
58 | [containerView addSubview:self.showImageView];
59 |
60 | POPSpringAnimation *imageMove = [POPSpringAnimation animationWithPropertyNamed:kPOPViewFrame];
61 | imageMove.fromValue = [NSValue valueWithCGRect:CGRectMake(self.showImageView.yy_x, self.showImageView.yy_y, self.showImageView.yy_width, self.showImageView.yy_height)];
62 | //计算图片浏览器中image的frame
63 | CGFloat imageOriginalWidth = self.showImageView.image.size.width;
64 | CGFloat imageOriginalHeight = self.showImageView.image.size.height;
65 | CGFloat imageWidth = kMainScreenWidth;
66 | CGFloat imageHeight = imageOriginalHeight / imageOriginalWidth * imageWidth;
67 | CGFloat imageY = (kMainScreenHeight - imageHeight) * 0.5;
68 | imageY = imageY < 0 ? 0 : imageY;
69 | imageMove.toValue = [NSValue valueWithCGRect:CGRectMake(0, imageY, imageWidth, imageHeight)];
70 | imageMove.beginTime = CACurrentMediaTime();
71 | imageMove.springBounciness = popSpringBounciness;
72 | imageMove.springSpeed = popSpringSpeed;
73 | imageMove.completionBlock = ^(POPAnimation *anim ,BOOL isEnd){
74 |
75 | self.showImageView.hidden = YES;
76 | self.photoBrowserMainScrollView.hidden = NO;
77 | [transitionContext completeTransition:YES];
78 | };
79 | [self.showImageView pop_addAnimation:imageMove forKey:nil];
80 |
81 | //隐藏外部的图片
82 | ((UIImageView *)self.imageViewArray[self.currentIndex]).hidden = YES;
83 | }
84 | else//隐藏
85 | {
86 | //transitionContext:转场上下文
87 | //转场过程中显示的view,所有动画控件都应该加在这上面
88 | __block UIView *containerView = [transitionContext containerView];
89 | //转场的来源控制器
90 | UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
91 | //转场去往的控制器
92 | UIViewController *toVc = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
93 |
94 | //隐藏photoBrowser里的mainScrollView
95 | self.photoBrowserMainScrollView.hidden = YES;
96 |
97 | //隐藏或显示对应的外部imageView
98 | for (int i = 0; i < self.imageViewArray.count; i++)
99 | {
100 | ((UIImageView *)self.imageViewArray[i]).hidden = (i == self.currentIndex);
101 | }
102 |
103 | //要消失的vc
104 | fromVC.view.alpha = 1;
105 | [containerView addSubview:fromVC.view];
106 | [UIView animateWithDuration:0.5 animations:^{
107 | fromVC.view.alpha = 0;
108 | } completion:^(BOOL finished) {
109 |
110 | }];
111 |
112 | //显示和移动图片
113 | [containerView bringSubviewToFront:self.showImageView];
114 | self.showImageView.hidden = NO;
115 | POPSpringAnimation *imageMove = [POPSpringAnimation animationWithPropertyNamed:kPOPViewFrame];
116 | //计算图片浏览器中image的frame
117 | CGFloat imageOriginalWidth = self.showImageView.image.size.width;
118 | CGFloat imageOriginalHeight = self.showImageView.image.size.height;
119 | CGFloat imageWidth = kMainScreenWidth;
120 | CGFloat imageHeight = imageOriginalHeight / imageOriginalWidth * imageWidth;
121 | CGFloat imageY = (kMainScreenHeight - imageHeight) * 0.5;
122 | imageMove.fromValue = [NSValue valueWithCGRect:self.backImageFrame];//[NSValue valueWithCGRect:CGRectMake(0, imageY, imageWidth, imageHeight)];
123 | imageMove.toValue = self.imageViewFrameArray[self.currentIndex];
124 | imageMove.beginTime = CACurrentMediaTime();
125 | imageMove.springBounciness = popSpringBounciness;
126 | imageMove.springSpeed = popSpringSpeed;
127 | imageMove.completionBlock = ^(POPAnimation *anim ,BOOL isEnd){
128 |
129 | ((UIImageView *)self.imageViewArray[self.currentIndex]).hidden = NO;
130 | [transitionContext completeTransition:YES];
131 | };
132 | [self.showImageView pop_addAnimation:imageMove forKey:nil];
133 | }
134 | }
135 |
136 | #pragma mark - setter
137 | - (void)setCurrentIndex:(int)currentIndex
138 | {
139 | _currentIndex = currentIndex;
140 |
141 | //index改变时,image也要改变
142 | self.showImageView.image = ((UIImageView *)self.imageViewArray[currentIndex]).image;//[UIImage imageNamed:self.imageNameArray[currentIndex]];
143 | self.showImageView.yy_width = [self.imageViewFrameArray[currentIndex] CGRectValue].size.width;
144 | self.showImageView.yy_height = [self.imageViewFrameArray[currentIndex] CGRectValue].size.height;
145 | self.showImageView.yy_x = [self.imageViewFrameArray[currentIndex] CGRectValue].origin.x;
146 | self.showImageView.yy_y = [self.imageViewFrameArray[currentIndex] CGRectValue].origin.y;
147 |
148 | //不在这里隐藏或显示外部image,因为在这里做,外部图片会闪一下
149 | }
150 |
151 | #pragma mark - 懒加载
152 | - (UIImageView *)showImageView
153 | {
154 | if (!_showImageView)
155 | {
156 | _showImageView = [[UIImageView alloc] init];
157 | _showImageView.backgroundColor = [UIColor whiteColor];
158 | // _showImageView.image = [UIImage imageNamed:self.imageNameArray[self.currentIndex]];
159 | _showImageView.contentMode = UIViewContentModeScaleAspectFill;
160 | _showImageView.layer.masksToBounds = YES;
161 | }
162 | return _showImageView;
163 | }
164 |
165 | @end
166 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Main/TestVc/TestViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // TestViewController.h
3 | // YYPhotoBrowserLikeWX
4 | //
5 | // Created by yuyou on 2017/12/5.
6 | // Copyright © 2017年 yy. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface TestViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Main/TestVc/TestViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // TestViewController.m
3 | // YYPhotoBrowserLikeWX
4 | //
5 | // Created by yuyou on 2017/12/5.
6 | // Copyright © 2017年 yy. All rights reserved.
7 | //
8 |
9 | #import "TestViewController.h"
10 | #import "YYPhotoBrowserViewController.h"
11 |
12 | @interface TestViewController ()
13 |
14 | @property (nonatomic,strong) NSArray *imageNameArray;//图片名数组
15 | @property (nonatomic,strong) NSMutableArray *imageViewArray;//图片控件数组
16 | @property (nonatomic,strong) NSMutableArray *imageViewFrameArray;//图片控件在window中的位置
17 |
18 | @end
19 |
20 | @implementation TestViewController
21 |
22 | #pragma mark - 生命周期
23 | - (void)viewDidLoad
24 | {
25 | [super viewDidLoad];
26 |
27 | [self setUIComponent];
28 | }
29 |
30 | #pragma mark - UI构建
31 | - (void)setUIComponent
32 | {
33 | self.view.backgroundColor = UIColorFromRGB(0xdddddd);
34 |
35 | CGFloat leftRightMargin = 15.0;//左右间距
36 | CGFloat marginBetweenImage = 10.0;//图片间间距
37 | CGFloat imageWidth = ([UIScreen mainScreen].bounds.size.width - 2 * leftRightMargin - 2 * marginBetweenImage) / 3.0;//图片宽
38 | CGFloat imageHeight = imageWidth / 3.0 * 2.0;//图片高
39 | CGFloat imagesBeginY = 100;
40 | for (int i = 0; i < self.imageNameArray.count; i++)
41 | {
42 | UIImageView *imageView = [[UIImageView alloc] init];
43 | [self.view addSubview:imageView];
44 | [self.imageViewArray addObject:imageView];
45 | int row = i / 3;
46 | int col = i % 3;
47 | imageView.frame = CGRectMake(leftRightMargin + col * (imageWidth + marginBetweenImage), imagesBeginY + row * (imageHeight + marginBetweenImage), imageWidth, imageHeight);
48 | [self saveWindowFrameWithOriginalFrame:imageView.frame];
49 | imageView.contentMode = UIViewContentModeScaleAspectFill;
50 | imageView.layer.masksToBounds = YES;
51 | imageView.image = [UIImage imageNamed:self.imageNameArray[i]];
52 | imageView.tag = i;
53 | imageView.userInteractionEnabled = YES;
54 | [imageView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(clickImage:)]];
55 | }
56 | }
57 |
58 | #pragma mark - 事件响应
59 | /** 根据图片再view中的位置,算出在window中的位置,并保存 */
60 | - (void)saveWindowFrameWithOriginalFrame:(CGRect)originalFrame
61 | {
62 | //因为这里恰好在view中的位置就是在window中的位置,所以不需要转frame
63 | //因为数组不能存结构体,所以存的时候转成NSValue
64 | NSValue *frameValue = [NSValue valueWithCGRect:originalFrame];
65 | [self.imageViewFrameArray addObject:frameValue];
66 | }
67 |
68 | /** 点击了图片 */
69 | - (void)clickImage:(UITapGestureRecognizer *)tap
70 | {
71 | NSInteger tag = tap.view.tag;
72 | NSLog(@"%ld",tag);
73 |
74 | YYPhotoBrowserViewController *photo = [[YYPhotoBrowserViewController alloc] initWithImageNameArray:self.imageNameArray currentImageIndex:((int)tag) imageViewArray:self.imageViewArray imageViewFrameArray:self.imageViewFrameArray];
75 | [self presentViewController:photo animated:YES completion:nil];
76 | }
77 |
78 | #pragma mark - 懒加载
79 | - (NSArray *)imageNameArray
80 | {
81 | if (!_imageNameArray)
82 | {
83 | _imageNameArray = [NSArray arrayWithObjects:@"01.jpg", @"02.jpg", @"03.jpg", @"04.jpg", @"05.jpg", @"06.jpg", nil];
84 | }
85 | return _imageNameArray;
86 | }
87 |
88 | - (NSMutableArray *)imageViewArray
89 | {
90 | if (!_imageViewArray)
91 | {
92 | _imageViewArray = [NSMutableArray array];
93 | }
94 | return _imageViewArray;
95 | }
96 |
97 | - (NSMutableArray *)imageViewFrameArray
98 | {
99 | if (!_imageViewFrameArray)
100 | {
101 | _imageViewFrameArray = [NSMutableArray array];
102 | }
103 | return _imageViewFrameArray;
104 | }
105 |
106 | @end
107 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Other/PrefixHeader.pch:
--------------------------------------------------------------------------------
1 | //
2 | // PrefixHeader.pch
3 | // YYPhotoBrowserLikeWX
4 | //
5 | // Created by yuyou on 2017/12/5.
6 | // Copyright © 2017年 yy. All rights reserved.
7 | //
8 |
9 | #ifndef PrefixHeader_pch
10 | #define PrefixHeader_pch
11 |
12 | /**
13 | * import 头文件 - 开始
14 | */
15 |
16 | #import "UIView+YYExtension.h"
17 |
18 | /**
19 | * import 头文件 - 结束
20 | */
21 |
22 |
23 |
24 | /**
25 | * 宏 - 开始
26 | */
27 |
28 | /** 设备屏幕宽 */
29 | #define kMainScreenWidth [UIScreen mainScreen].bounds.size.width
30 | /** 设备屏幕高度 */
31 | #define kMainScreenHeight [UIScreen mainScreen].bounds.size.height
32 |
33 | /** 6位十六进制颜色转换 */
34 | #define UIColorFromRGB(rgbValue) \
35 | [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
36 | /** 6位十六进制颜色转换,带透明度 */
37 | #define UIAlphaColorFromRGB(rgbValue,a) \
38 | [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:a]
39 |
40 | /**
41 | * 宏 - 结束
42 | */
43 |
44 | #endif /* PrefixHeader_pch */
45 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Other/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // YYPhotoBrowserLikeWX
4 | //
5 | // Created by yuyou on 2017/12/5.
6 | // Copyright © 2017年 yy. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/UIView+YYExtension/UIView+YYExtension.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+XMGExtension.h
3 | // 01-百思不得姐
4 | //
5 | // Created by xiaomage on 15/7/22.
6 | // Copyright (c) 2015年 小码哥. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface UIView (YYExtension)
12 | @property (nonatomic, assign) CGSize yy_size;
13 | @property (nonatomic, assign) CGFloat yy_width;
14 | @property (nonatomic, assign) CGFloat yy_height;
15 | @property (nonatomic, assign) CGFloat yy_x;
16 | @property (nonatomic, assign) CGFloat yy_y;
17 | @property (nonatomic, assign) CGFloat yy_centerX;
18 | @property (nonatomic, assign) CGFloat yy_centerY;
19 |
20 | //判断是否包含某个类的subview
21 | - (BOOL)doHaveSubViewOfSubViewClassName:(NSString *)subViewClassName;
22 |
23 | //删除某个类的subview
24 | - (void)removeSomeSubViewOfSubViewClassName:(NSString *)subViewClassName;
25 |
26 | //得到某个类的subview
27 | - (void)getTheSubViewOfSubViewClassName:(NSString *)subViewClassName block:(void(^)(UIView *subView))block;
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/UIView+YYExtension/UIView+YYExtension.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+XMGExtension.m
3 | // 01-百思不得姐
4 | //
5 | // Created by xiaomage on 15/7/22.
6 | // Copyright (c) 2015年 小码哥. All rights reserved.
7 | //
8 |
9 | #import "UIView+YYExtension.h"
10 |
11 | @implementation UIView (YYExtension)
12 |
13 | - (void)setYy_size:(CGSize)yy_size
14 | {
15 | CGRect frame = self.frame;
16 | frame.size = yy_size;
17 | self.frame = frame;
18 | }
19 |
20 | - (CGSize)yy_size
21 | {
22 | return self.frame.size;
23 | }
24 |
25 | - (void)setYy_width:(CGFloat)yy_width
26 | {
27 | if (isnan(yy_width)) {
28 |
29 | return;
30 | }
31 | CGRect frame = self.frame;
32 | frame.size.width = yy_width;
33 | self.frame = frame;
34 | }
35 |
36 | - (void)setYy_height:(CGFloat)yy_height
37 | {
38 | if (isnan(yy_height)) {
39 |
40 | return;
41 | }
42 | CGRect frame = self.frame;
43 | frame.size.height = yy_height;
44 | self.frame = frame;
45 | }
46 |
47 | - (void)setYy_x:(CGFloat)yy_x
48 | {
49 | if (isnan(yy_x)) {
50 |
51 | return;
52 | }
53 | CGRect frame = self.frame;
54 | frame.origin.x = yy_x;
55 | self.frame = frame;
56 | }
57 |
58 | - (void)setYy_y:(CGFloat)yy_y
59 | {
60 | CGRect frame = self.frame;
61 | frame.origin.y = yy_y;
62 | self.frame = frame;
63 | }
64 |
65 | - (void)setYy_centerX:(CGFloat)yy_centerX
66 | {
67 | CGPoint center = self.center;
68 | center.x = yy_centerX;
69 | self.center = center;
70 | }
71 |
72 | - (void)setYy_centerY:(CGFloat)yy_centerY
73 | {
74 | CGPoint center = self.center;
75 | center.y = yy_centerY;
76 | self.center = center;
77 | }
78 |
79 | - (CGFloat)yy_centerY
80 | {
81 | return self.center.y;
82 | }
83 |
84 | - (CGFloat)yy_centerX
85 | {
86 | return self.center.x;
87 | }
88 |
89 | - (CGFloat)yy_width
90 | {
91 | return self.frame.size.width;
92 | }
93 |
94 | - (CGFloat)yy_height
95 | {
96 | return self.frame.size.height;
97 | }
98 |
99 | - (CGFloat)yy_x
100 | {
101 | return self.frame.origin.x;
102 | }
103 |
104 | - (CGFloat)yy_y
105 | {
106 | return self.frame.origin.y;
107 | }
108 |
109 | //判断是否包含某个类的subview
110 | - (BOOL)doHaveSubViewOfSubViewClassName:(NSString *)subViewClassName
111 | {
112 | BOOL doHave = NO;
113 | for (UIView *subView in self.subviews)
114 | {
115 | if ([subView isKindOfClass:NSClassFromString(subViewClassName)])
116 | {
117 | doHave = YES;
118 | break;
119 | }
120 | }
121 | return doHave;
122 | }
123 |
124 | //删除某个类的subview
125 | - (void)removeSomeSubViewOfSubViewClassName:(NSString *)subViewClassName
126 | {
127 | for (UIView *subView in self.subviews)
128 | {
129 | if ([subView isKindOfClass:NSClassFromString(subViewClassName)])
130 | {
131 | [subView removeFromSuperview];
132 | }
133 | }
134 | }
135 |
136 | //得到某个类的subview
137 | - (void)getTheSubViewOfSubViewClassName:(NSString *)subViewClassName block:(void(^)(UIView *subView))block;
138 | {
139 | dispatch_async(dispatch_get_main_queue(), ^{
140 | for (UIView *subView in self.subviews)
141 | {
142 | if ([subView isKindOfClass:NSClassFromString(subViewClassName)])
143 | {
144 | block(subView);
145 | }
146 | }
147 | block(nil);
148 | });
149 | }
150 |
151 | @end
152 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POP.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #ifndef POP_POP_H
11 | #define POP_POP_H
12 |
13 | //#import
14 | #import "POPDefines.h"
15 |
16 | //#import
17 | #import "POPAnimatableProperty.h"
18 | //#import
19 | #import "POPAnimation.h"
20 | //#import
21 | #import "POPAnimationEvent.h"
22 | //#import
23 | #import "POPAnimationExtras.h"
24 | //#import
25 | #import "POPAnimationTracer.h"
26 | //#import
27 | #import "POPAnimator.h"
28 | //#import
29 | #import "POPBasicAnimation.h"
30 | //#import
31 | #import "POPCustomAnimation.h"
32 | //#import
33 | #import "POPDecayAnimation.h"
34 | //#import
35 | #import "POPGeometry.h"
36 | //#import
37 | #import "POPLayerExtras.h"
38 | //#import
39 | #import "POPPropertyAnimation.h"
40 | //#import
41 | #import "POPSpringAnimation.h"
42 |
43 | #endif /* POP_POP_H */
44 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPAction.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #ifndef POPACTION_H
11 | #define POPACTION_H
12 |
13 | #import
14 |
15 | //#import
16 | #import "POPDefines.h"
17 |
18 | #ifdef __cplusplus
19 |
20 | namespace POP {
21 |
22 | /**
23 | @abstract Disables Core Animation actions using RAII.
24 | @discussion The disablement of actions is scoped to the current transaction.
25 | */
26 | class ActionDisabler
27 | {
28 | BOOL state;
29 |
30 | public:
31 | ActionDisabler() POP_NOTHROW
32 | {
33 | state = [CATransaction disableActions];
34 | [CATransaction setDisableActions:YES];
35 | }
36 |
37 | ~ActionDisabler()
38 | {
39 | [CATransaction setDisableActions:state];
40 | }
41 | };
42 |
43 | /**
44 | @abstract Enables Core Animation actions using RAII.
45 | @discussion The enablement of actions is scoped to the current transaction.
46 | */
47 | class ActionEnabler
48 | {
49 | BOOL state;
50 |
51 | public:
52 | ActionEnabler() POP_NOTHROW
53 | {
54 | state = [CATransaction disableActions];
55 | [CATransaction setDisableActions:NO];
56 | }
57 |
58 | ~ActionEnabler()
59 | {
60 | [CATransaction setDisableActions:state];
61 | }
62 | };
63 |
64 | }
65 |
66 | #endif /* __cplusplus */
67 |
68 | #endif /* POPACTION_H */
69 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPAnimatableProperty.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | #import
13 |
14 | //#import
15 | #import "POPDefines.h"
16 |
17 | @class POPMutableAnimatableProperty;
18 |
19 | /**
20 | @abstract Describes an animatable property.
21 | */
22 | @interface POPAnimatableProperty : NSObject
23 |
24 | /**
25 | @abstract Property accessor.
26 | @param name The name of the property.
27 | @return The animatable property with that name or nil if it does not exist.
28 | @discussion Common animatable properties are included by default. Use the provided constants to reference.
29 | */
30 | + (id)propertyWithName:(NSString *)name;
31 |
32 | /**
33 | @abstract The designated initializer.
34 | @param name The name of the property.
35 | @param block The block used to configure the property on creation.
36 | @return The animatable property with name if it exists, otherwise a newly created instance configured by block.
37 | @discussion Custom properties should use reverse-DNS naming. A newly created instance is only mutable in the scope of block. Once constructed, a property becomes immutable.
38 | */
39 | + (id)propertyWithName:(NSString *)name initializer:(void (^)(POPMutableAnimatableProperty *prop))block;
40 |
41 | /**
42 | @abstract The name of the property.
43 | @discussion Used to uniquely identify an animatable property.
44 | */
45 | @property (readonly, nonatomic, copy) NSString *name;
46 |
47 | /**
48 | @abstract Block used to read values from a property into an array of floats.
49 | */
50 | @property (readonly, nonatomic, copy) void (^readBlock)(id obj, CGFloat values[]);
51 |
52 | /**
53 | @abstract Block used to write values from an array of floats into a property.
54 | */
55 | @property (readonly, nonatomic, copy) void (^writeBlock)(id obj, const CGFloat values[]);
56 |
57 | /**
58 | @abstract The threshold value used when determining completion of dynamics simulations.
59 | */
60 | @property (readonly, nonatomic, assign) CGFloat threshold;
61 |
62 | @end
63 |
64 | /**
65 | @abstract A mutable animatable property intended for configuration.
66 | */
67 | @interface POPMutableAnimatableProperty : POPAnimatableProperty
68 |
69 | /**
70 | @abstract A read-write version of POPAnimatableProperty name property.
71 | */
72 | @property (readwrite, nonatomic, copy) NSString *name;
73 |
74 | /**
75 | @abstract A read-write version of POPAnimatableProperty readBlock property.
76 | */
77 | @property (readwrite, nonatomic, copy) void (^readBlock)(id obj, CGFloat values[]);
78 |
79 | /**
80 | @abstract A read-write version of POPAnimatableProperty writeBlock property.
81 | */
82 | @property (readwrite, nonatomic, copy) void (^writeBlock)(id obj, const CGFloat values[]);
83 |
84 | /**
85 | @abstract A read-write version of POPAnimatableProperty threshold property.
86 | */
87 | @property (readwrite, nonatomic, assign) CGFloat threshold;
88 |
89 | @end
90 |
91 | /**
92 | Common CALayer property names.
93 | */
94 | extern NSString * const kPOPLayerBackgroundColor;
95 | extern NSString * const kPOPLayerBounds;
96 | extern NSString * const kPOPLayerCornerRadius;
97 | extern NSString * const kPOPLayerBorderWidth;
98 | extern NSString * const kPOPLayerBorderColor;
99 | extern NSString * const kPOPLayerOpacity;
100 | extern NSString * const kPOPLayerPosition;
101 | extern NSString * const kPOPLayerPositionX;
102 | extern NSString * const kPOPLayerPositionY;
103 | extern NSString * const kPOPLayerRotation;
104 | extern NSString * const kPOPLayerRotationX;
105 | extern NSString * const kPOPLayerRotationY;
106 | extern NSString * const kPOPLayerScaleX;
107 | extern NSString * const kPOPLayerScaleXY;
108 | extern NSString * const kPOPLayerScaleY;
109 | extern NSString * const kPOPLayerSize;
110 | extern NSString * const kPOPLayerSubscaleXY;
111 | extern NSString * const kPOPLayerSubtranslationX;
112 | extern NSString * const kPOPLayerSubtranslationXY;
113 | extern NSString * const kPOPLayerSubtranslationY;
114 | extern NSString * const kPOPLayerSubtranslationZ;
115 | extern NSString * const kPOPLayerTranslationX;
116 | extern NSString * const kPOPLayerTranslationXY;
117 | extern NSString * const kPOPLayerTranslationY;
118 | extern NSString * const kPOPLayerTranslationZ;
119 | extern NSString * const kPOPLayerZPosition;
120 | extern NSString * const kPOPLayerShadowColor;
121 | extern NSString * const kPOPLayerShadowOffset;
122 | extern NSString * const kPOPLayerShadowOpacity;
123 | extern NSString * const kPOPLayerShadowRadius;
124 |
125 | /**
126 | Common CAShapeLayer property names.
127 | */
128 | extern NSString * const kPOPShapeLayerStrokeStart;
129 | extern NSString * const kPOPShapeLayerStrokeEnd;
130 | extern NSString * const kPOPShapeLayerStrokeColor;
131 | extern NSString * const kPOPShapeLayerFillColor;
132 | extern NSString * const kPOPShapeLayerLineWidth;
133 | extern NSString * const kPOPShapeLayerLineDashPhase;
134 |
135 | /**
136 | Common NSLayoutConstraint property names.
137 | */
138 | extern NSString * const kPOPLayoutConstraintConstant;
139 |
140 |
141 | #if TARGET_OS_IPHONE
142 |
143 | /**
144 | Common UIView property names.
145 | */
146 | extern NSString * const kPOPViewAlpha;
147 | extern NSString * const kPOPViewBackgroundColor;
148 | extern NSString * const kPOPViewBounds;
149 | extern NSString * const kPOPViewCenter;
150 | extern NSString * const kPOPViewFrame;
151 | extern NSString * const kPOPViewScaleX;
152 | extern NSString * const kPOPViewScaleXY;
153 | extern NSString * const kPOPViewScaleY;
154 | extern NSString * const kPOPViewSize;
155 | extern NSString * const kPOPViewTintColor;
156 |
157 | /**
158 | Common UIScrollView property names.
159 | */
160 | extern NSString * const kPOPScrollViewContentOffset;
161 | extern NSString * const kPOPScrollViewContentSize;
162 | extern NSString * const kPOPScrollViewZoomScale;
163 | extern NSString * const kPOPScrollViewContentInset;
164 | extern NSString * const kPOPScrollViewScrollIndicatorInsets;
165 |
166 | /**
167 | Common UITableView property names.
168 | */
169 | extern NSString * const kPOPTableViewContentOffset;
170 | extern NSString * const kPOPTableViewContentSize;
171 |
172 | /**
173 | Common UICollectionView property names.
174 | */
175 | extern NSString * const kPOPCollectionViewContentOffset;
176 | extern NSString * const kPOPCollectionViewContentSize;
177 |
178 | /**
179 | Common UINavigationBar property names.
180 | */
181 | extern NSString * const kPOPNavigationBarBarTintColor;
182 |
183 | /**
184 | Common UIToolbar property names.
185 | */
186 | extern NSString * const kPOPToolbarBarTintColor;
187 |
188 | /**
189 | Common UITabBar property names.
190 | */
191 | extern NSString * const kPOPTabBarBarTintColor;
192 |
193 | /**
194 | Common UILabel property names.
195 | */
196 | extern NSString * const kPOPLabelTextColor;
197 |
198 | #else
199 |
200 | /**
201 | Common NSView property names.
202 | */
203 | extern NSString * const kPOPViewFrame;
204 | extern NSString * const kPOPViewBounds;
205 | extern NSString * const kPOPViewAlphaValue;
206 | extern NSString * const kPOPViewFrameRotation;
207 | extern NSString * const kPOPViewFrameCenterRotation;
208 | extern NSString * const kPOPViewBoundsRotation;
209 |
210 | /**
211 | Common NSWindow property names.
212 | */
213 | extern NSString * const kPOPWindowFrame;
214 | extern NSString * const kPOPWindowAlphaValue;
215 | extern NSString * const kPOPWindowBackgroundColor;
216 |
217 | #endif
218 |
219 | #if SCENEKIT_SDK_AVAILABLE
220 |
221 | /**
222 | Common SceneKit property names.
223 | */
224 | extern NSString * const kPOPSCNNodePosition;
225 | extern NSString * const kPOPSCNNodePositionX;
226 | extern NSString * const kPOPSCNNodePositionY;
227 | extern NSString * const kPOPSCNNodePositionZ;
228 | extern NSString * const kPOPSCNNodeTranslation;
229 | extern NSString * const kPOPSCNNodeTranslationX;
230 | extern NSString * const kPOPSCNNodeTranslationY;
231 | extern NSString * const kPOPSCNNodeTranslationZ;
232 | extern NSString * const kPOPSCNNodeRotation;
233 | extern NSString * const kPOPSCNNodeRotationX;
234 | extern NSString * const kPOPSCNNodeRotationY;
235 | extern NSString * const kPOPSCNNodeRotationZ;
236 | extern NSString * const kPOPSCNNodeRotationW;
237 | extern NSString * const kPOPSCNNodeEulerAngles;
238 | extern NSString * const kPOPSCNNodeEulerAnglesX;
239 | extern NSString * const kPOPSCNNodeEulerAnglesY;
240 | extern NSString * const kPOPSCNNodeEulerAnglesZ;
241 | extern NSString * const kPOPSCNNodeOrientation;
242 | extern NSString * const kPOPSCNNodeOrientationX;
243 | extern NSString * const kPOPSCNNodeOrientationY;
244 | extern NSString * const kPOPSCNNodeOrientationZ;
245 | extern NSString * const kPOPSCNNodeOrientationW;
246 | extern NSString * const kPOPSCNNodeScale;
247 | extern NSString * const kPOPSCNNodeScaleX;
248 | extern NSString * const kPOPSCNNodeScaleY;
249 | extern NSString * const kPOPSCNNodeScaleZ;
250 | extern NSString * const kPOPSCNNodeScaleXY;
251 |
252 | #endif
253 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPAnimation.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | //#import
13 | #import "POPAnimationTracer.h"
14 | //#import
15 | #import "POPGeometry.h"
16 |
17 | @class CAMediaTimingFunction;
18 |
19 | /**
20 | @abstract The abstract animation base class.
21 | @discussion Instantiate and use one of the concrete animation subclasses.
22 | */
23 | @interface POPAnimation : NSObject
24 |
25 | /**
26 | @abstract The name of the animation.
27 | @discussion Optional property to help identify the animation.
28 | */
29 | @property (copy, nonatomic) NSString *name;
30 |
31 | /**
32 | @abstract The beginTime of the animation in media time.
33 | @discussion Defaults to 0 and starts immediately.
34 | */
35 | @property (assign, nonatomic) CFTimeInterval beginTime;
36 |
37 | /**
38 | @abstract The animation delegate.
39 | @discussion See {@ref POPAnimationDelegate} for details.
40 | */
41 | @property (weak, nonatomic) id delegate;
42 |
43 | /**
44 | @abstract The animation tracer.
45 | @discussion Returns the existing tracer, creating one if needed. Call start/stop on the tracer to toggle event collection.
46 | */
47 | @property (readonly, nonatomic) POPAnimationTracer *tracer;
48 |
49 | /**
50 | @abstract Optional block called on animation start.
51 | */
52 | @property (copy, nonatomic) void (^animationDidStartBlock)(POPAnimation *anim);
53 |
54 | /**
55 | @abstract Optional block called when value meets or exceeds to value.
56 | */
57 | @property (copy, nonatomic) void (^animationDidReachToValueBlock)(POPAnimation *anim);
58 |
59 | /**
60 | @abstract Optional block called on animation completion.
61 | */
62 | @property (copy, nonatomic) void (^completionBlock)(POPAnimation *anim, BOOL finished);
63 |
64 | /**
65 | @abstract Optional block called each frame animation is applied.
66 | */
67 | @property (copy, nonatomic) void (^animationDidApplyBlock)(POPAnimation *anim);
68 |
69 | /**
70 | @abstract Flag indicating whether animation should be removed on completion.
71 | @discussion Setting to NO can facilitate animation reuse. Defaults to YES.
72 | */
73 | @property (assign, nonatomic) BOOL removedOnCompletion;
74 |
75 | /**
76 | @abstract Flag indicating whether animation is paused.
77 | @discussion A paused animation is excluded from the list of active animations. On initial creation, defaults to YES. On animation addition, the animation is implicity unpaused. On animation completion, the animation is implicity paused including for animations with removedOnCompletion set to NO.
78 | */
79 | @property (assign, nonatomic, getter = isPaused) BOOL paused;
80 |
81 | /**
82 | @abstract Flag indicating whether animation autoreverses.
83 | @discussion An animation that autoreverses will have twice the duration before it is considered finished. It will animate to the toValue, stop, then animate back to the original fromValue. The delegate methods are called as follows:
84 |
85 | 1) animationDidStart: is called at the beginning, as usual, and then after each toValue is reached and the autoreverse is going to start.
86 | 2) animationDidReachToValue: is called every time the toValue is reached. The toValue is swapped with the fromValue at the end of each animation segment. This means that with autoreverses set to YES, the animationDidReachToValue: delegate method will be called a minimum of twice.
87 | 3) animationDidStop:finished: is called every time the toValue is reached, the finished argument will be NO if the autoreverse is not yet complete.
88 | */
89 | @property (assign, nonatomic) BOOL autoreverses;
90 |
91 | /**
92 | @abstract The number of times to repeat the animation.
93 | @discussion A repeatCount of 0 or 1 means that the animation will not repeat, just like Core Animation. A repeatCount of 2 or greater means that the animation will run that many times before stopping. The delegate methods are called as follows:
94 |
95 | 1) animationDidStart: is called at the beginning of each animation repeat.
96 | 2) animationDidReachToValue: is called every time the toValue is reached.
97 | 3) animationDidStop:finished: is called every time the toValue is reached, the finished argument will be NO if the autoreverse is not yet complete.
98 |
99 | When combined with the autoreverses property, a singular animation is effectively twice as long.
100 | */
101 | @property (assign, nonatomic) NSInteger repeatCount;
102 |
103 | /**
104 | @abstract Repeat the animation forever.
105 | @discussion This property will make the animation repeat forever. The value of the repeatCount property is undefined when this property is set. The finished parameter of the delegate callback animationDidStop:finished: will always be NO.
106 | */
107 | @property (assign, nonatomic) BOOL repeatForever;
108 |
109 | @end
110 |
111 | /**
112 | @abstract The animation delegate.
113 | */
114 | @protocol POPAnimationDelegate
115 | @optional
116 |
117 | /**
118 | @abstract Called on animation start.
119 | @param anim The relevant animation.
120 | */
121 | - (void)pop_animationDidStart:(POPAnimation *)anim;
122 |
123 | /**
124 | @abstract Called when value meets or exceeds to value.
125 | @param anim The relevant animation.
126 | */
127 | - (void)pop_animationDidReachToValue:(POPAnimation *)anim;
128 |
129 | /**
130 | @abstract Called on animation stop.
131 | @param anim The relevant animation.
132 | @param finished Flag indicating finished state. Flag is true if the animation reached completion before being removed.
133 | */
134 | - (void)pop_animationDidStop:(POPAnimation *)anim finished:(BOOL)finished;
135 |
136 | /**
137 | @abstract Called each frame animation is applied.
138 | @param anim The relevant animation.
139 | */
140 | - (void)pop_animationDidApply:(POPAnimation *)anim;
141 |
142 | @end
143 |
144 |
145 | @interface NSObject (POP)
146 |
147 | /**
148 | @abstract Add an animation to the reciver.
149 | @param anim The animation to add.
150 | @param key The key used to identify the animation.
151 | @discussion The 'key' may be any string such that only one animation per unique key is added per object.
152 | */
153 | - (void)pop_addAnimation:(POPAnimation *)anim forKey:(NSString *)key;
154 |
155 | /**
156 | @abstract Remove all animations attached to the receiver.
157 | */
158 | - (void)pop_removeAllAnimations;
159 |
160 | /**
161 | @abstract Remove any animation attached to the receiver for 'key'.
162 | @param key The key used to identify the animation.
163 | */
164 | - (void)pop_removeAnimationForKey:(NSString *)key;
165 |
166 | /**
167 | @abstract Returns an array containing the keys of all animations currently attached to the receiver.
168 | The order of keys reflects the order in which animations will be applied.
169 | */
170 | - (NSArray *)pop_animationKeys;
171 |
172 | /**
173 | @abstract Returns any animation attached to the receiver.
174 | @param key The key used to identify the animation.
175 | @returns The animation currently attached, or nil if no such animation exists.
176 | */
177 | - (id)pop_animationForKey:(NSString *)key;
178 |
179 | @end
180 |
181 | /**
182 | * This implementation of NSCopying does not do any copying of animation's state, but only configuration.
183 | * i.e. you cannot copy an animation and expect to apply it to a view and have the copied animation pick up where the original left off.
184 | * Two common uses of copying animations:
185 | * * you need to apply the same animation to multiple different views.
186 | * * you need to absolutely ensure that the the caller of your function cannot mutate the animation once it's been passed in.
187 | */
188 | @interface POPAnimation (NSCopying)
189 |
190 | @end
191 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPAnimation.mm:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import "POPAnimationExtras.h"
11 | #import "POPAnimationInternal.h"
12 |
13 | #import
14 |
15 | #import "POPAction.h"
16 | #import "POPAnimationRuntime.h"
17 | #import "POPAnimationTracerInternal.h"
18 | #import "POPAnimatorPrivate.h"
19 |
20 | using namespace POP;
21 |
22 | #pragma mark - POPAnimation
23 |
24 | @implementation POPAnimation
25 | @synthesize solver = _solver;
26 | @synthesize currentValue = _currentValue;
27 | @synthesize progressMarkers = _progressMarkers;
28 |
29 | #pragma mark - Lifecycle
30 |
31 | - (id)init
32 | {
33 | [NSException raise:NSStringFromClass([self class]) format:@"Attempting to instantiate an abstract class. Use a concrete subclass instead."];
34 | return nil;
35 | }
36 |
37 | - (id)_init
38 | {
39 | self = [super init];
40 | if (nil != self) {
41 | [self _initState];
42 | }
43 | return self;
44 | }
45 |
46 | - (void)_initState
47 | {
48 | _state = new POPAnimationState(self);
49 | }
50 |
51 | - (void)dealloc
52 | {
53 | if (_state) {
54 | delete _state;
55 | _state = NULL;
56 | };
57 | }
58 |
59 | #pragma mark - Properties
60 |
61 | - (id)delegate
62 | {
63 | return _state->delegate;
64 | }
65 |
66 | - (void)setDelegate:(id)delegate
67 | {
68 | _state->setDelegate(delegate);
69 | }
70 |
71 | - (BOOL)isPaused
72 | {
73 | return _state->paused;
74 | }
75 |
76 | - (void)setPaused:(BOOL)paused
77 | {
78 | _state->setPaused(paused ? true : false);
79 | }
80 |
81 | - (NSInteger)repeatCount
82 | {
83 | if (_state->autoreverses) {
84 | return _state->repeatCount / 2;
85 | } else {
86 | return _state->repeatCount;
87 | }
88 | }
89 |
90 | - (void)setRepeatCount:(NSInteger)repeatCount
91 | {
92 | if (repeatCount > 0) {
93 | if (repeatCount > NSIntegerMax / 2) {
94 | repeatCount = NSIntegerMax / 2;
95 | }
96 |
97 | if (_state->autoreverses) {
98 | _state->repeatCount = (repeatCount * 2);
99 | } else {
100 | _state->repeatCount = repeatCount;
101 | }
102 | }
103 | }
104 |
105 | - (BOOL)autoreverses
106 | {
107 | return _state->autoreverses;
108 | }
109 |
110 | - (void)setAutoreverses:(BOOL)autoreverses
111 | {
112 | _state->autoreverses = autoreverses;
113 | if (autoreverses) {
114 | if (_state->repeatCount == 0) {
115 | [self setRepeatCount:1];
116 | }
117 | }
118 | }
119 |
120 | FB_PROPERTY_GET(POPAnimationState, type, POPAnimationType);
121 | DEFINE_RW_PROPERTY_OBJ_COPY(POPAnimationState, animationDidStartBlock, setAnimationDidStartBlock:, POPAnimationDidStartBlock);
122 | DEFINE_RW_PROPERTY_OBJ_COPY(POPAnimationState, animationDidReachToValueBlock, setAnimationDidReachToValueBlock:, POPAnimationDidReachToValueBlock);
123 | DEFINE_RW_PROPERTY_OBJ_COPY(POPAnimationState, completionBlock, setCompletionBlock:, POPAnimationCompletionBlock);
124 | DEFINE_RW_PROPERTY_OBJ_COPY(POPAnimationState, animationDidApplyBlock, setAnimationDidApplyBlock:, POPAnimationDidApplyBlock);
125 | DEFINE_RW_PROPERTY_OBJ_COPY(POPAnimationState, name, setName:, NSString*);
126 | DEFINE_RW_PROPERTY(POPAnimationState, beginTime, setBeginTime:, CFTimeInterval);
127 | DEFINE_RW_FLAG(POPAnimationState, removedOnCompletion, removedOnCompletion, setRemovedOnCompletion:);
128 | DEFINE_RW_FLAG(POPAnimationState, repeatForever, repeatForever, setRepeatForever:);
129 |
130 | - (id)valueForUndefinedKey:(NSString *)key
131 | {
132 | return _state->dict[key];
133 | }
134 |
135 | - (void)setValue:(id)value forUndefinedKey:(NSString *)key
136 | {
137 | if (!value) {
138 | [_state->dict removeObjectForKey:key];
139 | } else {
140 | if (!_state->dict)
141 | _state->dict = [[NSMutableDictionary alloc] init];
142 | _state->dict[key] = value;
143 | }
144 | }
145 |
146 | - (POPAnimationTracer *)tracer
147 | {
148 | if (!_state->tracer) {
149 | _state->tracer = [[POPAnimationTracer alloc] initWithAnimation:self];
150 | }
151 | return _state->tracer;
152 | }
153 |
154 | - (NSString *)description
155 | {
156 | NSMutableString *s = [NSMutableString stringWithFormat:@"<%@:%p", NSStringFromClass([self class]), self];
157 | [self _appendDescription:s debug:NO];
158 | [s appendString:@">"];
159 | return s;
160 | }
161 |
162 | - (NSString *)debugDescription
163 | {
164 | NSMutableString *s = [NSMutableString stringWithFormat:@"<%@:%p", NSStringFromClass([self class]), self];
165 | [self _appendDescription:s debug:YES];
166 | [s appendString:@">"];
167 | return s;
168 | }
169 |
170 | #pragma mark - Utility
171 |
172 | POPAnimationState *POPAnimationGetState(POPAnimation *a)
173 | {
174 | return a->_state;
175 | }
176 |
177 | - (BOOL)_advance:(id)object currentTime:(CFTimeInterval)currentTime elapsedTime:(CFTimeInterval)elapsedTime
178 | {
179 | return YES;
180 | }
181 |
182 | - (void)_appendDescription:(NSMutableString *)s debug:(BOOL)debug
183 | {
184 | if (_state->name)
185 | [s appendFormat:@"; name = %@", _state->name];
186 |
187 | if (!self.removedOnCompletion)
188 | [s appendFormat:@"; removedOnCompletion = %@", POPStringFromBOOL(self.removedOnCompletion)];
189 |
190 | if (debug) {
191 | if (_state->active)
192 | [s appendFormat:@"; active = %@", POPStringFromBOOL(_state->active)];
193 |
194 | if (_state->paused)
195 | [s appendFormat:@"; paused = %@", POPStringFromBOOL(_state->paused)];
196 | }
197 |
198 | if (_state->beginTime) {
199 | [s appendFormat:@"; beginTime = %f", _state->beginTime];
200 | }
201 |
202 | for (NSString *key in _state->dict) {
203 | [s appendFormat:@"; %@ = %@", key, _state->dict[key]];
204 | }
205 | }
206 |
207 | @end
208 |
209 |
210 | #pragma mark - POPPropertyAnimation
211 |
212 | #pragma mark - POPBasicAnimation
213 |
214 | #pragma mark - POPDecayAnimation
215 |
216 | @implementation NSObject (POP)
217 |
218 | - (void)pop_addAnimation:(POPAnimation *)anim forKey:(NSString *)key
219 | {
220 | [[POPAnimator sharedAnimator] addAnimation:anim forObject:self key:key];
221 | }
222 |
223 | - (void)pop_removeAllAnimations
224 | {
225 | [[POPAnimator sharedAnimator] removeAllAnimationsForObject:self];
226 | }
227 |
228 | - (void)pop_removeAnimationForKey:(NSString *)key
229 | {
230 | [[POPAnimator sharedAnimator] removeAnimationForObject:self key:key];
231 | }
232 |
233 | - (NSArray *)pop_animationKeys
234 | {
235 | return [[POPAnimator sharedAnimator] animationKeysForObject:self];
236 | }
237 |
238 | - (id)pop_animationForKey:(NSString *)key
239 | {
240 | return [[POPAnimator sharedAnimator] animationForObject:self key:key];
241 | }
242 |
243 | @end
244 |
245 | @implementation NSProxy (POP)
246 |
247 | - (void)pop_addAnimation:(POPAnimation *)anim forKey:(NSString *)key
248 | {
249 | [[POPAnimator sharedAnimator] addAnimation:anim forObject:self key:key];
250 | }
251 |
252 | - (void)pop_removeAllAnimations
253 | {
254 | [[POPAnimator sharedAnimator] removeAllAnimationsForObject:self];
255 | }
256 |
257 | - (void)pop_removeAnimationForKey:(NSString *)key
258 | {
259 | [[POPAnimator sharedAnimator] removeAnimationForObject:self key:key];
260 | }
261 |
262 | - (NSArray *)pop_animationKeys
263 | {
264 | return [[POPAnimator sharedAnimator] animationKeysForObject:self];
265 | }
266 |
267 | - (id)pop_animationForKey:(NSString *)key
268 | {
269 | return [[POPAnimator sharedAnimator] animationForObject:self key:key];
270 | }
271 |
272 | @end
273 |
274 | @implementation POPAnimation (NSCopying)
275 |
276 | - (instancetype)copyWithZone:(NSZone *)zone
277 | {
278 | /*
279 | * Must use [self class] instead of POPAnimation so that subclasses can call this via super.
280 | * Even though POPAnimation and POPPropertyAnimation throw exceptions on init,
281 | * it's safe to call it since you can only copy objects that have been successfully created.
282 | */
283 | POPAnimation *copy = [[[self class] allocWithZone:zone] init];
284 |
285 | if (copy) {
286 | copy.name = self.name;
287 | copy.beginTime = self.beginTime;
288 | copy.delegate = self.delegate;
289 | copy.animationDidStartBlock = self.animationDidStartBlock;
290 | copy.animationDidReachToValueBlock = self.animationDidReachToValueBlock;
291 | copy.completionBlock = self.completionBlock;
292 | copy.animationDidApplyBlock = self.animationDidApplyBlock;
293 | copy.removedOnCompletion = self.removedOnCompletion;
294 |
295 | copy.autoreverses = self.autoreverses;
296 | copy.repeatCount = self.repeatCount;
297 | copy.repeatForever = self.repeatForever;
298 | }
299 |
300 | return copy;
301 | }
302 |
303 | @end
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPAnimationEvent.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | /**
13 | @abstract Enumeraton of animation event types.
14 | */
15 | typedef NS_ENUM(NSUInteger, POPAnimationEventType) {
16 | kPOPAnimationEventPropertyRead = 0,
17 | kPOPAnimationEventPropertyWrite,
18 | kPOPAnimationEventToValueUpdate,
19 | kPOPAnimationEventFromValueUpdate,
20 | kPOPAnimationEventVelocityUpdate,
21 | kPOPAnimationEventBouncinessUpdate,
22 | kPOPAnimationEventSpeedUpdate,
23 | kPOPAnimationEventFrictionUpdate,
24 | kPOPAnimationEventMassUpdate,
25 | kPOPAnimationEventTensionUpdate,
26 | kPOPAnimationEventDidStart,
27 | kPOPAnimationEventDidStop,
28 | kPOPAnimationEventDidReachToValue,
29 | kPOPAnimationEventAutoreversed
30 | };
31 |
32 | /**
33 | @abstract The base animation event class.
34 | */
35 | @interface POPAnimationEvent : NSObject
36 |
37 | /**
38 | @abstract The event type. See {@ref POPAnimationEventType} for possible values.
39 | */
40 | @property (readonly, nonatomic, assign) POPAnimationEventType type;
41 |
42 | /**
43 | @abstract The time of event.
44 | */
45 | @property (readonly, nonatomic, assign) CFTimeInterval time;
46 |
47 | /**
48 | @abstract Optional string describing the animation at time of event.
49 | */
50 | @property (readonly, nonatomic, copy) NSString *animationDescription;
51 |
52 | @end
53 |
54 | /**
55 | @abstract An animation event subclass for recording value and velocity.
56 | */
57 | @interface POPAnimationValueEvent : POPAnimationEvent
58 |
59 | /**
60 | @abstract The value recorded.
61 | */
62 | @property (readonly, nonatomic, strong) id value;
63 |
64 | /**
65 | @abstract The velocity recorded, if any.
66 | */
67 | @property (readonly, nonatomic, strong) id velocity;
68 |
69 | @end
70 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPAnimationEvent.mm:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import "POPAnimationEvent.h"
11 | #import "POPAnimationEventInternal.h"
12 |
13 | static NSString *stringFromType(POPAnimationEventType aType)
14 | {
15 | switch (aType) {
16 | case kPOPAnimationEventPropertyRead:
17 | return @"read";
18 | case kPOPAnimationEventPropertyWrite:
19 | return @"write";
20 | case kPOPAnimationEventToValueUpdate:
21 | return @"toValue";
22 | case kPOPAnimationEventFromValueUpdate:
23 | return @"fromValue";
24 | case kPOPAnimationEventVelocityUpdate:
25 | return @"velocity";
26 | case kPOPAnimationEventSpeedUpdate:
27 | return @"speed";
28 | case kPOPAnimationEventBouncinessUpdate:
29 | return @"bounciness";
30 | case kPOPAnimationEventFrictionUpdate:
31 | return @"friction";
32 | case kPOPAnimationEventMassUpdate:
33 | return @"mass";
34 | case kPOPAnimationEventTensionUpdate:
35 | return @"tension";
36 | case kPOPAnimationEventDidStart:
37 | return @"didStart";
38 | case kPOPAnimationEventDidStop:
39 | return @"didStop";
40 | case kPOPAnimationEventDidReachToValue:
41 | return @"didReachToValue";
42 | case kPOPAnimationEventAutoreversed:
43 | return @"autoreversed";
44 | default:
45 | return nil;
46 | }
47 | }
48 |
49 | @implementation POPAnimationEvent
50 | @synthesize type = _type;
51 | @synthesize time = _time;
52 | @synthesize animationDescription = _animationDescription;
53 |
54 | - (instancetype)initWithType:(POPAnimationEventType)aType time:(CFTimeInterval)aTime
55 | {
56 | self = [super init];
57 | if (nil != self) {
58 | _type = aType;
59 | _time = aTime;
60 | }
61 | return self;
62 | }
63 |
64 | - (NSString *)description
65 | {
66 | NSMutableString *s = [NSMutableString stringWithFormat:@""];
69 | return s;
70 | }
71 |
72 | // subclass override
73 | - (void)_appendDescription:(NSMutableString *)s
74 | {
75 | if (0 != _animationDescription.length) {
76 | [s appendFormat:@"; animation = %@", _animationDescription];
77 | }
78 | }
79 |
80 | @end
81 |
82 | @implementation POPAnimationValueEvent
83 | @synthesize value = _value;
84 | @synthesize velocity = _velocity;
85 |
86 | - (instancetype)initWithType:(POPAnimationEventType)aType time:(CFTimeInterval)aTime value:(id)aValue
87 | {
88 | self = [self initWithType:aType time:aTime];
89 | if (nil != self) {
90 | _value = aValue;
91 | }
92 | return self;
93 | }
94 |
95 | - (void)_appendDescription:(NSMutableString *)s
96 | {
97 | [super _appendDescription:s];
98 |
99 | if (nil != _value) {
100 | [s appendFormat:@"; value = %@", _value];
101 | }
102 |
103 | if (nil != _velocity) {
104 | [s appendFormat:@"; velocity = %@", _velocity];
105 | }
106 | }
107 |
108 | @end
109 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPAnimationEventInternal.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | #import "POPAnimationEvent.h"
13 |
14 | @interface POPAnimationEvent ()
15 |
16 | /**
17 | @abstract Default initializer.
18 | */
19 | - (instancetype)initWithType:(POPAnimationEventType)type time:(CFTimeInterval)time;
20 |
21 | /**
22 | @abstract Readwrite redefinition of public property.
23 | */
24 | @property (readwrite, nonatomic, copy) NSString *animationDescription;
25 |
26 | @end
27 |
28 | @interface POPAnimationValueEvent ()
29 |
30 | /**
31 | @abstract Default initializer.
32 | */
33 | - (instancetype)initWithType:(POPAnimationEventType)type time:(CFTimeInterval)time value:(id)value;
34 |
35 | /**
36 | @abstract Readwrite redefinition of public property.
37 | */
38 | @property (readwrite, nonatomic, strong) id velocity;
39 |
40 | @end
41 |
42 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPAnimationExtras.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | //#import
13 | #import "POPDefines.h"
14 | //#import
15 | #import "POPSpringAnimation.h"
16 |
17 | /**
18 | @abstract The current drag coefficient.
19 | @discussion A value greater than 1.0 indicates Simulator slow-motion animations are enabled. Defaults to 1.0.
20 | */
21 | extern CGFloat POPAnimationDragCoefficient();
22 |
23 | @interface CAAnimation (POPAnimationExtras)
24 |
25 | /**
26 | @abstract Apply the current drag coefficient to animation speed.
27 | @discussion Convenience utility to respect Simulator slow-motion animation settings.
28 | */
29 | - (void)pop_applyDragCoefficient;
30 |
31 | @end
32 |
33 | @interface POPSpringAnimation (POPAnimationExtras)
34 |
35 | /**
36 | @abstract Converts from spring bounciness and speed to tension, friction and mass dynamics values.
37 | */
38 | + (void)convertBounciness:(CGFloat)bounciness speed:(CGFloat)speed toTension:(CGFloat *)outTension friction:(CGFloat *)outFriction mass:(CGFloat *)outMass;
39 |
40 | /**
41 | @abstract Converts from dynamics tension, friction and mass to spring bounciness and speed values.
42 | */
43 | + (void)convertTension:(CGFloat)tension friction:(CGFloat)friction toBounciness:(CGFloat *)outBounciness speed:(CGFloat *)outSpeed;
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPAnimationExtras.mm:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import "POPAnimationExtras.h"
11 | #import "POPAnimationPrivate.h"
12 |
13 | #if TARGET_OS_IPHONE
14 | #import
15 | #endif
16 |
17 | #if TARGET_IPHONE_SIMULATOR
18 | UIKIT_EXTERN float UIAnimationDragCoefficient(); // UIKit private drag coefficient, use judiciously
19 | #endif
20 |
21 | #import "POPMath.h"
22 |
23 | CGFloat POPAnimationDragCoefficient()
24 | {
25 | #if TARGET_IPHONE_SIMULATOR
26 | return UIAnimationDragCoefficient();
27 | #else
28 | return 1.0;
29 | #endif
30 | }
31 |
32 | @implementation CAAnimation (POPAnimationExtras)
33 |
34 | - (void)pop_applyDragCoefficient
35 | {
36 | CGFloat k = POPAnimationDragCoefficient();
37 | if (k != 0 && k != 1)
38 | self.speed = 1 / k;
39 | }
40 |
41 | @end
42 |
43 | @implementation POPSpringAnimation (POPAnimationExtras)
44 |
45 | static const CGFloat POPBouncy3NormalizationRange = 20.0;
46 | static const CGFloat POPBouncy3NormalizationScale = 1.7;
47 | static const CGFloat POPBouncy3BouncinessNormalizedMin = 0.0;
48 | static const CGFloat POPBouncy3BouncinessNormalizedMax = 0.8;
49 | static const CGFloat POPBouncy3SpeedNormalizedMin = 0.5;
50 | static const CGFloat POPBouncy3SpeedNormalizedMax = 200;
51 | static const CGFloat POPBouncy3FrictionInterpolationMax = 0.01;
52 |
53 | + (void)convertBounciness:(CGFloat)bounciness speed:(CGFloat)speed toTension:(CGFloat *)outTension friction:(CGFloat *)outFriction mass:(CGFloat *)outMass
54 | {
55 | double b = POPNormalize(bounciness / POPBouncy3NormalizationScale, 0, POPBouncy3NormalizationRange);
56 | b = POPProjectNormal(b, POPBouncy3BouncinessNormalizedMin, POPBouncy3BouncinessNormalizedMax);
57 |
58 | double s = POPNormalize(speed / POPBouncy3NormalizationScale, 0, POPBouncy3NormalizationRange);
59 |
60 | CGFloat tension = POPProjectNormal(s, POPBouncy3SpeedNormalizedMin, POPBouncy3SpeedNormalizedMax);
61 | CGFloat friction = POPQuadraticOutInterpolation(b, POPBouncy3NoBounce(tension), POPBouncy3FrictionInterpolationMax);
62 |
63 | tension = POP_ANIMATION_TENSION_FOR_QC_TENSION(tension);
64 | friction = POP_ANIMATION_FRICTION_FOR_QC_FRICTION(friction);
65 |
66 | if (outTension) {
67 | *outTension = tension;
68 | }
69 |
70 | if (outFriction) {
71 | *outFriction = friction;
72 | }
73 |
74 | if (outMass) {
75 | *outMass = 1.0;
76 | }
77 | }
78 |
79 | + (void)convertTension:(CGFloat)tension friction:(CGFloat)friction toBounciness:(CGFloat *)outBounciness speed:(CGFloat *)outSpeed
80 | {
81 | // Convert to QC values, in which our calculations are done.
82 | CGFloat qcFriction = QC_FRICTION_FOR_POP_ANIMATION_FRICTION(friction);
83 | CGFloat qcTension = QC_TENSION_FOR_POP_ANIMATION_TENSION(tension);
84 |
85 | // Friction is a function of bounciness and tension, according to the following:
86 | // friction = POPQuadraticOutInterpolation(b, POPBouncy3NoBounce(tension), POPBouncy3FrictionInterpolationMax);
87 | // Solve for bounciness, given a tension and friction.
88 |
89 | CGFloat nobounceTension = POPBouncy3NoBounce(qcTension);
90 | CGFloat bounciness1, bounciness2;
91 |
92 | POPQuadraticSolve((nobounceTension - POPBouncy3FrictionInterpolationMax), // a
93 | 2 * (POPBouncy3FrictionInterpolationMax - nobounceTension), // b
94 | (nobounceTension - qcFriction), // c
95 | bounciness1, // x1
96 | bounciness2); // x2
97 |
98 |
99 | // Choose the quadratic solution within the normalized bounciness range
100 | CGFloat projectedNormalizedBounciness = (bounciness2 < POPBouncy3BouncinessNormalizedMax) ? bounciness2 : bounciness1;
101 | CGFloat projectedNormalizedSpeed = qcTension;
102 |
103 | // Reverse projection + normalization
104 | CGFloat bounciness = ((POPBouncy3NormalizationRange * POPBouncy3NormalizationScale) / (POPBouncy3BouncinessNormalizedMax - POPBouncy3BouncinessNormalizedMin)) * (projectedNormalizedBounciness - POPBouncy3BouncinessNormalizedMin);
105 | CGFloat speed = ((POPBouncy3NormalizationRange * POPBouncy3NormalizationScale) / (POPBouncy3SpeedNormalizedMax - POPBouncy3SpeedNormalizedMin)) * (projectedNormalizedSpeed - POPBouncy3SpeedNormalizedMin);
106 |
107 | // Write back results
108 | if (outBounciness) {
109 | *outBounciness = bounciness;
110 | }
111 |
112 | if (outSpeed) {
113 | *outSpeed = speed;
114 | }
115 | }
116 |
117 | @end
118 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPAnimationPrivate.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | //#import
11 | #import "POPAnimation.h"
12 |
13 | #define POP_ANIMATION_FRICTION_FOR_QC_FRICTION(qcFriction) (25.0 + (((qcFriction - 8.0) / 2.0) * (25.0 - 19.0)))
14 | #define POP_ANIMATION_TENSION_FOR_QC_TENSION(qcTension) (194.0 + (((qcTension - 30.0) / 50.0) * (375.0 - 194.0)))
15 |
16 | #define QC_FRICTION_FOR_POP_ANIMATION_FRICTION(fbFriction) (8.0 + 2.0 * ((fbFriction - 25.0)/(25.0 - 19.0)))
17 | #define QC_TENSION_FOR_POP_ANIMATION_TENSION(fbTension) (30.0 + 50.0 * ((fbTension - 194.0)/(375.0 - 194.0)))
18 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPAnimationRuntime.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | #import
13 |
14 | #import "POPVector.h"
15 |
16 | enum POPValueType
17 | {
18 | kPOPValueUnknown = 0,
19 | kPOPValueInteger,
20 | kPOPValueFloat,
21 | kPOPValuePoint,
22 | kPOPValueSize,
23 | kPOPValueRect,
24 | kPOPValueEdgeInsets,
25 | kPOPValueAffineTransform,
26 | kPOPValueTransform,
27 | kPOPValueRange,
28 | kPOPValueColor,
29 | kPOPValueSCNVector3,
30 | kPOPValueSCNVector4,
31 | };
32 |
33 | using namespace POP;
34 |
35 | /**
36 | Returns value type based on objc type description, given list of supported value types and length.
37 | */
38 | extern POPValueType POPSelectValueType(const char *objctype, const POPValueType *types, size_t length);
39 |
40 | /**
41 | Returns value type based on objc object, given a list of supported value types and length.
42 | */
43 | extern POPValueType POPSelectValueType(id obj, const POPValueType *types, size_t length);
44 |
45 | /**
46 | Array of all value types.
47 | */
48 | extern const POPValueType kPOPAnimatableAllTypes[12];
49 |
50 | /**
51 | Array of all value types supported for animation.
52 | */
53 | extern const POPValueType kPOPAnimatableSupportTypes[10];
54 |
55 | /**
56 | Returns a string description of a value type.
57 | */
58 | extern NSString *POPValueTypeToString(POPValueType t);
59 |
60 | /**
61 | Returns a mutable dictionary of weak pointer keys to weak pointer values.
62 | */
63 | extern CFMutableDictionaryRef POPDictionaryCreateMutableWeakPointerToWeakPointer(NSUInteger capacity) CF_RETURNS_RETAINED;
64 |
65 | /**
66 | Returns a mutable dictionary of weak pointer keys to weak pointer values.
67 | */
68 | extern CFMutableDictionaryRef POPDictionaryCreateMutableWeakPointerToStrongObject(NSUInteger capacity) CF_RETURNS_RETAINED;
69 |
70 | /**
71 | Box a vector.
72 | */
73 | extern id POPBox(VectorConstRef vec, POPValueType type, bool force = false);
74 |
75 | /**
76 | Unbox a vector.
77 | */
78 | extern VectorRef POPUnbox(id value, POPValueType &type, NSUInteger &count, bool validate);
79 |
80 | /**
81 | Read/write block typedefs for convenience.
82 | */
83 | typedef void(^pop_animatable_read_block)(id obj, CGFloat *value);
84 | typedef void(^pop_animatable_write_block)(id obj, const CGFloat *value);
85 |
86 | /**
87 | Read object value and return a Vector4r.
88 | */
89 | NS_INLINE Vector4r read_values(pop_animatable_read_block read, id obj, size_t count)
90 | {
91 | Vector4r vec = Vector4r::Zero();
92 | if (0 == count)
93 | return vec;
94 |
95 | read(obj, vec.data());
96 |
97 | return vec;
98 | }
99 |
100 | NS_INLINE NSString *POPStringFromBOOL(BOOL value)
101 | {
102 | return value ? @"YES" : @"NO";
103 | }
104 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPAnimationTracer.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | //#import
13 | #import "POPAnimationEvent.h"
14 |
15 | @class POPAnimation;
16 |
17 | /**
18 | @abstract Tracer of animation events to facilitate unit testing & debugging.
19 | */
20 | @interface POPAnimationTracer : NSObject
21 |
22 | /**
23 | @abstract Start recording events.
24 | */
25 | - (void)start;
26 |
27 | /**
28 | @abstract Stop recording events.
29 | */
30 | - (void)stop;
31 |
32 | /**
33 | @abstract Resets any recoded events. Continues recording events if already started.
34 | */
35 | - (void)reset;
36 |
37 | /**
38 | @abstract Property representing all recorded events.
39 | @discussion Events are returned in order of occurrence.
40 | */
41 | @property (nonatomic, assign, readonly) NSArray *allEvents;
42 |
43 | /**
44 | @abstract Property representing all recorded write events for convenience.
45 | @discussion Events are returned in order of occurrence.
46 | */
47 | @property (nonatomic, assign, readonly) NSArray *writeEvents;
48 |
49 | /**
50 | @abstract Queries for events of specified type.
51 | @param type The type of event to return.
52 | @returns An array of events of specified type in order of occurrence.
53 | */
54 | - (NSArray *)eventsWithType:(POPAnimationEventType)type;
55 |
56 | /**
57 | @abstract Property indicating whether tracer should automatically log events and reset collection on animation completion.
58 | */
59 | @property (nonatomic, assign) BOOL shouldLogAndResetOnCompletion;
60 |
61 | @end
62 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPAnimationTracer.mm:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import "POPAnimationTracer.h"
11 |
12 | #import
13 |
14 | #import "POPAnimationEventInternal.h"
15 | #import "POPAnimationInternal.h"
16 | #import "POPSpringAnimation.h"
17 |
18 | @implementation POPAnimationTracer
19 | {
20 | __weak POPAnimation *_animation;
21 | POPAnimationState *_animationState;
22 | NSMutableArray *_events;
23 | BOOL _animationHasVelocity;
24 | }
25 | @synthesize shouldLogAndResetOnCompletion = _shouldLogAndResetOnCompletion;
26 |
27 | static POPAnimationEvent *create_event(POPAnimationTracer *self, POPAnimationEventType type, id value = nil, bool recordAnimation = false)
28 | {
29 | bool useLocalTime = 0 != self->_animationState->startTime;
30 | CFTimeInterval time = useLocalTime
31 | ? self->_animationState->lastTime - self->_animationState->startTime
32 | : self->_animationState->lastTime;
33 |
34 | POPAnimationEvent *event;
35 | __strong POPAnimation* animation = self->_animation;
36 |
37 | if (!value) {
38 | event = [[POPAnimationEvent alloc] initWithType:type time:time];
39 | } else {
40 | event = [[POPAnimationValueEvent alloc] initWithType:type time:time value:value];
41 | if (self->_animationHasVelocity) {
42 | [(POPAnimationValueEvent *)event setVelocity:[(POPSpringAnimation *)animation velocity]];
43 | }
44 | }
45 |
46 | if (recordAnimation) {
47 | event.animationDescription = [animation description];
48 | }
49 |
50 | return event;
51 | }
52 |
53 | - (id)initWithAnimation:(POPAnimation *)anAnim
54 | {
55 | self = [super init];
56 | if (nil != self) {
57 | _animation = anAnim;
58 | _animationState = POPAnimationGetState(anAnim);
59 | _events = [[NSMutableArray alloc] initWithCapacity:50];
60 | _animationHasVelocity = [anAnim respondsToSelector:@selector(velocity)];
61 | }
62 | return self;
63 | }
64 |
65 | - (void)readPropertyValue:(id)aValue
66 | {
67 | POPAnimationEvent *event = create_event(self, kPOPAnimationEventPropertyRead, aValue);
68 | [_events addObject:event];
69 | }
70 |
71 | - (void)writePropertyValue:(id)aValue
72 | {
73 | POPAnimationEvent *event = create_event(self, kPOPAnimationEventPropertyWrite, aValue);
74 | [_events addObject:event];
75 | }
76 |
77 | - (void)updateToValue:(id)aValue
78 | {
79 | POPAnimationEvent *event = create_event(self, kPOPAnimationEventToValueUpdate, aValue);
80 | [_events addObject:event];
81 | }
82 |
83 | - (void)updateFromValue:(id)aValue
84 | {
85 | POPAnimationEvent *event = create_event(self, kPOPAnimationEventFromValueUpdate, aValue);
86 | [_events addObject:event];
87 | }
88 |
89 | - (void)updateVelocity:(id)aValue
90 | {
91 | POPAnimationEvent *event = create_event(self, kPOPAnimationEventVelocityUpdate, aValue);
92 | [_events addObject:event];
93 | }
94 |
95 | - (void)updateSpeed:(float)aFloat
96 | {
97 | POPAnimationEvent *event = create_event(self, kPOPAnimationEventSpeedUpdate, @(aFloat));
98 | [_events addObject:event];
99 | }
100 |
101 | - (void)updateBounciness:(float)aFloat
102 | {
103 | POPAnimationEvent *event = create_event(self, kPOPAnimationEventBouncinessUpdate, @(aFloat));
104 | [_events addObject:event];
105 | }
106 |
107 | - (void)updateFriction:(float)aFloat
108 | {
109 | POPAnimationEvent *event = create_event(self, kPOPAnimationEventFrictionUpdate, @(aFloat));
110 | [_events addObject:event];
111 | }
112 |
113 | - (void)updateMass:(float)aFloat
114 | {
115 | POPAnimationEvent *event = create_event(self, kPOPAnimationEventMassUpdate, @(aFloat));
116 | [_events addObject:event];
117 | }
118 |
119 | - (void)updateTension:(float)aFloat
120 | {
121 | POPAnimationEvent *event = create_event(self, kPOPAnimationEventTensionUpdate, @(aFloat));
122 | [_events addObject:event];
123 | }
124 |
125 | - (void)didStart
126 | {
127 | POPAnimationEvent *event = create_event(self, kPOPAnimationEventDidStart, nil, true);
128 | [_events addObject:event];
129 | }
130 |
131 | - (void)didStop:(BOOL)finished
132 | {
133 | POPAnimationEvent *event = create_event(self, kPOPAnimationEventDidStop, @(finished), true);
134 | [_events addObject:event];
135 |
136 | if (_shouldLogAndResetOnCompletion) {
137 | NSLog(@"events:%@", self.allEvents);
138 | [self reset];
139 | }
140 | }
141 |
142 | - (void)didReachToValue:(id)aValue
143 | {
144 | POPAnimationEvent *event = create_event(self, kPOPAnimationEventDidReachToValue, aValue);
145 | [_events addObject:event];
146 | }
147 |
148 | - (void)autoreversed
149 | {
150 | POPAnimationEvent *event = create_event(self, kPOPAnimationEventAutoreversed);
151 | [_events addObject:event];
152 | }
153 |
154 | - (void)start
155 | {
156 | POPAnimationState *s = POPAnimationGetState(_animation);
157 | s->tracing = true;
158 | }
159 |
160 | - (void)stop
161 | {
162 | POPAnimationState *s = POPAnimationGetState(_animation);
163 | s->tracing = false;
164 | }
165 |
166 | - (void)reset
167 | {
168 | [_events removeAllObjects];
169 | }
170 |
171 | - (NSArray *)allEvents
172 | {
173 | return [_events copy];
174 | }
175 |
176 | - (NSArray *)writeEvents
177 | {
178 | return [self eventsWithType:kPOPAnimationEventPropertyWrite];
179 | }
180 |
181 | - (NSArray *)eventsWithType:(POPAnimationEventType)aType
182 | {
183 | NSMutableArray *array = [NSMutableArray array];
184 | for (POPAnimationEvent *event in _events) {
185 | if (aType == event.type) {
186 | [array addObject:event];
187 | }
188 | }
189 | return array;
190 | }
191 |
192 | @end
193 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPAnimationTracerInternal.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | //#import
13 | #import "POPAnimationTracer.h"
14 |
15 | @interface POPAnimationTracer (Internal)
16 |
17 | /**
18 | @abstract Designated initializer. Pass the animation being traced.
19 | */
20 | - (instancetype)initWithAnimation:(POPAnimation *)anAnim;
21 |
22 | /**
23 | @abstract Records read value.
24 | */
25 | - (void)readPropertyValue:(id)aValue;
26 |
27 | /**
28 | @abstract Records write value.
29 | */
30 | - (void)writePropertyValue:(id)aValue;
31 |
32 | /**
33 | Records to value update.
34 | */
35 | - (void)updateToValue:(id)aValue;
36 |
37 | /**
38 | @abstract Records from value update.
39 | */
40 | - (void)updateFromValue:(id)aValue;
41 |
42 | /**
43 | @abstract Records from value update.
44 | */
45 | - (void)updateVelocity:(id)aValue;
46 |
47 | /**
48 | @abstract Records bounciness update.
49 | */
50 | - (void)updateBounciness:(float)aFloat;
51 |
52 | /**
53 | @abstract Records speed update.
54 | */
55 | - (void)updateSpeed:(float)aFloat;
56 |
57 | /**
58 | @abstract Records friction update.
59 | */
60 | - (void)updateFriction:(float)aFloat;
61 |
62 | /**
63 | @abstract Records mass update.
64 | */
65 | - (void)updateMass:(float)aFloat;
66 |
67 | /**
68 | @abstract Records tension update.
69 | */
70 | - (void)updateTension:(float)aFloat;
71 |
72 | /**
73 | @abstract Records did add.
74 | */
75 | - (void)didAdd;
76 |
77 | /**
78 | @abstract Records did start.
79 | */
80 | - (void)didStart;
81 |
82 | /**
83 | @abstract Records did stop.
84 | */
85 | - (void)didStop:(BOOL)finished;
86 |
87 | /**
88 | @abstract Records did reach to value.
89 | */
90 | - (void)didReachToValue:(id)aValue;
91 |
92 | /**
93 | @abstract Records when an autoreverse animation takes place.
94 | */
95 | - (void)autoreversed;
96 |
97 | @end
98 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPAnimator.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | @protocol POPAnimatorDelegate;
13 |
14 | /**
15 | @abstract The animator class renders animations.
16 | */
17 | @interface POPAnimator : NSObject
18 |
19 | /**
20 | @abstract The shared animator instance.
21 | @discussion Consumers should generally use the shared instance in lieu of creating new instances.
22 | */
23 | + (instancetype)sharedAnimator;
24 |
25 | #if !TARGET_OS_IPHONE
26 | /**
27 | @abstract Allows to select display to bind. Returns nil if failed to create the display link.
28 | */
29 | - (instancetype)initWithDisplayID:(CGDirectDisplayID)displayID;
30 | #endif
31 |
32 | /**
33 | @abstract The optional animator delegate.
34 | */
35 | @property (weak, nonatomic) id delegate;
36 |
37 | /**
38 | @abstract Retrieves the nominal refresh period of a display link. Returns zero if unavailable.
39 | */
40 | @property (readonly, nonatomic) CFTimeInterval refreshPeriod;
41 |
42 | @end
43 |
44 | /**
45 | @abstract The animator delegate.
46 | */
47 | @protocol POPAnimatorDelegate
48 |
49 | /**
50 | @abstract Called on each frame before animation application.
51 | */
52 | - (void)animatorWillAnimate:(POPAnimator *)animator;
53 |
54 | /**
55 | @abstract Called on each frame after animation application.
56 | */
57 | - (void)animatorDidAnimate:(POPAnimator *)animator;
58 |
59 | @end
60 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPAnimatorPrivate.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | //#import
11 | #import "POPAnimator.h"
12 |
13 | @class POPAnimation;
14 |
15 | @protocol POPAnimatorObserving
16 | @required
17 |
18 | /**
19 | @abstract Called on each observer after animator has advanced. Core Animation actions are disabled by default.
20 | */
21 | - (void)animatorDidAnimate:(POPAnimator *)animator;
22 |
23 | @end
24 |
25 | @interface POPAnimator ()
26 |
27 | #if !TARGET_OS_IPHONE
28 | /**
29 | Determines whether or not to use a high priority background thread for animation updates. Using a background thread can result in faster, more responsive updates, but may be less compatible. Defaults to YES.
30 | */
31 | + (BOOL)disableBackgroundThread;
32 | + (void)setDisableBackgroundThread:(BOOL)flag;
33 |
34 | /**
35 | Determines the frequency (Hz) of the timer used when no display is available. Defaults to 60Hz.
36 | */
37 | + (uint64_t)displayTimerFrequency;
38 | + (void)setDisplayTimerFrequency:(uint64_t)frequency;
39 | #endif
40 |
41 | /**
42 | Used for externally driven animator instances.
43 | */
44 | @property (assign, nonatomic) BOOL disableDisplayLink;
45 |
46 | /**
47 | Time used when starting animations. Defaults to 0 meaning current media time is used. Exposed for unit testing.
48 | */
49 | @property (assign, nonatomic) CFTimeInterval beginTime;
50 |
51 | /**
52 | Exposed for unit testing.
53 | */
54 | - (void)renderTime:(CFTimeInterval)time;
55 |
56 | /**
57 | Funnel methods for category additions.
58 | */
59 | - (void)addAnimation:(POPAnimation *)anim forObject:(id)obj key:(NSString *)key;
60 | - (void)removeAllAnimationsForObject:(id)obj;
61 | - (void)removeAnimationForObject:(id)obj key:(NSString *)key;
62 | - (NSArray *)animationKeysForObject:(id)obj;
63 | - (POPAnimation *)animationForObject:(id)obj key:(NSString *)key;
64 |
65 | /**
66 | @abstract Add an animator observer. Observer will be notified of each subsequent animator advance until removal.
67 | */
68 | - (void)addObserver:(id)observer;
69 |
70 | /**
71 | @abstract Remove an animator observer.
72 | */
73 | - (void)removeObserver:(id)observer;
74 |
75 | @end
76 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPBasicAnimation.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | //#import
11 | #import "POPPropertyAnimation.h"
12 |
13 | /**
14 | @abstract A concrete basic animation class.
15 | @discussion Animation is achieved through interpolation.
16 | */
17 | @interface POPBasicAnimation : POPPropertyAnimation
18 |
19 | /**
20 | @abstract The designated initializer.
21 | @returns An instance of a basic animation.
22 | */
23 | + (instancetype)animation;
24 |
25 | /**
26 | @abstract Convenience initializer that returns an animation with animatable property of name.
27 | @param name The name of the animatable property.
28 | @returns An instance of a basic animation configured with specified animatable property.
29 | */
30 | + (instancetype)animationWithPropertyNamed:(NSString *)name;
31 |
32 | /**
33 | @abstract Convenience constructor.
34 | @returns Returns a basic animation with kCAMediaTimingFunctionDefault timing function.
35 | */
36 | + (instancetype)defaultAnimation;
37 |
38 | /**
39 | @abstract Convenience constructor.
40 | @returns Returns a basic animation with kCAMediaTimingFunctionLinear timing function.
41 | */
42 | + (instancetype)linearAnimation;
43 |
44 | /**
45 | @abstract Convenience constructor.
46 | @returns Returns a basic animation with kCAMediaTimingFunctionEaseIn timing function.
47 | */
48 | + (instancetype)easeInAnimation;
49 |
50 | /**
51 | @abstract Convenience constructor.
52 | @returns Returns a basic animation with kCAMediaTimingFunctionEaseOut timing function.
53 | */
54 | + (instancetype)easeOutAnimation;
55 |
56 | /**
57 | @abstract Convenience constructor.
58 | @returns Returns a basic animation with kCAMediaTimingFunctionEaseInEaseOut timing function.
59 | */
60 | + (instancetype)easeInEaseOutAnimation;
61 |
62 | /**
63 | @abstract The duration in seconds. Defaults to 0.4.
64 | */
65 | @property (assign, nonatomic) CFTimeInterval duration;
66 |
67 | /**
68 | @abstract A timing function defining the pacing of the animation. Defaults to nil indicating pacing according to kCAMediaTimingFunctionDefault.
69 | */
70 | @property (strong, nonatomic) CAMediaTimingFunction *timingFunction;
71 |
72 | @end
73 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPBasicAnimation.mm:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import "POPBasicAnimationInternal.h"
11 |
12 | @implementation POPBasicAnimation
13 |
14 | #undef __state
15 | #define __state ((POPBasicAnimationState *)_state)
16 |
17 | #pragma mark - Lifecycle
18 |
19 | + (instancetype)animation
20 | {
21 | return [[self alloc] init];
22 | }
23 |
24 | + (instancetype)animationWithPropertyNamed:(NSString *)aName
25 | {
26 | POPBasicAnimation *anim = [self animation];
27 | anim.property = [POPAnimatableProperty propertyWithName:aName];
28 | return anim;
29 | }
30 |
31 | - (void)_initState
32 | {
33 | _state = new POPBasicAnimationState(self);
34 | }
35 |
36 | + (instancetype)linearAnimation
37 | {
38 | POPBasicAnimation *anim = [self animation];
39 | anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
40 | return anim;
41 | }
42 |
43 | + (instancetype)easeInAnimation
44 | {
45 | POPBasicAnimation *anim = [self animation];
46 | anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
47 | return anim;
48 | }
49 |
50 | + (instancetype)easeOutAnimation
51 | {
52 | POPBasicAnimation *anim = [self animation];
53 | anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
54 | return anim;
55 | }
56 |
57 | + (instancetype)easeInEaseOutAnimation
58 | {
59 | POPBasicAnimation *anim = [self animation];
60 | anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
61 | return anim;
62 | }
63 |
64 | + (instancetype)defaultAnimation
65 | {
66 | POPBasicAnimation *anim = [self animation];
67 | anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];
68 | return anim;
69 | }
70 |
71 | - (id)init
72 | {
73 | return [self _init];
74 | }
75 |
76 | #pragma mark - Properties
77 |
78 | DEFINE_RW_PROPERTY(POPBasicAnimationState, duration, setDuration:, CFTimeInterval);
79 | DEFINE_RW_PROPERTY_OBJ(POPBasicAnimationState, timingFunction, setTimingFunction:, CAMediaTimingFunction*, __state->updatedTimingFunction(););
80 |
81 | #pragma mark - Utility
82 |
83 | - (void)_appendDescription:(NSMutableString *)s debug:(BOOL)debug
84 | {
85 | [super _appendDescription:s debug:debug];
86 | if (__state->duration)
87 | [s appendFormat:@"; duration = %f", __state->duration];
88 | }
89 |
90 | @end
91 |
92 | @implementation POPBasicAnimation (NSCopying)
93 |
94 | - (instancetype)copyWithZone:(NSZone *)zone {
95 |
96 | POPBasicAnimation *copy = [super copyWithZone:zone];
97 |
98 | if (copy) {
99 | copy.duration = self.duration;
100 | copy.timingFunction = self.timingFunction; // not a 'copy', but timing functions are publicly immutable.
101 | }
102 |
103 | return copy;
104 | }
105 |
106 | @end
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPBasicAnimationInternal.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import "POPBasicAnimation.h"
11 |
12 | #import "POPPropertyAnimationInternal.h"
13 |
14 | // default animation duration
15 | static CGFloat const kPOPAnimationDurationDefault = 0.4;
16 |
17 | // progress threshold for computing done
18 | static CGFloat const kPOPProgressThreshold = 1e-6;
19 |
20 | static void interpolate(POPValueType valueType, NSUInteger count, const CGFloat *fromVec, const CGFloat *toVec, CGFloat *outVec, CGFloat p)
21 | {
22 | switch (valueType) {
23 | case kPOPValueInteger:
24 | case kPOPValueFloat:
25 | case kPOPValuePoint:
26 | case kPOPValueSize:
27 | case kPOPValueRect:
28 | case kPOPValueEdgeInsets:
29 | case kPOPValueColor:
30 | POPInterpolateVector(count, outVec, fromVec, toVec, p);
31 | break;
32 | default:
33 | NSCAssert(false, @"unhandled type %d", valueType);
34 | break;
35 | }
36 | }
37 |
38 | struct _POPBasicAnimationState : _POPPropertyAnimationState
39 | {
40 | CAMediaTimingFunction *timingFunction;
41 | double timingControlPoints[4];
42 | CFTimeInterval duration;
43 | CFTimeInterval timeProgress;
44 |
45 | _POPBasicAnimationState(id __unsafe_unretained anim) : _POPPropertyAnimationState(anim),
46 | timingFunction(nil),
47 | timingControlPoints{0.},
48 | duration(kPOPAnimationDurationDefault),
49 | timeProgress(0.)
50 | {
51 | type = kPOPAnimationBasic;
52 | }
53 |
54 | bool isDone() {
55 | if (_POPPropertyAnimationState::isDone()) {
56 | return true;
57 | }
58 | return timeProgress + kPOPProgressThreshold >= 1.;
59 | }
60 |
61 | void updatedTimingFunction()
62 | {
63 | float vec[4] = {0.};
64 | [timingFunction getControlPointAtIndex:1 values:&vec[0]];
65 | [timingFunction getControlPointAtIndex:2 values:&vec[2]];
66 | for (NSUInteger idx = 0; idx < POP_ARRAY_COUNT(vec); idx++) {
67 | timingControlPoints[idx] = vec[idx];
68 | }
69 | }
70 |
71 | bool advance(CFTimeInterval time, CFTimeInterval dt, id obj) {
72 | // default timing function
73 | if (!timingFunction) {
74 | ((POPBasicAnimation *)self).timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];
75 | }
76 |
77 | // solve for normalized time, aka progress [0, 1]
78 | CGFloat p = 1.0f;
79 | if (duration > 0.0f) {
80 | // cap local time to duration
81 | CFTimeInterval t = MIN(time - startTime, duration) / duration;
82 | p = POPTimingFunctionSolve(timingControlPoints, t, SOLVE_EPS(duration));
83 | timeProgress = t;
84 | } else {
85 | timeProgress = 1.;
86 | }
87 |
88 | // interpolate and advance
89 | interpolate(valueType, valueCount, fromVec->data(), toVec->data(), currentVec->data(), p);
90 | progress = p;
91 | clampCurrentValue();
92 |
93 | return true;
94 | }
95 | };
96 |
97 | typedef struct _POPBasicAnimationState POPBasicAnimationState;
98 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPCGUtils.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | #if TARGET_OS_IPHONE
13 | #import
14 | #else
15 | #import
16 | #endif
17 |
18 | #import "POPDefines.h"
19 |
20 | #if SCENEKIT_SDK_AVAILABLE
21 | #import
22 | #endif
23 |
24 | POP_EXTERN_C_BEGIN
25 |
26 | NS_INLINE CGPoint values_to_point(const CGFloat values[])
27 | {
28 | return CGPointMake(values[0], values[1]);
29 | }
30 |
31 | NS_INLINE CGSize values_to_size(const CGFloat values[])
32 | {
33 | return CGSizeMake(values[0], values[1]);
34 | }
35 |
36 | NS_INLINE CGRect values_to_rect(const CGFloat values[])
37 | {
38 | return CGRectMake(values[0], values[1], values[2], values[3]);
39 | }
40 |
41 | #if SCENEKIT_SDK_AVAILABLE
42 | NS_INLINE SCNVector3 values_to_vec3(const CGFloat values[])
43 | {
44 | return SCNVector3Make(values[0], values[1], values[2]);
45 | }
46 |
47 | NS_INLINE SCNVector4 values_to_vec4(const CGFloat values[])
48 | {
49 | return SCNVector4Make(values[0], values[1], values[2], values[3]);
50 | }
51 | #endif
52 |
53 | #if TARGET_OS_IPHONE
54 |
55 | NS_INLINE UIEdgeInsets values_to_edge_insets(const CGFloat values[])
56 | {
57 | return UIEdgeInsetsMake(values[0], values[1], values[2], values[3]);
58 | }
59 |
60 | #endif
61 |
62 | NS_INLINE void values_from_point(CGFloat values[], CGPoint p)
63 | {
64 | values[0] = p.x;
65 | values[1] = p.y;
66 | }
67 |
68 | NS_INLINE void values_from_size(CGFloat values[], CGSize s)
69 | {
70 | values[0] = s.width;
71 | values[1] = s.height;
72 | }
73 |
74 | NS_INLINE void values_from_rect(CGFloat values[], CGRect r)
75 | {
76 | values[0] = r.origin.x;
77 | values[1] = r.origin.y;
78 | values[2] = r.size.width;
79 | values[3] = r.size.height;
80 | }
81 |
82 | #if SCENEKIT_SDK_AVAILABLE
83 | NS_INLINE void values_from_vec3(CGFloat values[], SCNVector3 v)
84 | {
85 | values[0] = v.x;
86 | values[1] = v.y;
87 | values[2] = v.z;
88 | }
89 |
90 | NS_INLINE void values_from_vec4(CGFloat values[], SCNVector4 v)
91 | {
92 | values[0] = v.x;
93 | values[1] = v.y;
94 | values[2] = v.z;
95 | values[3] = v.w;
96 | }
97 | #endif
98 |
99 | #if TARGET_OS_IPHONE
100 |
101 | NS_INLINE void values_from_edge_insets(CGFloat values[], UIEdgeInsets i)
102 | {
103 | values[0] = i.top;
104 | values[1] = i.left;
105 | values[2] = i.bottom;
106 | values[3] = i.right;
107 | }
108 |
109 | #endif
110 |
111 | /**
112 | Takes a CGColorRef and converts it into RGBA components, if necessary.
113 | */
114 | extern void POPCGColorGetRGBAComponents(CGColorRef color, CGFloat components[]);
115 |
116 | /**
117 | Takes RGBA components and returns a CGColorRef.
118 | */
119 | extern CGColorRef POPCGColorRGBACreate(const CGFloat components[]) CF_RETURNS_RETAINED;
120 |
121 | /**
122 | Takes a color reference and returns a CGColor.
123 | */
124 | extern CGColorRef POPCGColorWithColor(id color) CF_RETURNS_NOT_RETAINED;
125 |
126 | #if TARGET_OS_IPHONE
127 |
128 | /**
129 | Takes a UIColor and converts it into RGBA components, if necessary.
130 | */
131 | extern void POPUIColorGetRGBAComponents(UIColor *color, CGFloat components[]);
132 |
133 | /**
134 | Takes RGBA components and returns a UIColor.
135 | */
136 | extern UIColor *POPUIColorRGBACreate(const CGFloat components[]) NS_RETURNS_RETAINED;
137 |
138 | #else
139 |
140 | /**
141 | Takes a NSColor and converts it into RGBA components, if necessary.
142 | */
143 | extern void POPNSColorGetRGBAComponents(NSColor *color, CGFloat components[]);
144 |
145 | /**
146 | Takes RGBA components and returns a NSColor.
147 | */
148 | extern NSColor *POPNSColorRGBACreate(const CGFloat components[]) NS_RETURNS_RETAINED;
149 |
150 | #endif
151 |
152 | POP_EXTERN_C_END
153 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPCGUtils.mm:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import "POPCGUtils.h"
11 |
12 | #import
13 |
14 | void POPCGColorGetRGBAComponents(CGColorRef color, CGFloat components[])
15 | {
16 | if (color) {
17 | const CGFloat *colors = CGColorGetComponents(color);
18 | size_t count = CGColorGetNumberOfComponents(color);
19 |
20 | if (4 == count) {
21 | // RGB colorspace
22 | components[0] = colors[0];
23 | components[1] = colors[1];
24 | components[2] = colors[2];
25 | components[3] = colors[3];
26 | } else if (2 == count) {
27 | // Grey colorspace
28 | components[0] = components[1] = components[2] = colors[0];
29 | components[3] = colors[1];
30 | } else {
31 | // Use CI to convert
32 | CIColor *ciColor = [CIColor colorWithCGColor:color];
33 | components[0] = ciColor.red;
34 | components[1] = ciColor.green;
35 | components[2] = ciColor.blue;
36 | components[3] = ciColor.alpha;
37 | }
38 | } else {
39 | memset(components, 0, 4 * sizeof(components[0]));
40 | }
41 | }
42 |
43 | CGColorRef POPCGColorRGBACreate(const CGFloat components[])
44 | {
45 | #if TARGET_OS_IPHONE
46 | CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
47 | CGColorRef color = CGColorCreate(space, components);
48 | CGColorSpaceRelease(space);
49 | return color;
50 | #else
51 | return CGColorCreateGenericRGB(components[0], components[1], components[2], components[3]);
52 | #endif
53 | }
54 |
55 | CGColorRef POPCGColorWithColor(id color)
56 | {
57 | if (CFGetTypeID((__bridge CFTypeRef)color) == CGColorGetTypeID()) {
58 | return ((__bridge CGColorRef)color);
59 | }
60 | #if TARGET_OS_IPHONE
61 | else if ([color isKindOfClass:[UIColor class]]) {
62 | return [color CGColor];
63 | }
64 | #else
65 | else if ([color isKindOfClass:[NSColor class]]) {
66 | // -[NSColor CGColor] is only supported since OSX 10.8+
67 | if ([color respondsToSelector:@selector(CGColor)]) {
68 | return [color CGColor];
69 | }
70 |
71 | /*
72 | * Otherwise create a CGColorRef manually.
73 | *
74 | * The original accessor is (or would be) declared as:
75 | * @property(readonly) CGColorRef CGColor;
76 | * - (CGColorRef)CGColor NS_RETURNS_INNER_POINTER CF_RETURNS_NOT_RETAINED;
77 | *
78 | * (Please note that OSX' accessor is atomic, while iOS' isn't.)
79 | *
80 | * The access to the NSColor object must thus be synchronized
81 | * and the CGColorRef be stored as an associated object,
82 | * to return a reference which doesn't need to be released manually.
83 | */
84 | @synchronized(color) {
85 | static const void* key = &key;
86 |
87 | CGColorRef colorRef = (__bridge CGColorRef)objc_getAssociatedObject(color, key);
88 |
89 | if (!colorRef) {
90 | size_t numberOfComponents = [(NSColor *)color numberOfComponents];
91 | CGFloat components[numberOfComponents];
92 | CGColorSpaceRef colorSpace = [[(NSColor *)color colorSpace] CGColorSpace];
93 |
94 | [color getComponents:components];
95 |
96 | colorRef = CGColorCreate(colorSpace, components);
97 |
98 | objc_setAssociatedObject(color, key, (__bridge id)colorRef, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
99 | CGColorRelease(colorRef);
100 | }
101 |
102 | return colorRef;
103 | }
104 | }
105 | #endif
106 | return nil;
107 | }
108 |
109 | #if TARGET_OS_IPHONE
110 |
111 | void POPUIColorGetRGBAComponents(UIColor *color, CGFloat components[])
112 | {
113 | return POPCGColorGetRGBAComponents(POPCGColorWithColor(color), components);
114 | }
115 |
116 | UIColor *POPUIColorRGBACreate(const CGFloat components[])
117 | {
118 | CGColorRef colorRef = POPCGColorRGBACreate(components);
119 | UIColor *color = [[UIColor alloc] initWithCGColor:colorRef];
120 | CGColorRelease(colorRef);
121 | return color;
122 | }
123 |
124 | #else
125 |
126 | void POPNSColorGetRGBAComponents(NSColor *color, CGFloat components[])
127 | {
128 | return POPCGColorGetRGBAComponents(POPCGColorWithColor(color), components);
129 | }
130 |
131 | NSColor *POPNSColorRGBACreate(const CGFloat components[])
132 | {
133 | CGColorRef colorRef = POPCGColorRGBACreate(components);
134 | NSColor *color = nil;
135 |
136 | if (colorRef) {
137 | if ([NSColor respondsToSelector:@selector(colorWithCGColor:)]) {
138 | color = [NSColor colorWithCGColor:colorRef];
139 | } else {
140 | color = [NSColor colorWithCIColor:[CIColor colorWithCGColor:colorRef]];
141 | }
142 |
143 | CGColorRelease(colorRef);
144 | }
145 |
146 | return color;
147 | }
148 |
149 | #endif
150 |
151 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPCustomAnimation.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | //#import
11 | #import "POPAnimation.h"
12 |
13 | @class POPCustomAnimation;
14 |
15 | /**
16 | @abstract POPCustomAnimationBlock is the callback block of a custom animation.
17 | @discussion This block will be executed for each animation frame and should update the property or properties being animated based on current timing.
18 | @param target The object being animated. Reference the passed in target to help avoid retain loops.
19 | @param animation The custom animation instance. Use to determine the current and elapsed time since last callback. Reference the passed in animation to help avoid retain loops.
20 | @return Flag indicating whether the animation should continue animating. Return NO to indicate animation is done.
21 | */
22 | typedef BOOL (^POPCustomAnimationBlock)(id target, POPCustomAnimation *animation);
23 |
24 | /**
25 | @abstract POPCustomAnimation is a concrete animation subclass for custom animations.
26 | */
27 | @interface POPCustomAnimation : POPAnimation
28 |
29 | /**
30 | @abstract Creates and returns an initialized custom animation instance.
31 | @discussion This is the designated initializer.
32 | @param block The custom animation callback block. See {@ref POPCustomAnimationBlock}.
33 | @return The initialized custom animation instance.
34 | */
35 | + (instancetype)animationWithBlock:(POPCustomAnimationBlock)block;
36 |
37 | /**
38 | @abstract The current animation time at time of callback.
39 | */
40 | @property (readonly, nonatomic) CFTimeInterval currentTime;
41 |
42 | /**
43 | @abstract The elapsed animation time since last callback.
44 | */
45 | @property (readonly, nonatomic) CFTimeInterval elapsedTime;
46 |
47 | @end
48 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPCustomAnimation.mm:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import "POPAnimationInternal.h"
11 |
12 | #import "POPCustomAnimation.h"
13 |
14 | @interface POPCustomAnimation ()
15 | @property (nonatomic, copy) POPCustomAnimationBlock animate;
16 | @end
17 |
18 | @implementation POPCustomAnimation
19 | @synthesize currentTime = _currentTime;
20 | @synthesize elapsedTime = _elapsedTime;
21 | @synthesize animate = _animate;
22 |
23 | + (instancetype)animationWithBlock:(BOOL(^)(id target, POPCustomAnimation *))block
24 | {
25 | POPCustomAnimation *b = [[self alloc] _init];
26 | b.animate = block;
27 | return b;
28 | }
29 |
30 | - (id)_init
31 | {
32 | self = [super _init];
33 | if (nil != self) {
34 | _state->type = kPOPAnimationCustom;
35 | }
36 | return self;
37 | }
38 |
39 | - (CFTimeInterval)beginTime
40 | {
41 | POPAnimationState *s = POPAnimationGetState(self);
42 | return s->startTime > 0 ? s->startTime : s->beginTime;
43 | }
44 |
45 | - (BOOL)_advance:(id)object currentTime:(CFTimeInterval)currentTime elapsedTime:(CFTimeInterval)elapsedTime
46 | {
47 | _currentTime = currentTime;
48 | _elapsedTime = elapsedTime;
49 | return _animate(object, self);
50 | }
51 |
52 | - (void)_appendDescription:(NSMutableString *)s debug:(BOOL)debug
53 | {
54 | [s appendFormat:@"; elapsedTime = %f; currentTime = %f;", _elapsedTime, _currentTime];
55 | }
56 |
57 | @end
58 |
59 | /**
60 | * Note that only the animate block is copied, but not the current/elapsed times
61 | */
62 | @implementation POPCustomAnimation (NSCopying)
63 |
64 | - (instancetype)copyWithZone:(NSZone *)zone {
65 |
66 | POPCustomAnimation *copy = [super copyWithZone:zone];
67 |
68 | if (copy) {
69 | copy.animate = self.animate;
70 | }
71 |
72 | return copy;
73 | }
74 |
75 | @end
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPDecayAnimation.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | //#import
11 | #import "POPPropertyAnimation.h"
12 |
13 | /**
14 | @abstract A concrete decay animation class.
15 | @discussion Animation is achieved through gradual decay of animation value.
16 | */
17 | @interface POPDecayAnimation : POPPropertyAnimation
18 |
19 | /**
20 | @abstract The designated initializer.
21 | @returns An instance of a decay animation.
22 | */
23 | + (instancetype)animation;
24 |
25 | /**
26 | @abstract Convenience initializer that returns an animation with animatable property of name.
27 | @param name The name of the animatable property.
28 | @returns An instance of a decay animation configured with specified animatable property.
29 | */
30 | + (instancetype)animationWithPropertyNamed:(NSString *)name;
31 |
32 | /**
33 | @abstract The current velocity value.
34 | @discussion Set before animation start to account for initial velocity. Expressed in change of value units per second. The only POPValueTypes supported for velocity are: kPOPValuePoint, kPOPValueInteger, kPOPValueFloat, kPOPValueRect, and kPOPValueSize.
35 | */
36 | @property (copy, nonatomic) id velocity;
37 |
38 | /**
39 | @abstract The original velocity value.
40 | @discussion Since the velocity property is modified as the animation progresses, this property stores the original, passed in velocity to support autoreverse and repeatCount.
41 | */
42 | @property (copy, nonatomic, readonly) id originalVelocity;
43 |
44 | /**
45 | @abstract The deceleration factor.
46 | @discussion Values specifies should be in the range [0, 1]. Lower values results in faster deceleration. Defaults to 0.998.
47 | */
48 | @property (assign, nonatomic) CGFloat deceleration;
49 |
50 | /**
51 | @abstract The expected duration.
52 | @discussion Derived based on input velocity and deceleration values.
53 | */
54 | @property (readonly, assign, nonatomic) CFTimeInterval duration;
55 |
56 | /**
57 | The to value is derived based on input velocity and deceleration.
58 | */
59 | - (void)setToValue:(id)toValue NS_UNAVAILABLE;
60 |
61 | /**
62 | @abstract The reversed velocity.
63 | @discussion The reversed velocity based on the originalVelocity when the animation was set up.
64 | */
65 | - (id)reversedVelocity;
66 |
67 | @end
68 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPDecayAnimation.mm:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import "POPDecayAnimationInternal.h"
11 |
12 | #if TARGET_OS_IPHONE
13 | #import
14 | #endif
15 |
16 | const POPValueType supportedVelocityTypes[6] = { kPOPValuePoint, kPOPValueInteger, kPOPValueFloat, kPOPValueRect, kPOPValueSize, kPOPValueEdgeInsets };
17 |
18 | @implementation POPDecayAnimation
19 |
20 | #pragma mark - Lifecycle
21 |
22 | #undef __state
23 | #define __state ((POPDecayAnimationState *)_state)
24 |
25 | + (instancetype)animation
26 | {
27 | return [[self alloc] init];
28 | }
29 |
30 | + (instancetype)animationWithPropertyNamed:(NSString *)aName
31 | {
32 | POPDecayAnimation *anim = [self animation];
33 | anim.property = [POPAnimatableProperty propertyWithName:aName];
34 | return anim;
35 | }
36 |
37 | - (id)init
38 | {
39 | return [self _init];
40 | }
41 |
42 | - (void)_initState
43 | {
44 | _state = new POPDecayAnimationState(self);
45 | }
46 |
47 | #pragma mark - Properties
48 |
49 | DEFINE_RW_PROPERTY(POPDecayAnimationState, deceleration, setDeceleration:, CGFloat, __state->toVec = NULL;);
50 |
51 | @dynamic velocity;
52 |
53 | - (id)toValue
54 | {
55 | [self _ensureComputedProperties];
56 | return POPBox(__state->toVec, __state->valueType);
57 | }
58 |
59 | - (CFTimeInterval)duration
60 | {
61 | [self _ensureComputedProperties];
62 | return __state->duration;
63 | }
64 |
65 | - (void)setFromValue:(id)fromValue
66 | {
67 | super.fromValue = fromValue;
68 | [self _invalidateComputedProperties];
69 | }
70 |
71 | - (void)setToValue:(id)aValue
72 | {
73 | // no-op
74 | NSLog(@"ignoring to value on decay animation %@", self);
75 | }
76 |
77 | - (id)reversedVelocity
78 | {
79 | id reversedVelocity = nil;
80 |
81 | POPValueType velocityType = POPSelectValueType(self.originalVelocity, supportedVelocityTypes, POP_ARRAY_COUNT(supportedVelocityTypes));
82 | if (velocityType == kPOPValueFloat) {
83 | #if CGFLOAT_IS_DOUBLE
84 | CGFloat originalVelocityFloat = [(NSNumber *)self.originalVelocity doubleValue];
85 | #else
86 | CGFloat originalVelocityFloat = [(NSNumber *)self.originalVelocity floatValue];
87 | #endif
88 | NSNumber *negativeOriginalVelocityNumber = @(-originalVelocityFloat);
89 | reversedVelocity = negativeOriginalVelocityNumber;
90 | } else if (velocityType == kPOPValueInteger) {
91 | NSInteger originalVelocityInteger = [(NSNumber *)self.originalVelocity integerValue];
92 | NSNumber *negativeOriginalVelocityNumber = @(-originalVelocityInteger);
93 | reversedVelocity = negativeOriginalVelocityNumber;
94 | } else if (velocityType == kPOPValuePoint) {
95 | CGPoint originalVelocityPoint = [self.originalVelocity CGPointValue];
96 | CGPoint negativeOriginalVelocityPoint = CGPointMake(-originalVelocityPoint.x, -originalVelocityPoint.y);
97 | reversedVelocity = [NSValue valueWithCGPoint:negativeOriginalVelocityPoint];
98 | } else if (velocityType == kPOPValueRect) {
99 | CGRect originalVelocityRect = [self.originalVelocity CGRectValue];
100 | CGRect negativeOriginalVelocityRect = CGRectMake(-originalVelocityRect.origin.x, -originalVelocityRect.origin.y, -originalVelocityRect.size.width, -originalVelocityRect.size.height);
101 | reversedVelocity = [NSValue valueWithCGRect:negativeOriginalVelocityRect];
102 | } else if (velocityType == kPOPValueSize) {
103 | CGSize originalVelocitySize = [self.originalVelocity CGSizeValue];
104 | CGSize negativeOriginalVelocitySize = CGSizeMake(-originalVelocitySize.width, -originalVelocitySize.height);
105 | reversedVelocity = [NSValue valueWithCGSize:negativeOriginalVelocitySize];
106 | } else if (velocityType == kPOPValueEdgeInsets) {
107 | #if TARGET_OS_IPHONE
108 | UIEdgeInsets originalVelocityInsets = [self.originalVelocity UIEdgeInsetsValue];
109 | UIEdgeInsets negativeOriginalVelocityInsets = UIEdgeInsetsMake(-originalVelocityInsets.top, -originalVelocityInsets.left, -originalVelocityInsets.bottom, -originalVelocityInsets.right);
110 | reversedVelocity = [NSValue valueWithUIEdgeInsets:negativeOriginalVelocityInsets];
111 | #endif
112 | }
113 |
114 | return reversedVelocity;
115 | }
116 |
117 | - (id)originalVelocity
118 | {
119 | return POPBox(__state->originalVelocityVec, __state->valueType);
120 | }
121 |
122 | - (id)velocity
123 | {
124 | return POPBox(__state->velocityVec, __state->valueType);
125 | }
126 |
127 | - (void)setVelocity:(id)aValue
128 | {
129 | POPValueType valueType = POPSelectValueType(aValue, supportedVelocityTypes, POP_ARRAY_COUNT(supportedVelocityTypes));
130 | if (valueType != kPOPValueUnknown) {
131 | VectorRef vec = POPUnbox(aValue, __state->valueType, __state->valueCount, YES);
132 | VectorRef origVec = POPUnbox(aValue, __state->valueType, __state->valueCount, YES);
133 |
134 | if (!vec_equal(vec, __state->velocityVec)) {
135 | __state->velocityVec = vec;
136 | __state->originalVelocityVec = origVec;
137 |
138 | if (__state->tracing) {
139 | [__state->tracer updateVelocity:aValue];
140 | }
141 |
142 | [self _invalidateComputedProperties];
143 |
144 | // automatically unpause active animations
145 | if (__state->active && __state->paused) {
146 | __state->fromVec = NULL;
147 | __state->setPaused(false);
148 | }
149 | }
150 | } else {
151 | __state->velocityVec = NULL;
152 | NSLog(@"Invalid velocity value for the decayAnimation: %@", aValue);
153 | }
154 | }
155 |
156 | #pragma mark - Utility
157 |
158 | - (void)_ensureComputedProperties
159 | {
160 | if (NULL == __state->toVec) {
161 | __state->computeDuration();
162 | __state->computeToValue();
163 | }
164 | }
165 |
166 | - (void)_invalidateComputedProperties
167 | {
168 | __state->toVec = NULL;
169 | __state->duration = 0;
170 | }
171 |
172 | - (void)_appendDescription:(NSMutableString *)s debug:(BOOL)debug
173 | {
174 | [super _appendDescription:s debug:debug];
175 |
176 | if (0 != self.duration) {
177 | [s appendFormat:@"; duration = %f", self.duration];
178 | }
179 |
180 | if (__state->deceleration) {
181 | [s appendFormat:@"; deceleration = %f", __state->deceleration];
182 | }
183 | }
184 |
185 | @end
186 |
187 | @implementation POPDecayAnimation (NSCopying)
188 |
189 | - (instancetype)copyWithZone:(NSZone *)zone {
190 |
191 | POPDecayAnimation *copy = [super copyWithZone:zone];
192 |
193 | if (copy) {
194 | // Set the velocity to the animation's original velocity, not its current.
195 | copy.velocity = self.originalVelocity;
196 | copy.deceleration = self.deceleration;
197 |
198 | }
199 |
200 | return copy;
201 | }
202 |
203 | @end
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPDecayAnimationInternal.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import "POPDecayAnimation.h"
11 |
12 | #import
13 |
14 | #import "POPPropertyAnimationInternal.h"
15 |
16 | // minimal velocity factor before decay animation is considered complete, in units / s
17 | static CGFloat kPOPAnimationDecayMinimalVelocityFactor = 5.;
18 |
19 | // default decay animation deceleration
20 | static CGFloat kPOPAnimationDecayDecelerationDefault = 0.998;
21 |
22 | static void decay_position(CGFloat *x, CGFloat *v, NSUInteger count, CFTimeInterval dt, CGFloat deceleration)
23 | {
24 | dt *= 1000;
25 |
26 | // v0 = v / 1000
27 | // v = v0 * powf(deceleration, dt);
28 | // v = v * 1000;
29 |
30 | // x0 = x;
31 | // x = x0 + v0 * deceleration * (1 - powf(deceleration, dt)) / (1 - deceleration)
32 | float v0[count];
33 | float kv = powf(deceleration, dt);
34 | float kx = deceleration * (1 - kv) / (1 - deceleration);
35 |
36 | for (NSUInteger idx = 0; idx < count; idx++) {
37 | v0[idx] = v[idx] / 1000.;
38 | v[idx] = v0[idx] * kv * 1000.;
39 | x[idx] = x[idx] + v0[idx] * kx;
40 | }
41 | }
42 |
43 | struct _POPDecayAnimationState : _POPPropertyAnimationState
44 | {
45 | double deceleration;
46 | CFTimeInterval duration;
47 |
48 | _POPDecayAnimationState(id __unsafe_unretained anim) :
49 | _POPPropertyAnimationState(anim),
50 | deceleration(kPOPAnimationDecayDecelerationDefault),
51 | duration(0)
52 | {
53 | type = kPOPAnimationDecay;
54 | }
55 |
56 | bool isDone() {
57 | if (_POPPropertyAnimationState::isDone()) {
58 | return true;
59 | }
60 |
61 | CGFloat f = dynamicsThreshold * kPOPAnimationDecayMinimalVelocityFactor;
62 | const CGFloat *velocityValues = vec_data(velocityVec);
63 | for (NSUInteger idx = 0; idx < valueCount; idx++) {
64 | if (std::abs((velocityValues[idx])) >= f)
65 | return false;
66 | }
67 | return true;
68 |
69 | }
70 |
71 | void computeDuration() {
72 |
73 | // compute duration till threshold velocity
74 | Vector4r scaledVelocity = vector4(velocityVec) / 1000.;
75 |
76 | double k = dynamicsThreshold * kPOPAnimationDecayMinimalVelocityFactor / 1000.;
77 | double vx = k / scaledVelocity.x;
78 | double vy = k / scaledVelocity.y;
79 | double vz = k / scaledVelocity.z;
80 | double vw = k / scaledVelocity.w;
81 | double d = log(deceleration) * 1000.;
82 | duration = MAX(MAX(MAX(log(fabs(vx)) / d, log(fabs(vy)) / d), log(fabs(vz)) / d), log(fabs(vw)) / d);
83 |
84 | // ensure velocity threshold is exceeded
85 | if (std::isnan(duration) || duration < 0) {
86 | duration = 0;
87 | }
88 | }
89 |
90 | void computeToValue() {
91 | // to value assuming final velocity as a factor of dynamics threshold
92 | // derived from v' = v * d^dt used in decay_position
93 | // to compute the to value with maximal dt, p' = p + (v * d) / (1 - d)
94 | VectorRef fromValue = NULL != currentVec ? currentVec : fromVec;
95 | if (!fromValue) {
96 | return;
97 | }
98 |
99 | // ensure duration is computed
100 | if (0 == duration) {
101 | computeDuration();
102 | }
103 |
104 | // compute to value
105 | VectorRef toValue(Vector::new_vector(fromValue.get()));
106 | Vector4r velocity = velocityVec->vector4r();
107 | decay_position(toValue->data(), velocity.data(), valueCount, duration, deceleration);
108 | toVec = toValue;
109 | }
110 |
111 | bool advance(CFTimeInterval time, CFTimeInterval dt, id obj) {
112 | // advance past not yet initialized animations
113 | if (NULL == currentVec) {
114 | return false;
115 | }
116 |
117 | decay_position(currentVec->data(), velocityVec->data(), valueCount, dt, deceleration);
118 |
119 | // clamp to compute end value; avoid possibility of decaying past
120 | clampCurrentValue(kPOPAnimationClampEnd | clampMode);
121 |
122 | return true;
123 | }
124 |
125 | };
126 |
127 | typedef struct _POPDecayAnimationState POPDecayAnimationState;
128 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPDefines.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #ifndef POP_POPDefines_h
11 | #define POP_POPDefines_h
12 |
13 | #import
14 |
15 | #ifdef __cplusplus
16 | # define POP_EXTERN_C_BEGIN extern "C" {
17 | # define POP_EXTERN_C_END }
18 | #else
19 | # define POP_EXTERN_C_BEGIN
20 | # define POP_EXTERN_C_END
21 | #endif
22 |
23 | #define POP_ARRAY_COUNT(x) sizeof(x) / sizeof(x[0])
24 |
25 | #if defined (__cplusplus) && defined (__GNUC__)
26 | # define POP_NOTHROW __attribute__ ((nothrow))
27 | #else
28 | # define POP_NOTHROW
29 | #endif
30 |
31 | #if defined(POP_USE_SCENEKIT)
32 | # if TARGET_OS_MAC || TARGET_OS_IPHONE
33 | # define SCENEKIT_SDK_AVAILABLE 1
34 | # endif
35 | #endif
36 |
37 | #endif
38 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPGeometry.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | #if TARGET_OS_IPHONE
13 | #import
14 | #endif
15 |
16 | #if !TARGET_OS_IPHONE
17 |
18 | /** NSValue extensions to support animatable types. */
19 | @interface NSValue (POP)
20 |
21 | /**
22 | @abstract Creates an NSValue given a CGPoint.
23 | */
24 | + (NSValue *)valueWithCGPoint:(CGPoint)point;
25 |
26 | /**
27 | @abstract Creates an NSValue given a CGSize.
28 | */
29 | + (NSValue *)valueWithCGSize:(CGSize)size;
30 |
31 | /**
32 | @abstract Creates an NSValue given a CGRect.
33 | */
34 | + (NSValue *)valueWithCGRect:(CGRect)rect;
35 |
36 | /**
37 | @abstract Creates an NSValue given a CFRange.
38 | */
39 | + (NSValue *)valueWithCFRange:(CFRange)range;
40 |
41 | /**
42 | @abstract Creates an NSValue given a CGAffineTransform.
43 | */
44 | + (NSValue *)valueWithCGAffineTransform:(CGAffineTransform)transform;
45 |
46 | /**
47 | @abstract Returns the underlying CGPoint value.
48 | */
49 | - (CGPoint)CGPointValue;
50 |
51 | /**
52 | @abstract Returns the underlying CGSize value.
53 | */
54 | - (CGSize)CGSizeValue;
55 |
56 | /**
57 | @abstract Returns the underlying CGRect value.
58 | */
59 | - (CGRect)CGRectValue;
60 |
61 | /**
62 | @abstract Returns the underlying CFRange value.
63 | */
64 | - (CFRange)CFRangeValue;
65 |
66 | /**
67 | @abstract Returns the underlying CGAffineTransform value.
68 | */
69 | - (CGAffineTransform)CGAffineTransformValue;
70 |
71 | @end
72 |
73 | #endif
74 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPGeometry.mm:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import "POPGeometry.h"
11 |
12 | #if !TARGET_OS_IPHONE
13 | @implementation NSValue (POP)
14 |
15 | + (NSValue *)valueWithCGPoint:(CGPoint)point {
16 | return [NSValue valueWithBytes:&point objCType:@encode(CGPoint)];
17 | }
18 |
19 | + (NSValue *)valueWithCGSize:(CGSize)size {
20 | return [NSValue valueWithBytes:&size objCType:@encode(CGSize)];
21 | }
22 |
23 | + (NSValue *)valueWithCGRect:(CGRect)rect {
24 | return [NSValue valueWithBytes:&rect objCType:@encode(CGRect)];
25 | }
26 |
27 | + (NSValue *)valueWithCFRange:(CFRange)range {
28 | return [NSValue valueWithBytes:&range objCType:@encode(CFRange)];
29 | }
30 |
31 | + (NSValue *)valueWithCGAffineTransform:(CGAffineTransform)transform
32 | {
33 | return [NSValue valueWithBytes:&transform objCType:@encode(CGAffineTransform)];
34 | }
35 |
36 | - (CGPoint)CGPointValue {
37 | CGPoint result;
38 | [self getValue:&result];
39 | return result;
40 | }
41 |
42 | - (CGSize)CGSizeValue {
43 | CGSize result;
44 | [self getValue:&result];
45 | return result;
46 | }
47 |
48 | - (CGRect)CGRectValue {
49 | CGRect result;
50 | [self getValue:&result];
51 | return result;
52 | }
53 |
54 | - (CFRange)CFRangeValue {
55 | CFRange result;
56 | [self getValue:&result];
57 | return result;
58 | }
59 |
60 | - (CGAffineTransform)CGAffineTransformValue {
61 | CGAffineTransform result;
62 | [self getValue:&result];
63 | return result;
64 | }
65 | @end
66 |
67 | #endif
68 |
69 | #if TARGET_OS_IPHONE
70 | #import "POPDefines.h"
71 |
72 | #if SCENEKIT_SDK_AVAILABLE
73 | #import
74 |
75 | /**
76 | Dirty hacks because iOS is weird and decided to define both SCNVector3's and SCNVector4's objCType as "t". However @encode(SCNVector3) and @encode(SCNVector4) both return the proper definition ("{SCNVector3=fff}" and "{SCNVector4=ffff}" respectively)
77 |
78 | [[NSValue valueWithSCNVector3:SCNVector3Make(0.0, 0.0, 0.0)] objcType] returns "t", whereas it should return "{SCNVector3=fff}".
79 |
80 | *flips table*
81 | */
82 | @implementation NSValue (SceneKitFixes)
83 |
84 | + (NSValue *)valueWithSCNVector3:(SCNVector3)vec3 {
85 | return [NSValue valueWithBytes:&vec3 objCType:@encode(SCNVector3)];
86 | }
87 |
88 | + (NSValue *)valueWithSCNVector4:(SCNVector4)vec4 {
89 | return [NSValue valueWithBytes:&vec4 objCType:@encode(SCNVector4)];
90 | }
91 |
92 | @end
93 | #endif
94 | #endif
95 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPLayerExtras.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | //#import
13 | #import "POPDefines.h"
14 |
15 | POP_EXTERN_C_BEGIN
16 |
17 | #pragma mark - Scale
18 |
19 | /**
20 | @abstract Returns layer scale factor for the x axis.
21 | */
22 | extern CGFloat POPLayerGetScaleX(CALayer *l);
23 |
24 | /**
25 | @abstract Set layer scale factor for the x axis.
26 | */
27 | extern void POPLayerSetScaleX(CALayer *l, CGFloat f);
28 |
29 | /**
30 | @abstract Returns layer scale factor for the y axis.
31 | */
32 | extern CGFloat POPLayerGetScaleY(CALayer *l);
33 |
34 | /**
35 | @abstract Set layer scale factor for the y axis.
36 | */
37 | extern void POPLayerSetScaleY(CALayer *l, CGFloat f);
38 |
39 | /**
40 | @abstract Returns layer scale factor for the z axis.
41 | */
42 | extern CGFloat POPLayerGetScaleZ(CALayer *l);
43 |
44 | /**
45 | @abstract Set layer scale factor for the z axis.
46 | */
47 | extern void POPLayerSetScaleZ(CALayer *l, CGFloat f);
48 |
49 | /**
50 | @abstract Returns layer scale factors for x and y access as point.
51 | */
52 | extern CGPoint POPLayerGetScaleXY(CALayer *l);
53 |
54 | /**
55 | @abstract Sets layer x and y scale factors given point.
56 | */
57 | extern void POPLayerSetScaleXY(CALayer *l, CGPoint p);
58 |
59 | #pragma mark - Translation
60 |
61 | /**
62 | @abstract Returns layer translation factor for the x axis.
63 | */
64 | extern CGFloat POPLayerGetTranslationX(CALayer *l);
65 |
66 | /**
67 | @abstract Set layer translation factor for the x axis.
68 | */
69 | extern void POPLayerSetTranslationX(CALayer *l, CGFloat f);
70 |
71 | /**
72 | @abstract Returns layer translation factor for the y axis.
73 | */
74 | extern CGFloat POPLayerGetTranslationY(CALayer *l);
75 |
76 | /**
77 | @abstract Set layer translation factor for the y axis.
78 | */
79 | extern void POPLayerSetTranslationY(CALayer *l, CGFloat f);
80 |
81 | /**
82 | @abstract Returns layer translation factor for the z axis.
83 | */
84 | extern CGFloat POPLayerGetTranslationZ(CALayer *l);
85 |
86 | /**
87 | @abstract Set layer translation factor for the z axis.
88 | */
89 | extern void POPLayerSetTranslationZ(CALayer *l, CGFloat f);
90 |
91 | /**
92 | @abstract Returns layer translation factors for x and y access as point.
93 | */
94 | extern CGPoint POPLayerGetTranslationXY(CALayer *l);
95 |
96 | /**
97 | @abstract Sets layer x and y translation factors given point.
98 | */
99 | extern void POPLayerSetTranslationXY(CALayer *l, CGPoint p);
100 |
101 | #pragma mark - Rotation
102 |
103 | /**
104 | @abstract Returns layer rotation, in radians, in the X axis.
105 | */
106 | extern CGFloat POPLayerGetRotationX(CALayer *l);
107 |
108 | /**
109 | @abstract Sets layer rotation, in radians, in the X axis.
110 | */
111 | extern void POPLayerSetRotationX(CALayer *l, CGFloat f);
112 |
113 | /**
114 | @abstract Returns layer rotation, in radians, in the Y axis.
115 | */
116 | extern CGFloat POPLayerGetRotationY(CALayer *l);
117 |
118 | /**
119 | @abstract Sets layer rotation, in radians, in the Y axis.
120 | */
121 | extern void POPLayerSetRotationY(CALayer *l, CGFloat f);
122 |
123 | /**
124 | @abstract Returns layer rotation, in radians, in the Z axis.
125 | */
126 | extern CGFloat POPLayerGetRotationZ(CALayer *l);
127 |
128 | /**
129 | @abstract Sets layer rotation, in radians, in the Z axis.
130 | */
131 | extern void POPLayerSetRotationZ(CALayer *l, CGFloat f);
132 |
133 | /**
134 | @abstract Returns layer rotation, in radians, in the Z axis.
135 | */
136 | extern CGFloat POPLayerGetRotation(CALayer *l);
137 |
138 | /**
139 | @abstract Sets layer rotation, in radians, in the Z axis.
140 | */
141 | extern void POPLayerSetRotation(CALayer *l, CGFloat f);
142 |
143 | #pragma mark - Sublayer Scale
144 |
145 | /**
146 | @abstract Returns sublayer scale factors for x and y access as point.
147 | */
148 | extern CGPoint POPLayerGetSubScaleXY(CALayer *l);
149 |
150 | /**
151 | @abstract Sets sublayer x and y scale factors given point.
152 | */
153 | extern void POPLayerSetSubScaleXY(CALayer *l, CGPoint p);
154 |
155 | #pragma mark - Sublayer Translation
156 |
157 | /**
158 | @abstract Returns sublayer translation factor for the x axis.
159 | */
160 | extern CGFloat POPLayerGetSubTranslationX(CALayer *l);
161 |
162 | /**
163 | @abstract Set sublayer translation factor for the x axis.
164 | */
165 | extern void POPLayerSetSubTranslationX(CALayer *l, CGFloat f);
166 |
167 | /**
168 | @abstract Returns sublayer translation factor for the y axis.
169 | */
170 | extern CGFloat POPLayerGetSubTranslationY(CALayer *l);
171 |
172 | /**
173 | @abstract Set sublayer translation factor for the y axis.
174 | */
175 | extern void POPLayerSetSubTranslationY(CALayer *l, CGFloat f);
176 |
177 | /**
178 | @abstract Returns sublayer translation factor for the z axis.
179 | */
180 | extern CGFloat POPLayerGetSubTranslationZ(CALayer *l);
181 |
182 | /**
183 | @abstract Set sublayer translation factor for the z axis.
184 | */
185 | extern void POPLayerSetSubTranslationZ(CALayer *l, CGFloat f);
186 |
187 | /**
188 | @abstract Returns sublayer translation factors for x and y access as point.
189 | */
190 | extern CGPoint POPLayerGetSubTranslationXY(CALayer *l);
191 |
192 | /**
193 | @abstract Sets sublayer x and y translation factors given point.
194 | */
195 | extern void POPLayerSetSubTranslationXY(CALayer *l, CGPoint p);
196 |
197 | POP_EXTERN_C_END
198 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPLayerExtras.mm:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import "POPLayerExtras.h"
11 |
12 | #include "TransformationMatrix.h"
13 |
14 | using namespace WebCore;
15 |
16 | #define DECOMPOSE_TRANSFORM(L) \
17 | TransformationMatrix _m(L.transform); \
18 | TransformationMatrix::DecomposedType _d; \
19 | _m.decompose(_d);
20 |
21 | #define RECOMPOSE_TRANSFORM(L) \
22 | _m.recompose(_d); \
23 | L.transform = _m.transform3d();
24 |
25 | #define RECOMPOSE_ROT_TRANSFORM(L) \
26 | _m.recompose(_d, true); \
27 | L.transform = _m.transform3d();
28 |
29 | #define DECOMPOSE_SUBLAYER_TRANSFORM(L) \
30 | TransformationMatrix _m(L.sublayerTransform); \
31 | TransformationMatrix::DecomposedType _d; \
32 | _m.decompose(_d);
33 |
34 | #define RECOMPOSE_SUBLAYER_TRANSFORM(L) \
35 | _m.recompose(_d); \
36 | L.sublayerTransform = _m.transform3d();
37 |
38 | #pragma mark - Scale
39 |
40 | NS_INLINE void ensureNonZeroValue(CGFloat &f)
41 | {
42 | if (f == 0) {
43 | f = 1e-6;
44 | }
45 | }
46 |
47 | NS_INLINE void ensureNonZeroValue(CGPoint &p)
48 | {
49 | if (p.x == 0 && p.y == 0) {
50 | p.x = 1e-6;
51 | p.y = 1e-6;
52 | }
53 | }
54 |
55 | CGFloat POPLayerGetScaleX(CALayer *l)
56 | {
57 | DECOMPOSE_TRANSFORM(l);
58 | return _d.scaleX;
59 | }
60 |
61 | void POPLayerSetScaleX(CALayer *l, CGFloat f)
62 | {
63 | ensureNonZeroValue(f);
64 | DECOMPOSE_TRANSFORM(l);
65 | _d.scaleX = f;
66 | RECOMPOSE_TRANSFORM(l);
67 | }
68 |
69 | CGFloat POPLayerGetScaleY(CALayer *l)
70 | {
71 | DECOMPOSE_TRANSFORM(l);
72 | return _d.scaleY;
73 | }
74 |
75 | void POPLayerSetScaleY(CALayer *l, CGFloat f)
76 | {
77 | ensureNonZeroValue(f);
78 | DECOMPOSE_TRANSFORM(l);
79 | _d.scaleY = f;
80 | RECOMPOSE_TRANSFORM(l);
81 | }
82 |
83 | CGFloat POPLayerGetScaleZ(CALayer *l)
84 | {
85 | DECOMPOSE_TRANSFORM(l);
86 | return _d.scaleZ;
87 | }
88 |
89 | void POPLayerSetScaleZ(CALayer *l, CGFloat f)
90 | {
91 | ensureNonZeroValue(f);
92 | DECOMPOSE_TRANSFORM(l);
93 | _d.scaleZ = f;
94 | RECOMPOSE_TRANSFORM(l);
95 | }
96 |
97 | CGPoint POPLayerGetScaleXY(CALayer *l)
98 | {
99 | DECOMPOSE_TRANSFORM(l);
100 | return CGPointMake(_d.scaleX, _d.scaleY);
101 | }
102 |
103 | void POPLayerSetScaleXY(CALayer *l, CGPoint p)
104 | {
105 | ensureNonZeroValue(p);
106 | DECOMPOSE_TRANSFORM(l);
107 | _d.scaleX = p.x;
108 | _d.scaleY = p.y;
109 | RECOMPOSE_TRANSFORM(l);
110 | }
111 |
112 | #pragma mark - Translation
113 |
114 | CGFloat POPLayerGetTranslationX(CALayer *l)
115 | {
116 | DECOMPOSE_TRANSFORM(l);
117 | return _d.translateX;
118 | }
119 |
120 | void POPLayerSetTranslationX(CALayer *l, CGFloat f)
121 | {
122 | DECOMPOSE_TRANSFORM(l);
123 | _d.translateX = f;
124 | RECOMPOSE_TRANSFORM(l);
125 | }
126 |
127 | CGFloat POPLayerGetTranslationY(CALayer *l)
128 | {
129 | DECOMPOSE_TRANSFORM(l);
130 | return _d.translateY;
131 | }
132 |
133 | void POPLayerSetTranslationY(CALayer *l, CGFloat f)
134 | {
135 | DECOMPOSE_TRANSFORM(l);
136 | _d.translateY = f;
137 | RECOMPOSE_TRANSFORM(l);
138 | }
139 |
140 | CGFloat POPLayerGetTranslationZ(CALayer *l)
141 | {
142 | DECOMPOSE_TRANSFORM(l);
143 | return _d.translateZ;
144 | }
145 |
146 | void POPLayerSetTranslationZ(CALayer *l, CGFloat f)
147 | {
148 | DECOMPOSE_TRANSFORM(l);
149 | _d.translateZ = f;
150 | RECOMPOSE_TRANSFORM(l);
151 | }
152 |
153 | CGPoint POPLayerGetTranslationXY(CALayer *l)
154 | {
155 | DECOMPOSE_TRANSFORM(l);
156 | return CGPointMake(_d.translateX, _d.translateY);
157 | }
158 |
159 | void POPLayerSetTranslationXY(CALayer *l, CGPoint p)
160 | {
161 | DECOMPOSE_TRANSFORM(l);
162 | _d.translateX = p.x;
163 | _d.translateY = p.y;
164 | RECOMPOSE_TRANSFORM(l);
165 | }
166 |
167 | #pragma mark - Rotation
168 |
169 | CGFloat POPLayerGetRotationX(CALayer *l)
170 | {
171 | DECOMPOSE_TRANSFORM(l);
172 | return _d.rotateX;
173 | }
174 |
175 | void POPLayerSetRotationX(CALayer *l, CGFloat f)
176 | {
177 | DECOMPOSE_TRANSFORM(l);
178 | _d.rotateX = f;
179 | RECOMPOSE_ROT_TRANSFORM(l);
180 | }
181 |
182 | CGFloat POPLayerGetRotationY(CALayer *l)
183 | {
184 | DECOMPOSE_TRANSFORM(l);
185 | return _d.rotateY;
186 | }
187 |
188 | void POPLayerSetRotationY(CALayer *l, CGFloat f)
189 | {
190 | DECOMPOSE_TRANSFORM(l);
191 | _d.rotateY = f;
192 | RECOMPOSE_ROT_TRANSFORM(l);
193 | }
194 |
195 | CGFloat POPLayerGetRotationZ(CALayer *l)
196 | {
197 | DECOMPOSE_TRANSFORM(l);
198 | return _d.rotateZ;
199 | }
200 |
201 | void POPLayerSetRotationZ(CALayer *l, CGFloat f)
202 | {
203 | DECOMPOSE_TRANSFORM(l);
204 | _d.rotateZ = f;
205 | RECOMPOSE_ROT_TRANSFORM(l);
206 | }
207 |
208 | CGFloat POPLayerGetRotation(CALayer *l)
209 | {
210 | return POPLayerGetRotationZ(l);
211 | }
212 |
213 | void POPLayerSetRotation(CALayer *l, CGFloat f)
214 | {
215 | POPLayerSetRotationZ(l, f);
216 | }
217 |
218 | #pragma mark - Sublayer Scale
219 |
220 | CGPoint POPLayerGetSubScaleXY(CALayer *l)
221 | {
222 | DECOMPOSE_SUBLAYER_TRANSFORM(l);
223 | return CGPointMake(_d.scaleX, _d.scaleY);
224 | }
225 |
226 | void POPLayerSetSubScaleXY(CALayer *l, CGPoint p)
227 | {
228 | ensureNonZeroValue(p);
229 | DECOMPOSE_SUBLAYER_TRANSFORM(l);
230 | _d.scaleX = p.x;
231 | _d.scaleY = p.y;
232 | RECOMPOSE_SUBLAYER_TRANSFORM(l);
233 | }
234 |
235 | #pragma mark - Sublayer Translation
236 |
237 | extern CGFloat POPLayerGetSubTranslationX(CALayer *l)
238 | {
239 | DECOMPOSE_SUBLAYER_TRANSFORM(l);
240 | return _d.translateX;
241 | }
242 |
243 | extern void POPLayerSetSubTranslationX(CALayer *l, CGFloat f)
244 | {
245 | DECOMPOSE_SUBLAYER_TRANSFORM(l);
246 | _d.translateX = f;
247 | RECOMPOSE_SUBLAYER_TRANSFORM(l);
248 | }
249 |
250 | extern CGFloat POPLayerGetSubTranslationY(CALayer *l)
251 | {
252 | DECOMPOSE_SUBLAYER_TRANSFORM(l);
253 | return _d.translateY;
254 | }
255 |
256 | extern void POPLayerSetSubTranslationY(CALayer *l, CGFloat f)
257 | {
258 | DECOMPOSE_SUBLAYER_TRANSFORM(l);
259 | _d.translateY = f;
260 | RECOMPOSE_SUBLAYER_TRANSFORM(l);
261 | }
262 |
263 | extern CGFloat POPLayerGetSubTranslationZ(CALayer *l)
264 | {
265 | DECOMPOSE_SUBLAYER_TRANSFORM(l);
266 | return _d.translateZ;
267 | }
268 |
269 | extern void POPLayerSetSubTranslationZ(CALayer *l, CGFloat f)
270 | {
271 | DECOMPOSE_SUBLAYER_TRANSFORM(l);
272 | _d.translateZ = f;
273 | RECOMPOSE_SUBLAYER_TRANSFORM(l);
274 | }
275 |
276 | extern CGPoint POPLayerGetSubTranslationXY(CALayer *l)
277 | {
278 | DECOMPOSE_SUBLAYER_TRANSFORM(l);
279 | return CGPointMake(_d.translateX, _d.translateY);
280 | }
281 |
282 | extern void POPLayerSetSubTranslationXY(CALayer *l, CGPoint p)
283 | {
284 | DECOMPOSE_SUBLAYER_TRANSFORM(l);
285 | _d.translateX = p.x;
286 | _d.translateY = p.y;
287 | RECOMPOSE_SUBLAYER_TRANSFORM(l);
288 | }
289 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPMath.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | #import
13 |
14 | #import "POPDefines.h"
15 | #import "POPVector.h"
16 |
17 | NS_INLINE CGFloat sqrtr(CGFloat f)
18 | {
19 | #if CGFLOAT_IS_DOUBLE
20 | return sqrt(f);
21 | #else
22 | return sqrtf(f);
23 | #endif
24 | }
25 |
26 | // round to nearest sub; pass 2.0 to round to every 0.5 (eg: retina pixels)
27 | NS_INLINE CGFloat POPSubRound(CGFloat f, CGFloat sub)
28 | {
29 | return round(f * sub) / sub;
30 | }
31 |
32 | #define MIX(a, b, f) ((a) + (f) * ((b) - (a)))
33 |
34 | // the longer the duration, the higher the necessary precision
35 | #define SOLVE_EPS(dur) (1. / (1000. * (dur)))
36 |
37 | #define _EQLF_(x, y, epsilon) (fabsf ((x) - (y)) < epsilon)
38 |
39 | extern void POPInterpolateVector(NSUInteger count, CGFloat *dst, const CGFloat *from, const CGFloat *to, CGFloat f);
40 |
41 | extern double POPTimingFunctionSolve(const double vec[4], double t, double eps);
42 |
43 | // quadratic mapping of t [0, 1] to [start, end]
44 | extern double POPQuadraticOutInterpolation(double t, double start, double end);
45 |
46 | // normalize value to [0, 1] based on its range [startValue, endValue]
47 | extern double POPNormalize(double value, double startValue, double endValue);
48 |
49 | // project a normalized value [0, 1] to a given range [start, end]
50 | extern double POPProjectNormal(double n, double start, double end);
51 |
52 | // solve a quadratic equation of the form a * x^2 + b * x + c = 0
53 | extern void POPQuadraticSolve(CGFloat a, CGFloat b, CGFloat c, CGFloat &x1, CGFloat &x2);
54 |
55 | // for a given tension return the bouncy 3 friction that produces no bounce
56 | extern double POPBouncy3NoBounce(double tension);
57 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPMath.mm:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import "POPMath.h"
11 |
12 | #import "POPAnimationPrivate.h"
13 | #import "UnitBezier.h"
14 |
15 | void POPInterpolateVector(NSUInteger count, CGFloat *dst, const CGFloat *from, const CGFloat *to, CGFloat f)
16 | {
17 | for (NSUInteger idx = 0; idx < count; idx++) {
18 | dst[idx] = MIX(from[idx], to[idx], f);
19 | }
20 | }
21 |
22 | double POPTimingFunctionSolve(const double vec[4], double t, double eps)
23 | {
24 | WebCore::UnitBezier bezier(vec[0], vec[1], vec[2], vec[3]);
25 | return bezier.solve(t, eps);
26 | }
27 |
28 | double POPNormalize(double value, double startValue, double endValue)
29 | {
30 | return (value - startValue) / (endValue - startValue);
31 | }
32 |
33 | double POPProjectNormal(double n, double start, double end)
34 | {
35 | return start + (n * (end - start));
36 | }
37 |
38 | static double linear_interpolation(double t, double start, double end)
39 | {
40 | return t * end + (1.f - t) * start;
41 | }
42 |
43 | double POPQuadraticOutInterpolation(double t, double start, double end)
44 | {
45 | return linear_interpolation(2*t - t*t, start, end);
46 | }
47 |
48 | static double b3_friction1(double x)
49 | {
50 | return (0.0007 * pow(x, 3)) - (0.031 * pow(x, 2)) + 0.64 * x + 1.28;
51 | }
52 |
53 | static double b3_friction2(double x)
54 | {
55 | return (0.000044 * pow(x, 3)) - (0.006 * pow(x, 2)) + 0.36 * x + 2.;
56 | }
57 |
58 | static double b3_friction3(double x)
59 | {
60 | return (0.00000045 * pow(x, 3)) - (0.000332 * pow(x, 2)) + 0.1078 * x + 5.84;
61 | }
62 |
63 | double POPBouncy3NoBounce(double tension)
64 | {
65 | double friction = 0;
66 | if (tension <= 18.) {
67 | friction = b3_friction1(tension);
68 | } else if (tension > 18 && tension <= 44) {
69 | friction = b3_friction2(tension);
70 | } else if (tension > 44) {
71 | friction = b3_friction3(tension);
72 | } else {
73 | assert(false);
74 | }
75 | return friction;
76 | }
77 |
78 | void POPQuadraticSolve(CGFloat a, CGFloat b, CGFloat c, CGFloat &x1, CGFloat &x2)
79 | {
80 | CGFloat discriminant = sqrt(b * b - 4 * a * c);
81 | x1 = (-b + discriminant) / (2 * a);
82 | x2 = (-b - discriminant) / (2 * a);
83 | }
84 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPPropertyAnimation.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | //#import
11 | #import "POPAnimatableProperty.h"
12 |
13 | //#import
14 | #import "POPAnimation.h"
15 |
16 | /**
17 | @abstract Flags for clamping animation values.
18 | @discussion Animation values can optionally be clamped to avoid overshoot. kPOPAnimationClampStart ensures values are more than fromValue and kPOPAnimationClampEnd ensures values are less than toValue.
19 | */
20 | typedef NS_OPTIONS(NSUInteger, POPAnimationClampFlags)
21 | {
22 | kPOPAnimationClampNone = 0,
23 | kPOPAnimationClampStart = 1UL << 0,
24 | kPOPAnimationClampEnd = 1UL << 1,
25 | kPOPAnimationClampBoth = kPOPAnimationClampStart | kPOPAnimationClampEnd,
26 | };
27 |
28 | /**
29 | @abstract The semi-concrete property animation subclass.
30 | */
31 | @interface POPPropertyAnimation : POPAnimation
32 |
33 | /**
34 | @abstract The property to animate.
35 | */
36 | @property (strong, nonatomic) POPAnimatableProperty *property;
37 |
38 | /**
39 | @abstract The value to animate from.
40 | @discussion The value type should match the property. If unspecified, the value is initialized to the object's current value on animation start.
41 | */
42 | @property (copy, nonatomic) id fromValue;
43 |
44 | /**
45 | @abstract The value to animate to.
46 | @discussion The value type should match the property. If unspecified, the value is initialized to the object's current value on animation start.
47 | */
48 | @property (copy, nonatomic) id toValue;
49 |
50 | /**
51 | @abstract The rounding factor applied to the current animated value.
52 | @discussion Specify 1.0 to animate between integral values. Defaults to 0 meaning no rounding.
53 | */
54 | @property (assign, nonatomic) CGFloat roundingFactor;
55 |
56 | /**
57 | @abstract The clamp mode applied to the current animated value.
58 | @discussion See {@ref POPAnimationClampFlags} for possible values. Defaults to kPOPAnimationClampNone.
59 | */
60 | @property (assign, nonatomic) NSUInteger clampMode;
61 |
62 | /**
63 | @abstract The flag indicating whether values should be "added" each frame, rather than set.
64 | @discussion Addition may be type dependent. Defaults to NO.
65 | */
66 | @property (assign, nonatomic, getter = isAdditive) BOOL additive;
67 |
68 | @end
69 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPPropertyAnimation.mm:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import "POPPropertyAnimationInternal.h"
11 |
12 | @implementation POPPropertyAnimation
13 |
14 | #pragma mark - Lifecycle
15 |
16 | #undef __state
17 | #define __state ((POPPropertyAnimationState *)_state)
18 |
19 | - (void)_initState
20 | {
21 | _state = new POPPropertyAnimationState(self);
22 | }
23 |
24 | #pragma mark - Properties
25 |
26 | DEFINE_RW_FLAG(POPPropertyAnimationState, additive, isAdditive, setAdditive:);
27 | DEFINE_RW_PROPERTY(POPPropertyAnimationState, roundingFactor, setRoundingFactor:, CGFloat);
28 | DEFINE_RW_PROPERTY(POPPropertyAnimationState, clampMode, setClampMode:, NSUInteger);
29 | DEFINE_RW_PROPERTY_OBJ(POPPropertyAnimationState, property, setProperty:, POPAnimatableProperty*, ((POPPropertyAnimationState*)_state)->updatedDynamicsThreshold(););
30 | DEFINE_RW_PROPERTY_OBJ_COPY(POPPropertyAnimationState, progressMarkers, setProgressMarkers:, NSArray*, ((POPPropertyAnimationState*)_state)->updatedProgressMarkers(););
31 |
32 | - (id)fromValue
33 | {
34 | return POPBox(__state->fromVec, __state->valueType);
35 | }
36 |
37 | - (void)setFromValue:(id)aValue
38 | {
39 | POPPropertyAnimationState *s = __state;
40 | VectorRef vec = POPUnbox(aValue, s->valueType, s->valueCount, YES);
41 | if (!vec_equal(vec, s->fromVec)) {
42 | s->fromVec = vec;
43 |
44 | if (s->tracing) {
45 | [s->tracer updateFromValue:aValue];
46 | }
47 | }
48 | }
49 |
50 | - (id)toValue
51 | {
52 | return POPBox(__state->toVec, __state->valueType);
53 | }
54 |
55 | - (void)setToValue:(id)aValue
56 | {
57 | POPPropertyAnimationState *s = __state;
58 | VectorRef vec = POPUnbox(aValue, s->valueType, s->valueCount, YES);
59 |
60 | if (!vec_equal(vec, s->toVec)) {
61 | s->toVec = vec;
62 |
63 | // invalidate to dependent state
64 | s->didReachToValue = false;
65 | s->distanceVec = NULL;
66 |
67 | if (s->tracing) {
68 | [s->tracer updateToValue:aValue];
69 | }
70 |
71 | // automatically unpause active animations
72 | if (s->active && s->paused) {
73 | s->setPaused(false);
74 | }
75 | }
76 | }
77 |
78 | - (id)currentValue
79 | {
80 | return POPBox(__state->currentValue(), __state->valueType);
81 | }
82 |
83 | #pragma mark - Utility
84 |
85 | - (void)_appendDescription:(NSMutableString *)s debug:(BOOL)debug
86 | {
87 | [s appendFormat:@"; from = %@; to = %@", describe(__state->fromVec), describe(__state->toVec)];
88 |
89 | if (_state->active)
90 | [s appendFormat:@"; currentValue = %@", describe(__state->currentValue())];
91 |
92 | if (__state->velocityVec && 0 != __state->velocityVec->norm())
93 | [s appendFormat:@"; velocity = %@", describe(__state->velocityVec)];
94 |
95 | if (!self.removedOnCompletion)
96 | [s appendFormat:@"; removedOnCompletion = %@", POPStringFromBOOL(self.removedOnCompletion)];
97 |
98 | if (__state->progressMarkers)
99 | [s appendFormat:@"; progressMarkers = [%@]", [__state->progressMarkers componentsJoinedByString:@", "]];
100 |
101 | if (_state->active)
102 | [s appendFormat:@"; progress = %f", __state->progress];
103 | }
104 |
105 | @end
106 |
107 | @implementation POPPropertyAnimation (NSCopying)
108 |
109 | - (instancetype)copyWithZone:(NSZone *)zone {
110 |
111 | POPPropertyAnimation *copy = [super copyWithZone:zone];
112 |
113 | if (copy) {
114 | copy.property = [self.property copyWithZone:zone];
115 | copy.fromValue = self.fromValue;
116 | copy.toValue = self.toValue;
117 | copy.roundingFactor = self.roundingFactor;
118 | copy.clampMode = self.clampMode;
119 | copy.additive = self.additive;
120 | }
121 |
122 | return copy;
123 | }
124 |
125 | @end
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPSpringAnimation.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | //#import
11 | #import "POPPropertyAnimation.h"
12 |
13 | /**
14 | @abstract A concrete spring animation class.
15 | @discussion Animation is achieved through modeling spring dynamics.
16 | */
17 | @interface POPSpringAnimation : POPPropertyAnimation
18 |
19 | /**
20 | @abstract The designated initializer.
21 | @returns An instance of a spring animation.
22 | */
23 | + (instancetype)animation;
24 |
25 | /**
26 | @abstract Convenience initializer that returns an animation with animatable property of name.
27 | @param name The name of the animatable property.
28 | @returns An instance of a spring animation configured with specified animatable property.
29 | */
30 | + (instancetype)animationWithPropertyNamed:(NSString *)name;
31 |
32 | /**
33 | @abstract The current velocity value.
34 | @discussion Set before animation start to account for initial velocity. Expressed in change of value units per second.
35 | */
36 | @property (copy, nonatomic) id velocity;
37 |
38 | /**
39 | @abstract The effective bounciness.
40 | @discussion Use in conjunction with 'springSpeed' to change animation effect. Values are converted into corresponding dynamics constants. Higher values increase spring movement range resulting in more oscillations and springiness. Defined as a value in the range [0, 20]. Defaults to 4.
41 | */
42 | @property (assign, nonatomic) CGFloat springBounciness;
43 |
44 | /**
45 | @abstract The effective speed.
46 | @discussion Use in conjunction with 'springBounciness' to change animation effect. Values are converted into corresponding dynamics constants. Higher values increase the dampening power of the spring resulting in a faster initial velocity and more rapid bounce slowdown. Defined as a value in the range [0, 20]. Defaults to 12.
47 | */
48 | @property (assign, nonatomic) CGFloat springSpeed;
49 |
50 | /**
51 | @abstract The tension used in the dynamics simulation.
52 | @discussion Can be used over bounciness and speed for finer grain tweaking of animation effect.
53 | */
54 | @property (assign, nonatomic) CGFloat dynamicsTension;
55 |
56 | /**
57 | @abstract The friction used in the dynamics simulation.
58 | @discussion Can be used over bounciness and speed for finer grain tweaking of animation effect.
59 | */
60 | @property (assign, nonatomic) CGFloat dynamicsFriction;
61 |
62 | /**
63 | @abstract The mass used in the dynamics simulation.
64 | @discussion Can be used over bounciness and speed for finer grain tweaking of animation effect.
65 | */
66 | @property (assign, nonatomic) CGFloat dynamicsMass;
67 |
68 | @end
69 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPSpringAnimation.mm:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import "POPSpringAnimationInternal.h"
11 |
12 | @implementation POPSpringAnimation
13 |
14 | #pragma mark - Lifecycle
15 |
16 | #undef __state
17 | #define __state ((POPSpringAnimationState *)_state)
18 |
19 | + (instancetype)animation
20 | {
21 | return [[self alloc] init];
22 | }
23 |
24 | + (instancetype)animationWithPropertyNamed:(NSString *)aName
25 | {
26 | POPSpringAnimation *anim = [self animation];
27 | anim.property = [POPAnimatableProperty propertyWithName:aName];
28 | return anim;
29 | }
30 |
31 | - (void)_initState
32 | {
33 | _state = new POPSpringAnimationState(self);
34 | }
35 |
36 | - (id)init
37 | {
38 | self = [super _init];
39 | if (nil != self) {
40 | __state->solver = new SpringSolver4d(1, 1, 1);
41 | __state->updatedDynamicsThreshold();
42 | __state->updatedBouncinessAndSpeed();
43 | }
44 | return self;
45 | }
46 |
47 | - (void)dealloc
48 | {
49 | if (__state) {
50 | delete __state->solver;
51 | __state->solver = NULL;
52 | }
53 | }
54 |
55 | #pragma mark - Properties
56 |
57 | - (id)velocity
58 | {
59 | return POPBox(__state->velocityVec, __state->valueType);
60 | }
61 |
62 | - (void)setVelocity:(id)aValue
63 | {
64 | POPPropertyAnimationState *s = __state;
65 | VectorRef vec = POPUnbox(aValue, s->valueType, s->valueCount, YES);
66 | VectorRef origVec = POPUnbox(aValue, s->valueType, s->valueCount, YES);
67 | if (!vec_equal(vec, s->velocityVec)) {
68 | s->velocityVec = vec;
69 | s->originalVelocityVec = origVec;
70 |
71 | if (s->tracing) {
72 | [s->tracer updateVelocity:aValue];
73 | }
74 | }
75 | }
76 |
77 | DEFINE_RW_PROPERTY(POPSpringAnimationState, dynamicsTension, setDynamicsTension:, CGFloat, [self _updatedDynamicsTension];);
78 | DEFINE_RW_PROPERTY(POPSpringAnimationState, dynamicsFriction, setDynamicsFriction:, CGFloat, [self _updatedDynamicsFriction];);
79 | DEFINE_RW_PROPERTY(POPSpringAnimationState, dynamicsMass, setDynamicsMass:, CGFloat, [self _updatedDynamicsMass];);
80 |
81 | FB_PROPERTY_GET(POPSpringAnimationState, springSpeed, CGFloat);
82 | - (void)setSpringSpeed:(CGFloat)aFloat
83 | {
84 | POPSpringAnimationState *s = __state;
85 | if (s->userSpecifiedDynamics || aFloat != s->springSpeed) {
86 | s->springSpeed = aFloat;
87 | s->userSpecifiedDynamics = false;
88 | s->updatedBouncinessAndSpeed();
89 | if (s->tracing) {
90 | [s->tracer updateSpeed:aFloat];
91 | }
92 | }
93 | }
94 |
95 | FB_PROPERTY_GET(POPSpringAnimationState, springBounciness, CGFloat);
96 | - (void)setSpringBounciness:(CGFloat)aFloat
97 | {
98 | POPSpringAnimationState *s = __state;
99 | if (s->userSpecifiedDynamics || aFloat != s->springBounciness) {
100 | s->springBounciness = aFloat;
101 | s->userSpecifiedDynamics = false;
102 | s->updatedBouncinessAndSpeed();
103 | if (s->tracing) {
104 | [s->tracer updateBounciness:aFloat];
105 | }
106 | }
107 | }
108 |
109 | - (SpringSolver4d *)solver
110 | {
111 | return __state->solver;
112 | }
113 |
114 | - (void)setSolver:(SpringSolver4d *)aSolver
115 | {
116 | if (aSolver != __state->solver) {
117 | if (__state->solver) {
118 | delete(__state->solver);
119 | }
120 | __state->solver = aSolver;
121 | }
122 | }
123 |
124 | #pragma mark - Utility
125 |
126 | - (void)_updatedDynamicsTension
127 | {
128 | __state->userSpecifiedDynamics = true;
129 | if(__state->tracing) {
130 | [__state->tracer updateTension:__state->dynamicsTension];
131 | }
132 | __state->updatedDynamics();
133 | }
134 |
135 | - (void)_updatedDynamicsFriction
136 | {
137 | __state->userSpecifiedDynamics = true;
138 | if(__state->tracing) {
139 | [__state->tracer updateFriction:__state->dynamicsFriction];
140 | }
141 | __state->updatedDynamics();
142 | }
143 |
144 | - (void)_updatedDynamicsMass
145 | {
146 | __state->userSpecifiedDynamics = true;
147 | if(__state->tracing) {
148 | [__state->tracer updateMass:__state->dynamicsMass];
149 | }
150 | __state->updatedDynamics();
151 | }
152 |
153 | - (void)_appendDescription:(NSMutableString *)s debug:(BOOL)debug
154 | {
155 | [super _appendDescription:s debug:debug];
156 |
157 | if (debug) {
158 | if (_state->userSpecifiedDynamics) {
159 | [s appendFormat:@"; dynamics = (tension:%f, friction:%f, mass:%f)", __state->dynamicsTension, __state->dynamicsFriction, __state->dynamicsMass];
160 | } else {
161 | [s appendFormat:@"; bounciness = %f; speed = %f", __state->springBounciness, __state->springSpeed];
162 | }
163 | }
164 | }
165 |
166 | @end
167 |
168 | @implementation POPSpringAnimation (NSCopying)
169 |
170 | - (instancetype)copyWithZone:(NSZone *)zone {
171 |
172 | POPSpringAnimation *copy = [super copyWithZone:zone];
173 |
174 | if (copy) {
175 | id velocity = POPBox(__state->originalVelocityVec, __state->valueType);
176 |
177 | // If velocity never gets set, then POPBox will return nil, messing up __state->valueCount.
178 | if (velocity) {
179 | copy.velocity = velocity;
180 | }
181 |
182 | copy.springBounciness = self.springBounciness;
183 | copy.springSpeed = self.springSpeed;
184 | copy.dynamicsTension = self.dynamicsTension;
185 | copy.dynamicsFriction = self.dynamicsFriction;
186 | copy.dynamicsMass = self.dynamicsMass;
187 | }
188 |
189 | return copy;
190 | }
191 |
192 | @end
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPSpringAnimationInternal.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | #import "POPAnimationExtras.h"
13 | #import "POPPropertyAnimationInternal.h"
14 |
15 | struct _POPSpringAnimationState : _POPPropertyAnimationState
16 | {
17 | SpringSolver4d *solver;
18 | CGFloat springSpeed;
19 | CGFloat springBounciness; // normalized springiness
20 | CGFloat dynamicsTension; // tension
21 | CGFloat dynamicsFriction; // friction
22 | CGFloat dynamicsMass; // mass
23 |
24 | _POPSpringAnimationState(id __unsafe_unretained anim) : _POPPropertyAnimationState(anim),
25 | solver(nullptr),
26 | springSpeed(12.),
27 | springBounciness(4.),
28 | dynamicsTension(0),
29 | dynamicsFriction(0),
30 | dynamicsMass(0)
31 | {
32 | type = kPOPAnimationSpring;
33 | }
34 |
35 | bool hasConverged()
36 | {
37 | NSUInteger count = valueCount;
38 | if (shouldRound()) {
39 | return vec_equal(previous2Vec, previousVec) && vec_equal(previousVec, toVec);
40 | } else {
41 | if (!previousVec || !previous2Vec)
42 | return false;
43 |
44 | CGFloat t = dynamicsThreshold / 5;
45 |
46 | const CGFloat *toValues = toVec->data();
47 | const CGFloat *previousValues = previousVec->data();
48 | const CGFloat *previous2Values = previous2Vec->data();
49 |
50 | for (NSUInteger idx = 0; idx < count; idx++) {
51 | if ((std::abs(toValues[idx] - previousValues[idx]) >= t) || (std::abs(previous2Values[idx] - previousValues[idx]) >= t)) {
52 | return false;
53 | }
54 | }
55 | return true;
56 | }
57 | }
58 |
59 | bool isDone() {
60 | if (_POPPropertyAnimationState::isDone()) {
61 | return true;
62 | }
63 | return solver->started() && (hasConverged() || solver->hasConverged());
64 | }
65 |
66 | void updatedDynamics()
67 | {
68 | if (NULL != solver) {
69 | solver->setConstants(dynamicsTension, dynamicsFriction, dynamicsMass);
70 | }
71 | }
72 |
73 | void updatedDynamicsThreshold()
74 | {
75 | _POPPropertyAnimationState::updatedDynamicsThreshold();
76 | if (NULL != solver) {
77 | solver->setThreshold(dynamicsThreshold);
78 | }
79 | }
80 |
81 | void updatedBouncinessAndSpeed() {
82 | [POPSpringAnimation convertBounciness:springBounciness speed:springSpeed toTension:&dynamicsTension friction:&dynamicsFriction mass:&dynamicsMass];
83 | updatedDynamics();
84 | }
85 |
86 | bool advance(CFTimeInterval time, CFTimeInterval dt, id obj) {
87 | // advance past not yet initialized animations
88 | if (NULL == currentVec) {
89 | return false;
90 | }
91 |
92 | CFTimeInterval localTime = time - startTime;
93 |
94 | Vector4d value = vector4d(currentVec);
95 | Vector4d toValue = vector4d(toVec);
96 | Vector4d velocity = vector4d(velocityVec);
97 |
98 | SSState4d state;
99 | state.p = toValue - value;
100 |
101 | // the solver assumes a spring of size zero
102 | // flip the velocity from user perspective to solver perspective
103 | state.v = velocity * -1;
104 |
105 | solver->advance(state, localTime, dt);
106 | value = toValue - state.p;
107 |
108 | // flip velocity back to user perspective
109 | velocity = state.v * -1;
110 |
111 | *currentVec = value;
112 |
113 | if (velocityVec) {
114 | *velocityVec = velocity;
115 | }
116 |
117 | clampCurrentValue();
118 |
119 | return true;
120 | }
121 |
122 | virtual void reset(bool all) {
123 | _POPPropertyAnimationState::reset(all);
124 |
125 | if (solver) {
126 | solver->setConstants(dynamicsTension, dynamicsFriction, dynamicsMass);
127 | solver->reset();
128 | }
129 | }
130 | };
131 |
132 | typedef struct _POPSpringAnimationState POPSpringAnimationState;
133 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPSpringSolver.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | #import "POPVector.h"
13 |
14 | namespace POP {
15 |
16 | template
17 | struct SSState
18 | {
19 | T p;
20 | T v;
21 | };
22 |
23 | template
24 | struct SSDerivative
25 | {
26 | T dp;
27 | T dv;
28 | };
29 |
30 | typedef SSState SSState4d;
31 | typedef SSDerivative SSDerivative4d;
32 |
33 | const CFTimeInterval solverDt = 0.001f;
34 | const CFTimeInterval maxSolverDt = 30.0f;
35 |
36 | /**
37 | Templated spring solver class.
38 | */
39 | template
40 | class SpringSolver
41 | {
42 | double _k; // stiffness
43 | double _b; // dampening
44 | double _m; // mass
45 |
46 | double _tp; // threshold
47 | double _tv; // threshold velocity
48 | double _ta; // threshold acceleration
49 |
50 | CFTimeInterval _accumulatedTime;
51 | SSState _lastState;
52 | T _lastDv;
53 | bool _started;
54 |
55 | public:
56 | SpringSolver(double k, double b, double m = 1) : _k(k), _b(b), _m(m), _started(false)
57 | {
58 | _accumulatedTime = 0;
59 | _lastState.p = T::Zero();
60 | _lastState.v = T::Zero();
61 | _lastDv = T::Zero();
62 | setThreshold(1.);
63 | }
64 |
65 | ~SpringSolver()
66 | {
67 | }
68 |
69 | bool started()
70 | {
71 | return _started;
72 | }
73 |
74 | void setConstants(double k, double b, double m)
75 | {
76 | _k = k;
77 | _b = b;
78 | _m = m;
79 | }
80 |
81 | void setThreshold(double t)
82 | {
83 | _tp = t / 2; // half a unit
84 | _tv = 25.0 * t; // 5 units per second, squared for comparison
85 | _ta = 625.0 * t * t; // 5 units per second squared, squared for comparison
86 | }
87 |
88 | T acceleration(const SSState &state, double t)
89 | {
90 | return state.p*(-_k/_m) - state.v*(_b/_m);
91 | }
92 |
93 | SSDerivative evaluate(const SSState &initial, double t)
94 | {
95 | SSDerivative output;
96 | output.dp = initial.v;
97 | output.dv = acceleration(initial, t);
98 | return output;
99 | }
100 |
101 | SSDerivative evaluate(const SSState &initial, double t, double dt, const SSDerivative &d)
102 | {
103 | SSState state;
104 | state.p = initial.p + d.dp*dt;
105 | state.v = initial.v + d.dv*dt;
106 | SSDerivative output;
107 | output.dp = state.v;
108 | output.dv = acceleration(state, t+dt);
109 | return output;
110 | }
111 |
112 | void integrate(SSState &state, double t, double dt)
113 | {
114 | SSDerivative a = evaluate(state, t);
115 | SSDerivative b = evaluate(state, t, dt*0.5, a);
116 | SSDerivative c = evaluate(state, t, dt*0.5, b);
117 | SSDerivative d = evaluate(state, t, dt, c);
118 |
119 | T dpdt = (a.dp + (b.dp + c.dp)*2.0 + d.dp) * (1.0/6.0);
120 | T dvdt = (a.dv + (b.dv + c.dv)*2.0 + d.dv) * (1.0/6.0);
121 |
122 | state.p = state.p + dpdt*dt;
123 | state.v = state.v + dvdt*dt;
124 |
125 | _lastDv = dvdt;
126 | }
127 |
128 | SSState interpolate(const SSState &previous, const SSState ¤t, double alpha)
129 | {
130 | SSState state;
131 | state.p = current.p*alpha + previous.p*(1-alpha);
132 | state.v = current.v*alpha + previous.v*(1-alpha);
133 | return state;
134 | }
135 |
136 | void advance(SSState &state, double t, double dt)
137 | {
138 | _started = true;
139 |
140 | if (dt > maxSolverDt) {
141 | // excessive time step, force shut down
142 | _lastDv = _lastState.v = _lastState.p = T::Zero();
143 | } else {
144 | _accumulatedTime += dt;
145 |
146 | SSState previousState = state, currentState = state;
147 | while (_accumulatedTime >= solverDt) {
148 | previousState = currentState;
149 | this->integrate(currentState, t, solverDt);
150 | t += solverDt;
151 | _accumulatedTime -= solverDt;
152 | }
153 | CFTimeInterval alpha = _accumulatedTime / solverDt;
154 | _lastState = state = this->interpolate(previousState, currentState, alpha);
155 | }
156 | }
157 |
158 | bool hasConverged()
159 | {
160 | if (!_started) {
161 | return false;
162 | }
163 |
164 | for (size_t idx = 0; idx < _lastState.p.size(); idx++) {
165 | if (fabs(_lastState.p(idx)) >= _tp) {
166 | return false;
167 | }
168 | }
169 |
170 | return (_lastState.v.squaredNorm() < _tv) && (_lastDv.squaredNorm() < _ta);
171 | }
172 |
173 | void reset()
174 | {
175 | _accumulatedTime = 0;
176 | _lastState.p = T::Zero();
177 | _lastState.v = T::Zero();
178 | _lastDv = T::Zero();
179 | _started = false;
180 | }
181 | };
182 |
183 | /**
184 | Convenience spring solver type definitions.
185 | */
186 | typedef SpringSolver SpringSolver2d;
187 | typedef SpringSolver SpringSolver3d;
188 | typedef SpringSolver SpringSolver4d;
189 | }
190 |
191 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/POPVector.mm:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2014-present, Facebook, Inc.
3 | All rights reserved.
4 |
5 | This source code is licensed under the BSD-style license found in the
6 | LICENSE file in the root directory of this source tree. An additional grant
7 | of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import "POPVector.h"
11 |
12 | #import "POPDefines.h"
13 | #import "POPCGUtils.h"
14 |
15 | namespace POP
16 | {
17 |
18 | Vector::Vector(const size_t count)
19 | {
20 | _count = count;
21 | _values = 0 != count ? (CGFloat *)calloc(count, sizeof(CGFloat)) : NULL;
22 | }
23 |
24 | Vector::Vector(const Vector& other)
25 | {
26 | _count = other.size();
27 | _values = 0 != _count ? (CGFloat *)calloc(_count, sizeof(CGFloat)) : NULL;
28 | if (0 != _count) {
29 | memcpy(_values, other.data(), _count * sizeof(CGFloat));
30 | }
31 | }
32 |
33 | Vector::~Vector()
34 | {
35 | if (NULL != _values) {
36 | free(_values);
37 | _values = NULL;
38 | }
39 | _count = 0;
40 | }
41 |
42 | void Vector::swap(Vector &first, Vector &second)
43 | {
44 | using std::swap;
45 | swap(first._count, second._count);
46 | swap(first._values, second._values);
47 | }
48 |
49 | Vector& Vector::operator=(const Vector& other)
50 | {
51 | Vector temp(other);
52 | swap(*this, temp);
53 | return *this;
54 | }
55 |
56 | bool Vector::operator==(const Vector &other) const {
57 | if (_count != other.size()) {
58 | return false;
59 | }
60 |
61 | const CGFloat * const values = other.data();
62 |
63 | for (NSUInteger idx = 0; idx < _count; idx++) {
64 | if (_values[idx] != values[idx]) {
65 | return false;
66 | }
67 | }
68 |
69 | return true;
70 | }
71 |
72 | bool Vector::operator!=(const Vector &other) const {
73 | if (_count == other.size()) {
74 | return false;
75 | }
76 |
77 | const CGFloat * const values = other.data();
78 |
79 | for (NSUInteger idx = 0; idx < _count; idx++) {
80 | if (_values[idx] != values[idx]) {
81 | return false;
82 | }
83 | }
84 |
85 | return true;
86 | }
87 |
88 | Vector *Vector::new_vector(NSUInteger count, const CGFloat *values)
89 | {
90 | if (0 == count) {
91 | return NULL;
92 | }
93 |
94 | Vector *v = new Vector(count);
95 | if (NULL != values) {
96 | memcpy(v->_values, values, count * sizeof(CGFloat));
97 | }
98 | return v;
99 | }
100 |
101 | Vector *Vector::new_vector(const Vector * const other)
102 | {
103 | if (NULL == other) {
104 | return NULL;
105 | }
106 |
107 | return Vector::new_vector(other->size(), other->data());
108 | }
109 |
110 | Vector *Vector::new_vector(NSUInteger count, Vector4r vec)
111 | {
112 | if (0 == count) {
113 | return NULL;
114 | }
115 |
116 | Vector *v = new Vector(count);
117 |
118 | NSCAssert(count <= 4, @"unexpected count %lu", (unsigned long)count);
119 | for (NSUInteger i = 0; i < MIN(count, (NSUInteger)4); i++) {
120 | v->_values[i] = vec[i];
121 | }
122 |
123 | return v;
124 | }
125 |
126 | Vector4r Vector::vector4r() const
127 | {
128 | Vector4r v = Vector4r::Zero();
129 | for (size_t i = 0; i < _count; i++) {
130 | v(i) = _values[i];
131 | }
132 | return v;
133 | }
134 |
135 | Vector2r Vector::vector2r() const
136 | {
137 | Vector2r v = Vector2r::Zero();
138 | if (_count > 0) v(0) = _values[0];
139 | if (_count > 1) v(1) = _values[1];
140 | return v;
141 | }
142 |
143 | Vector *Vector::new_cg_float(CGFloat f)
144 | {
145 | Vector *v = new Vector(1);
146 | v->_values[0] = f;
147 | return v;
148 | }
149 |
150 | CGPoint Vector::cg_point () const
151 | {
152 | Vector2r v = vector2r();
153 | return CGPointMake(v(0), v(1));
154 | }
155 |
156 | Vector *Vector::new_cg_point(const CGPoint &p)
157 | {
158 | Vector *v = new Vector(2);
159 | v->_values[0] = p.x;
160 | v->_values[1] = p.y;
161 | return v;
162 | }
163 |
164 | CGSize Vector::cg_size () const
165 | {
166 | Vector2r v = vector2r();
167 | return CGSizeMake(v(0), v(1));
168 | }
169 |
170 | Vector *Vector::new_cg_size(const CGSize &s)
171 | {
172 | Vector *v = new Vector(2);
173 | v->_values[0] = s.width;
174 | v->_values[1] = s.height;
175 | return v;
176 | }
177 |
178 | CGRect Vector::cg_rect() const
179 | {
180 | return _count < 4 ? CGRectZero : CGRectMake(_values[0], _values[1], _values[2], _values[3]);
181 | }
182 |
183 | Vector *Vector::new_cg_rect(const CGRect &r)
184 | {
185 | Vector *v = new Vector(4);
186 | v->_values[0] = r.origin.x;
187 | v->_values[1] = r.origin.y;
188 | v->_values[2] = r.size.width;
189 | v->_values[3] = r.size.height;
190 | return v;
191 | }
192 |
193 | #if TARGET_OS_IPHONE
194 |
195 | UIEdgeInsets Vector::ui_edge_insets() const
196 | {
197 | return _count < 4 ? UIEdgeInsetsZero : UIEdgeInsetsMake(_values[0], _values[1], _values[2], _values[3]);
198 | }
199 |
200 | Vector *Vector::new_ui_edge_insets(const UIEdgeInsets &i)
201 | {
202 | Vector *v = new Vector(4);
203 | v->_values[0] = i.top;
204 | v->_values[1] = i.left;
205 | v->_values[2] = i.bottom;
206 | v->_values[3] = i.right;
207 | return v;
208 | }
209 |
210 | #endif
211 |
212 | CGAffineTransform Vector::cg_affine_transform() const
213 | {
214 | if (_count < 6) {
215 | return CGAffineTransformIdentity;
216 | }
217 |
218 | NSCAssert(size() >= 6, @"unexpected vector size:%lu", (unsigned long)size());
219 | CGAffineTransform t;
220 | t.a = _values[0];
221 | t.b = _values[1];
222 | t.c = _values[2];
223 | t.d = _values[3];
224 | t.tx = _values[4];
225 | t.ty = _values[5];
226 | return t;
227 | }
228 |
229 | Vector *Vector::new_cg_affine_transform(const CGAffineTransform &t)
230 | {
231 | Vector *v = new Vector(6);
232 | v->_values[0] = t.a;
233 | v->_values[1] = t.b;
234 | v->_values[2] = t.c;
235 | v->_values[3] = t.d;
236 | v->_values[4] = t.tx;
237 | v->_values[5] = t.ty;
238 | return v;
239 | }
240 |
241 | CGColorRef Vector::cg_color() const
242 | {
243 | if (_count < 4) {
244 | return NULL;
245 | }
246 | return POPCGColorRGBACreate(_values);
247 | }
248 |
249 | Vector *Vector::new_cg_color(CGColorRef color)
250 | {
251 | CGFloat rgba[4];
252 | POPCGColorGetRGBAComponents(color, rgba);
253 | return new_vector(4, rgba);
254 | }
255 |
256 | #if SCENEKIT_SDK_AVAILABLE
257 | SCNVector3 Vector::scn_vector3() const
258 | {
259 | return _count < 3 ? SCNVector3Make(0.0, 0.0, 0.0) : SCNVector3Make(_values[0], _values[1], _values[2]);
260 | }
261 |
262 | Vector *Vector::new_scn_vector3(const SCNVector3 &vec3)
263 | {
264 | Vector *v = new Vector(3);
265 | v->_values[0] = vec3.x;
266 | v->_values[1] = vec3.y;
267 | v->_values[2] = vec3.z;
268 | return v;
269 | }
270 |
271 | SCNVector4 Vector::scn_vector4() const
272 | {
273 | return _count < 4 ? SCNVector4Make(0.0, 0.0, 0.0, 0.0) : SCNVector4Make(_values[0], _values[1], _values[2], _values[3]);
274 | }
275 |
276 | Vector *Vector::new_scn_vector4(const SCNVector4 &vec4)
277 | {
278 | Vector *v = new Vector(4);
279 | v->_values[0] = vec4.x;
280 | v->_values[1] = vec4.y;
281 | v->_values[2] = vec4.z;
282 | v->_values[3] = vec4.w;
283 | return v;
284 | }
285 | #endif
286 |
287 | void Vector::subRound(CGFloat sub)
288 | {
289 | for (NSUInteger idx = 0; idx < _count; idx++) {
290 | _values[idx] = POPSubRound(_values[idx], sub);
291 | }
292 | }
293 |
294 | CGFloat Vector::norm() const
295 | {
296 | return sqrtr(squaredNorm());
297 | }
298 |
299 | CGFloat Vector::squaredNorm() const
300 | {
301 | CGFloat d = 0;
302 | for (NSUInteger idx = 0; idx < _count; idx++) {
303 | d += (_values[idx] * _values[idx]);
304 | }
305 | return d;
306 | }
307 |
308 | NSString * Vector::toString() const
309 | {
310 | if (0 == _count)
311 | return @"()";
312 |
313 | if (1 == _count)
314 | return [NSString stringWithFormat:@"%f", _values[0]];
315 |
316 | if (2 == _count)
317 | return [NSString stringWithFormat:@"(%.3f, %.3f)", _values[0], _values[1]];
318 |
319 | NSMutableString *s = [NSMutableString stringWithCapacity:10];
320 |
321 | for (NSUInteger idx = 0; idx < _count; idx++) {
322 | if (0 == idx) {
323 | [s appendFormat:@"[%.3f", _values[idx]];
324 | } else if (idx == _count - 1) {
325 | [s appendFormat:@", %.3f]", _values[idx]];
326 | } else {
327 | [s appendFormat:@", %.3f", _values[idx]];
328 | }
329 | }
330 |
331 | return s;
332 |
333 | }
334 | }
335 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/WebCore/FloatConversion.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2007 Apple Inc. All rights reserved.
3 | *
4 | * Redistribution and use in source and binary forms, with or without
5 | * modification, are permitted provided that the following conditions
6 | * are met:
7 | *
8 | * 1. Redistributions of source code must retain the above copyright
9 | * notice, this list of conditions and the following disclaimer.
10 | * 2. Redistributions in binary form must reproduce the above copyright
11 | * notice, this list of conditions and the following disclaimer in the
12 | * documentation and/or other materials provided with the distribution.
13 | * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 | * its contributors may be used to endorse or promote products derived
15 | * from this software without specific prior written permission.
16 | *
17 | * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | */
28 |
29 | #ifndef FloatConversion_h
30 | #define FloatConversion_h
31 |
32 | #include
33 |
34 | namespace WebCore {
35 |
36 | template
37 | float narrowPrecisionToFloat(T);
38 |
39 | template<>
40 | inline float narrowPrecisionToFloat(double number)
41 | {
42 | return static_cast(number);
43 | }
44 |
45 | template
46 | CGFloat narrowPrecisionToCGFloat(T);
47 |
48 | template<>
49 | inline CGFloat narrowPrecisionToCGFloat(double number)
50 | {
51 | return static_cast(number);
52 | }
53 |
54 | } // namespace WebCore
55 |
56 | #endif // FloatConversion_h
57 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/WebCore/UnitBezier.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3 | *
4 | * Redistribution and use in source and binary forms, with or without
5 | * modification, are permitted provided that the following conditions
6 | * are met:
7 | * 1. Redistributions of source code must retain the above copyright
8 | * notice, this list of conditions and the following disclaimer.
9 | * 2. Redistributions in binary form must reproduce the above copyright
10 | * notice, this list of conditions and the following disclaimer in the
11 | * documentation and/or other materials provided with the distribution.
12 | *
13 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 |
26 | #ifndef UnitBezier_h
27 | #define UnitBezier_h
28 |
29 | #include
30 |
31 | namespace WebCore {
32 |
33 | struct UnitBezier {
34 | UnitBezier(double p1x, double p1y, double p2x, double p2y)
35 | {
36 | // Calculate the polynomial coefficients, implicit first and last control points are (0,0) and (1,1).
37 | cx = 3.0 * p1x;
38 | bx = 3.0 * (p2x - p1x) - cx;
39 | ax = 1.0 - cx -bx;
40 |
41 | cy = 3.0 * p1y;
42 | by = 3.0 * (p2y - p1y) - cy;
43 | ay = 1.0 - cy - by;
44 | }
45 |
46 | double sampleCurveX(double t)
47 | {
48 | // `ax t^3 + bx t^2 + cx t' expanded using Horner's rule.
49 | return ((ax * t + bx) * t + cx) * t;
50 | }
51 |
52 | double sampleCurveY(double t)
53 | {
54 | return ((ay * t + by) * t + cy) * t;
55 | }
56 |
57 | double sampleCurveDerivativeX(double t)
58 | {
59 | return (3.0 * ax * t + 2.0 * bx) * t + cx;
60 | }
61 |
62 | // Given an x value, find a parametric value it came from.
63 | double solveCurveX(double x, double epsilon)
64 | {
65 | double t0;
66 | double t1;
67 | double t2;
68 | double x2;
69 | double d2;
70 | int i;
71 |
72 | // First try a few iterations of Newton's method -- normally very fast.
73 | for (t2 = x, i = 0; i < 8; i++) {
74 | x2 = sampleCurveX(t2) - x;
75 | if (fabs (x2) < epsilon)
76 | return t2;
77 | d2 = sampleCurveDerivativeX(t2);
78 | if (fabs(d2) < 1e-6)
79 | break;
80 | t2 = t2 - x2 / d2;
81 | }
82 |
83 | // Fall back to the bisection method for reliability.
84 | t0 = 0.0;
85 | t1 = 1.0;
86 | t2 = x;
87 |
88 | if (t2 < t0)
89 | return t0;
90 | if (t2 > t1)
91 | return t1;
92 |
93 | while (t0 < t1) {
94 | x2 = sampleCurveX(t2);
95 | if (fabs(x2 - x) < epsilon)
96 | return t2;
97 | if (x > x2)
98 | t0 = t2;
99 | else
100 | t1 = t2;
101 | t2 = (t1 - t0) * .5 + t0;
102 | }
103 |
104 | // Failure.
105 | return t2;
106 | }
107 |
108 | double solve(double x, double epsilon)
109 | {
110 | return sampleCurveY(solveCurveX(x, epsilon));
111 | }
112 |
113 | private:
114 | double ax;
115 | double bx;
116 | double cx;
117 |
118 | double ay;
119 | double by;
120 | double cy;
121 | };
122 | }
123 | #endif
124 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/module.modulemap:
--------------------------------------------------------------------------------
1 | framework module pop {
2 | umbrella header "POP.h"
3 |
4 | exclude header "POPAnimationPrivate.h"
5 | exclude header "POPAnimatorPrivate.h"
6 | }
7 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/pop-ios-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.facebook.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSHumanReadableCopyright
24 | Copyright © 2014 Facebook. All rights reserved.
25 | NSPrincipalClass
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/pop-osx-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | com.facebook.${PRODUCT_NAME:rfc1034identifier}
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | FMWK
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | NSHumanReadableCopyright
26 | Copyright © 2014 Facebook. All rights reserved.
27 | NSPrincipalClass
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Classes/Utils/pop/pop-tvos-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.facebook.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Supporting Files/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YYProgrammer/YYPhotoBrowserLikeWX/50506d404b1607ea14947d5740fbc30ed3659547/YYPhotoBrowserLikeWX/Supporting Files/.DS_Store
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Supporting Files/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Supporting Files/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Supporting Files/Assets.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "orientation" : "portrait",
5 | "idiom" : "iphone",
6 | "extent" : "full-screen",
7 | "minimum-system-version" : "11.0",
8 | "subtype" : "2436h",
9 | "scale" : "3x"
10 | },
11 | {
12 | "orientation" : "landscape",
13 | "idiom" : "iphone",
14 | "extent" : "full-screen",
15 | "minimum-system-version" : "11.0",
16 | "subtype" : "2436h",
17 | "scale" : "3x"
18 | },
19 | {
20 | "orientation" : "portrait",
21 | "idiom" : "iphone",
22 | "extent" : "full-screen",
23 | "minimum-system-version" : "8.0",
24 | "subtype" : "736h",
25 | "scale" : "3x"
26 | },
27 | {
28 | "orientation" : "landscape",
29 | "idiom" : "iphone",
30 | "extent" : "full-screen",
31 | "minimum-system-version" : "8.0",
32 | "subtype" : "736h",
33 | "scale" : "3x"
34 | },
35 | {
36 | "orientation" : "portrait",
37 | "idiom" : "iphone",
38 | "extent" : "full-screen",
39 | "minimum-system-version" : "8.0",
40 | "subtype" : "667h",
41 | "scale" : "2x"
42 | },
43 | {
44 | "orientation" : "portrait",
45 | "idiom" : "iphone",
46 | "extent" : "full-screen",
47 | "minimum-system-version" : "7.0",
48 | "scale" : "2x"
49 | },
50 | {
51 | "orientation" : "portrait",
52 | "idiom" : "iphone",
53 | "extent" : "full-screen",
54 | "minimum-system-version" : "7.0",
55 | "subtype" : "retina4",
56 | "scale" : "2x"
57 | },
58 | {
59 | "orientation" : "portrait",
60 | "idiom" : "ipad",
61 | "extent" : "full-screen",
62 | "minimum-system-version" : "7.0",
63 | "scale" : "1x"
64 | },
65 | {
66 | "orientation" : "landscape",
67 | "idiom" : "ipad",
68 | "extent" : "full-screen",
69 | "minimum-system-version" : "7.0",
70 | "scale" : "1x"
71 | },
72 | {
73 | "orientation" : "portrait",
74 | "idiom" : "ipad",
75 | "extent" : "full-screen",
76 | "minimum-system-version" : "7.0",
77 | "scale" : "2x"
78 | },
79 | {
80 | "orientation" : "landscape",
81 | "idiom" : "ipad",
82 | "extent" : "full-screen",
83 | "minimum-system-version" : "7.0",
84 | "scale" : "2x"
85 | },
86 | {
87 | "orientation" : "portrait",
88 | "idiom" : "iphone",
89 | "extent" : "full-screen",
90 | "scale" : "1x"
91 | },
92 | {
93 | "orientation" : "portrait",
94 | "idiom" : "iphone",
95 | "extent" : "full-screen",
96 | "scale" : "2x"
97 | },
98 | {
99 | "orientation" : "portrait",
100 | "idiom" : "iphone",
101 | "extent" : "full-screen",
102 | "subtype" : "retina4",
103 | "scale" : "2x"
104 | },
105 | {
106 | "orientation" : "portrait",
107 | "idiom" : "ipad",
108 | "extent" : "to-status-bar",
109 | "scale" : "1x"
110 | },
111 | {
112 | "orientation" : "portrait",
113 | "idiom" : "ipad",
114 | "extent" : "full-screen",
115 | "scale" : "1x"
116 | },
117 | {
118 | "orientation" : "landscape",
119 | "idiom" : "ipad",
120 | "extent" : "to-status-bar",
121 | "scale" : "1x"
122 | },
123 | {
124 | "orientation" : "landscape",
125 | "idiom" : "ipad",
126 | "extent" : "full-screen",
127 | "scale" : "1x"
128 | },
129 | {
130 | "orientation" : "portrait",
131 | "idiom" : "ipad",
132 | "extent" : "to-status-bar",
133 | "scale" : "2x"
134 | },
135 | {
136 | "orientation" : "portrait",
137 | "idiom" : "ipad",
138 | "extent" : "full-screen",
139 | "scale" : "2x"
140 | },
141 | {
142 | "orientation" : "landscape",
143 | "idiom" : "ipad",
144 | "extent" : "to-status-bar",
145 | "scale" : "2x"
146 | },
147 | {
148 | "orientation" : "landscape",
149 | "idiom" : "ipad",
150 | "extent" : "full-screen",
151 | "scale" : "2x"
152 | }
153 | ],
154 | "info" : {
155 | "version" : 1,
156 | "author" : "xcode"
157 | }
158 | }
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Supporting Files/Images/01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YYProgrammer/YYPhotoBrowserLikeWX/50506d404b1607ea14947d5740fbc30ed3659547/YYPhotoBrowserLikeWX/Supporting Files/Images/01.jpg
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Supporting Files/Images/02.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YYProgrammer/YYPhotoBrowserLikeWX/50506d404b1607ea14947d5740fbc30ed3659547/YYPhotoBrowserLikeWX/Supporting Files/Images/02.jpg
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Supporting Files/Images/03.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YYProgrammer/YYPhotoBrowserLikeWX/50506d404b1607ea14947d5740fbc30ed3659547/YYPhotoBrowserLikeWX/Supporting Files/Images/03.jpg
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Supporting Files/Images/04.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YYProgrammer/YYPhotoBrowserLikeWX/50506d404b1607ea14947d5740fbc30ed3659547/YYPhotoBrowserLikeWX/Supporting Files/Images/04.jpg
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Supporting Files/Images/05.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YYProgrammer/YYPhotoBrowserLikeWX/50506d404b1607ea14947d5740fbc30ed3659547/YYPhotoBrowserLikeWX/Supporting Files/Images/05.jpg
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Supporting Files/Images/06.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YYProgrammer/YYPhotoBrowserLikeWX/50506d404b1607ea14947d5740fbc30ed3659547/YYPhotoBrowserLikeWX/Supporting Files/Images/06.jpg
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Supporting Files/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | Launch Screen
25 | UIRequiredDeviceCapabilities
26 |
27 | armv7
28 |
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 |
33 | UISupportedInterfaceOrientations~ipad
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationPortraitUpsideDown
37 | UIInterfaceOrientationLandscapeLeft
38 | UIInterfaceOrientationLandscapeRight
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWX/Supporting Files/Launch Screen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
30 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWXTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWXTests/YYPhotoBrowserLikeWXTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // YYPhotoBrowserLikeWXTests.m
3 | // YYPhotoBrowserLikeWXTests
4 | //
5 | // Created by yuyou on 2017/12/5.
6 | // Copyright © 2017年 yy. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface YYPhotoBrowserLikeWXTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation YYPhotoBrowserLikeWXTests
16 |
17 | - (void)setUp {
18 | [super setUp];
19 | // Put setup code here. This method is called before the invocation of each test method in the class.
20 | }
21 |
22 | - (void)tearDown {
23 | // Put teardown code here. This method is called after the invocation of each test method in the class.
24 | [super tearDown];
25 | }
26 |
27 | - (void)testExample {
28 | // This is an example of a functional test case.
29 | // Use XCTAssert and related functions to verify your tests produce the correct results.
30 | }
31 |
32 | - (void)testPerformanceExample {
33 | // This is an example of a performance test case.
34 | [self measureBlock:^{
35 | // Put the code you want to measure the time of here.
36 | }];
37 | }
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWXUITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/YYPhotoBrowserLikeWXUITests/YYPhotoBrowserLikeWXUITests.m:
--------------------------------------------------------------------------------
1 | //
2 | // YYPhotoBrowserLikeWXUITests.m
3 | // YYPhotoBrowserLikeWXUITests
4 | //
5 | // Created by yuyou on 2017/12/5.
6 | // Copyright © 2017年 yy. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface YYPhotoBrowserLikeWXUITests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation YYPhotoBrowserLikeWXUITests
16 |
17 | - (void)setUp {
18 | [super setUp];
19 |
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 |
22 | // In UI tests it is usually best to stop immediately when a failure occurs.
23 | self.continueAfterFailure = NO;
24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
25 | [[[XCUIApplication alloc] init] launch];
26 |
27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
28 | }
29 |
30 | - (void)tearDown {
31 | // Put teardown code here. This method is called after the invocation of each test method in the class.
32 | [super tearDown];
33 | }
34 |
35 | - (void)testExample {
36 | // Use recording to get started writing UI tests.
37 | // Use XCTAssert and related functions to verify your tests produce the correct results.
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------