Marquee Effect

Marquee Effect

Demo Download Address

Now left us to see the effect
Marquee Effect Gif

我們可以看到跑马灯的效果,其实是由一条虚实线做循环移动组成的。
如果我们要做这个效果是要把什么地方绘制一个小横线,空一段,这样循环下去吗???那移动的动画又要怎样做呢!!好像变得无比复杂。

  • 这个时候,我们就要用到CAShapeLayer这个特殊的Layer。
  • 它有个属性lineDashPhase,我们要利用它做出虚实线。

上代码

[ self setFillColor: [ UIColor clearColor ].CGColor ];
[ self setStrokeColor: [ UIColor whiteColor ].CGColor ];
[ self setLineWidth: 2.F ];
[ self setLineJoin: kCALineJoinRound ];
[ self setLineDashPattern: @[@(10), @(5)] ];

先让填充色为无颜色,再者设置线段实线部分的颜色,设置lineDashPattern这个属性,第一个参数是设置实线的长度,第二个参数是填写虚线部分的长度[即空白的线段长度]。
那此时就是可以了吗?不行,要设置layer的path属性,最终绘制的虚实线,是根据path来绘制的。

上代码

- ( void ) SetAnimationPath
{
    if ( self.superlayer == nil )
    {
        return;
    }

    UIWindow* aTopWindow = [[ UIApplication sharedApplication ].windows lastObject];

    while ( aTopWindow.superview != nil )
    {
        UIView* aView = aTopWindow.superview;
        aTopWindow = (UIWindow*)aView;
    }

    CALayer* aTopLayer      = aTopWindow.layer;
    CGRect aTopFrame        = [ self convertRect: self.bounds toLayer: aTopLayer ];
    CGRect aTopIntersection = CGRectIntersection(aTopFrame, aTopLayer.bounds);
    CGRect aAnimationPath   = [ self convertRect: aTopIntersection fromLayer: aTopLayer ];

    CGMutablePathRef const aPath = CGPathCreateMutable();
    CGPathAddRect(aPath, NULL, aAnimationPath);
    self.path                    = aPath;
    CGPathRelease(aPath);
}

为什么我不直接就根据 CAShapeLayer 这个实例的frame去设置path???

而是用通过顶级Layer去设置Path

其实是因为如果当path过大的时候[超过1024*1024],边的样式不是纯实线的时候,将需要很大的性能去计算,如果机子的性能支撑不住就会直接重启。所以我们就需要把path控制到只有整个设备屏幕的区域内,或略大于设备屏幕大小。这样就可以做出区域过大,依然正确显示的假象。
也因为这样,所以当CAShapeLayer移动的时候,需要不断设置frame,以获取当前区域path应该所在的位置

动画

/**
 *
 *
 */
- ( void ) OnStartAnimation
{
    if ( [ self animationForKey: @"linePhase" ] )
    {
        [ self removeAnimationForKey: @"linePhase" ];
    }

    @autoreleasepool
    {
        self.hidden = NO;

        CABasicAnimation* const aDashAnimation = [ CABasicAnimation animationWithKeyPath: @"lineDashPhase" ];
        [ aDashAnimation setFromValue: @( 0.0F ) ];
        [ aDashAnimation setToValue: @( 15 ) ];
        [ aDashAnimation setDuration: 0.75F ];
        [ aDashAnimation setRepeatCount: 100000 ];

        [ self addAnimation: aDashAnimation
                     forKey: @"linePhase" ];
    }
}

/**
 *
 *
 */
- ( void ) OnExitAnimation
{
    if ( [ self animationForKey: @"linePhase" ] )
    {
        [ self removeAnimationForKey: @"linePhase" ];
    }
}

其实动画就是设置lineDashPhase,那lineDashPhase是什么??其实就是虚线一开始绘制的位置,那动画如何设置能够无缝衔接。我们可以想象一下,就好比我们跑圈一样,如果设置动画起始刚好就是一圈的长度,那就能够无缝结合。那怎样判断一圈的定义长度,其实就是可以看我们的画的虚线长度,实线长度。就是上面我们设置的lineDashPattern,通过这个可以知道我们一圈的长度为15

好啦!!你也动手试试吧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值