gpt4 book ai didi

ios - 预渲染的 Core Graphics 动画不流畅且占用内存

转载 作者:行者123 更新时间:2023-11-29 12:08:23 25 4
gpt4 key购买 nike

我发布这个问题是为了回应 the answers 之一关于我之前的问题:Multiple CALayer masks causing performance issues

所以,现在我正在尝试使用预渲染动画方法,但我仍然无法获得流畅的动画。不仅如此,当在实际设备上运行时,该应用程序还会因内存问题而定期崩溃。

你可以看到这里运行的动画:http://cl.ly/e3Qu (从视频上看可能没那么糟糕,但专注于动画的边缘,在实际设备上表现更差。)

这是我的代码:

static CGFloat const animationDuration = 1.5;
static CGFloat const calculationRate = (1.0/40.0); // 40fps max.
static CGFloat const calculationCycles = animationDuration/calculationRate;


@implementation splashView {

CADisplayLink* l;

CGImageRef backgroundImg;

UIColor* color;

NSMutableArray* animationImages;

NSTimeInterval currentTime;
}

-(void) beginAnimating {
static dispatch_once_t d;
dispatch_once(&d, ^{

CGFloat totalDistance = 0;
CGFloat screenProgress = 0;
CGFloat deltaScreenProgress = 0;


totalDistance = screenHeight()+screenWidth();

color = [[lzyColors colors] randomColor];

backgroundImg = textBG(color, screenSize()).CGImage;

animationImages = [NSMutableArray array];

NSLog(@"start");

UIGraphicsBeginImageContextWithOptions(screenSize(), YES, 0);

CGContextRef c = UIGraphicsGetCurrentContext();

for (int i = 0; i <= (calculationCycles+1); i++) {

UIImage* img = lzyCGImageFromDrawing(^{

CGFloat height = screenHeight();
CGFloat width = screenWidth();

CGMutablePathRef p = CGPathCreateMutable();

CGPoint startingPoint = [self pointBForProgress:screenProgress];

CGPathMoveToPoint(p, nil, startingPoint.x, startingPoint.y);
lzyCGPathAddLineToPath(p, [self pointAForProgress:screenProgress]);
if ((width < screenProgress) && (screenProgress-deltaScreenProgress) < width) {
lzyCGPathAddLineToPath(p, (CGPoint){width, 0});
}
if (deltaScreenProgress != 0) lzyCGPathAddLineToPath(p, [self pointAForProgress:screenProgress-deltaScreenProgress-1]);
if (deltaScreenProgress != 0) lzyCGPathAddLineToPath(p, [self pointBForProgress:screenProgress-deltaScreenProgress-1]);
if ((height < screenProgress) && (screenProgress-deltaScreenProgress) < height) {
lzyCGPathAddLineToPath(p, (CGPoint){0, height});
}
CGPathCloseSubpath(p);

CGContextAddPath(c, p);
CGContextClip(c);
CGPathRelease(p);

CGContextSetFillColorWithColor(c, color.CGColor);
CGContextFillRect(c, self.bounds);


CGContextDrawImage(c, self.bounds, backgroundImg);

});


[animationImages addObject:img];

deltaScreenProgress = screenProgress;
screenProgress = (i*totalDistance)/calculationCycles;
deltaScreenProgress = screenProgress-deltaScreenProgress;
}


NSLog(@"stop");


currentTime = 0;

l = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkDidFire)];
[l addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];

});


}

-(void) displayLinkDidFire {

NSTimeInterval deltaTime = l.duration;
currentTime += deltaTime;

if (currentTime <= animationDuration) {

CGFloat prg = (currentTime/animationDuration);
NSInteger image = roundf(([animationImages count]-1)*prg);

[CATransaction begin];
[CATransaction setDisableActions:YES];
self.layer.contents = (__bridge id _Nullable)(((UIImage*)[animationImages objectAtIndex:image]).CGImage);
[CATransaction commit];
} else {

[CATransaction begin];
[CATransaction setDisableActions:YES];
self.layer.contents = (__bridge id _Nullable)(((UIImage*)[animationImages lastObject]).CGImage);
[CATransaction commit];
[l invalidate];
animationImages = nil;
}

}


-(CGPoint) pointAForProgress:(CGFloat)progressVar {
CGFloat width = screenWidth();
return (CGPoint){(progressVar<width)?progressVar:width+1, (progressVar>width)?progressVar-width:-1};
}

-(CGPoint) pointBForProgress:(CGFloat)progressVar {
CGFloat height = screenHeight();
return (CGPoint){(progressVar>height)?(progressVar-height):-1, (progressVar<height)?progressVar:height+1};
}

@end

textBG() 函数只是做了一些相当简单的 Core Graphics 绘图来获取背景图像。

我只能假设我在这里做了一些根本性的错误,但我想不出它是什么。

关于如何提高性能和减少内存消耗(不降低动画质量)有什么建议吗?

最佳答案

通过层内容动画化全屏图像肯定会出现性能和内存问题,尤其是在@3x 设备上。对于您在另一个问题 (this video) 中展示的动画,看起来您实际上根本不需要任何 mask ——创建一系列矩形纯色图层(黑色、浅紫色、中紫色、深色)紫色),将它们从前到后分层(文本层位于浅层和中层之间),将它们旋转到您需要的角度,并根据需要移动它们。

如果您最终需要一种更复杂的动画,而该方法无法适用——或者通常来说,无法为任意全屏内容制作动画——您需要 (1) 将其预渲染为视频 (离线或使用 AVFoundation API)并以这种方式播放它或(2)使用 OpenGL 或 Metal 进行绘图。

关于ios - 预渲染的 Core Graphics 动画不流畅且占用内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34231105/

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