Android 立方體翻轉效果
今天我們來看看如何實現一個立方體翻轉的效果,如圖
看上去很麻煩,實際上實現起來還是蠻輕鬆的。
這裡我們使用到的有兩個類。
-
android.graphic.Camera
這是在影象學概念裡的攝像機,這是一個透視攝像機
。 -
android.graphic.Matrix
矩陣,用來表示影象的變化。
頭疼的鑽研路開始
我們先從攝像頭上的角度分析:
正常情況下,我們是這麼看畫面的(那個電池一樣的東西就當是攝像頭吧)
我們要產生立方體的效果,那邏輯上應該是這麼看:
Camera提供了幾個介面,我們這使用到的介面有兩個:
-
Rotate 旋轉
-
Translate 平移
這兩個函式的操作都對畫布
這裡我們首先要有2個View。xml結構入下:
<cn.geminiwen.canvassupport.view.SplashLayout
android:text="@string/hello_world"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000" >
<RelativeLayout
android:layout_width ="match_parent"
android:layout_height="match_parent"
android:background="#f00">
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0f0">
</RelativeLayout >
</cn.geminiwen.canvassupport.view.SplashLayout>
SplashLayout就是我的自定義佈局,用來繪製立方體效果的佈局。
我們把第一個view作為backgroundView
,第二個View作為foregroundView
,使得效果是從backgroundView
翻轉到foregroundView
。
具體程式碼入下:
private void cube(Canvas canvas, double interpolation) {
View foregroundView = getChildAt(0);
View backgroundView = getChildAt(1);
int width = getWidth();
int height = getHeight();
long drawingTime = getDrawingTime();
float rotate;
//begin drawForeground
rotate = (float)(- sFinalDegree * interpolation);
mCamera.save();
mCamera.translate((float)(width - interpolation * width), 0, 0);
mCamera.rotateY(rotate);
mCamera.getMatrix(mMatrix);
mCamera.restore();
mMatrix.postTranslate(0, height / 2);
mMatrix.preTranslate(-width, -height / 2);
canvas.save();
canvas.concat(mMatrix);
drawChild(canvas, foregroundView, drawingTime);
canvas.restore();
//end drawForeground
//draw Background
rotate = (float)(sFinalDegree - sFinalDegree * interpolation);
mCamera.save();
mCamera.translate((float)(-width * interpolation), 0, 0);
mCamera.rotateY(rotate);
mCamera.getMatrix(mMatrix);
mCamera.restore();
mMatrix.postTranslate(width, height / 2);
mMatrix.preTranslate(0, -height / 2);
canvas.save();
canvas.concat(mMatrix);
drawChild(canvas, backgroundView, drawingTime);
canvas.restore();
//end draw Background
}
這段程式碼放到ViewGroup
的dispatchDraw
方法裡即可,因為ViewGroup
只能在dispatchDraw
方法中繪製子檢視。
其中,canvas
代表畫布,interpolation
代表動畫從0.0
到 1.0 的過程,方便插入器的使用。
這裡來解釋下我們的過程。
View狀態變換
起始狀態background
是這樣的:
-
繞Y軸正方向轉90度
-
畫布x軸移動到width的位置。
可以參照上圖中的畫布2
的狀態。
終點狀態是這樣:
-
繞Y軸正方向0度。
-
畫布x軸移動到0的位置。
可以參考上圖中的畫布的狀態。
旋轉問題
綜上所述,我們設定轉動角度sFinalDegree
為90。interpolation
從0到1的過程,background
的rotate就變成了從90
到0
的過程。
平移問題
這時候我們考慮平移的情況,這個情況會比較複雜,因為我們這裡有兩種平移方式,平移攝像機
或者直接平移畫布
。
這裡我們說下區別,如果移動攝像機,會導致影象的投影發生變化,舉個例子:
比如我們已經在投影上繞Y軸旋轉90度,如果移動X軸的話,看如下圖的區別:
1、未平移攝像機
2、平移攝像機
從圖上我們知道,這個旋轉過的畫布的前端和後端我們都是可以看見的,這當然不符合我們要求,那麼我們直接平移畫布是什麼意思呢?
我們知道對攝像機做了操作之後,應用到畫布上,實際是畫一個畫布的投影,直接移動畫布的話,就是改變其座標系系統,達到效果,我們可以理解為同時對攝像機和view進行平移,最終達到的效果就是攝像頭相對view的位置和1
一樣,但是我們的畫布卻平移了,這就達到了我們最終的要求。
我們看程式碼雖然我們平移的是畫布,但是我們平移的過程中確是使用移動攝像機的方式來繪製投影,這又是為什麼呢?
我們從三角函式的投影來解釋這個問題。
首先看見我平移攝像頭的方式是線性的,也就是y=kt
這種方式,斜率一定,也就是隨著時間變化,我平移的距離是線性增加的。那麼考慮旋轉的時候的投影情況:
被旋轉的角就是角a
,我們的畫布長為width
,那麼畫布的投影長度為 width * cos(a)
它是一個三角函式。變化趨勢先快後慢,因此我們在旋轉過程中會看見右邊露出背景,造成視覺上的不友好,怎麼解決這個問題呢?
這時候就藉助我們的攝像機平移的投影方式。
這裡綠色的線是我們的投影線,它的投影長度比cos(a) * width
要長很多,因此它就可以讓我們在旋轉過程中不產生黑邊,給人視覺上的飽滿感,會讓我們的視覺效果好很多。
我們的foregroundView
就是一個backgroundView
的逆向過程,因此使用類似的程式碼,然後假設interpolation
是從1-0的過程即可,同時它的座標系整體要往左移動一個螢幕。
總結
做UI的效果,特別需要一些比較好的資料基礎,在影象處理中,搞清楚透視、矩陣的一些計算方式和概念非常重要,今天我們介紹了利用Camera
來進行輔助我們進行矩陣的計算。
原始碼
相關推薦
Android 立方體翻轉效果
今天我們來看看如何實現一個立方體翻轉的效果,如圖 看上去很麻煩,實際上實現起來還是蠻輕鬆的。 這裡我們使用到的有兩個類。 android.graphic.Camera 這是在影象學概念裡的攝像機,這是一個透視攝像機。 android.graphic.Matrix
Android 動畫分析之翻轉效果
大家一定看到過三維的翻轉效果,所以今天在這裡簡單的給大家分析一下,我們怎麼樣才能實現Android中的翻轉動畫效果的實現,首先看一下執行效果如下圖所示。 效果圖: Android中並沒有提供直接做3D翻轉的動畫,所以關於3D翻轉的動畫效果需要我們自己實現,那麼我們首先
HTML5+CSS3立方體3D翻轉效果
1、呼叫CSS樣式: <link rel="stylesheet" type="text/css" href="css/style.css" /> 2、呼叫JS外掛程式碼: <script src="js/prefixfree.min.js"></script> 3、新增
Android頁面翻轉動畫(模仿CSDN賬號登入的翻轉效果)
昨天下載了CSDN的APP,進入多種方式選擇登入的頁面,然後我選擇用CSDN賬號登入,發現有頁面翻轉的效果進入登入頁面。瞬時感覺好炫,自己感覺效果很好。平時別的APP登入的時候,就是直接進入登入頁面,沒有任何效果。這次看到旋轉的效果,頓時眼前一亮,所以我就研究了一下,想做個
android 翻轉效果動畫原始碼
最近專案上要求做一個翻轉的動畫效果,由於動畫還沒有怎麼使用過。然後再網上找到一份很實用的翻轉動畫先用起來,以後再學習下動畫相關的。 原始碼修改後如下: public class Fl
Android Vibrator震動效果
can cnblogs () 否則 指定 pan log 需要 動效 android震動器:Vibrator Android手機中的震動由Vibrator實現。 Vibrator vibrator = (Vibrator) getSystemService(VIBRATO
Android 仿 窗簾效果 和 登錄界面拖動效果 (Scroller類的應用) 附 2個DEMO及源代碼
@override 宋體 off down != 過程 事件 學習 border 在android學習中,動作交互是軟件中重要的一部分。當中的Scroller就是提供了拖動效果的類,在網上。比方說一些Launcher實現滑屏都能夠通過這個類去實現。以下要說的
Qml翻轉效果
vra code pretty class chan examples 狀態改變 gif avr 使用Flipable, 根據狀態改變進行翻轉動畫 Flipable{ id: flip width: 300 heig
android 水波紋效果實現
drawable color utf true odi lec .com enc orm 1.在drawable文件下,新建seletor,作為button的背景,這裏我用的是兩個圓角的shape <?xml version="1.0" encoding="utf-
Android時間軸效果,直接使用在你的項目中
Coding return pro 查詢 gpo ava person turn rst 近期開發app搞到歷史查詢,受騰訊qq的啟示,搞一個具有時間軸效果的ui
圖片點擊翻轉效果
com cli ive frame 註意事項 from UNC orm ase 此處寫法是 css===寫好樣式放在一個新class名 1 @keyframes flipping{ 2 from{transform:rotateY(0);} 3 to{tr
flip 翻轉效果 css3實現
分享圖片 參數 back res absolute font name position serve 1.實現代碼 <!DOCTYPE html> <html lang="zh"> <head> &
Android點陣屏效果的控制元件
最近發現了一個比較好玩的效果,android實現的LED點陣螢幕效果,挺有意思的,於是花了點時間實現了一下,這個用在演唱會上的粉絲當成牌子舉是不是挺好的呢,或者是送給妹子?哈哈~ 實現思路比較簡單,主要是計算漢字對應的點陣矩陣,漢字通過GB2312編碼,每個漢字對用兩個byte來表示,而一個漢字
Android懸浮窗效果的實現
具體懸浮窗效果實現參考大神部落格:http://blog.csdn.net/stevenhu_223/article/details/8504058 至於在拖動懸浮窗時會產生抖動,這是因為OnTouch事件中呼叫錯了函式,在網上查了下,弄明白這兩個函式的區別: event.getX()
Android刮彩票效果
實現分析: 1.底部一張圖片 2.圖片頭部是一個矩形遮擋圖片 3.通過滑動監聽,讓矩形缺失,露出底部圖片 主要程式碼如下: private RectF rectf; private Bitmap bitmap = BitmapFactory.de
Android 水波紋效果
今天翻看部落格,發現了水波紋效果。順便研究了一下 一,Touch Feedback(觸控反饋) 1,原始自帶效果 程式碼: <Button android:layout_width="wrap_content" an
移動開發----Android模仿打字機效果的自定義View實現
前言 在做splash介面的時候,需要做類似於打字機打字的效果,字一個一個地蹦出來,顯示每一個字都帶有打字的聲音。 效果演示 實現原理: 這個其實不難實現,通過一個定時器不斷呼叫TextView的setText就行了,在setTex
Android點贊效果的實現
先看下點讚的效果圖 首先新增依賴 api 'com.sackcentury:shinebutton:0.2.0' xml佈局 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=
Android DrawerLayout抽屜效果和Toolbar標題欄的簡單使用
話不多說先看執行效果: View層 佈局layout: activity_main.xml <?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayou
Css圖片的翻轉效果
效果圖: 程式碼: .turn{ -moz-transform: scaleX(-1); -o-transform: scaleX(-1); -webkit-transform: scaleX(-1); -ms-transform: scale