這交互炸了(三):閃屏頁是像雲同樣消失的

《交互炸了》或許是一系列高端特效教程, 文中會介紹一些比較炫酷的特效,以及實現的思路。特效實現自己也許不會有太大的難度。難點在於實現的思路。一旦思路被打開,特效將很簡單實現。java

效果項目地址: https://github.com/githubwing/WowSplashgit

本期是第三期,第二期作的比較草率,好像並不太符合「交互炸了」這一主題,因此之後我會保證質量,而不是爲了跟進數量湊數。此次給你們分享的效果是一個閃屏頁的效果,效果以下:github

有沒有眼前一亮?如今許多炫酷的閃屏頁或者引導頁喜歡用視頻來作,可是我偏不,緣由有兩個:canvas

1.視頻會增長App體積,爲了這一個閃屏頁,多增長用戶下載流量,這是很噁心的一件事情。

2.第二段雲擴散融合效果,視頻實現起來比較棘手。

動效製做思路發散

前面一篇跟你們分享了一寫關於動畫的小技巧。動畫這種東西跟魔術同樣,只要用戶看的開心,怎麼實現無所謂,因此作一些障眼法來取悅用戶是沒有問題的。這裏的障眼法大概有以下幾點:緩存

1.View放大不是真正的放大。markdown

2.View平移以後,可能懸浮在頂部的已經換成了一個如出一轍的雙胞胎View。ide

3.比較特殊的如上面的效果,擴散並非View本身被擴散。工具

因此在作動效的時候,應該從一個魔術師的角度去考慮,而不能從用戶的角度來考慮,作到思惟的發散。這裏能夠去看看一些魔術揭祕教程~作到看起來很炫酷,原理很簡單,基本上動效的思路就有啦。post

WowSplash實現思路

咱們先把特效分爲兩段,一段爲描邊動畫。另外一段爲雲霧擴散動畫。首先來研究第一段。動畫

第一階段

第一段其實很簡單,大部分小夥伴一眼就能夠看出來,這就是SVG結合Path實現的動畫。恩,對~你說的沒錯,網上有不少關於這種動畫的實現,這裏直接把須要的東西給到你們~

首先,你須要一張SVG圖片,怎麼得到呢,美工會配合我嗎? 想多了,徹底不須要美工大大幫忙~咱們能夠本身動手來。

首先須要用到一個神器: Vector Magic 他能夠幫咱們把普通圖片轉換爲SVG圖片。這裏我就找來了一張鐵塔的簡筆畫~ 轉換以後,就能夠獲得SVG文件了~

其次,須要用到一個工具類,用於把SVG轉換成Path.這裏我直接拿了GAStudio哥的一個工具類:SvgPathParser 接下來,咱們把拿到的SVG保存在String.xml文件中待用~

接下來使用PathMeasure 來進行SVG轉換後Path的繪製,具體的細節,請看源碼~這裏不過多闡述。

float stop = mLength * mAnimatorValue;
 mTowerPathMeasure.getSegment(0, stop, mTowerDst, true);
 canvas.drawPath(mTowerDst, mPaint);

鐵塔完畢後,有點單調~ 咱們來給他繪製一些雲彩~ 每一個雲彩都是一個Path,因此畫雲彩只是繪製一些Path.

private void drawCould(Canvas canvas) {
    for (int i = 0; i < mCouldPaths.length; i++) {
      setupCouldPath(mCouldPaths[i], i);
      canvas.drawPath(mCouldPaths[i], mPaint);
    }
  }

最後,加上動畫~ 讓他不生硬。最後暴漏一個方法,在進入Activity的時候執行,第一個階段就完成啦~

public void startAnimate() {

    restore();
    //start tower animate
    getTowerValueAnimator().start();

    //start could animate
    for (int i = 0; i < mCouldPaths.length; i++) {
      final ValueAnimator couldAnimator = getCouldValueAnimator(i);
      postDelayed(new Runnable() {
        @Override public void run() {
          couldAnimator.start();
        }
      }, mDuration / 2);
    }

    getTitleAnimate().start();
  }

第二階段

第二階段看起來比較炫,其實也是比較簡單的,擴散很差搞,能夠換一個思路嘛。因此這裏我就想到使用Xfermode,沒錯,你看到發散的雲,其實又是另外一張圖片:

哈哈哈哈,這張圖片一貼出來,你是否是想笑。原來看起來很炫的效果,真實這麼搞笑。

好的,有了思路就很好繼續了。我只須要讓兩個圖片使用Xfermode搞基一番,而且在過程當中讓這個View逐漸透明,遮罩圖片逐漸放大便可。

固然,有了思路變成很簡單,其實仍是有些坑的,說說遇到的坑。

關於Xfermode小夥伴們用到過的可能瞭解,他有坑,很是大的坑。。常常發現與Demo圖出不來同樣的效果。因此我專門總結了一篇博客以下:PorterDuffXferMode不正確的真正緣由,感興趣的能夠看下。這裏再來重複下Xfermode坑如何避免。

最終大總結,若是想讓PorterDuffXferMode按照預期Demo(或者效果圖)的效果圖像實現,必須知足如下條件:

一、關閉硬件加速。(實際爲開啓硬離屏緩存)

二、兩個bitmap大小盡可能同樣。

三、背景色爲透明色。

四、若是兩個bitmap位置不徹底同樣,可能也是預期效果,只不過你看到的效果和你本身腦補的預期效果不一致。

因此,爲了不這些坑,我把View分爲了兩個,第一階段是一個View,第二階段是一個View。當第一段View執行完以後,把該View截屏,轉換爲bitmap交給第二個View。同時第一個View設置gone來避免過分繪製,第二個View繪製的其實是兩個bitmap,而且開啓硬離屏緩存來實現Xfermode的正確效果。

//解決硬件加速的bug
setLayerType(View.LAYER_TYPE_HARDWARE, null);
//將第一個View的bitmap交給第二個View
mWowView.startAnimate(wowSplashView.getDrawingCache());

最後,在使用動畫讓第二個View從0擴大到數倍,同時改變透明度就達到咱們想要的效果了。

好啦,本期《交互炸了》到此就結束了,最後附上項目地址,若是你以爲不錯,歡迎star,關注我能夠得到最新動態哦。

https://github.com/githubwing/WowSplash

相關文章
相關標籤/搜索