iOS炫酷動(dòng)畫(二)

O(∩_∩)O哈利诺!又是一個(gè)很cool的動(dòng)畫剩燥。原作者在這里灭红。畫面看著太美好,于是又試著用Swift寫了一個(gè)变擒。我的在這里

1.gif
動(dòng)畫分解

1赁项、首先是橢圓背景色的漸變,灰色---》淡藍(lán)色悠菜。

2、臉的動(dòng)畫摩窃。這里又分為臉盤(??就這么叫吧)和器官(2眼睛+1嘴巴)的動(dòng)畫。

  • 臉盤的動(dòng)畫鹦聪,比較簡單蒂秘,就是x的位移。
  • 眼睛+嘴巴這個(gè)整體的動(dòng)畫姻僧,有個(gè)回彈的效果。先是向右飛出去赌莺,然后到達(dá)右邊之后松嘶,又從左邊飛進(jìn)來,最后回彈一下巢音。

3尽超、嘴巴的動(dòng)畫。off的時(shí)候橙弱,是個(gè)長方形的嘴,切換到on斜筐,變成了笑臉嘴蛀缝,并且有個(gè)逐漸張開的過程。

AIYA嗤练,還真是難描述在讶。

元素分解

知道了動(dòng)畫步驟之后,元素就比較好分了革答。臉盤是1個(gè)layer,2眼睛+嘴巴==1個(gè)layer途茫,橢圓背景=1view溪食。

開工開工
嘴巴

首先注意到的是嘴巴的繪制错沃,on和off的狀態(tài)其實(shí)是2種不同的曲線,長方形很好畫捎废,那么張開的嘴呢致燥?當(dāng)然都是用萬能的貝塞爾曲線啦嫌蚤。其實(shí)看了代碼,都覺得簡單o(>﹏<)o智政。

閉嘴的frame=(0.25w, 0.7h, 0.5w, 0.1h)
張嘴的箱蝠,x,y,w都是一樣的,只不過是控制2個(gè)control point的位置宦搬。

private func mouthPath() -> UIBezierPath {
        
        if isOn {
            let path = UIBezierPath()

            path.moveToPoint(CGPointMake(mouthRect().origin.x, mouthRect().origin.y))
            path.addCurveToPoint(CGPointMake(mouthLenth() + mouthRect().origin.x, mouthY()), controlPoint1: CGPointMake(mouthRect().origin.x + mouthOffset / 4, mouthY() + mouthOffset / 2),
                                 controlPoint2: CGPointMake(mouthRect().origin.x + mouthOffset * 3 / 4, mouthY() + mouthOffset / 2))
            path.closePath()
            
            return path
        } else {
            let path = UIBezierPath(rect: mouthRect())
            return path
        }
    }

眼睛

眼睛就是2個(gè)橢圓间校,有現(xiàn)成的。frame=(0.2w, 0.25h, 0.4w, 0.6h)

private func rightEyePath() -> UIBezierPath {
        let origin = rightEyeOrigin()
        let size = eyeSize()
        let path = UIBezierPath(ovalInRect: CGRectMake(origin.x, origin.y, size.width, size.height))
        
        return path
    }
眼睛+嘴巴

其實(shí)就是在layer上面胁附,分別把他們畫上去滓彰。

override func drawInContext(ctx: CGContext) {
        
        let bezierLeft = leftEyePath()
        let bezierRight = rightEyePath()
        let bezierMouth = mouthPath()
        
        CGContextAddPath(ctx, bezierLeft.CGPath)
        CGContextAddPath(ctx, bezierRight.CGPath)
        CGContextAddPath(ctx, bezierMouth.CGPath)
        CGContextSetFillColorWithColor(ctx, color().CGColor)
        CGContextSetStrokeColorWithColor(ctx, UIColor.clearColor().CGColor)
        CGContextFillPath(ctx)
    }

臉盤/橢圓背景

這個(gè)更簡單了,用cornerRadius或者bezierPath都行饼暑。

嘴張開的動(dòng)畫

因?yàn)樽焓怯胋ezier曲線畫的,有2個(gè)control point彰居。所以主要是操控control point撰筷,來實(shí)現(xiàn)張開的效果。

為了支持自定義屬性動(dòng)畫抬闯,需要用到needsDisplayForKey关筒,改變屬性后,可以引發(fā)drawInContext重繪蒸播。mouthOffset最后其實(shí)是等于mounLength的,所以只需要將mouthOffset從0變到mounLength即可胀屿。

internal override class func needsDisplayForKey(key: String) -> Bool {
        if key == "mouthOffset" {
            return true
        }
        
        return super.needsDisplayForKey(key)
    }
    
動(dòng)畫順序

拿從off到on的過程來說包雀。
1、背景漸變+臉盤移動(dòng)+器官向右飛出
2葡兑、臉盤移動(dòng)的動(dòng)畫結(jié)束后赞草,器官從左往右飛出,并回彈蜕劝。同時(shí)嘴巴開始張開動(dòng)畫轰异。
3、回彈動(dòng)畫結(jié)束搭独,整個(gè)動(dòng)畫結(jié)束牙肝。

動(dòng)畫注意

在動(dòng)畫結(jié)束之后嗤朴,要將對(duì)應(yīng)值設(shè)成動(dòng)畫之后的值虫溜。

override func animationDidStop(anim: CAAnimation, finished flag: Bool) {
        if flag {
            if let type = anim.valueForKey("animation") as? String {
                // 臉盤移動(dòng)到端點(diǎn)
                if type == "faceBgLayerAnimation" {
                    
                    faceBgLayer.removeAllAnimations()
                    faceBgLayer.position = positionOfFaceView(!isOn)
                    
                    faceLayer.isOn = !isOn
                    faceLayer.mouthOffset = !isOn ? faceLayer.bounds.size.width / 2 : 0
                    faceLayer.setNeedsDisplay()
                
                    if (!isOn) {
                        mouthAnimation(isOn, offset: faceLayer.bounds.size.width / 2)
                        moveRightBackAnimation()
                    } else {
                        moveLeftBackAnimation()
                    }
                } else if type == "backgroundAnimation" {
                    
                    self.backgroundColor = isOn ? onColor : offColor
                    
                } else if type == "moveBackAnimation" {
                    
                    faceLayer.removeAllAnimations()

                    isOn = !isOn
                    isAnimating = false
                }
            }
        }
    }

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末衡楞,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子歧杏,更是在濱河造成了極大的恐慌迷守,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凯力,死亡現(xiàn)場(chǎng)離奇詭異急膀,居然都是意外死亡龄捡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來奸腺,“玉大人,你說我怎么就攤上這事帮非《锬ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵陨舱,是天一觀的道長版仔。 經(jīng)常有香客問我误墓,道長益缎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任畦娄,我火速辦了婚禮弊仪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘驳癌。我一直安慰自己役听,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布甜滨。 她就那樣靜靜地躺著瘤袖,像睡著了一般。 火紅的嫁衣襯著肌膚如雪艾扮。 梳的紋絲不亂的頭發(fā)上占婉,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音酌予,去河邊找鬼奖慌。 笑死,一個(gè)胖子當(dāng)著我的面吹牛升薯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播广凸,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼谅海,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了扭吁?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤蝌诡,失蹤者是張志新(化名)和其女友劉穎枫吧,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體颁湖,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡例隆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年镀层,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鹿响。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡惶我,死狀恐怖博投,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情毅哗,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布尿瞭,位于F島的核電站翅睛,受9級(jí)特大地震影響黑竞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜疏旨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一很魂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧檐涝,春花似錦遏匆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至惰爬,卻和暖如春喊暖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背撕瞧。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來泰國打工陵叽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留丛版,地道東北人巩掺。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像页畦,于是被迫代替她去往敵國和親胖替。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

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

  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果豫缨,實(shí)現(xiàn)這些動(dòng)畫的過程并不復(fù)雜独令,今天將帶大家一窺ios動(dòng)畫全貌。在這里你可以看...
    每天刷兩次牙閱讀 8,495評(píng)論 6 30
  • 轉(zhuǎn)載:http://www.reibang.com/p/32fcadd12108 每個(gè)UIView有一個(gè)伙伴稱為l...
    F麥子閱讀 6,210評(píng)論 0 13
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,167評(píng)論 25 707
  • 每個(gè)UIView有一個(gè)伙伴稱為layer好芭,一個(gè)CALayer燃箭。UIView實(shí)際上并沒有把自己畫到屏幕上;它繪制本身...
    shenzhenboy閱讀 3,110評(píng)論 0 17
  • 我忍不住想睡了 它卻一直阻攔我 打開我的眼 卻什么都看不見 也不知道 張開眼看見的 和睡了 有何區(qū)別
    滿島遙閱讀 130評(píng)論 0 0