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

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

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

3. Animations 動畫對象是抽象類CAAnimation的實(shí)例, 定義所有動畫類型共有的一些核心動畫行為.該框架定義了CAAnimation的許多具體子類. 最常用的就是CABasicAnimation和CAKeyFrameAniation. 這些類將動畫狀態(tài)變?yōu)閱为?dú)的圖層屬性, 以便創(chuàng)建簡單的和復(fù)雜的動畫效果. CABasicAnimation 可以讓你創(chuàng)建簡單的單關(guān)鍵幀動畫, 意味著在一段時間內(nèi)將屬性狀態(tài)以動畫方式由一種狀態(tài)變?yōu)榱硪环N狀態(tài). 這個類實(shí)現(xiàn)簡單動畫時非常實(shí)用. 比如動態(tài)調(diào)整圖層的尺寸, 位置和背景色. CAKeyFrameAnimation用于實(shí)現(xiàn)更高級的功能, 它對動畫中的關(guān)鍵幀有著更多的控制. 比如當(dāng)一個圖層沿著Bezier路徑動態(tài)顯示, 可以用到關(guān)鍵幀動畫來指定具體的時間和節(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平臺創(chuàng)建實(shí)時動畫效果的方法幾乎一樣. 最大的區(qū)別在于運(yùn)行動畫的時間模型. 當(dāng)創(chuàng)建實(shí)時動畫時, CAAnimation實(shí)例從系統(tǒng)主機(jī)獲取執(zhí)行時間.

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

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

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

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

9. 創(chuàng)建一個簡單的THTimeLineItem對象THTittleItem, 用于將動畫標(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)建淡入淡出動畫效果

@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)題圖片添加動畫

- (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)用一個3d繞y軸旋轉(zhuǎn)動畫, 必須設(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)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市矩乐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖拗胜,帶你破解...
    沈念sama閱讀 221,430評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件歧匈,死亡現(xiàn)場離奇詭異败许,居然都是意外死亡王带,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評論 3 398
  • 文/潘曉璐 我一進(jìn)店門市殷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來愕撰,“玉大人,你說我怎么就攤上這事醋寝「阏酰” “怎么了?”我有些...
    開封第一講書人閱讀 167,834評論 0 360
  • 文/不壞的土叔 我叫張陵音羞,是天一觀的道長囱桨。 經(jīng)常有香客問我,道長黄选,這世上最難降的妖魔是什么蝇摸? 我笑而不...
    開封第一講書人閱讀 59,543評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮办陷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘律歼。我一直安慰自己民镜,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,547評論 6 397
  • 文/花漫 我一把揭開白布险毁。 她就那樣靜靜地躺著制圈,像睡著了一般。 火紅的嫁衣襯著肌膚如雪畔况。 梳的紋絲不亂的頭發(fā)上鲸鹦,一...
    開封第一講書人閱讀 52,196評論 1 308
  • 那天,我揣著相機(jī)與錄音跷跪,去河邊找鬼馋嗜。 笑死,一個胖子當(dāng)著我的面吹牛吵瞻,可吹牛的內(nèi)容都是我干的葛菇。 我是一名探鬼主播甘磨,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼眯停!你這毒婦竟也來了济舆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,671評論 0 276
  • 序言:老撾萬榮一對情侶失蹤莺债,失蹤者是張志新(化名)和其女友劉穎滋觉,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體齐邦,經(jīng)...
    沈念sama閱讀 46,221評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡椎瘟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,303評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了侄旬。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肺蔚。...
    茶點(diǎn)故事閱讀 40,444評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖儡羔,靈堂內(nèi)的尸體忽然破棺而出宣羊,到底是詐尸還是另有隱情,我是刑警寧澤汰蜘,帶...
    沈念sama閱讀 36,134評論 5 350
  • 正文 年R本政府宣布仇冯,位于F島的核電站,受9級特大地震影響族操,放射性物質(zhì)發(fā)生泄漏苛坚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,810評論 3 333
  • 文/蒙蒙 一色难、第九天 我趴在偏房一處隱蔽的房頂上張望泼舱。 院中可真熱鬧,春花似錦枷莉、人聲如沸娇昙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽冒掌。三九已至,卻和暖如春蹲盘,著一層夾襖步出監(jiān)牢的瞬間股毫,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評論 1 272
  • 我被黑心中介騙來泰國打工召衔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留铃诬,地道東北人。 一個月前我還...
    沈念sama閱讀 48,837評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像氧急,于是被迫代替她去往敵國和親颗胡。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,455評論 2 359

推薦閱讀更多精彩內(nèi)容

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