【问题标题】:Darker border around circular CALayer圆形 CALayer 周围较暗的边框
【发布时间】:2015-02-14 05:04:45
【问题描述】:

我正在创建一个自定义视图来显示单一颜色,它用于图像中的颜色选择器,因此颜色可能会很快改变。为了防止颜色在光标移动时闪烁,我已经做到了,颜色变化的动画时间超过 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;
}

【问题讨论】:

  • 这可能只是核心动画在 RGB 而不是 HSV/HSB 空间中工作的效果吗?当然,不能保证通过 RGB 立方体的路径不会通过不同亮度的颜色,即使它的端点同样明亮......
  • 这就是为什么我想使用过滤器或类似的东西,以便显示实际的较暗版本,而不仅仅是过渡。
  • 您可以使用关键帧动画,其值在 HSV 空间而非 RGB 空间中显式插值...
  • 你会怎么做?我是 CoreAnimation 的新手,我真的不知道。
  • 这里的要点是:你使用CAKeyframeAnimation而不是CABasicAnimation,提供valueskeyTimes数组,其中包含通过颜色空间的路径的分段表示。您可以使用与您使用的相同的 NSColor 便捷方法,但您将指定足够数量的颜色以在 HSV 空间中遵循所需的弧线,而不是通过 RGB 空间的默认线性轨迹。

标签: objective-c cocoa core-animation


【解决方案1】:

通过使用CAKeyframeAnimation 而不是CABasicAnimation,您可以提供valueskeyTimes 数组,其中包含通过颜色空间的路径的分段表示。您可以使用与您使用的相同的 NSColor 便捷方法,但您将指定足够数量的颜色以在 HSV 空间中遵循所需的弧线,而不是通过 RGB 空间的默认线性轨迹。

【讨论】:

    猜你喜欢
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-07
    • 2020-10-15
    • 2017-08-25
    • 2020-03-03
    • 1970-01-01
    相关资源
    最近更新 更多