iOS_追光动效(色值渐变)

2022-07-20 14:57:41 浏览数 (3)

追光动效实现

效果如下:

实现:

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

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

代码语言:javascript复制
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) 。。。。 为此,顺时针算出所有的坐标:

代码语言:javascript复制
- (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的坐标:

代码语言:javascript复制
__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 地址

0 人点赞