自定義View(六)Path基礎(chǔ)

Path(路徑)這個知識點GcsSloop大神寫了大概三篇文章進行了詳細的講解,是一個挺重要的知識點。
先解釋一下Path(路徑)這個詞,Path這個詞解釋為路徑,也就是我們畫在屏幕上的圖像,之前我們見到的Canvas中都是畫一些固定的形狀,現(xiàn)在我們能用Path對象進行一些復雜圖形的繪制了,路徑可以隨便畫,不必再被特殊的圖形所限制。

Path封裝了由直線和曲線(二次,三次貝塞爾曲線)構(gòu)成的幾何路徑。你能用Canvas中的drawPath來把這條路徑畫出來(同樣支持Paint的不同繪制模式),也可以用于剪裁畫布和根據(jù)路徑繪制文字。我們有時會用Path來描述一個圖像的輪廓,所以也會稱為輪廓線(輪廓線僅是Path的一種使用方法,兩者并不等價)

Path 常用方法表

作用 相關(guān)方法 備注
移動起點 moveTo 移動下一次操作的起點位置
設(shè)置終點 setLastPoint 重置當前path中最后一個點位置,如果在繪制之前調(diào)用,效果和moveTo相同
連接直線 lineTo 添加上一個點到當前點之間的直線到Path
閉合路徑 close 連接第一個點連接到最后一個點,形成一個閉合區(qū)域
添加內(nèi)容 addRect, addRoundRect, addOval, addCircle, addPath, addArc,arcTo 添加(矩形, 圓角矩形, 橢圓, 圓, 路徑, 圓弧) 到當前Path (注意addArcarcTo的區(qū)別)
是否為空 isEmpty 判斷Path是否為空
是否為矩形 isRect 判斷path是否是一個矩形
替換路徑 set 用新的路徑替換到當前路徑所有內(nèi)容
偏移路徑 offset 對當前路徑之前的操作進行偏移(不會影響之后的操作)
貝塞爾曲線 quadTo, cubicTo 分別為二次和三次貝塞爾曲線的方法
rXxx方法 rMoveTo, rLineTo,rQuadTo, rCubicTo 不帶r的方法是基于原點的坐標系(偏移量), rXxx方法是基于當前點坐標系(偏移量)
填充模式 setFillType, getFillType, isInverseFillType, toggleInverseFillType 設(shè)置,獲取,判斷和切換填充模式
提示方法 incReserve 提示Path還有多少個點等待加入(這個方法貌似會讓Path優(yōu)化存儲結(jié)構(gòu))
布爾操作(API19) op 對兩個Path進行布爾運算(即取交集、并集等操作)
計算邊界 computeBounds 計算Path的邊界
重置路徑 reset,rewind 清除Path中的內(nèi)容 reset不保留內(nèi)部數(shù)據(jù)結(jié)構(gòu),但會保留FillType.rewind會保留內(nèi)部的數(shù)據(jù)結(jié)構(gòu),但不保留FillType
矩陣操作 transform 矩陣變換

Path基礎(chǔ)

moveTosetLastPoint、 lineToclose

path.moveTo(10,10);
path.lineTo(20,20);
moveTo()方法是指定從哪一點開始走路經(jīng),僅僅制定了路徑的起點。既然moveTo()指定了路徑的起點,那么lineTo()這個方法就是指定下一步往哪走。萬一提前沒有moveTo()方法,那么默認的起始點就是坐標系原點。
setLastPoint();方法是改變上一個點的位置:

canvas.translate(mWidth / 2, mHeight / 2);  // 移動坐標系到屏幕中心

Path path = new Path();                     // 創(chuàng)建Path

path.lineTo(200, 200);                      // lineTo

path.setLastPoint(200,100);                 // setLastPoint

path.lineTo(200,0);                         // lineTo

canvas.drawPath(path, mPaint);              // 繪制Path

image.png

這個例子是從默認點出發(fā),走到(200,200),然后調(diào)用setLastPoint(200,100)這個方法將路徑從上一個點改變到這一個點上,然后繼續(xù)走到(200,0)。
如果在linTo()之后調(diào)用moveTo()方法會怎樣呢?

canvas.translate(mWidth / 2, mHeight / 2);  // 移動坐標系到屏幕中心

Path path = new Path();                     // 創(chuàng)建Path

path.lineTo(200, 200);                      // lineTo

path.moveTo(200,100);                       // moveTo

path.lineTo(200,0);                         // lineTo

canvas.drawPath(path, mPaint);              // 繪制Path

image.png

lineTo()方法之后調(diào)用moveTo(),相當于重新開始了一個路徑,重新設(shè)置了新路徑的起點。并不會連接上一個點。
close()方法作用是連接起始點(moveTo()方法指定的點,如果沒有moveTo()方法指定,那就是坐標系原點。)和終點。

        canvas.translate(mWidth/2,mHeight/2);
        Path path = new Path();
        path.lineTo(200,200);
        path.lineTo(300,200);
        path.moveTo(200,100);
        path.lineTo(200,0);
        path.lineTo(300,0);
        path.close();
        canvas.drawPath(path,paint);

close()

上邊我們看到,close()只作用在了moveTo()方法開始的路徑,前邊的路徑?jīng)]有被閉合。說明moveTo()是新開了一條路徑。

addXxx()

第一類添加基本圖形。

這類方法主要是往path中添加圖形。

// 第一類(基本形狀)

// 圓形
public void addCircle (float x, float y, float radius, Path.Direction dir)
// 橢圓
public void addOval (RectF oval, Path.Direction dir)
// 矩形
public void addRect (float left, float top, float right, float bottom, Path.Direction dir)
public void addRect (RectF rect, Path.Direction dir)
// 圓角矩形
public void addRoundRect (RectF rect, float[] radii, Path.Direction dir)
public void addRoundRect (RectF rect, float rx, float ry, Path.Direction dir)

主要是添加矩形,橢圓等圖形,跟前面的操作區(qū)別不大。我們主要注意Path.Direction 這個參數(shù),

類型 解釋 翻譯
CW clockwise 順時針
CCW counter-clockwise 逆時針

這個參數(shù)主要是定義了圖形的閉合路徑,從左上角開始,是順時針閉合還是逆時針閉合。一個正常的矩形,不論順時針還是逆時針都沒什么區(qū)別,但是如果是不規(guī)則多邊形,順時針和逆時針就不同了。

canvas.translate(mWidth / 2, mHeight / 2);  // 移動坐標系到屏幕中心

Path path = new Path();

path.addRect(-200,-200,200,200, Path.Direction.CW);

path.setLastPoint(-300,300);                // <-- 重置最后一個點的位置

canvas.drawPath(path,mPaint);
順時針
canvas.translate(mWidth / 2, mHeight / 2);  // 移動坐標系到屏幕中心

Path path = new Path();

path.addRect(-200,-200,200,200, Path.Direction.CCW);

path.setLastPoint(-300,300);                // <-- 重置最后一個點的位置

canvas.drawPath(path,mPaint);

逆時針

上邊兩個例子是一個相同路徑的順時針和逆時針的兩種表現(xiàn)形式。
Path.Direction不僅影響圖形的形狀,還會影響圖形的填充效果。下邊會講到。

第二類(addPath

// 第二類(Path)
// path
public void addPath (Path src)
public void addPath (Path src, float dx, float dy)
public void addPath (Path src, Matrix matrix)

這個方法其實就是將兩個路徑合并到一塊。
第二個方法后邊兩個參數(shù)作用是將src進行位移之后添加到指定path中。
第三個方法是將src進行matrix變換之后添加到指定的path中。

第三類(addArcarcTo)

// 第三類(addArc與arcTo)

// addArc
public void addArc (RectF oval, float startAngle, float sweepAngle)
// arcTo
public void arcTo (RectF oval, float startAngle, float sweepAngle)
public void arcTo (RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)

這是在當前path添加圓弧的方法。

參數(shù) 摘要
oval 圓弧的外切矩形。
startAngle 開始角度
sweepAngle 掃過角度(-360 <= sweepAngle <360)
forceMoveTo 是否強制使用MoveTo

addArc()方法直接添加一個圓弧到指定path中,而arcTo()是將圓弧添加到path中,根據(jù)forceMoveTo參數(shù)值來判斷,如果forceMoveTotrue,則將圓弧移動,將圓弧的起點和path的終點連接起來,如果forceMoveTofalse,則將圓弧的起點和path的重點連接起來。

第3組:isEmptyisRect、isConvexsetoffset

isEmpty

判斷path中是否有內(nèi)容

isRect(RectF rect)

判斷path是不是一個矩形,如果是矩形,則將矩形信息存儲到rect

set(Path path1)

將新的path復制給老的path

path.set(path1);
//等價于
path=path1;

offset

public void offset (float dx, float dy)
public void offset (float dx, float dy, Path dst)

這個方法就是將path進行位移

dst狀態(tài) 效果
dst不為空 將當前path平移后的狀態(tài)存入dst中,不會影響當前path
dst為空(null) 平移將作用于當前path,相當于第一種方法
canvas.translate(mWidth / 2, mHeight / 2);  // 移動坐標系到屏幕中心
canvas.scale(1,-1);                         // <-- 注意 翻轉(zhuǎn)y坐標軸

Path path = new Path();                     // path中添加一個圓形(圓心在坐標原點)
path.addCircle(0,0,100, Path.Direction.CW);

Path dst = new Path();                      // dst中添加一個矩形
dst.addRect(-200,-200,200,200, Path.Direction.CW);

path.offset(300,0,dst);                     // 平移

canvas.drawPath(path,mPaint);               // 繪制path

mPaint.setColor(Color.BLUE);                // 更改畫筆顏色

canvas.drawPath(dst,mPaint);                // 繪制dst
offset

本來感覺沒多少內(nèi)容的,寫著寫著就變得那么多。。。。
總結(jié):

path就是一條路徑,我們可以調(diào)用CanvasdrawPath()方法將path繪制到屏幕上。path可以自己畫路徑,使用moveTolineTo、setLastPoint、close等方法。也可以addXxx添加矩形,橢圓等圖形到path中,也可以使用addPath添加path到指定path中,當然我們也可以判斷path是否為空,是否是矩形,也可以使用offset方法對path進行平移。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容