美文网首页
Facebook_Pop的使用指北

Facebook_Pop的使用指北

作者: All_Be_Alright | 来源:发表于2021-08-04 11:30 被阅读0次

    背景

    • 最近公司有了一个创新项目,就是在视频视图之上添加一层视图,视图设计涉及到了复杂的控件动画,会根据视频的播放,显示一些控件,控件有位移、缩放、旋转、shake等动画。
    • 在网上调研了一下,对比了苹果的CoreAnimation,觉得Facebook_Pop使用起来更加简单一些,并且有很多优点。
    • 在使用中,遇到了一个bug,Pop的kPOPLayerRotationY存在Bug,大于90度就会出错。
    pop bug

    Pop介绍

    pop
    • Pop的Github

    • Facebook 在发布了 Paper 之后,似乎还不满足于只是将其作为一个概念性产品,更进一步开源了其背后的动画引擎 POP,此举大有三年前发布的 iOS UI 框架 Three20 的意味。而 POP 开源后也不负 Facebook 的厚望。

    • POP背后的开发者是 Kimon Tsinteris, Push Pop Press 的联合创始人,曾经在Apple担任高级工程师,并参与了 iPhone 和 iPad 上软件的研发(iPhone的指南针以及地图)。2011年的时候 Facebook 收购了他的公司,此后他便加入了 Facebook 负责 Facebook iOS 版本的开发。

    • 如果你打开 Push Pop Press 开发的 AI Gore 这款 App,你会发现交互和动画与Paper几乎如出一辙。对,他们都是 Kimon Tsinteris 开发的。

    • 不满于 Apple 自身动画框架的单调,Push Pop Press 致力于创造一个逼真的、充满物理效应的体验。 POP 就是这个理念下最新一代的成果。

    • POP 使用 Objective-C++ 编写,Objective-C++ 是对 C++ 的扩展,就像 Objective-C 是 C 的扩展。而至于为什么他们用 Objective-C++ 而不是纯粹的 Objective-C,原因是他们更喜欢 Objective-C++ 的语法特性所提供的便利。

    继承关系

    WX20210804-160255@2x.png

    POPAnimation

    • 属性
    // 动画名称
    @property (copy, nonatomic) NSString *name;
    
    // 开始时间,默认立即开始
    @property (assign, nonatomic) CFTimeInterval beginTime;
    
    // 代理
    @property (weak, nonatomic) id delegate;
    
    // 事件追踪
    @property (readonly, nonatomic) POPAnimationTracer *tracer;
    
    // 开始的block
    @property (copy, nonatomic) void (^animationDidStartBlock)(POPAnimation *anim);
    
    // 动画触发toValue值的block
    @property (copy, nonatomic) void (^animationDidReachToValueBlock)(POPAnimation *anim);
    
    // 动画完成的回调
    @property (copy, nonatomic) void (^completionBlock)(POPAnimation *anim, BOOL finished);
    
    // 动画每一帧的回调
    @property (copy, nonatomic) void (^animationDidApplyBlock)(POPAnimation *anim);
    
    // 动画是否在结束后移除,默认为YES
    @property (assign, nonatomic) BOOL removedOnCompletion;
    
    // 暂停
    @property (assign, nonatomic, getter = isPaused) BOOL paused;
    
    // 动画是否返回原来的状态,以动画形式返回
    @property (assign, nonatomic) BOOL autoreverses;
    
    // 重复次数
    @property (assign, nonatomic) NSInteger repeatCount;
    
    // 是都永远重复
    @property (assign, nonatomic) BOOL repeatForever;
    

    POPPropertyAnimation

    • 属性
    // 动画的属性,我们可以借助此属性,做一些自定义
    @property (strong, nonatomic) POPAnimatableProperty *property;
    
    // 动画开始的值
    @property (copy, nonatomic) id fromValue;
    
    // 动画结束的值
    @property (copy, nonatomic) id toValue;
    
    // 动画的细腻度,设置很大的值会有bug 【0,1】
    @property (assign, nonatomic) CGFloat roundingFactor;
    
    // 没理解
    @property (assign, nonatomic) NSUInteger clampMode;
    
    // 没理解
    @property (assign, nonatomic, getter = isAdditive) BOOL additive;
    

    POPBaseAnimation

    • 初始化方法,一般使用下面的初始化方法
    + (instancetype)animationWithPropertyNamed:(NSString *)name;
    
    • 动画方式属性:timingFunction
    // 线性的
    kCAMediaTimingFunctionLinear
    // 慢->快
    kCAMediaTimingFunctionEaseIn
    // 快->慢
    kCAMediaTimingFunctionEaseOut
    // 慢->快->慢
    kCAMediaTimingFunctionEaseInEaseOut
    
    • 动画时长:duration

    • 例子1:简单的位移

    POPBasicAnimation *baseAnim = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter];
    baseAnim.completionBlock = ^(POPAnimation *anim, BOOL finished) {
        NSLog(@"动画完成”);
    };
    baseAnim.beginTime = CACurrentMediaTime() + 0.0;
    baseAnim.duration = 0.5;
    baseAnim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
    baseAnim.fromValue = @(self.demoView.center);
    baseAnim.toValue = @(self.view.center);
    [self.demoView pop_addAnimation:baseAnim forKey:@"baseAnim”];
    
    • 效果图1


      效果1
    • 例子2:倒计时

    POPAnimatableProperty *prop = [POPAnimatableProperty propertyWithName:@"countdown" initializer:^(POPMutableAnimatableProperty *prop) {
        prop.writeBlock = ^(id obj, const CGFloat *values) {
            NSLog(@"%d", (int)values[0]);
            int value = (int)values[0];
            NSString *timeStr = [NSString stringWithFormat:@"%02d:%02d:%02d", value/60, value%60,(int)(values[0]*100)%100];
            self.label.text = timeStr;
        };
    }];
    
    POPBasicAnimation *anBasic = [POPBasicAnimation linearAnimation];   //秒表当然必须是线性的时间函数
    anBasic.property = prop;    //自定义属性
    anBasic.fromValue = @(1*60);   //从0开始
    anBasic.toValue = @(0);  //180秒
    anBasic.duration = 3*60;    //持续3分钟
    anBasic.beginTime = CACurrentMediaTime();    //延迟1秒开始
    [self.label pop_addAnimation:anBasic forKey:@"countdown”];
    
    • 效果图2


      效果图2

    POPSpringAnimation

    • 构造方法
    + (instancetype)animationWithPropertyNamed:(NSString *)name;
    
    • 属性
    // 初始速度
    @property (copy, nonatomic) id velocity;
    
    // 弹力 [0,20],默认为4
    @property (assign, nonatomic) CGFloat springBounciness;
    
    // 弹簧速度 [0,20],默认为12
    @property (assign, nonatomic) CGFloat springSpeed;
    
    // 拉力,张力
    @property (assign, nonatomic) CGFloat dynamicsTension;
    
    // 摩擦力
    @property (assign, nonatomic) CGFloat dynamicsFriction;
    
    // 质量
    @property (assign, nonatomic) CGFloat dynamicsMass;
    
    • 例子3:弹性移动
    POPSpringAnimation *anSpr = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter];
    anSpr.completionBlock = ^(POPAnimation *anim, BOOL finished) {
        NSLog(@"动画完成”);
    };
    anSpr.beginTime = CACurrentMediaTime() + 0.0;
    anSpr.springSpeed = 100;
    anSpr.springBounciness = 20.0;
    anSpr.fromValue = @(self.demoView.center);
    anSpr.toValue = @(self.view.center);
    [self.demoView pop_addAnimation:anSpr forKey:@"anSpr”];
    
    • 效果图3


      效果图3

    POPDecayAnimation

    • Decay Animation 就是 POP 提供的另外一个非常特别的动画,他实现了一个衰减的效果。这个动画有一个重要的参数 velocity(速率),一般并不用于物体的自发动画,而是与用户的交互共生。这个和 iOS7 引入的 UIDynamic 非常相似,如果你想实现一些物理效果,这个也是非常不错的选择。

    • Decay 的动画没有 toValue 只有 fromValue,然后按照 velocity 来做衰减操作。

    -例子4:衰减转动

    - (void)jumpAnimation {
        
        [self.demoView.layer pop_removeAllAnimations];
        POPDecayAnimation *anRotaion=[POPDecayAnimation animation];
        anRotaion.property = [POPAnimatableProperty propertyWithName:kPOPLayerRotation];
        anRotaion.beginTime = CACurrentMediaTime() + 0.0;
        
        if (self.animated) {
            anRotaion.velocity = @(-150);
        }else{
            anRotaion.velocity = @(150);
            anRotaion.fromValue =  @(25.0);
        }
        
        self.animated = !self.animated;
        
        anRotaion.completionBlock = ^(POPAnimation *anim, BOOL finished) {
            if (finished) {
                [self jumpAnimation];
            }
        };
        
        [self.demoView.layer pop_addAnimation:anRotaion forKey:@"myRotationView”];
    }
    
    • 效果图4


      效果图4

    值得关注的 POP 周边

    • POP-HandApp 这就是本文的示例App,包含了大量动画的操作方法和上述介绍的实例。

    • AGGeometryKit-POP 通过 POP 对图片进行变形操作,非常酷。

    • POP-MCAnimate POP 的一个封装,可以让你更方便的使用 POP。

    • Rebound POP 的 Android 部分实现,主要是 Spring 的效果,移植自 Facebook 的rebound-js。

    相关文章

      网友评论

          本文标题:Facebook_Pop的使用指北

          本文链接:https://www.haomeiwen.com/subject/tyquvltx.html