Ios 在动画期间将图像剪切为CALayers内容 我创建了一个CalALE子类,用自定义颜色绘制了一个饼图的切片(颜色< /代码>),一个开始角(实际启动角< /COD>),一个端点(实际角度> )和一个图像(图像< /代码>)[这个图像应该总是在切片的中间]因为使用普通的CAShapeLayer无法设置动画。当前绘制的图层如下所示: - (void)drawInContext:(CGContextRef)ctx{ CGContextBeginPath(ctx); CGContextMoveToPoint(ctx, self.center.x, self.center.y); CGContextAddArc(ctx, self.center.x, self.center.y, self.radius, self.actualEndAngle, self.actualStartAngle, YES); CGContextClosePath(ctx); CGContextSetFillColorWithColor(ctx, self.color); CGContextSetLineWidth(ctx, 0); CGContextDrawPath(ctx, kCGPathFillStroke); if (self.image) { CGContextDrawImage(ctx, [self getFrameForImgLayerWithStartAngle:self.actualStartAngle andEndAngle:self.actualEndAngle], self.image); } }
这些单独的切片通过以下方式设置动画:Ios 在动画期间将图像剪切为CALayers内容 我创建了一个CalALE子类,用自定义颜色绘制了一个饼图的切片(颜色< /代码>),一个开始角(实际启动角< /COD>),一个端点(实际角度> )和一个图像(图像< /代码>)[这个图像应该总是在切片的中间]因为使用普通的CAShapeLayer无法设置动画。当前绘制的图层如下所示: - (void)drawInContext:(CGContextRef)ctx{ CGContextBeginPath(ctx); CGContextMoveToPoint(ctx, self.center.x, self.center.y); CGContextAddArc(ctx, self.center.x, self.center.y, self.radius, self.actualEndAngle, self.actualStartAngle, YES); CGContextClosePath(ctx); CGContextSetFillColorWithColor(ctx, self.color); CGContextSetLineWidth(ctx, 0); CGContextDrawPath(ctx, kCGPathFillStroke); if (self.image) { CGContextDrawImage(ctx, [self getFrameForImgLayerWithStartAngle:self.actualStartAngle andEndAngle:self.actualEndAngle], self.image); } },ios,objective-c,animation,calayer,cgpath,Ios,Objective C,Animation,Calayer,Cgpath,这些单独的切片通过以下方式设置动画: [CATransaction begin]; CABasicAnimation *colorAnimation = [CABasicAnimation animationWithKeyPath:@"color"]; colorAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; colorAnimati
[CATransaction begin];
CABasicAnimation *colorAnimation = [CABasicAnimation animationWithKeyPath:@"color"];
colorAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
colorAnimation.duration = duration;
colorAnimation.fromValue = (id)self.color;
colorAnimation.toValue = (id)colorTU.CGColor;
CABasicAnimation *startAngleAnimation = [CABasicAnimation animationWithKeyPath:@"actualStartAngle"];
startAngleAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
startAngleAnimation.duration = duration;
startAngleAnimation.fromValue = [self valueForKey:@"actualStartAngle"];
startAngleAnimation.toValue = [[NSNumber alloc] initWithFloat:newStartAngle];
CABasicAnimation *endAngleAnimation = [CABasicAnimation animationWithKeyPath:@"actualEndAngle"];
endAngleAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
endAngleAnimation.duration = duration;
endAngleAnimation.fromValue = [self valueForKey:@"actualEndAngle"];
endAngleAnimation.toValue = [[NSNumber alloc] initWithFloat:newEndAngle];
if (completionBlock) {
[CATransaction setCompletionBlock:completionBlock];
}
if (colorTU && colorTU.CGColor != self.color) {
[self addAnimation:colorAnimation forKey:@"color"];
}
if (newStartAngle != self.actualStartAngle) {
[self addAnimation:startAngleAnimation forKey:@"actualStartAngle"];
}
if (newEndAngle != self.actualEndAngle) {
[self addAnimation:endAngleAnimation forKey:@"actualEndAngle"];
}
[CATransaction commit];
问题是,我希望图像只占用单个层占用的空间(分别是其中的形状)。这通常通过以下方法解决:
- (BOOL)imageFitsIntoSliceWithStartAngle:(float)sA andEndAngle:(float)eA{
BOOL fits = YES;
CGRect rectToUse = [self getFrameForImgLayerWithStartAngle:sA andEndAngle:eA];
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:self.center];
[path addArcWithCenter:self.center radius:self.deg startAngle:sA endAngle:eA clockwise:YES];
for (int w = 0; w <= 1; w++) {
if (fits) {
for (int h = 0; h <= 1; h++) {
if (![path containsPoint:CGPointMake(rectToUse.origin.x + rectToUse.size.width * w, rectToUse.origin.y + rectToUse.size.height * h)]) {
fits = NO;
break;
}
}
}
}
return fits;
}
-(BOOL)图像安装在具有起始角度:(浮点)sA和终止角度:(浮点)eA的OSLICE中{
布尔拟合=是;
CGRect RECTOUSE=[self-getFrameForImgLayerWithStartAngle:sA和andangle:eA];
UIBezierPath*路径=[UIBezierPath bezierPath];
[路径移动点:self.center];
[path addArcWithCenter:self.center radius:self.deg startAngle:sA endAngle:eA顺时针:是];
对于(int w=0;w而言,我不知道这是否有帮助,但下面是饼图零件的绘图代码:
- (void)drawChartWithFrame:(CGRect)frame startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle fillColor:(UIColor *)fillColor strokeColor:(UIColor *)strokeColor
{
//// Oval Drawing
CGRect ovalRect = CGRectMake(CGRectGetMinX(frame),CGRectGetMinY(frame), CGRectGetWidth(frame), CGRectGetHeight(frame));
UIBezierPath* ovalPath = UIBezierPath.bezierPath;
[ovalPath addArcWithCenter: CGPointMake(CGRectGetMidX(ovalRect), CGRectGetMidY(ovalRect)) radius: CGRectGetWidth(ovalRect) / 2 startAngle: -(startAngle - 25) * M_PI/180 endAngle: -(endAngle - 93) * M_PI/180 clockwise: YES];
[ovalPath addLineToPoint: CGPointMake(CGRectGetMidX(ovalRect), CGRectGetMidY(ovalRect))];
[ovalPath closePath];ansform ovalTransform = CGAffineTransformMakeTranslation(CGRectGetMidX(ovalRect), CGRectGetMidY(ovalRect));
ovalTransform = CGAffineTransformScale(ovalTransform, 1, CGRectGetHeight(ovalRect) / CGRectGetWidth(ovalRect));
[ovalPath applyTransform: ovalTransform];
[fillColor setFill];
[ovalPath fill];
[strokeColor setStroke];
ovalPath.lineWidth = 1;
[ovalPath stroke];
}
制作真实图像的动画要轻得多。对不起,我没有时间深入研究你的代码,但你试过CGContextClipToMask吗?我怎么理解,CGContextClipToMask
即使可以工作,也非常低效。我基本上通过将掩码应用到单独的图像层来“解决”这个问题,但这确实是一个低效的问题使用ent方法,会产生很大的延迟。绘制图像会更加困难,对吗?哇,你的图像有多大?好吧,我必须用每一帧重新绘制,它大约是400x400像素,在视网膜上也是如此(分别是视网膜高清6加@3x)这是以每分钟30帧的速度运行的800像素和1200像素。看起来很平滑…哦,好的。看起来确实很大。你能给我看一下图像本身吗?我能画一个饼图。我尝试的是动态地放置一个图像(任何东西[房子、门、人、苹果,任何东西])在每个单独的图表切片的中间,然后我想动画这个,并且图像应该逻辑上只占用像切片一样多的空间,而不是重叠。