1. 程式人生 > >在Canvas上顯示動畫

在Canvas上顯示動畫

如果想為自定義的UI控制元件新增動畫效果,會發現動畫相關的API是很有限的。那麼有沒有API可以直接向螢幕繪圖呢?答案是肯定的。Android提供了Canvas滿足這一要求。

在這個例子中,我們將以方塊在螢幕上彈跳為例分析如何使用Canvas類在螢幕上繪製圖形,併為其新增動畫效果。應用程式最終效果如下:

這裡寫圖片描述

我們先需要了解Canvas類的基本概念:“我們可以把Canvas視為Surface的替身或者介面,圖形便是繪製在Surface上的。Canvas封裝了所有繪圖呼叫。通過Canvas,繪製到Surface上的內容首先儲存到與之關聯的Bitmap中,該Bitmap最終會呈現到視窗上。”

Activity程式碼如下:

package com.example.huangfei.hack;

import android.app.Activity;
import android.os.Bundle;
import android.view.Display;

public class MainActivity extends Activity {
    private DrawView mDrawView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //獲取螢幕的寬和高
Display display = getWindowManager().getDefaultDisplay(); mDrawView = new DrawView(this); mDrawView.width = display.getWidth(); mDrawView.height = display.getHeight(); //以DrawView作為Activity的內容檢視,DrawView佔據所有可用空間 setContentView(mDrawView); } }

DrawView類程式碼如下:

package com.example.huangfei.hack;

import android.content.Context;
import android.graphics.Canvas;
import android.view.View;

/**
 * 該類負責在螢幕上繪製一個方塊,並不斷更新方塊的位置
 */
public class DrawView extends View {
    private Rectangle mRectangle;
    public int width;
    public int height;

    public DrawView(Context context) {
        super(context);

        /**
         * 建立方塊物件。Rectangle類內部實現了將自身繪製到Canvas上的邏輯,並且已經包含了正確變換其位置
         * 的程式碼邏輯。
         */
        mRectangle = new Rectangle(context, this);
        mRectangle.setARGB(255, 255, 0, 0);
        mRectangle.setSpeedX(3);
        mRectangle.setSpeedY(3);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        mRectangle.move();//變換方塊位置
        mRectangle.onDraw(canvas);//將方塊繪製到Canvas上

        /**
         *invalidate()方法強制重繪檢視。把該方法放在onDraw()的目的是為了在View繪製完自身後,可以立即重新
         * 呼叫onDraw()。換句話說,通過迴圈呼叫Rectangle的move()和onDraw()方法實現了一個動畫效果。
         */
        invalidate();
    }
}

Rectangle類程式碼如下:

package com.example.huangfei.hack;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.view.View;

/**
 * 建立一個方塊
 */
public class Rectangle extends View {
    private static final int MAX_SIZE = 40;//方塊距右端或底部的距離,一般為方塊的大小mRealSize
    private static final int ALPHA = 255;//畫筆的透明度

    private DrawView mDrawView;
    private Paint mInnerPaint;//畫筆
    private RectF mDrawFect;//矩形座標

    private float mCoordX;//方塊當前x軸位置
    private float mCoordY;//方塊當前Y軸位置
    private int mRealSize = 40;//方塊的大小
    private int mSpeedX = 3;//方塊x軸每次移動的距離
    private int mSpeedY = 3;//方塊軸每次移動的距離

    private boolean goRight = true;//是否向右移動
    private boolean goDown = true;//是否向下移動

    public Rectangle(Context context, DrawView drawView) {
        super(context);

        mDrawView = drawView;
        mInnerPaint = new Paint();
        mDrawFect = new RectF();

        //設定畫筆的預設顏色為紅色
        mInnerPaint.setARGB(ALPHA, 255, 0, 0);
        //處理畫筆的鋸齒
        mInnerPaint.setAntiAlias(true);
    }

    public void setARGB(int a, int r, int g, int b) {
        mInnerPaint.setARGB(a, r, g, b);
    }

    @Override
    public float getX() {
        return mCoordX;
    }

    @Override
    public void setX(float x) {
        mCoordX = x;
    }

    @Override
    public float getY() {
        return mCoordY;
    }

    @Override
    public void setY(float y) {
        mCoordY = y;
    }

    public int getSize() {
        return mRealSize;
    }

    public void setSize(int realSize) {
        mRealSize = realSize;
    }

    public int getSpeedX() {
        return mSpeedX;
    }

    public void setSpeedX(int speedX) {
        mSpeedX = speedX;
    }

    public int getSpeedY() {
        return mSpeedY;
    }

    public void setSpeedY(int speedY) {
        mSpeedY = speedY;
    }

    public void move() {
        moveTo(mSpeedX, mSpeedY);
    }

    private void moveTo(int goX, int goY){
        //判斷X軸方向的邊界
        if(mCoordX > mDrawView.width - MAX_SIZE){
            goRight = false;
        }
        if(mCoordX < 0){
            goRight = true;
        }

        //判斷Y軸方向的邊界
        if(mCoordY > mDrawView.height - MAX_SIZE){
            goDown = false;
        }
        if(mCoordY < 0){
            goDown = true;
        }

        //移動方塊
        if(goRight){
            mCoordX += goX;
        }else{
            mCoordX -= goX;
        }
        if(goDown){
            mCoordY += goY;
        }else{
            mCoordY -= goY;
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        mDrawFect.set(mCoordX, mCoordY, mCoordX + mRealSize, mCoordY + mRealSize);
        canvas.drawRoundRect(mDrawFect, 0, 0, mInnerPaint);
    }
}

在onDraw()方法中通過呼叫invalidate()方法變換檢視的位置是實現自定義動畫的簡單方法。如果你想開發一款小遊戲,使用這個小技巧處理遊戲的主迴圈是一個簡單的方法。

程式碼地址

相關推薦

【移動開發】在Canvas顯示動畫

本文翻譯自《50 android hacks》當自定義View的時候,可以利用Canvas給View新增一些動畫效果。下面的例子,是在螢幕上繪製一個紅色的小方塊,這個小方塊會在螢幕上面“亂跳”。知識點使用到的知識點:(1) 在View的子類的draw()中呼叫invalida

Canvas顯示動畫

如果想為自定義的UI控制元件新增動畫效果,會發現動畫相關的API是很有限的。那麼有沒有API可以直接向螢幕繪圖呢?答案是肯定的。Android提供了Canvas滿足這一要求。 在這個例子中,我們將以方塊在螢幕上彈跳為例分析如何使用Canvas類在螢幕上繪製圖形

Jscript動畫系列(1)-----用JS在Canvas畫一個小球

最近在學習JS動畫,有一些心的同大家分享!由於前期內容比較少,樣式什麼的就寫在Html檔案裡了! 首先(Index.html) <!doctype html> <html>

Html+JavaScript 在canvas繪製帶日期顯示的時鐘 (自己繪製刻度)

       此為博主在研究參考多個時鐘程式碼後,自己總結創新編寫的一個簡潔齊全又美觀的時鐘,本著自己獲益也回饋大眾地分享出來,如有問題或更好的建議歡迎與我交流。       首先建立一個canvas來裝整個時鐘介面: <canvas id="MyClock" wi

placeholder怎樣用IE和谷歌顯示統一內容

blog 按鈕 xpl font 自定義工具欄 用戶 logs div 啟動 placeholder怎樣用IE和谷歌上顯示統一內容 擊“開始”菜單中的“運行”命令,並在其對話框中輸入“gpedit.msc”命令,進入“組策略”操作窗口。    在“組策略”左操作窗口中依次

css3 實現鼠標放到一個div顯示出另一個隱藏的div

webkit body charset font ans round size posit test <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="u

(轉)第03節:在Canvas插入圖片並設置旋轉屬性

doctype script border wid bsp viewport 設置 css樣式 png 我們已經學會了在Canvas上畫簡單的圖形,這節我們就在Canvas上加一張圖片。用到fabric.Image對象把圖片添加到Canvas上。 HTML文件:為了效果更好

始終難以追外來動畫,國產動畫還有春天嗎?

加速 變革 藝術 杭州 福音 保持 lib img pla 《刀劍神域序列之爭》已經確定要在中國上映!新海誠又有作品要出了?近幾年來,以動畫產業大國日本和美國為代表的外來動畫已滲入中國動畫市場,國產動畫遭到差別對待,最直接的表現就是人們討論的幾乎都是外來動畫,對宮崎駿和新

傳圖片在頁面顯示

doc this o-c post ring asc sof ros 顯示 看了別人寫的 自己照著寫了一下 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%

jupyter notebook在網頁顯示作圖

jupyter notebook matplotlib 今天嘗試使用jupyter notebook作圖像展示工具時,發現用matplotlib所作的圖像會自動啟動一個圖像展示窗口,無法顯示在網頁上,而我的初衷是使用jupyter notebook做圖像即時呈現及存儲(有點類似PPT作圖)

Excel中的的經緯度坐標在地圖顯示

excelExcel中有這樣關於經緯度的數據:22.56614225113.980836822.68620526113.940525222.57651183113.95719822.56484081114.244571122.55888775113.950722722.55899906114.24131742

canvas 之星空動畫

每次 context i++ math.sqrt 通過 改變 size count 坐標 最近看到位博主的博客背景圖很是炫酷,查找下資料了解是canvas實現效果,今天就來看看詳細解剖下吧。 實現思路 首先了解下canvas中的動畫原理?canvas中的動畫其實是通過不斷的

在瀏覽器顯示helloworld

name itl bsp pat tran head control scheme shee <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%String path

動畫組(顯示動畫)

cab rec red mage point creat __bridge pat 關鍵幀動畫 動畫組 CABasicAnimation和CAKeyframeAnimation僅僅作用於單獨的屬性,而CAAnimationGroup可以把這些動畫組合在一起。CAAnimat

canvas遊戲和動畫中的碰撞檢測

底部 bsp rect circle 進行 eight nbsp odi word 碰撞檢測關鍵步驟 碰撞檢測需要處理經歷下面兩個關鍵的步驟: 計算判斷兩個物體是否發生碰撞 發生碰撞後,兩個物體的狀態和動畫效果的處理 計算碰撞 只要兩個物體相互接觸,它們就會發生碰撞

animate.css+wow.js頁面滾動即時顯示動畫

wow github gpo () ati sheet span div mobile 1、地址引入 <link href="css/animate.min.css" rel="stylesheet" type="text/css"> <script

在狀態欄顯示時間

bsp ctime todo login gettext 程序代碼 cstring comm stat // TODO: 在此添加消息處理程序代碼和/或調用默認值 //獲得當前的系統時間 CTime t=CTime::GetCurrentTime();

HTML5 Canvas水波紋動畫特效

實用 containe tex settings dex apple IV vertical 動畫 HTML5的Canvas特性非常實用,我們不僅可以在Canvas畫布上繪制各種圖形,也可以制作絢麗的動畫,比如這次介紹的水波紋動畫特效。以前我們也分享過一款基於HTML5 W

使用Ajax+jQuery來實現前端收到的數據在console顯示+簡單的主頁設計與bootstrap插件實現圖片輪播

value size 靠譜 實現圖 active length oot function 想要 1.實現前端輸入的數據在console上顯示 上一篇是解決了在前端的輸入信息在cygwin上顯示,這次要給前臺們能看見的數據,因為數據庫裏插入的數據少,所以寫的語句翻來覆去就那幾

改變Tomcat在地址欄顯示的小貓圖標

tomcat-8 pan 一個 推薦一個 eba con oot 替換 如何 部署在Tomcat上的項目通常在地址欄會顯示一個小貓的圖標,那麽如何改變這個圖標呢? 第一步、制作自己顯示的圖標 這裏使用的是在線制作的方式,推薦一個在線制作的網站---比特蟲:ht