围绕圆形CALayer加深边框

3
我正在创建一个自定义视图来显示单个颜色,这是从图像中选择颜色的颜色选择器,因此颜色可能会相当快地更改。为了防止光标移动时颜色闪烁,我使颜色变化在0.2秒内进行动画处理。
我正在使用CALayer来完成这项任务。目前情况下,这几乎按预期工作,但是我想要一个轮廓线围绕该层,其颜色略暗于内容,类似于OS X Yosemite关闭和调整窗口按钮。
我目前使用的方法确实有效,但是有时边框颜色动画似乎不遵循主要颜色动画,有时会经过较浅的颜色。我认为我可以使用滤镜来完成这项任务,但我对如何做到这一点感到非常困惑,并且在网上找不到太多文档。我对CoreAnimation的经验非常少,因此我不确定是否这是最好的方法,或者是否显而易见。
- (id)initWithFrame:(NSRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        _pickerColour = [NSColor whiteColor];
        strokeColour = [NSColor whiteColor];

        [self setWantsLayer: true];

        innerLayer = [CALayer layer];
        [innerLayer setCornerRadius: frame.size.width / 2];
        [innerLayer setBorderWidth: 4];
        [innerLayer setFrame: CGRectMake(frame.origin.x - frame.size.width / 2, frame.origin.y - frame.size.width / 2, frame.size.width - 2, frame.size.height - 2)];

        [self.layer addSublayer:innerLayer];
    }

    return self;
}

- (void) setPickerColour:(NSColor *)pickerColour{
    CABasicAnimation *backgroundAnimation = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
    backgroundAnimation.fillMode = kCAFillModeForwards;
    backgroundAnimation.removedOnCompletion = NO;
    backgroundAnimation.fromValue = (id)self.pickerColour.CGColor;
    backgroundAnimation.toValue = (id)pickerColour.CGColor;
    backgroundAnimation.duration = 0.1f;
    [innerLayer addAnimation:backgroundAnimation forKey:@"backgroundColor"];

    CGFloat h,s,b,a;
    [[self.pickerColour colorUsingColorSpaceName: NSCalibratedRGBColorSpace] getHue:&h saturation:&s brightness:&b alpha:&a];
    NSColor *newStrokeColour = [NSColor colorWithHue:h saturation:MIN(s, 1.0) brightness: MAX(b / 1.2, 0.0) alpha:a];

    CABasicAnimation *borderAnimation = [CABasicAnimation animationWithKeyPath:@"borderColor"];
    borderAnimation.fillMode = kCAFillModeForwards;
    borderAnimation.removedOnCompletion = NO;
    borderAnimation.fromValue = (id)strokeColour.CGColor;
    borderAnimation.toValue = (id)newStrokeColour.CGColor;
    borderAnimation.duration = 0.1f;
    [innerLayer addAnimation:borderAnimation forKey:@"borderColor"];

    strokeColour = newStrokeColour;
    _pickerColour = pickerColour;
}

- (NSColor *) pickerColour{
    return _pickerColour;
}

这可能仅是Core Animation在RGB空间而不是HSV / HSB空间中工作的效果吗?即使其端点同样明亮,通过RGB立方体的路径没有保证不经过亮度不同的颜色...... - warrenm
这就是为什么我想使用过滤器或类似的东西,以便显示实际更暗的版本,而不仅仅是一个过渡。 - Oliver Cooper
你可以使用关键帧动画,其值在HSV空间中明确插值,而不是RGB空间。 - warrenm
你会怎么做呢?我对CoreAnimation完全不了解,真的一点头绪都没有。 - Oliver Cooper
1
这是要点:您使用CAKeyframeAnimation而不是CABasicAnimation,提供包含颜色空间路径的分段表示的valueskeyTimes数组。您可以使用相同的NSColor便捷方法,但是您将在HSV空间中指定足够数量的颜色以遵循所需的弧线,而不是默认的RGB空间中的线性轨迹。 - warrenm
那个方法很有效,如果你想把它作为答案添加,我会接受它。 - Oliver Cooper
1个回答

2
通过使用CAKeyframeAnimation而不是CABasicAnimation,您可以提供valueskeyTimes数组,其中包含您在颜色空间中通过分段表示的路径。您可以使用相同的NSColor方便方法,但需要指定足够多的颜色以在HSV空间中沿所需弧线移动,而不是默认的RGB空间中的线性轨迹。请注意保留HTML标签。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接