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像素。看起来很平滑…哦,好的。看起来确实很大。你能给我看一下图像本身吗?我能画一个饼图。我尝试的是动态地放置一个图像(任何东西[房子、门、人、苹果,任何东西])在每个单独的图表切片的中间,然后我想动画这个,并且图像应该逻辑上只占用像切片一样多的空间,而不是重叠。