iOS_追光动效(色值渐变)

追光动效实现

效果如下:
在这里插入图片描述

实现:

如下图,红框为一个UIVIewCAGradientLayerstartPointendPoint的取值是(0,0)(1,1)

先实现简单的渐变效果,将红色和蓝色放入colors,从左上角到右下角渐变:

UIView *view = [[UIView alloc] initWithFrame:CGRectMake(20, 150, 300, 188)];
view.layer.cornerRadius = 4.0;
view.layer.masksToBounds = YES;

CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = view.bounds;
gradientLayer.colors = @[(__bridge id)[UIColor redColor].CGColor,
                         (__bridge id)[UIColor blueColor].CGColor];
gradientLayer.startPoint = CGPointMake(0.0, 0.0);
gradientLayer.endPoint = CGPointMake(1.0, 1.0);
[view.layer addSublayer:gradientLayer];

[self.view addSubview:view];

效果如下:
渐变
为了实现渐变的动态效果,可以将红色和蓝色的坐标以对角线的形式,沿着UIView的边框顺时针移动坐标:

如:红点移动到(0.5,0)时,蓝点移动到(0.5,1) 。。。。
为此,顺时针算出所有的坐标:

- (NSArray *)sidePoints {
    NSMutableArray *points = [NSMutableArray array];
    CGFloat min = 0.0;
    CGFloat max = 1.0;
    CGFloat spacing = 0.5;
    // top side
    for (CGFloat x = min; x <= max; x += spacing) {
        [points addObject:@[@(x), @(0)]];
    }
    // right side
    for (CGFloat y = min + spacing; y <= max; y += spacing) {
        [points addObject:@[@(1), @(y)]];
    }
    // bottom side
    for (CGFloat x = max - spacing; x >= min; x -= spacing) {
        [points addObject:@[@(x), @(1)]];
    }
    // left side
    for (CGFloat y = max - spacing; y >= min; y -= spacing) {
        [points addObject:@[@(0), @(y)]];
    }
    return [points copy];
}

然后用NSTimer不停的更换startPointendPoint的坐标:

__block NSUInteger index = 0;
_timer = [NSTimer scheduledTimerWithTimeInterval:0.1 repeats:YES block:^(NSTimer * _Nonnull timer) {

    NSUInteger redIndex = index % (points.count - 1);
    NSUInteger yelIndex = (index + (points.count / 2 + 1)) % (points.count - 1);

    NSArray *redArr = points[redIndex];
    NSArray *yelArr = points[yelIndex];

    NSNumber *redX = redArr[0];
    NSNumber *redY = redArr[1];
    NSNumber *yelX = yelArr[0];
    NSNumber *yelY = yelArr[1];

    gradientLayer.startPoint = CGPointMake(redX.floatValue, redY.floatValue);
    gradientLayer.endPoint = CGPointMake(yelX.floatValue, yelY.floatValue);

    index++;
    index = index % (points.count - 1);
}];
[_timer setFireDate:[NSDate date]];

效果如下:
在这里插入图片描述
为了让动效更湿滑,可以把sidePoints方法里的spacing改小。
然后将图盖在上面,最终效果如下:
在这里插入图片描述
Github Demo 地址

1、波纹动画主要依赖于CAShapeLayer的绘制,使用帧动画实现;需要使用多个CAShapeLayer通过y变换组成(这里我只是用了2个CAShapeLayer)。 2、渐变由CAGradientLayer完成。 ``` - (void)changeFirstWaveLayerPath { CGMutablePathRef path = CGPathCreateMutable(); CGFloat y = _wavePointY; CGPathMoveToPoint(path, nil, 0, y); for (float x = 0.0f; x <= _waveWidth; x ) { y = _waveAmplitude * 1.6 * sin((250 / _waveWidth) * (x * M_PI / 180) - _waveOffsetX * M_PI / 270) _wavePointY; CGPathAddLineToPoint(path, nil, x, y); } CGPathAddLineToPoint(path, nil, _waveWidth, 0); CGPathAddLineToPoint(path, nil, 0, 0); CGPathCloseSubpath(path); _shapeLayer1.path = path; CGPathRelease(path); } - (void)changeSecondWaveLayerPath { CGMutablePathRef path = CGPathCreateMutable(); CGFloat y = _wavePointY; CGPathMoveToPoint(path, nil, 0, y); for (float x = 0.0f; x <= _waveWidth; x ) { y = _waveAmplitude * 1.6 * sin((250 / _waveWidth) * (x * M_PI / 180) - _waveOffsetX * M_PI / 180) _wavePointY; CGPathAddLineToPoint(path, nil, x, y); } CGPathAddLineToPoint(path, nil, _waveWidth, 0); CGPathAddLineToPoint(path, nil, 0, 0); CGPathCloseSubpath(path); _shapeLayer2.path = path; CGPathRelease(path); } ``` 方法调用: ``` _waveOffsetX = _waveSpeed; [self changeFirstWaveLayerPath]; [self changeSecondWaveLayerPath]; [self.layer addSublayer:self.gradientLayer1]; self.gradientLayer1.mask = _shapeLayer1; [self.layer addSublayer:self.gradientLayer2]; self.gradientLayer2.mask = _shapeLayer2; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小莫同学~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值