gpt4 book ai didi

ios - UIBezierPath和CAShapeLayer初始动画跳转

转载 作者:行者123 更新时间:2023-12-01 18:50:20 24 4
gpt4 key购买 nike

我为自己的公司https://github.com/busycm/BZYStrokeTimer构建了这个代码,在构建过程中,我注意到了一个有趣的“错误”,使用UIBezierPath似乎无法缓解。就在动画开始时,路径会向前(或向后,取决于逆时针方向)跳跃一定数量的像素,而不是从平滑的增量动画开始。我发现真正有趣的是,路径向前跳跃了多少,实际上是CAShaperLayer的线宽值。

因此,例如,如果我的贝塞尔曲线路径开始于CGRectGetMidX(self.bounds)并且线为35,则动画实际上是从CGRectGetMidX(self.bounds)+35开始的,并且线宽越大,跳转越明显。有什么方法可以摆脱这种情况,以便从起点平滑地发出动画?

这是第一帧的图片。这是动画刚开始后的样子。

然后,当我恢复动画并再次暂停时,移动的距离约为您在图片中看到的距离的1/100。

这是我的贝塞尔曲线路径代码:

- (UIBezierPath *)generatePathWithXInset:(CGFloat)dx withYInset:(CGFloat)dy clockWise:(BOOL)clockwise{
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(CGRectGetMidX(self.bounds)+dx/2, dy/2)];
[path addLineToPoint:CGPointMake(CGRectGetMaxX(self.bounds)-dx/2, dy/2)];
[path addLineToPoint:CGPointMake(CGRectGetMaxX(self.bounds)-dx/2, CGRectGetMaxY(self.bounds)-dy/2)];
[path addLineToPoint:CGPointMake(dx/2, CGRectGetMaxY(self.bounds)-dy/2)];
[path addLineToPoint:CGPointMake(dx/2, dy/2)];
[path closePath];
return clockwise ? path : [path bezierPathByReversingPath];
}

这是动画代码:
CABasicAnimation *wind = [self generateAnimationWithDuration:self.duration == 0 ? kDefaultDuration : self.duration fromValue:@(self.shapeLayer.strokeStart) toValue:@(self.shapeLayer.strokeEnd) withKeypath:keypath withFillMode:kCAFillModeForwards];
wind.timingFunction = [CAMediaTimingFunction functionWithName:self.timingFunction];
wind.removedOnCompletion = NO;
self.shapeLayer.path = [self generatePathWithXInset:self.lineWidth withYInset:self.lineWidth clockWise:self.clockwise].CGPath;
[self.shapeLayer addAnimation:wind forKey:@"strokeEndAnimation"];

这就是我构造 CAShapeLayer的方法。
- (CAShapeLayer *)shapeLayer {
return !_shapeLayer ? _shapeLayer = ({
CAShapeLayer *layer = [CAShapeLayer layer];
layer.lineWidth = kDefaultLineWidth;
layer.fillColor = UIColor.clearColor.CGColor;
layer.strokeColor = [UIColor blackColor].CGColor;
layer.lineCap = kCALineCapSquare;
layer.frame = self.bounds;
layer.strokeStart = 0;
layer.strokeEnd = 1;
layer;
}) : _shapeLayer;
}

最佳答案

我认为在这里发生的是,在动画的这一帧中,您正在绘制一条包含单个点的线。由于线具有与之关联的粗细,并且线帽的类型为kCALineCapSquare,因此将其渲染为高度和宽度等于线宽的正方形。

您可以认为它就像在绘制带有正方形标记的线,然后将拖动标记的中点,使其穿过指定曲线中的每个点。对于该行中的第一个点,好像标记在该点着陆,在后面留下一个正方形。

Here's直观表示不同的线帽类型,希望可以使其更加直观。您可能应该将线帽样式更改为kCALineCapButt

旁注:
进行更改后,在此代码行中
[path moveToPoint:CGPointMake(CGRectGetMidX(self.bounds)+dx/2, dy/2)];
您可能不必再将x坐标偏移dx/2

关于ios - UIBezierPath和CAShapeLayer初始动画跳转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31486711/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com