Circle strokeWidth 改变动画而不改变圆半径

Posted

技术标签:

【中文标题】Circle strokeWidth 改变动画而不改变圆半径【英文标题】:Circle strokeWidth change animation without changing the circle radius 【发布时间】:2020-04-14 07:48:17 【问题描述】:

我有几个矩形,我用UIBezierPathCAShapeLayer 在其中画了一个圆圈。它们应该像按钮一样,当它们被点击时,它们被选中,当它们被点击时,它们被取消选择,其中每个状态都应该在这两个条件之间改变按钮外观:

取消选择: 选择:

这是通用代码(在选择更改时调用):

CGFloat radius = isSelected ? 9.8 : 13. ;
CGFloat strokeWidth = isSelected ? 10.5 : 2;

UIBezierPath *bezierPath = [UIBezierPath bezierPath];
CGPoint center = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect));
[bezierPath addArcWithCenter:center radius:radius startAngle:0 endAngle:2 * M_PI clockwise:YES];

CAShapeLayer *progressLayer = [[CAShapeLayer alloc] init];
[progressLayer setPath:bezierPath.CGPath];
[progressLayer setStrokeColor:[UIColor redColor].CGColor];
[progressLayer setLineWidth:strokeWidth]];
[self.layer addSublayer:progressLayer];

当这个矩形被选中时,我想只向内改变圆的strokeWidth,并保持原来的半径。当它被取消选择时,应该会发生相反的情况。 如您所见,我同时更改了半径和线宽,因为当我使 strokeWidth 变大时,外半径也在增长。正如我所说,我想保持不变。

问题是我希望它的动画在选择时宽度向内增长,在取消选择时向外增长,而完全不改变外半径。 到目前为止,我所拥有的是一个改变 strokeWidth 和半径的动画,以保持结果与出现的半径相同。但这不是我需要的。可以看到,这里只动画了半径变化,结果是一个不断扩大的圆圈,我不想要。

这是动画的代码(除了原代码):

  CABasicAnimation *changeCircle = [CABasicAnimation animationWithKeyPath:@"path"];
  changeCircle.duration = 0.6;
  changeCircle.fromValue = (__bridge id)oldPath; // current bezier path
  changeCircle.toValue = (__bridge id)newPath; // new bezier path

  [progressLayer addAnimation:changeCircle forKey:nil];

我也有相反的代码,它只对 strokeWidth 的变化进行动画处理。它也不能满足我的需要。 有没有办法在不改变外半径的情况下让 strokeWidth 变大或变小?

像这样:

【问题讨论】:

您是否尝试同时减小半径并增加 storkewidth?这应该工作。 【参考方案1】:

感谢@Chris,我设法解决了。

CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
pathAnimation.fromValue = (__bridge id) oldPath;
pathAnimation.toValue = (__bridge id) newPath;

CABasicAnimation *lineWidthAnimation = [CABasicAnimation animationWithKeyPath:@"lineWidth"];
lineWidthAnimation.fromValue = isSelected ? @2. : @10.5;
lineWidthAnimation.toValue = isSelected ? @10.5 : @2.;

CAAnimationGroup *group = [CAAnimationGroup animation];
group.duration = 0.3;
group.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
group.animations = @[pathAnimation, lineWidthAnimation];

CAShapeLayer *progressLayer = [[CAShapeLayer alloc] init];
[progressLayer setPath:bezierPath.CGPath];
[progressLayer setStrokeColor:self.color.CGColor];
[progressLayer setLineWidth:isSelected ? 10.5 : 2];
[progressLayer setFillColor:[UIColor clearColor].CGColor];
[progressLayer addAnimation:group forKey:@"selectedAnimations"];
[self.layer addSublayer:progressLayer];

【讨论】:

以上是关于Circle strokeWidth 改变动画而不改变圆半径的主要内容,如果未能解决你的问题,请参考以下文章

React Native SVG描边动画

SwiftUI Circle View 动画故障

Circle UIView调整大小,动画保持圆形

px/em fabricjs 中的 StrokeWidth 值

逐渐为 SVG 设置动画

我的<circle>去哪儿了?