• 滚珠菜单动效-b


    原型从网上找的,动效使用了CAAnimation和UIDynamic物理引擎。  gitHub  :https://github.com/BearRan/FlowMenuAnimation

    大致步骤如下:

    • 把效果图截取一张,拖到Sketch做背景

    • 新建图层,使用钢笔工具临摹背景图勾勒出路径

    • 注意:勾勒时可以选择非镜像的控制点,这样方便调整曲线


    接着点击Sketch右下角的倒出按钮,格式选为SVG格式


    将生成的SVG文件拖入到codePaint中,拖入成功后会直接看到如下界面

    看到代码路径后可以整段copy出来,当然,我建议把所有的点抽离出来,方便做适配

    代码绘制凹槽动画

    demo的AppDelegate.h中有以下这些开关,可以自己调配,方便观察


    单个滚珠动效演示,这样看应该比较容易理解。其实我是盖了一个新的图层专门用来做滚珠动效的。

    控制点就是用普通的UIAniamtion实现的,在动画之行的过程中,通过CADisplayLink实时观察Point的PresentLayer的position来不停的重绘贝塞尔曲线。


    2.滚珠动画该分解成几个步骤

    主要分为以下步骤
    阶段一:滚珠一起滚落下来时到最高点的阶段;
    阶段二:滚珠滚落到最高点后回流的的阶段;
    阶段三:滚珠消失阶段;

    3.如何分解滚珠的物理效果

    UIDynamic有以下物理效果

    • UIGravityBehavior:重力行为

    • UICollisionBehavior:碰撞行为

    • UISnapBehavior:捕捉行为

    • UIPushBehavior:推动行为

    • UIAttachmentBehavior:附着行为

    • UIDynamicItemBehavior:动力元素行为


    UIGravityBehavior:重力行为

     
    #pragma mark  重力行为
    - (UIGravityBehavior *)addGravityBehavior:(id <UIDynamicItem>)item
    {
        UIGravityBehavior *gravityBehavior = [[UIGravityBehavior alloc] init];
        [gravityBehavior addItem:item];
        [_animator addBehavior:gravityBehavior];
    
        return gravityBehavior;
    }




    UICollisionBehavior:碰撞行为

    适用于:UIView和父类view的边界碰撞,以及和其他UIView碰撞
    这里可以配合重力行为来设定小球的运动路径

       
    #pragma mark  碰撞行为
    - (UICollisionBehavior *)addCollisionBehavior:(id <UIDynamicItem>)item
    {
        UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc] init];
        [collisionBehavior addItem:item];
        [collisionBehavior addBoundaryWithIdentifier:@"path" forPath:_beizerPath];
        [_animator addBehavior:collisionBehavior];
        return collisionBehavior;
    }

    UISnapBehavior:捕捉行为

    顾名思义,不解释

    UIPushBehavior:推动行为
    使用瞬间或持续的力并按照某一方向作用于某个UIView
    用于开始或结束时的小球推动

     
    #pragma mark  显现动画,第一个球向右的推力
    - (UIPushBehavior *)addPushBehavior_inFirstBtn
    {
        UIButton *tempBtn = _btnArray[0];
        UIPushBehavior *pushBehavior = [[UIPushBehavior alloc] initWithItems:@[tempBtn] mode:UIPushBehaviorModeInstantaneous];
        pushBehavior.pushDirection = CGVectorMake(1, 0.3);
        pushBehavior.magnitude = 1.6;
        [_animator addBehavior:pushBehavior];
    
        return pushBehavior;
    }
     

    UIAttachmentBehavior:附着行为

    UIView和某个UIView的相互吸附行为
    此处用于小球见的相互吸附作用

     
    #pragma mark  添加球与球之间的附着行为
    - (UIAttachmentBehavior *)addAttachmentBehavior_item:(id <UIDynamicItem>)item attachToItem:(id <UIDynamicItem>)attachToItem
    {
        SpecialBtn *tempBtn = (SpecialBtn *)item;
        UIAttachmentBehavior *attachmentBehavior = [[UIAttachmentBehavior alloc] initWithItem:item attachedToItem:attachToItem];
        [attachmentBehavior setLength:tempBtn.width + 20];
        [attachmentBehavior setDamping:10.01];
        [attachmentBehavior setFrequency:1];
        [_animator addBehavior:attachmentBehavior];
    
        return attachmentBehavior;
    }
     

    UIDynamicItemBehavior:动力元素行为

    一些其他的物理元素,比如摩擦力,线速度阻力,角速度阻力等

     
    #pragma mark  动力元素行为
    - (UIDynamicItemBehavior *)addDynamicItemBehavior:(id <UIDynamicItem>)item
    {
        UIDynamicItemBehavior *itemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:@[item]];
        itemBehavior.resistance = 0;
        itemBehavior.allowsRotation = YES;
        itemBehavior.angularResistance = 4.0;
        itemBehavior.friction = 0.8;
        [_animator addBehavior:itemBehavior];
    
        return itemBehavior;
    }

    阶段一:滚珠一起滚落下来时到最高点的阶段球与球之间的附着行为 + 重力行为+碰撞行为+ 动力元素行为+ 第一个球向右的推力#pragma mark 显现动画

     
    #pragma mark 显现动画
    - (void)showBtnsAnimation
    {
        _animatorStatus = kAnimatorStatus_open;
        [_animator removeAllBehaviors];
    
        if (showPath) {
            _pathLayer.path = _beizerPath.CGPath;
            _pathLayer.fillColor = [UIColor clearColor].CGColor;
            _pathLayer.strokeColor = [UIColor orangeColor].CGColor;
            _pathLayer.lineWidth = 2.0;
            [self.layer addSublayer:_pathLayer];
        }
    
        CGFloat btn_gap = [self setXX:16];
        for (int i = 0; i < [_btnArray count]; i++) {
    
            SpecialBtn *tempBtn = _btnArray[i];
            tempBtn.tag = i;
            [self addSubview:tempBtn];
    
            //  设定初始位置
            [tempBtn setX:(tempBtn.width + btn_gap) * ([_btnArray count] - 1 - i) + btn_gap];
            [tempBtn setY:-tempBtn.height];
    
            //  添加球与球之间的附着行为
            if (i > 0) {
                [self addAttachmentBehavior_item:_btnArray[i] attachToItem:_btnArray[i - 1]];
            }
    
            //  重力行为
            UIGravityBehavior *gravityBehavior = [self addGravityBehavior:tempBtn];
            if (i == [_btnArray count] - 1) {
                //  最后一个球处理重力行为
                [self dealLastBtnGravityBehavior:gravityBehavior tempBtn:tempBtn];
            }
    
            //  碰撞行为
            [self addCollisionBehavior:tempBtn];
    
            //  动力元素行为
            UIDynamicItemBehavior *itemBehavior = [self addDynamicItemBehavior:tempBtn];
            if (i == [_btnArray count] - 1) {
                //  最后一个球增加密度,以防止出现的时候,由于惯性的原因导致飞起来
                itemBehavior.density = 1.8;
            }
    
        }
    
        //  第一个球向右的推力
        [self addPushBehavior_inFirstBtn];
    }

    阶段二:滚珠滚落到最高点后回流的的阶段球与球之间的附着行为 + 重力行为+碰撞行为+ 动力元素行为+ 最后一个球向左pushf

     
     
    for (int i = 0; i < [_btnArray count]; i++) {
        //  添加球与球之间的附着行为
        if (i > 0) {
                        UIAttachmentBehavior *attachmentBehavior = [self addAttachmentBehavior_item:_btnArray[i] attachToItem:_btnArray[i - 1]];
             [attachmentBehavior setFrequency:5];
             [attachmentBehavior setLength:tempBtn.width + 5];
         }
    
         //  重力行为
         [self addGravityBehavior:_btnArray[i]];
          //  碰撞行为
         [self addCollisionBehavior:_btnArray[i]];
          //  动力元素行为
         UIDynamicItemBehavior *itemBehavior = [self addDynamicItemBehavior:_btnArray[i]];
         itemBehavior.angularResistance = 15.0;
    
    }
    
     //  最后一个球向左push
    UIPushBehavior *pushBehavior = [[UIPushBehavior alloc] initWithItems:@[tempBtn] mode:UIPushBehaviorModeContinuous];
    pushBehavior.pushDirection = CGVectorMake(-1, -0.5);
    
    pushBehavior.magnitude = 2.3;
    
     [_animator addBehavior:pushBehavior];
       

    阶段三:滚珠消失阶段球与球之间的附着行为 + 重力行为+碰撞行为+ 动力元素行为+ 最后一个球向左push(和阶段二几本一致,只是推动的力大了一些)

     
     
    #pragma mark 消退动画
    - (void)closeBtnsAniamtion
    {
       NSLog(@"-- closeBtnsAniamtion");    _animatorStatus = kAnimatorStatus_close;    SpecialBtn *lastBtn = (SpecialBtn *)[_btnArray lastObject];    [_animator removeAllBehaviors];    for (int i = 0; i < [_btnArray count]; i++) {        //  添加球与球之间的附着行为        if (i > 0) {            UIAttachmentBehavior *attachmentBehavior = [self addAttachmentBehavior_item:_btnArray[i] attachToItem:_btnArray[i - 1]];            [attachmentBehavior setFrequency:5];            [attachmentBehavior setLength:lastBtn.width + 5];        }        //  重力行为        UIGravityBehavior *gravityBehavior = [self addGravityBehavior:_btnArray[i]];        if (i == 0) {            [self dealFirstDisappearBtnGravityBehavior:gravityBehavior tempBtn:_btnArray[i]];        }        //  碰撞行为        [self addCollisionBehavior:_btnArray[i]];        //  动力元素行为        [self addDynamicItemBehavior:_btnArray[i]];    }    //  最后一个球向左push    UIPushBehavior *pushBehavior = [[UIPushBehavior alloc] initWithItems:@[lastBtn] mode:UIPushBehaviorModeContinuous];    pushBehavior.pushDirection = CGVectorMake(-1, -0.5);    pushBehavior.magnitude = 10.0;    [_animator addBehavior:pushBehavior]; }
     
       

    demo地址:

    作者:熊熊xr

    原文地址:http://code4app.com/forum.php?mod=viewthread&tid=9264&extra=page%3D62%26filter%3Dsortid%26orderby%3Ddateline%26sortid%3D1

  • 相关阅读:
    基于socket的TCP和UDP编程
    (转)基于socket的TCP和UDP编程
    MFC的本质
    Windows程序内部运行机制 转自http://www.cnblogs.com/zhili/p/WinMain.html
    mysql主从切换
    mysql主从不一致解决方法
    postgresql+slony-i安装配置主从
    inndb存储引擎调优
    mysql 锁优化
    NDB Cluster 存储引擎物理备份
  • 原文地址:https://www.cnblogs.com/isItOk/p/5838305.html
Copyright © 2020-2023  润新知