iOS爆炸效果

在github上看到了android的爆炸效果,感覺做的不錯,自己也想做著試試,效果沒它的好,算是基本實現了。

效果圖如下,感覺gif錄制的不太清晰。

explosion.gif

實現原理

從圖中可以大致看出,爆炸點點都是取的某坐標的顏色值,然后根據一些動畫效果來完成的。

取色值

怎么取的view的某個點的顏色值呢?google一下,就可以找到很多答案。就不具體說了。創建1*1的位圖,然后渲染到屏幕上,然后得到RGBA。我這里寫的是UIView的extension。

extension UIView {

    public func colorOfPoint(point:CGPoint) -> UIColor
    {
        var pixel:[CUnsignedChar] = [0,0,0,0]

        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedLast.rawValue)

        let context = CGBitmapContextCreate(&pixel, 1, 1, 8, 4, colorSpace, bitmapInfo.rawValue)

        CGContextTranslateCTM(context, -point.x, -point.y)

        self.layer.renderInContext(context!)

        let red: CGFloat = CGFloat(pixel[0]) / 255.0
        let green: CGFloat = CGFloat(pixel[1]) / 255.0
        let blue: CGFloat = CGFloat(pixel[2]) / 255.0
        let alpha: CGFloat = CGFloat(pixel[3]) / 255.0

        return UIColor(red:red, green: green, blue:blue, alpha:alpha)
    }
}
粒子的生成

這里我寫的比較簡單,就是固定每個粒子大小,根據View的寬高算出橫向,縱向的粒子數,取該點的色值,設置粒子背景色,然后生成即可。

主要代碼如下:

frameDict是我預先計算好的坐標表,colorDict是顏色表。以"i-j"為key

class func createExplosionPoints(containerLayer: ExplosionLayer, targetView: UIView, animationType: ExplosionAnimationType) {

        let hCount = self.caculatePointHCount(containerLayer.targetSize.width)
        let vCount = self.caculatePointVCount(containerLayer.targetSize.height)

        for i in 0..<hCount {
            for j in 0..<vCount {
                let key = String(format: "%d-%d", i, j)
                if let rect = containerLayer.frameDict[key], color = containerLayer.colorDict[key] {

                    let layer = createExplosionPointLayer(rect, bgColor: color, targetViewSize: containerLayer.targetSize)

                    // animation
                    layer.explosionAnimation = self.createAnimationWithType(animationType, position: layer.position, targetViewSize: containerLayer.targetSize)

                    containerLayer.addSublayer(layer)
                    
                    layer.beginAnimation()
                }
            }
        }
    }

動畫效果

每個粒子都有一個CAAnimation動畫,數據由調用者提供,靈活點。
這里定義了一個protocol:ExplosionAnimationProtocol,可以自定義實現了該protocol的動畫對象,提供動畫效果。

protocol ExplosionAnimationProtocol {

    // 粒子初始位置
    var oldPosition: CGPoint { set get }
    
    // 粒子最終位置
    var newPosition: CGPoint { set get }
    
    // 縮放
    var scale: CGFloat { set get }
    
    // 動畫時長
    var duration: CFTimeInterval { set get }
    
    // 動畫重復次數
    var repeatCount: Float { set get }

    // 生成動畫
    func animation() -> CAAnimation
    
    // 設置動畫完之后的屬性
    func resetLayerProperty(layer: CALayer)
}
要發生爆炸view的動畫效果

這個比較簡單,就是上下左右震動下。具體代碼就不貼出來了,可以到demo里看。

let shakeAnimation = CAKeyframeAnimation(keyPath: "position")
...

代碼結構

大致思路就是這樣。代碼結構如下:

project@2x.png

ExplosionLayer是粒子的父容器,

ExplosionPointLayer是粒子本身

ExplosionHelper是個輔助類,用于計算粒子位置,顏色值。

FallAnimation,UpAnimation是實現了ExplosionAnimationProtocol的動畫,分別提供向下落,向上的效果。

碰到的問題

剛開始我是在邊計算顏色值,邊繪制粒子,發現會卡一下才會有爆炸效果出來,分析可能是在計算顏色值在主線程,時間較長,所以卡住了。

后來想到放到后臺線程中去做,但是在主線程中取色值的時候,后臺必須執行完,所以用了信號量來進行同步。

// 震動效果
private func shake() {

        self.createSemaphore()

        // 計算位置,色值
        self.caculate()

        let shakeAnimation = CAKeyframeAnimation(keyPath: "position")

        shakeAnimation.values = [NSValue.init(CGPoint: self.position), NSValue.init(CGPoint: CGPointMake(self.position.x, self.position.y + 1)), NSValue.init(CGPoint: CGPointMake(self.position.x + 1, self.position.y - 1)), NSValue.init(CGPoint: CGPointMake(self.position.x - 1, self.position.y + 1))]

        shakeAnimation.duration = 0.2
        shakeAnimation.repeatCount = 15
        shakeAnimation.delegate = self
        shakeAnimation.removedOnCompletion = true

        self.targetView?.layer.addAnimation(shakeAnimation, forKey: "shake")
    }

當要爆炸的view開始震動時,就開始在后臺計算。震動動畫結束后,等待計算完成。

override func animationDidStop(anim: CAAnimation, finished flag: Bool) {

        // wait for caculate
        dispatch_semaphore_wait(self.semaphore!, DISPATCH_TIME_FOREVER)

        print("shake animation stop")

        // begin explode
        if let targetView = self.targetView {
            self.parentLayer?.addSublayer(self)
            ExplosionHelper.createExplosionPoints(self, targetView: targetView, animationType: self.animationType)

            self.targetView?.hidden = true
        }
    }

在后續的創建粒子時,就直接從緩存中取就行了。

demo地址:https://github.com/silan-liu/ExplosionView.git

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,527評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,687評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,640評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,957評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,682評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,011評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,009評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,183評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,714評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,435評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,665評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,148評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,838評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,251評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,588評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,379評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,627評論 2 380

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,765評論 25 708
  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,179評論 4 61
  • 現在已經養成習慣,觀影之前不看預告不刷訊息,不因輿論而先入為主,不因劇透而錯過親身感受 春節檔,乃各電影兵馬必爭之...
    Panda盼子閱讀 582評論 2 0
  • 今天看了一本佳琪老師推薦給我的書《從零開始學運營》,這本書對于我這種對運營行業充滿期待小朋友還是很有幫助噠! 今天...
    K41閱讀 310評論 0 1
  • 教師節有感 又是一年教師節,每年這個時候,都是向老師致敬,也是被致敬的時候。 從小到大,在我們生命的每一段都有老師...
    諸慧的身心園地閱讀 172評論 0 0