




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第Android自定義View繪制貝塞爾曲線實(shí)現(xiàn)流程目錄前言二階貝塞爾曲線三階貝塞爾曲線
前言
對(duì)于Android開(kāi)發(fā),實(shí)現(xiàn)貝塞爾曲線還是比較方便的,有對(duì)應(yīng)的API供你調(diào)用。由于一階貝塞爾曲線就是一條直線,實(shí)際沒(méi)啥多大用處,因此,下面主要講解二階和三階。
二階貝塞爾曲線
在Android中,使用quadTo來(lái)實(shí)現(xiàn)二階貝塞爾
path.reset()
path.moveTo(startX,startY)
path.quadTo(currentX,currentY,endX,endY)
canvas.drawPath(path,curvePaint)
startX和startY,endX和endY為兩個(gè)固定點(diǎn),currentX和currentY就是控制點(diǎn),通過(guò)改變控制點(diǎn)的位置來(lái)改變二階貝塞爾曲線的形狀。
a點(diǎn)和b點(diǎn)就是固定點(diǎn),c點(diǎn)是控制點(diǎn),我們可以改變c點(diǎn)的位置來(lái)改變曲線的形狀。
overridefunonTouchEvent(event:MotionEvent):Boolean{
when(event.action){
MotionEvent.ACTION_DOWN,MotionEvent.ACTION_MOVE-{
currentX=event.x
currentY=event.y
postInvalidate()
returntrue
}
三階貝塞爾曲線
在Android中,使用cubicTo來(lái)實(shí)現(xiàn)三階貝塞爾
overridefunonDraw(canvas:Canvas){
super.onDraw(canvas)
path.reset()
path.moveTo(startX,startY)
path.cubicTo(fixedX1,fixedY1,fixedX2,fixedY2,endX,endY)
canvas.drawPath(path,curvePaint)
//繪制輔助線
drawHelpLine(canvas)
overridefunonTouchEvent(event:MotionEvent):Boolean{
when(event.action){
MotionEvent.ACTION_DOWN,MotionEvent.ACTION_MOVE-{
//divideLine區(qū)分觸摸點(diǎn)是左邊還是右邊
if(event.xdivideLine){
fixedX1=event.x
fixedY1=event.y
}else{
fixedX2=event.x
fixedY2=event.y
postInvalidate()
returntrue
}
其中,startX和startY,endX和endY為兩個(gè)固定點(diǎn),fixedX1和fixedY1,fixedX2和fixedY2分別為兩個(gè)控制點(diǎn),通過(guò)改變控制點(diǎn)的位置來(lái)改變?nèi)A貝塞爾曲線的形狀。
a點(diǎn)和b點(diǎn)就是固定點(diǎn),c點(diǎn)和d點(diǎn)是控制點(diǎn),我們可以改變c點(diǎn)或d點(diǎn)的位置來(lái)改變曲線的形狀。
OK,貝塞爾曲線的基礎(chǔ)到此就講完了,下面來(lái)個(gè)實(shí)戰(zhàn),體驗(yàn)一下貝塞爾曲線的絲滑吧!
關(guān)于貝塞爾曲線,最典型的應(yīng)用就是波浪球了,那咱們也來(lái)整一個(gè),先上圖
首先裁剪一下畫布,變?yōu)閳A形
valcirclePath=Path()
circlePath.addCircle(width/2f,height/2f,width/2f,Path.Direction.CW)
canvas.clipPath(circlePath)
Path.Direction.CW:沿順時(shí)針?lè)较蚶L制,Path.Direction.CCW:沿逆時(shí)針?lè)较蚶L制
以View為中心,畫圓
canvas.drawCircle(width/2f,height/2f,width/2f,circularPaint)
利用二階貝塞爾,繪制波浪,起點(diǎn)為屏幕外,circleLen為曲線1/4周期長(zhǎng)度
privatevalstartPoint=Point(-4*circleLen,0)
根據(jù)進(jìn)度改變起點(diǎn)坐標(biāo)的y值,控制點(diǎn)為曲線的頂部和底部,循環(huán)繪制,然后構(gòu)建曲線之下的封閉區(qū)域,填充
//根據(jù)進(jìn)度改變起點(diǎn)坐標(biāo)的y值
startPoint.y=((1-(progress/100.0))*height).toInt()
//移動(dòng)到起點(diǎn)
wavePath.moveTo(startPoint.x.toFloat(),startPoint.y.toFloat())
varj=1
//循環(huán)繪制曲線
for(iin1..8){
valcontrolX=(startPoint.x+circleLen*j).toFloat()
//波頂和波底
valcontrolY=
if(i%2==0)(startPoint.y+waveHeight).toFloat()else(startPoint.y-waveHeight).toFloat()
//二階貝塞爾
wavePath.quadTo(
controlX,
controlY,
(startPoint.x+circleLen*2*i).toFloat(),
startPoint.y.toFloat()
j+=2
//繪制封閉的區(qū)域
wavePath.lineTo(width.toFloat(),height.toFloat())
wavePath.lineTo(startPoint.x.toFloat(),height.toFloat())
wavePath.lineTo(startPoint.x.toFloat(),startPoint.y.toFloat())
wavePath.close()
canvas.drawPath(wavePath,wavePaint)
wavePath.reset()
//走完一周回到原點(diǎn)
startPoint.x=
if(startPoint.x+translateX=0)-circleLen*4elsestartPoint.x+translateX
這里是設(shè)置每隔100ms,進(jìn)度加一
progress=if(progress=100)0elseprogress+1
postInvalidateDelayed(100)
全部代碼如下
classProgressBallView:View{
//曲線1/4周期的長(zhǎng)度
privatevalcircleLen=DensityUtils.dp2px(context,53)
//曲線高度
privatevalwaveHeight=DensityUtils.dp2px(context,27)
//默認(rèn)的長(zhǎng)寬值
privatevaldefaultSize=DensityUtils.dp2px(context,300)
//進(jìn)度
privatevarprogress=0
//平移的長(zhǎng)度
privatevaltranslateX=circleLen/4
//圓形Paint
privatevalcircularPaint=Paint()
//波浪Paint
privatevalwavePaint=Paint()
//波浪的路徑
privatevalwavePath=Path()
//曲線的起始坐標(biāo)
privatevalstartPoint=Point(-4*circleLen,0)
constructor(context:Context):super(context)
constructor(context:Context,attributeSet:AttributeSet):super(context,attributeSet){
initPaint()
privatefuninitPaint(){
with(circularPaint){
isAntiAlias=true
color=Color.GRAY
with(wavePaint){
isAntiAlias=true
color=Color.RED
overridefunonMeasure(widthMeasureSpec:Int,heightMeasureSpec:Int){
super.onMeasure(widthMeasureSpec,heightMeasureSpec)
varviewWidth=measureView(widthMeasureSpec)
varviewHeight=measureView(heightMeasureSpec)
//取最小的,作為長(zhǎng)寬
viewWidth=min(viewWidth,viewHeight)
viewHeight=viewWidth
setMeasuredDimension(viewWidth,viewHeight)
privatefunmeasureView(measureSpec:Int):Int{
valmode=MeasureSpec.getMode(measureSpec)
returnif(mode==MeasureSpec.AT_MOST||mode==MeasureSpec.EXACTLY){
MeasureSpec.getSize(measureSpec)
}else{
defaultSize
overridefunonDraw(canvas:Canvas){
super.onDraw(canvas)
//裁剪畫布為圓形
cutCanvas(canvas)
//繪制圓形
drawRound(canvas)
//繪制波浪
drawWave(canvas)
//自動(dòng)增長(zhǎng)進(jìn)度
autoGrow()
//進(jìn)度從0-100,自動(dòng)增長(zhǎng)
privatefunautoGrow(){
progress=if(progress=100)0elseprogress+1
postInvalidateDelayed(100)
//裁剪畫布為圓形
privatefuncutCanvas(canvas:Canvas){
valcirclePath=Path()
circlePath.addCircle(width/2f,height/2f,width/2f,Path.Direction.CW)
canvas.clipPath(circlePath)
//繪制圓形
privatefundrawRound(canvas:Canvas){
canvas.drawCircle(width/2f,height/2f,width/2f,circularPaint)
//繪制波浪
privatefundrawWave(canvas:Canvas){
//根據(jù)進(jìn)度改變起點(diǎn)坐標(biāo)的y值
startPoint.y=((1-(progress/100.0))*height).toInt()
//移動(dòng)到起點(diǎn)
wavePath.moveTo(startPoint.x.toFloat(),startPoint.y.toFloat())
varj=1
//循環(huán)繪制曲線
for(iin1..8){
valcontrolX=(startPoint.x+circleLen*j).toFloat()
//波頂和波底
valcontrolY=
if(i%2==0)(start
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 藥品銷售員銷售崗位培訓(xùn)試題(附答案)
- 2025年四川雅安經(jīng)開(kāi)區(qū)招聘區(qū)屬國(guó)有企業(yè)管理人員考試筆試試題1(含答案)
- 老狐貍消防課件
- 肝病的早期診斷和治療方法課件
- 老年護(hù)理教學(xué)課件
- 老年便秘的護(hù)理課件
- 老師面部肌肉管理課件
- 2025年安全生產(chǎn)自查報(bào)告模版(三)
- 插班生安全教育與事故處理協(xié)議
- 钚鉑化物合同
- PE管道安裝單元工程質(zhì)量評(píng)定表 2
- 臨近建構(gòu)筑物的低凈空硬法咬合樁施工工法
- 老年人消防安全知識(shí)普及
- 國(guó)開(kāi)《工程經(jīng)濟(jì)與管理》形考任務(wù)1-12試題及答案
- 幼兒園玩教具明細(xì)表
- 旅游接待業(yè) 習(xí)題及答案匯總 重大 第1-10章 題庫(kù)
- 隋唐人的日常生活
- 2022年江蘇省公安廳招聘警務(wù)輔助人員和雇員筆試試題及答案
- 畢業(yè)50周年同學(xué)聚會(huì)邀請(qǐng)函匯編4篇
- 寧夏西吉縣公開(kāi)招考10名城市社區(qū)工作者高頻考點(diǎn)題庫(kù)模擬預(yù)測(cè)試卷(共1000練習(xí)題含答案解析)
- 亞科科技(安慶)有限公司高端生物緩沖劑及配套項(xiàng)目(一期)環(huán)境影響報(bào)告書(shū)
評(píng)論
0/150
提交評(píng)論