最基礎(chǔ)的動(dòng)畫組合(包括直播送禮物的優(yōu)化)

http://www.tuicool.com/articles/EVNFjqN

直播APP常用動(dòng)畫效果

時(shí)間?2016-11-14 09:50:37CocoaChina

原文http://www.cocoachina.com/ios/20161114/18073.html

主題iOS開(kāi)發(fā)

介紹

記錄、總結(jié)開(kāi)發(fā)遇到一些問(wèn)題,大家一起交流學(xué)習(xí)。

這次帶來(lái),對(duì)直播APP的常用動(dòng)畫總結(jié)。

效果展示

下面是一個(gè)很多平臺(tái)都有的入門豪華禮物動(dòng)畫——煙花。

一個(gè)復(fù)雜的禮物動(dòng)畫,首先是美術(shù)給出gif實(shí)現(xiàn)草圖素材,技術(shù)進(jìn)行動(dòng)畫剖析圖片壓縮,在程序中加載圖片實(shí)現(xiàn)動(dòng)畫,其中要注意內(nèi)存和CPU占用

圖片壓縮、加載與裁剪

1、圖片壓縮

美術(shù)給出的圖片,即使是壓縮過(guò),仍存在較大的壓縮空間,可以用這里或者更好的大小優(yōu)化。

2、圖片加載

主要有-imageNamed:和-imageWithContentsOfFile:兩種方式。

AnimationImageCache類是一個(gè)動(dòng)畫圖片加載類,用單例實(shí)現(xiàn)且內(nèi)部用NSCache持有引用。

注意,當(dāng)收到內(nèi)存不足警告時(shí),NSCache會(huì)自動(dòng)釋放內(nèi)存。所以每次訪問(wèn)NSCache,即使上一次已經(jīng)加載過(guò),也需要判斷返回值是否為空。

3、圖片裁剪

為了減少圖片資源的大小,有時(shí)候會(huì)把多個(gè)幀動(dòng)畫做成連續(xù)的一張圖。這時(shí)需要程序加載一整張資源圖,并在相應(yīng)的位置進(jìn)行裁剪。

UIImage* sourceImage = [UIImageimageNamed:@"image/animation/gift_boat"];CGSizesourceSize = sourceImage.size;CGImageRefcgimage =CGImageCreateWithImageInRect(sourceImage.CGImage,CGRectMake(0,0, const_position_boat_x, sourceSize.height));? ? gWaveFrameImage = [UIImageimageWithCGImage:cgimage];CGImageRelease(cgimage);? ? cgimage =CGImageCreateWithImageInRect(sourceImage.CGImage,CGRectMake(const_position_boat_x,0, const_position_boat_width, sourceSize.height));? ? gBoatFrameImage = [UIImageimageWithCGImage:cgimage];CGImageRelease(cgimage);? ? cgimage =CGImageCreateWithImageInRect(sourceImage.CGImage,CGRectMake(const_position_boat_x + const_position_boat_width,0, sourceSize.width - const_position_boat_x - const_position_boat_width, sourceSize.height));? ? gShadowFrameImage = [UIImageimageWithCGImage:cgimage];CGImageRelease(cgimage);

動(dòng)畫剖析與時(shí)間軸

下面這個(gè)是一個(gè)全屏類型的“天使”禮物動(dòng)畫,我們來(lái)剖析下這個(gè)動(dòng)畫的構(gòu)成。

1、背景變暗,出現(xiàn)星空;

2、流星劃過(guò)、月亮出現(xiàn)、云彩飄動(dòng);

3、兩側(cè)浮空島震動(dòng),中間浮空島出現(xiàn);

4、背光出現(xiàn),天使落下,翅膀扇動(dòng);

5、星星閃爍、鳳凰出現(xiàn);

6、漸隱消失;

時(shí)間軸實(shí)現(xiàn)

為了讓動(dòng)畫按照時(shí)間順序一一執(zhí)行,可以把動(dòng)畫按時(shí)間和對(duì)象分成多個(gè)方法,通過(guò)GCD在指定的時(shí)間調(diào)用。

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0* NSEC_PER_SEC)), dispatch_get_main_queue(), ^{? ? ? ? [self playMeteorAnimation];? ? });? ? dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{? ? ? ? [self playLandAnimation];});dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(6.0* NSEC_PER_SEC)), dispatch_get_main_queue(), ^{? ? ? ? [self playLightAnimation];? ? });? ? dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(7.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{? ? ? ? [self playStarAnimation];});dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(TOTAL_TIME* NSEC_PER_SEC)), dispatch_get_main_queue(), ^{? ? ? ? @weakify(self);? ? ? ? [UIView animateWithDuration:0.5 animations:^{? ? ? ? ? ? self.alpha = 0;? ? ? ? } completion:^(BOOL finished) {? ? ? ? ? ? @strongify(self);? ? ? ? ? ? [self removeFromSuperview];? ? ? ? ? ? [self callBackManager];? ? ? ? }];? ? });

常用動(dòng)畫效果

1、視圖變暗、變大

alpha值屬性是透明度,把背景設(shè)置成淡黑色,然后調(diào)整alpha可以達(dá)到背景漸變的視圖效果;

UIView的transform是可以用仿射變換矩陣來(lái)控制平移、放大縮小等。

[UIViewanimateWithDuration:1.5animations:^{self.mBackgroundView.alpha =0.5;self.mAngelView.transform =CGAffineTransformMakeScale(1.2,1.2);? ? }];

2、勻速運(yùn)動(dòng)、交錯(cuò)效果

right是項(xiàng)目封裝的一個(gè)屬性,本質(zhì)是對(duì)UIView的frame進(jìn)行操作;

兩朵云, 左邊的朝右,右邊的朝左,即可達(dá)到交錯(cuò)的效果。

[UIViewanimateWithDuration:TOTAL_TIMEdelay:0options:UIViewAnimationOptionCurveLinearanimations:^{self.mAngelCloudView0.right+=250;self.mAngelCloudView1.right-=190;? ? } completion:nil];

3、上下往返運(yùn)動(dòng)

CAKeyframeAnimation是關(guān)鍵幀動(dòng)畫,對(duì)layer的postion的y坐標(biāo)進(jìn)行操作;

設(shè)定好起始位置、經(jīng)過(guò)位置,最后回到起始位置,即可實(shí)現(xiàn)上下往返的效果。

CAKeyframeAnimation*upDownAnimation;? ? upDownAnimation = [CAKeyframeAnimationanimationWithKeyPath:@"position.y"];? ? upDownAnimation.values = @[@(self.mAngelLandView1.layer.position.y), @(self.mAngelLandView1.layer.position.y +5), @(self.mAngelLandView1.layer.position.y)];? ? upDownAnimation.duration =2;? ? upDownAnimation.fillMode = kCAFillModeBoth;? ? upDownAnimation.calculationMode = kCAAnimationCubic;? ? upDownAnimation.repeatCount = HUGE_VALF;? ? [self.mAngelLandView1.layer addAnimation:upDownAnimation forKey:@"upDownAnimation"];

4、閃爍效果

閃爍的本質(zhì)是alpha的變化,但是UIView的block動(dòng)畫不好實(shí)現(xiàn)重復(fù)效果;

UIView的alpha對(duì)應(yīng)的是layer的opacity屬性,設(shè)定好起始、過(guò)度和結(jié)束的狀態(tài),實(shí)現(xiàn)閃爍的效果。

CAKeyframeAnimation *opacityAnimation;? ? opacityAnimation = [CAKeyframeAnimationanimationWithKeyPath:@"opacity"];? ? opacityAnimation.values = @[@(0), @(1), @(0)];? ? opacityAnimation.duration =1.5;? ? opacityAnimation.fillMode = kCAFillModeBoth;? ? opacityAnimation.calculationMode = kCAAnimationCubic;? ? opacityAnimation.repeatCount = HUGE_VALF;? ? [self.mAngelStarView.layeraddAnimation:opacityAnimationforKey:@"opacityAnimation"];

5、貝塞爾曲線運(yùn)動(dòng)

貝塞爾曲線是優(yōu)化動(dòng)畫體驗(yàn)的很重要部分,比如說(shuō)天上掉下來(lái)的羽毛,地上冒起來(lái)的氣泡,空中飄蕩的氣球,都可以用貝塞爾曲線來(lái)繪制,從而獲得很好的視覺(jué)體驗(yàn);

本質(zhì)還是關(guān)鍵幀動(dòng)畫,這次操作的屬性是position,通過(guò)path屬性來(lái)確定路徑;

給貝塞爾曲線設(shè)定好目標(biāo)點(diǎn)后,把path賦值給關(guān)鍵幀動(dòng)畫,再把動(dòng)畫添加到layer上即可;

UIImage*image = [[AnimationImageCache shareInstance] getImageWithName:@"gift_castle_hot_air_balloon3.png"];UIImageView*hotAirBalloonView0 = [[UIImageViewalloc] initWithFrame:CGRectMake(50,100, image.size.width /2, image.size.height /2)];? ? [selfaddSubview:hotAirBalloonView0];? ? [hotAirBalloonView0 setImage:image];// 飄動(dòng)CGPointposition =CGPointMake(self.width, hotAirBalloonView0.top);CGFloatduration =5;CAKeyframeAnimation*positionAnimate = [CAKeyframeAnimationanimationWithKeyPath:@"position"];? ? positionAnimate.repeatCount =1;? ? positionAnimate.duration = duration;? ? positionAnimate.fillMode = kCAFillModeForwards;? ? positionAnimate.removedOnCompletion =NO;UIBezierPath*sPath = [UIBezierPathbezierPath];? ? [sPath moveToPoint:position];? ? [sPath addCurveToPoint:CGPointMake(-image.size.width /2, position.y) controlPoint1:CGPointMake(self.width /3*2, position.y -60) controlPoint2:CGPointMake(self.width /3, position.y +60)];? ? positionAnimate.path = sPath.CGPath;? ? [hotAirBalloonView0.layer addAnimation:positionAnimate forKey:@"positionAnimate"];

6、遮罩動(dòng)畫

遮罩效果可以實(shí)現(xiàn)彩虹出現(xiàn)、煙花爆炸、畫卷打開(kāi)等效果,通過(guò)改變遮罩的大小,影響原始圖片的展示,達(dá)到動(dòng)畫的效果;

先新建一個(gè)CAShapeLayer,并設(shè)置為layer的遮罩;

新建一個(gè)動(dòng)畫,設(shè)定初始和結(jié)束狀態(tài)并賦值給CAShapeLayer,完成一個(gè)遮罩動(dòng)畫。

UIBezierPath*maskStartPath = [UIBezierPathbezierPathWithRect:CGRectMake(CGRectGetWidth(rainbowView1.bounds),0,CGRectGetWidth(rainbowView1.bounds),CGRectGetHeight(rainbowView1.bounds))];UIBezierPath*maskFinalPath = [UIBezierPathbezierPathWithRect:rainbowView1.bounds];CAShapeLayer*maskLayer = [CAShapeLayerlayer];? ? rainbowView1.layer.mask = maskLayer;? ? maskLayer.path = maskFinalPath.CGPath;CABasicAnimation*maskLayerAnimation = [CABasicAnimationanimationWithKeyPath:@"path"];? ? maskLayerAnimation.fromValue = (__bridgeid)maskStartPath.CGPath;? ? maskLayerAnimation.toValue = (__bridgeid)maskFinalPath.CGPath;? ? maskLayerAnimation.removedOnCompletion =NO;? ? maskLayerAnimation.duration =2.0;? ? maskLayerAnimation.timingFunction = [CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseInEaseOut];? ? [maskLayer addAnimation:maskLayerAnimation forKey:@"maskLayerAnimation"];

7、旋轉(zhuǎn)效果

燈光掃動(dòng),花朵旋轉(zhuǎn)等旋轉(zhuǎn)效果,都可以transform的rotation.z屬性來(lái)實(shí)現(xiàn);

同樣使用CAKeyframeAnimation實(shí)現(xiàn),設(shè)定好初始、中間、結(jié)束狀態(tài),動(dòng)畫時(shí)間已經(jīng)重復(fù)次數(shù),并添加到layer,完成旋轉(zhuǎn)效果;

CAKeyframeAnimation* rotationAnimation;? ? rotationAnimation = [CAKeyframeAnimationanimationWithKeyPath:@"transform.rotation.z"];? ? rotationAnimation.values = @[@(M_PI/ 12), @(M_PI /3), @(M_PI /12)];? ? rotationAnimation.duration =2.5;? ? rotationAnimation.fillMode = kCAFillModeBoth;? ? rotationAnimation.calculationMode = kCAAnimationCubic;//? ? rotationAnimation.cumulative = YES;rotationAnimation.repeatCount = HUGE_VALF;? ? [self.mLightLeftView.layeraddAnimation:rotationAnimationforKey:@"rotationAnimation"];

8、幀動(dòng)畫

某些復(fù)雜動(dòng)畫不是靠對(duì)原始圖像操作進(jìn)行操作就能實(shí)現(xiàn),這時(shí)候就要用到幀動(dòng)畫

幀動(dòng)畫有兩種實(shí)現(xiàn)方式,一種是通過(guò)Timer(定時(shí)器),設(shè)定好時(shí)間間隔,手動(dòng)替換圖片;

另外一種是通過(guò)UIImageView的支持,實(shí)現(xiàn)幀動(dòng)畫。

UIImageView的幀動(dòng)畫沒(méi)有回調(diào),如果需要實(shí)現(xiàn)達(dá)到第幾幀之后,開(kāi)始另外的動(dòng)畫的效果,需要用第一種方法。

NSMutableArray*images = [NSMutableArrayarray];for(inti =0; i <6; ++i) {UIImage*img = [[AnimationImageCache shareInstance] getDriveImageWithName:[NSStringstringWithFormat:@"gift_animation_angel_phoenix%d.png", i]];if(img) {? ? ? ? ? ? [images addObject:img];? ? ? ? }? ? }self.mAngelPhoenixView.image = [[AnimationImageCache shareInstance] getDriveImageWithName:@"gift_animation_angel_phoenix0.png"];self.mAngelPhoenixView.animationImages = images;self.mAngelPhoenixView.animationDuration =0.8;self.mAngelPhoenixView.animationRepeatCount =1;? ? [self.mAngelPhoenixView startAnimating];

動(dòng)畫的性能優(yōu)化

直播APP的性能優(yōu)化-禮物篇

iOS開(kāi)發(fā)-視圖渲染與性能優(yōu)化

都有,不再贅述。

總結(jié)

UIView的block動(dòng)畫中,completion持有的是強(qiáng)引用,需要避免造成循環(huán)引用。

但在調(diào)用完畢completion后,會(huì)釋放引用。

天使動(dòng)畫的圖片大小為900KB,運(yùn)行時(shí)占內(nèi)存15MB,播放完畢后,如果收到內(nèi)存不足的警告會(huì)釋放內(nèi)存;

煙花動(dòng)畫的圖片大小為400KB,運(yùn)行時(shí)占用的內(nèi)存為20MB,播放完畢后,會(huì)馬上釋放內(nèi)存;

思考題

1、為什么煙花動(dòng)畫的圖片大小比較小,運(yùn)行時(shí)占用的內(nèi)存反而更多?

2、播放完畢馬上釋放和收到內(nèi)存不足警告再釋放,兩種圖片加載方式的優(yōu)缺點(diǎn)?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 在iOS實(shí)際開(kāi)發(fā)中常用的動(dòng)畫無(wú)非是以下四種:UIView動(dòng)畫,核心動(dòng)畫,幀動(dòng)畫,自定義轉(zhuǎn)場(chǎng)動(dòng)畫。 1.UIView...
    請(qǐng)叫我周小帥閱讀 3,142評(píng)論 1 23
  • 在iOS實(shí)際開(kāi)發(fā)中常用的動(dòng)畫無(wú)非是以下四種:UIView動(dòng)畫,核心動(dòng)畫,幀動(dòng)畫,自定義轉(zhuǎn)場(chǎng)動(dòng)畫。下面我們逐個(gè)介紹。...
    4b5cb36a2ee2閱讀 364評(píng)論 0 0
  • 現(xiàn)在分析到Y(jié)YImage 首先看文件 YYImage YYFrameImage YYSpriteSheetImag...
    充滿活力的早晨閱讀 2,567評(píng)論 0 3
  • Core Animation Core Animation,中文翻譯為核心動(dòng)畫,它是一組非常強(qiáng)大的動(dòng)畫處理API,...
    45b645c5912e閱讀 3,048評(píng)論 0 21
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒(méi)有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,132評(píng)論 1 32