1. 創建Vector Drawable
專注于為中小企業提供成都做網站、成都網站建設服務,電腦端+手機端+微信端的三站合一,更高效的管理,為中小企業巴東免費做網站提供優質的服務。我們立足成都,凝聚了一批互聯網行業人才,有力地推動了超過千家企業的穩健成長,幫助中小企業通過網站建設實現規模擴充和轉變。
從相似角度來看,VectorDrawable與標準SVG圖形都是利用path值繪制完成的。不過如何利用SVG path繪制圖形并不在本篇文章的探討范圍之內,大家可以點擊此處從W3C網站處獲取必要的說明資料。在本文當中,我們只需要了解到path標簽的作用是進行圖形繪制即可。讓我們首先從SVG文件入手,看看以下圖形是如何被繪制出來的:
這一圖形共由五個主要部分所組成:
?一個圓角四邊形作為CPU主體,該四邊形由兩條拱狀弧線構成。
?四組各自包含五根線條的圖形,用于充當CPU的外延線路。
雖然看起來有點繁雜,但大家其實用不著糾結于以上代碼的具體含義,而且這完全不會影響到我們接下來要進行的VectorDrawable繪制工作。不過需要強調的是,我將前面提到的五大圖形組成部分在代碼中作為獨立的區塊來處理,這是為了增強代碼內容的可讀性。
首先,我們需要利用兩條拱形弧線來繪制出圓角四邊形,而在接下來的內容中我們會探討如何分別表現出上、下、左、右四個方位的外延線條。為了將上述SVG代碼轉化為VectorDrawable,大家首先需要在XML當中定義vector對象。以下代碼提取自本篇文章示例代碼當中的vector_drawable_cpu.xml文件。
vector xmlns:android="" android:height="64dp" android:width="64dp" android:viewportHeight="600" android:viewportWidth="600" /vector
在此之后,大家可以向其中添加path數據。下列代碼同樣被拆分成了五個不同的path標簽而非將其作為整體處理,這當然也是為了保證內容的可讀性。
正如大家所見,每個path片段都只需要利用pathData屬性進行繪制。現在我們可以將VectorDrawable XML文件作為一個可繪制對象納入到標準ImageView當中,而且其能夠根據應用程序的實際需要任意進行尺寸縮放——完全不需要再修改任何Java代碼。
2. 為Vector Drawables添加動畫效果
現在我們已經了解了如何以純代碼方式創建圖形,接下來要做的是找點樂子——為其添加動畫效果。在以下動畫中,大家會發現作為延伸線路的各組線條會不斷指向并遠離CPU本體進行移動。
為了達到這一目標,大家需要將包含動畫效果的每個片段包含在一個group標簽當中。
接下來,我們需要為每個動畫類型創建animator文件。在本次示例中,每組線路各使用一個animator,這就意味著共需要四個animator。以下代碼所示為上方線路的動畫效果,大家還需要為下、左、右線路設定類似的效果。每個animator XML文件都被包含在了本項目的示例代碼當中。
如大家所見,propertyName被設定為translateY,這意味著該動畫將沿Y軸方向移動。而valueFrom與valueTo則控制著位移的起點與終點。通過將repeatMode設置為reverse而repeatCount設置為infinite,整個動畫會一直循環下去,其效果則在VectorDrawable處體現出來。該動畫的duration被設定為250,其時長單位為毫秒。
為了將該動畫應用到自己的可繪制文件當中,大家需要創建一個新的animated-vector XML文件,從而將這些animator分配給各VectorDrawable組。以下代碼的作用是創建該animated_cpu.xml文件。
?xml version="1.0" encoding="utf-8"? animated-vector xmlns:android="" android:drawable="@drawable/vector_drawable_cpu" target android:animation="@animator/pulse_top" android:name="top" / target android:animation="@animator/pulse_right" android:name="right" / target android:animation="@animator/pulse_left" android:name="left" / target android:animation="@animator/pulse_bottom" android:name="bottom" / /animated-vector
當所有必要的XML文件都已經準備完成后,大家就可以將animated_cpu.xml加入到ImageView當中進行顯示了。
import?java.awt.Canvas;
import?java.awt.Color;
import?java.awt.Dimension;
import?java.awt.EventQueue;
import?java.awt.Frame;
import?java.awt.Graphics;
import?java.awt.Graphics2D;
import?java.awt.Image;
import?java.awt.RenderingHints;
import?java.awt.event.KeyEvent;
import?java.awt.event.KeyListener;
import?java.awt.event.WindowAdapter;
import?java.awt.event.WindowEvent;
import?java.awt.image.BufferedImage;
import?java.io.File;
import?java.io.IOException;
import?javax.imageio.ImageIO;
public?class?TestImage?extends?Frame
{
private?static?final?long?serialVersionUID?=?1L;
private?static?boolean?PRESSED?=?false;
private?static?int?pointX?=?0;
private?static?int?pointy?=?200;
private?static?int?RIGHT_GO?=?0;
private?static?int?LEFT_GO?=?0;
private?static?int?DIR?=?0;
private?static?int?ANGLE?=?0;
private?static?int?W?=?50;
private?static?int?H?=?60;
private?_Canvas?canvas?=?null;
public?TestImage?()
{
add?(canvas?=?new?_Canvas?());
setIgnoreRepaint?(true);
requestFocus?();
}
public?class?_Canvas?extends?Canvas?implements?Runnable
{
private?static?final?long?serialVersionUID?=?1L;
private?BufferedImage?bi?=?null;
private?Image?bufferedImage?=?null;
private?Thread?thread?=?null;
private?long?sleepTime?=?10;
public?_Canvas?()
{
try
{
bi?=?ImageIO.read?(new?File?("go.png"));
}
catch?(IOException?e)
{}
setBackground?(Color.BLACK);
requestFocus?();
addKeyListener?(new?KeyListener?()
{
@Override
public?void?keyTyped?(?KeyEvent?e?)
{}
@Override
public?void?keyReleased?(?KeyEvent?e?)
{
RIGHT_GO?=?0;
PRESSED?=?false;
}
@Override
public?void?keyPressed?(?KeyEvent?e?)
{
//?38?40?37?39上下左右
DIR?=?e.getKeyCode?();
PRESSED?=?true;
}
});
}
@Override
public?void?paint?(?Graphics?g?)
{
Graphics2D?g2d?=?(Graphics2D)?g;
g2d.setRenderingHint?(RenderingHints.KEY_INTERPOLATION,?RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.drawImage?(rotateImage?(bi.getSubimage?(RIGHT_GO,?LEFT_GO,?W,?H),?ANGLE,?true),?pointX,?pointy,?W,?H,
this);
g2d.dispose?();
}
@Override
public?void?update?(?Graphics?g?)
{
if?(null?==?bufferedImage)
{
bufferedImage?=?createImage?(getWidth?(),?getHeight?());
}
Graphics?bufferedG?=?bufferedImage.getGraphics?();
bufferedG.clearRect?(0,?0,?getWidth?(),?getHeight?());
paint?(bufferedG);
bufferedG.dispose?();
g.drawImage?(bufferedImage,?0,?0,?this);
g.dispose?();
}
public?void?start?()
{
thread?=?new?Thread?(this);
thread.setName?("TestImage");
thread.setPriority?(Thread.MIN_PRIORITY);
thread.start?();
}
public?synchronized?void?stop?()
{
thread?=?null;
notify?();
}
@Override
public?void?run?()
{
Thread?me?=?Thread.currentThread?();
while?(thread?==?me??!isShowing?()?||?getSize?().width?==?0)
{
try
{
Thread.sleep?(555);
}
catch?(InterruptedException?e)
{
return;
}
}
while?(thread?==?me??isShowing?())
{
if?(PRESSED)
{
try
{
if?(DIR?==?39)
{
RIGHT_GO?=?RIGHT_GO?+?50;
LEFT_GO?=?0;
pointX?=?pointX?+?1;
if?(pointX??420)
{
ANGLE?=?90;
pointX--;
pointy--;
W?=?60;
H?=?50;
}
if?(RIGHT_GO??50)
{
RIGHT_GO?=?0;
}
}
else?if?(DIR?==?37)
{
pointX?=?pointX?-?1;
RIGHT_GO?=?RIGHT_GO?+?50;
LEFT_GO?=?60;
if?(pointX??0)
{
ANGLE?=?-90;
pointX++;
pointy--;
W?=?60;
H?=?50;
}
if?(RIGHT_GO??50)
{
RIGHT_GO?=?0;
}
}
else?if?(DIR?==?38)
{
W?=?50;
H?=?60;
pointy?=?150;
ANGLE?=?0;
RIGHT_GO?=?100;
}
else?if?(DIR?==?40)
{
W?=?50;
H?=?60;
ANGLE?=?0;
pointy?=?200;
RIGHT_GO?=?0;
}
Thread.sleep?(sleepTime);
repaint?();
}
catch?(InterruptedException?e)
{
break;
}
}
else
{
RIGHT_GO?=?RIGHT_GO?+?50;
LEFT_GO?=?0;
pointX?=?pointX?+?1;
if?(RIGHT_GO??50)
{
RIGHT_GO?=?0;
}
if?(pointX??500)
{
pointX?=?0;
}
try
{
Thread.sleep?(sleepTime);
repaint?();
}
catch?(InterruptedException?e)
{
break;
}
}
}
thread?=?null;
}
}
/**
?*?旋轉圖像為指定角度
?*?
?*?@param?degree
?*?@return
?*/
public?static?BufferedImage?rotateImage?(?final?BufferedImage?image,?final?int?angdeg,?final?boolean?d?)
{
int?w?=?image.getWidth?();
int?h?=?image.getHeight?();
int?type?=?image.getColorModel?().getTransparency?();
BufferedImage?img;
Graphics2D?graphics2d;
(?graphics2d?=?(?img?=?new?BufferedImage?(w,?h,?type)?).createGraphics?()?).setRenderingHint?(
RenderingHints.KEY_INTERPOLATION,?RenderingHints.VALUE_INTERPOLATION_BILINEAR);
graphics2d.rotate?(d???-Math.toRadians?(angdeg)?:?Math.toRadians?(angdeg),?w?/?2,?h?/?2);
graphics2d.drawImage?(image,?0,?0,?null);
graphics2d.dispose?();
return?img;
}
public?static?void?main?(?String[]?args?)
{
EventQueue.invokeLater?(new?Runnable?()
{
@Override
public?void?run?()
{
final?TestImage?ti?=?new?TestImage?();
ti.setSize?(new?Dimension?(500,?300));
ti.setLocationRelativeTo?(null);
ti.addWindowListener?(new?WindowAdapter?()
{
@Override
public?void?windowClosing?(?WindowEvent?e?)
{
System.exit?(0);
}
@Override
public?void?windowDeiconified?(?WindowEvent?e?)
{
ti.canvas.start?();
}
@Override
public?void?windowIconified?(?WindowEvent?e?)
{
ti.canvas.stop?();
}
});
ti.setResizable?(false);
ti.canvas.start?();
ti.setVisible?(true);
}
});
}
}
效果圖
參考代碼
import?java.awt.*;
import?java.awt.event.*;
import?javax.swing.*;
public?class?MoveTextFrame?extends?JFrame?{
JLabel?jl;//文字標簽
int?speed=2;//移動速度
public?MoveTextFrame()?{
jl?=?new?JLabel("文字動畫");
jl.setForeground(Color.RED);
add(jl);
setSize(380,?100);//窗口大小
setLocationRelativeTo(null);//窗口居中
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
//設置定時器,?每隔25毫秒,改變一次文字標簽的位置
Timer?t?=?new?Timer(25,?new?ActionListener()?{
public?void?actionPerformed(ActionEvent?e)?{
int?x?=?jl.getX()+speed;//計算移動后的位置
if(x=390){//如果超過就指定像素,就重新從左邊開水移動
x=-30;
}
jl.setLocation(x,?jl.getY());//更新位置
//repaint();
}
});
t.start();
}
public?static?void?main(String[]?args)?{
new?MoveTextFrame();
}
}
我記得雙緩存,就是畫的時候在一張全新的Graphics上畫,畫好后直接覆蓋就可以了。好多年前的事情了,記不起來了。
一: 用多線程播放一組圖片, 實現動畫片的效果; 類似于逐幀動畫,每個圖片是動畫的一幀
二: 在awt/swing界面里, 可以使用paint方法,去繪制圖形,然后用swing提供的Timer或者多線程技術,去刷新繪制的圖形
三:在JavaFX里, 本身就支持動畫,并且封裝了很多動畫效果可以直接使用,比如逐幀動畫.縮放動畫,漸變動畫,旋轉動畫,位置動畫等.
強烈推薦使用javaFX來實現動畫, 因為javaFX是現代化的圖形界面工具,具有簡單,強大,組件豐富,跨平臺,支持Html5, 支持表格, 支持動畫等多種優勢?
下面是一個javaFX繪制的動態表格
javaFX動態表格
本文標題:java實現幀動畫的代碼 創建幀動畫
當前地址:http://vcdvsql.cn/article40/doodeho.html
成都網站建設公司_創新互聯,為您提供電子商務、域名注冊、網站設計公司、移動網站建設、品牌網站建設、商城網站
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯