AVFoundation - 動(dòng)畫圖層內(nèi)容

1. CoreAnimation 在不需要使用OpenGL或OPenGL ES框架的前提下就可以很容易創(chuàng)建高性能, 基于GPU的動(dòng)畫效果. CoreAnimation框架提供的有硬件加速視頻渲染效果. 從高層次角度看, Core Animation包含兩類對(duì)象: Layers和Animations.

2. Layers 圖層對(duì)象有CALayer類定義, 并用于管理屏幕中可視化內(nèi)容的元素. 這里所說的內(nèi)容一般都是圖片或Bezier路徑, 不過圖層本身具有可被設(shè)置的可視化特征. 比如他的顏色, 透明度和角半徑. 除了CALayer框架還定義了很多實(shí)用的子類, 比如用于渲染貼圖內(nèi)容的CATextLayer類和用于渲染Beizier路徑的CAShapeLyer類. 這兩個(gè)類在創(chuàng)建動(dòng)畫疊加效果時(shí)都非常重要.

3. Animations 動(dòng)畫對(duì)象是抽象類CAAnimation的實(shí)例, 定義所有動(dòng)畫類型共有的一些核心動(dòng)畫行為.該框架定義了CAAnimation的許多具體子類. 最常用的就是CABasicAnimation和CAKeyFrameAniation. 這些類將動(dòng)畫狀態(tài)變?yōu)閱为?dú)的圖層屬性, 以便創(chuàng)建簡(jiǎn)單的和復(fù)雜的動(dòng)畫效果. CABasicAnimation 可以讓你創(chuàng)建簡(jiǎn)單的單關(guān)鍵幀動(dòng)畫, 意味著在一段時(shí)間內(nèi)將屬性狀態(tài)以動(dòng)畫方式由一種狀態(tài)變?yōu)榱硪环N狀態(tài). 這個(gè)類實(shí)現(xiàn)簡(jiǎn)單動(dòng)畫時(shí)非常實(shí)用. 比如動(dòng)態(tài)調(diào)整圖層的尺寸, 位置和背景色. CAKeyFrameAnimation用于實(shí)現(xiàn)更高級(jí)的功能, 它對(duì)動(dòng)畫中的關(guān)鍵幀有著更多的控制. 比如當(dāng)一個(gè)圖層沿著Bezier路徑動(dòng)態(tài)顯示, 可以用到關(guān)鍵幀動(dòng)畫來指定具體的時(shí)間和節(jié)奏.

CALayer *parentLayer = //parent layer

UIImage *image = [UIImage imageNamed:@"image.png"];

CALayer *imageLayer = [CALayer layer];

imageLayer.contents = (id)image.CGImage

imageLayer.contentScale = [UIScreen mainScreen].scale;

CGFloat midX = CGRectGetMidX(parentLayer.bounds);

CGFloat midY = CGRectGEtMidY(parentLayer.bounds);

imageLayer.bounds = CGRectMake(0, 0, image.size.width, image.size.height);

imageLayer.position = CGPointMake(midX, midY);

[parentLayer addSublayer:imageLayer];

CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];

rotationAnimation.toValue = @(2 * M_PI);

roationAnimation.duration = 3.0f;

rotationAnimation.repeatCount = HUGE_VALF;

[imageLayer addAnimation:rotationAnimation forKey:@"rotateAnimation"];

4. 在AVFoundation中使用Core Animation, 使用Core Animation為視頻應(yīng)用程序創(chuàng)建疊加效果的方法同使用它在iOS和OS X平臺(tái)創(chuàng)建實(shí)時(shí)動(dòng)畫效果的方法幾乎一樣. 最大的區(qū)別在于運(yùn)行動(dòng)畫的時(shí)間模型. 當(dāng)創(chuàng)建實(shí)時(shí)動(dòng)畫時(shí), CAAnimation實(shí)例從系統(tǒng)主機(jī)獲取執(zhí)行時(shí)間.

5. AVSynchronizedLayer播放, AVFoundation提供了一個(gè)專門的CALayer的子類AVSynchronizedLayer, 用于與給定的AVPlayerItem實(shí)例同步時(shí)間, 這個(gè)圖層本身不展示任何內(nèi)容. 僅用來與圖層子樹協(xié)同時(shí)間. 這樣所在的繼承關(guān)系中附屬于改圖層的動(dòng)畫都可以從激活的AVPlayerItem實(shí)例中獲取相應(yīng)的執(zhí)行時(shí)間. 通常使用AVSynchronizedLayer時(shí)會(huì)將其整合到播放器視圖的圖層繼承關(guān)系中. 同步圖層直接呈現(xiàn)在視頻圖層之上. 這樣就可以添加動(dòng)畫標(biāo)題, 水印或下沿字幕到播放器視頻中, 并與播放器欄行為保持完美同步.

6. 使用AVVideoCompositionCoreAnimationTool導(dǎo)出, 要將Core Animation圖層和動(dòng)畫整合到導(dǎo)出視頻中, 需要使用AVVideoCompositionCoreAnimationTool類, AVVideoComposition使用這個(gè)類將Core Animation效果作為視頻組合后期處理階段納入.

7. Core Animation框架的默認(rèn)行為是執(zhí)行動(dòng)畫并在動(dòng)畫行為完成后進(jìn)行處理, 通常這些行為就是我們希望在按理中使用的, 因?yàn)闀r(shí)間一旦過去就沒法返回了. 不過對(duì)于視頻動(dòng)畫就會(huì)有問題. 所以需要設(shè)置動(dòng)畫的removedOnCompletion屬性來NO來禁用這一行為. 如果不這樣做, 則動(dòng)畫效果是一次性的. 如果用戶重新播放視頻或在時(shí)間軸上移動(dòng)戳插條也不會(huì)再次看到動(dòng)畫. 動(dòng)畫的beginTime屬性被設(shè)置為0.0的話是不會(huì)看到動(dòng)畫效果的. Core Animation將值為0.0的beginTime對(duì)象轉(zhuǎn)換為CACurrentMediaTime(), 這是當(dāng)前主機(jī)時(shí)間, 同影片時(shí)間軸中的有效時(shí)間沒有關(guān)系. 如果希望在影片開頭加入動(dòng)畫, 將動(dòng)畫的beginTime屬性設(shè)置成AVCoreAnimationBeginTimeAtZero常量.

8. 添加動(dòng)畫標(biāo)題, 在Core Animation中使用AVComposition的一個(gè)挑戰(zhàn)就是協(xié)調(diào)不同的概念和時(shí)間模型. 在使用AVComposition時(shí), 考慮的是軌道以及CMTime和CMTimeRange值, Core Animation沒有軌道的概念并使用浮點(diǎn)型數(shù)值來表示時(shí)間. 在一個(gè)簡(jiǎn)單場(chǎng)景中我們可以使用Core Animation自己的概念, 不過當(dāng)需要?jiǎng)?chuàng)建一個(gè)更復(fù)雜的案例時(shí), 最好在兩個(gè)框架之間定義一個(gè)通用的抽象概念來使創(chuàng)建組合資源和動(dòng)畫時(shí)具有標(biāo)準(zhǔn)化的模型.?

9. 創(chuàng)建一個(gè)簡(jiǎn)單的THTimeLineItem對(duì)象THTittleItem, 用于將動(dòng)畫標(biāo)題添加到項(xiàng)目中.

@interface THTimtleItem: THTimelineItem

+ (instancetype)titleItemWithText:(NSString *)text image:(UIImage *)image;

- (instancetype)initWithText:(NSString *)text image:(UIImage *)image;

@property (copy, nonatomic) NSString *identifier;

@property (nonatomic) BOOL animateImage;

@property (nonatomic) BOOL useLargeFont;

- (CALayer *)buildLayer;

@end

@interface THTitleItem ()

@property (nonatomic, copy ) NSString *text;

@property (nonatomic, strong) UIImage *image;

@property (nonatomic) CGRect bounds;

@end

@implementation THTitleItem?

+ (instancetype)titleItemWithText:(NSString *)text image:(UIImage *)image {

? ? return [[self alloc] initWithText:text image:image];

}

- (instancetype)initWithText:(NSString *)text image:(UIImage *)image {

? ? self = [super init];

? ? if (self) {

? ? ? ? _text = text;

? ? ? ? _image = image;

? ? ? ? _bounds = TH720pVideoRect;

????}

? ? return self;

}

- (CALayer *)buildLayer {

? ? CALayer *parentLayer = [CALayer layer];

? ? parentLayer.frame = self.bounds;

? ? parentLayer.opacity = 0.0f;

? ? CALayer *imageLayer = [self makeImageLayer];

? ? [parentLayer addSubLayer:imageLayer];

? ? CALayer *textLayer = [self makeTextLayer];

? ? [parentLayer addSublayer:textLayer];

? ? return parentLayer;

}

- (CALayer *)makeImageLayer {

? ? CGSize imageSize = self.image.size;

? ? CALayer *layer = [CALayer layer];

? ? layer.contents = (id)self.image.CGImage;

? ? layer.allowsEdgeAntialiasing = YES;

? ? layer.bounds = CGRectMake(0, 0, imageSize.width, imageSize.height);

? ? layer.position = CGPointMake(CGRectGetMidX(self.bounds) - 20, 270);

? ? return layer;

}

- (CALayer *)makeTextLayer {

? ? CGFloat fontSize = self.userLargeFont ? 64 : 54;

? ? UIFont *font = [UIFont fontWithName:@"GillSans-Bold" size:fontSize];

? ? NSDictionary *attrs = @{NSFontAttributeName:font, NSForegroundColorAttributeName: (id)[UIColor whiteColor].CGColor};

? ? NSAttributeString *string = [[NSAttributedString alloc] initWithString:self.text attributes:attrs];

? ? CGSize textSize = [self.text sizeWithAttributes:attrs];

? ? CATextLayer *layer = [CATextLayer layer]; ? ?

? ? layer.string = string;

? ? layer.bounds = CGRectMake(0, 0, textSize.width, textSize.height);

? ? layer.position = CGPointMake(CGRectGetMidX(self.bounds), 470.0);

? ? layer.backgroundColor = [UIColor clearColor].CGColor;

? ? return layer;

}

@end

10. 創(chuàng)建淡入淡出動(dòng)畫效果

@implementation THTitleItme

...

- (CALayer *)buildLayer {

? ? CALayer *parentLayer = [CALayer layer];

? ? parentLayer.frame = self.bounds;

? ? parentLayer.opacity = 0.0f;

? ? CALayer *imageLayer = [self makeImageLayer];

? ? [parentLayer addSubLayer:imageLayer];

? ? CALayer *textLayer = [self makeTextLayer];

? ? [parentLayer addSublayer:textLayer];

? ? // --- build and attach animations ---

? ? CAAnimation *fadeInFadeOutAnimation = [self makeFadeInFadeOutAnimation];

? ? [parentLayer addAnimation:fadeInFadeOutAnimation forKey:nil];

? ? return parentLayer;

}

- (void)makeFadeInFadeOutAnimation {

? ? CAKeyframeAnimation *animation = [CAKeyAnimation animationWithKeyPath:@"opacity"];

? ? animation.values = @[@0, @1, @1, @0];

? ? animation.keyTimes = @[@0, @0.2, @0.8, @1];

? ? animation.removeOnCompletion = NO;

? ? return animation;

}

@end

11. 為標(biāo)題圖片添加動(dòng)畫

- (CALayer *)buildLayer {

? ? CALayer *parentLayer = [CALayer layer];

? ? parentLayer.frame = self.bounds;

? ? parentLayer.opacity = 0;

? ? CALayer *imageLayer = [self makeImageLayer];

????[parentLayer addSubLayer:imageLayer];

? ? CALayer *textLayer = [self makeTextLayer];

? ? [parentLayer addSubLayer:textLayer];

? ? CAAnimation *fadeInFadeOutAnimation = [self makeFadeInFadeOutAnimation];

? ? [parentLayer addAnimation:fadeInFadeOutAnimation forKey:nil];

? ? if (self.animateImage) {

? ????? //應(yīng)用一個(gè)3d繞y軸旋轉(zhuǎn)動(dòng)畫, 必須設(shè)置父視圖的透視變化

? ? ? ? parentLayer.sublayerTransform = THMakePerspectiveTransform(1000);

? ? ? ? CAAnimation *spinAnimation = [self make3DSpinAnimation]; ? ? ?

? ? ? ? NSTimeInterval offset = spinAnimation.beginTime + spinAnimation.duration - 0.5;

? ? ? ? CAAnimation *popAnimation = [self makePopAnimationWithTimingOffset:offset];

? ? [imageLayer addAnimation:spinAnimation forKey:nil];?

? ? [imageLayer addAnimation:popAnimation forKey:nil];

????}

? ? return parentLayer; ? ?

}

static CATransform3D THMakePerspectiveTransform(CGFloat eyePosition) {

? ? CATransform3d transform = CGTransform3DIdentify;

? ? transform.m34 = -1.0 / eyePosition;

? ? return transform;

}

- (CAAnimation *)make3DSpinAnimation {

? ? CABasicAnimation *animation = [CABasicAnimation?animationWithKeyPath@"transform.rotation.y"];

????animation.toValue = @{(4 * M_PI) * -1};? ??

? ? animation.beginTime = CMTimeGetSeconds(self.startTimeInTimeline) + 0.2;

? ? animation.duration = CGTimeGetSeconds(self.timeRange.duratoin) * 0.4;

? ? animation.removeOnCompletion = NO;

? ? animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

? ? return animation;

}

- (CAAnimation *)makePopAnimationWithTimingOffset:(NSTimeInterval)offset {

? ? CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];

? ? animation.toValue = @1.3;

? ? animation.beginTime = offset;

? ? animation.duration = 0.35;

? ? animation.autoreverses = YES; ? ?

? ? animation.removeOnCompletion = NO;

? ? animation.timingFunction = [CADediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];

? ? return animation;

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1 CALayer IOS SDK詳解之CALayer(一) http://doc.okbase.net/Hell...
    Kevin_Junbaozi閱讀 5,336評(píng)論 3 23
  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果,實(shí)現(xiàn)這些動(dòng)畫的過程并不復(fù)雜,今天將帶大家一窺iOS動(dòng)畫全貌。在這里你可以看...
    F麥子閱讀 5,270評(píng)論 5 13
  • 如果想讓事情變得順利,只有靠自己--夏爾·紀(jì)堯姆 上一章介紹了隱式動(dòng)畫的概念。隱式動(dòng)畫是在iOS平臺(tái)創(chuàng)建動(dòng)態(tài)用戶界...
    夜空下最亮的亮點(diǎn)閱讀 2,101評(píng)論 0 1
  • 顯式動(dòng)畫 顯式動(dòng)畫,它能夠?qū)σ恍傩宰鲋付ǖ淖远x動(dòng)畫,或者創(chuàng)建非線性動(dòng)畫,比如沿著任意一條曲線移動(dòng)。 屬性動(dòng)畫 ...
    清風(fēng)沐沐閱讀 2,094評(píng)論 1 5
  • 在iOS實(shí)際開發(fā)中常用的動(dòng)畫無非是以下四種:UIView動(dòng)畫,核心動(dòng)畫,幀動(dòng)畫,自定義轉(zhuǎn)場(chǎng)動(dòng)畫。 1.UIView...
    請(qǐng)叫我周小帥閱讀 3,324評(píng)論 1 23

友情鏈接更多精彩內(nèi)容