摘要:如果不想看步驟的可以直接看最后面有完整的代碼最近在做一個(gè)圓形的進(jìn)度條,在網(wǎng)上看了一些例子有些地方不太理解,后來自己寫了個(gè)一個(gè)分享一下先上一個(gè)最終的效果首先畫一整個(gè)圓定義進(jìn)度為定義總進(jìn)度為定義圓的半徑為至此大圓畫完上面的代碼需要注意的是方法的
如果不想看步驟的可以直接看最后面有完整的代碼
最近在做一個(gè)圓形的進(jìn)度條,在網(wǎng)上看了一些例子有些地方不太理解,后來自己寫了個(gè)一個(gè)分享一下
先上一個(gè)最終的效果
const cvsWitdh = 220 const cvsHeight = 220 const progess = 50 // 定義進(jìn)度為50 const maxPro = 100 // 定義總進(jìn)度為100 const r = 100 // 定義圓的半徑為100 this.cvs.width = cvsWitdh this.cvs.height = cvsHeight const ctx = this.cvs.getContext("2d") ctx.lineWidth = 10 ctx.strokeStyle = "#15496B" ctx.arc(r + 10, r + 10, r, 0, 2 * Math.PI) ctx.stroke() // 至此大圓畫完
上面的代碼需要注意的是 arc 方法的最后一側(cè)參數(shù)是弧度(2π)不是角度,畫圓的起點(diǎn)是表的3點(diǎn)的位置開始畫的不是12點(diǎn)位置然后是畫一個(gè)進(jìn)度的圓弧
畫圓弧度,主要是需要計(jì)算出起點(diǎn)的弧度和終點(diǎn)的弧度
ctx.beginPath() ctx.lineCap = "round" // 下面是漸變的代碼不需要的可以換成純色 let grd = ctx.createLinearGradient(0, 0, 220, 220) grd.addColorStop(0, "red") grd.addColorStop(1, "blue") ctx.strokeStyle = grd const startRadian = progress >= maxPro ? 0 : Math.PI * 1.5 const rate = progress / maxPro const endRadian = progress >= maxPro ? 2 * Math.PI : 2 * Math.PI * rate - Math.PI / 2 ctx.arc(r + 10, r + 10, r, startRadian, endRadian) ctx.stroke()
上面的代碼中 ctx.lineCap = "round" 這個(gè)是設(shè)置最終繪制的線是帶圓角的起點(diǎn)的弧度計(jì)算方式
const startRadian = progess >= maxPro ? 0 : Math.PI * 1.5
我們希望點(diǎn)的起點(diǎn)位置是鐘表12點(diǎn)鐘位置,整個(gè)圓的弧度是 2π==360° 推算得知12點(diǎn)鐘的位置是 1.5π==270°
終點(diǎn)的弧度計(jì)算方式const rate = progress / maxPro const endRadian = progress >= maxPro ? 2 * Math.PI : 2 * Math.PI * rate - Math.PI / 2
const rate = progress / maxProo 得值為進(jìn)度占圓的比率
2π * rate 就是進(jìn)度所需要的弧度
由于 arc 方法畫圓的起點(diǎn)是3點(diǎn)的方向而我們的起點(diǎn)是12點(diǎn)方向所以我們還需要減掉一個(gè) Math.PI / 2最終就得出了我們上面的公式
由于當(dāng)progress等于maxPro的時(shí)候算出來的終點(diǎn)等于我們的起點(diǎn)最終畫的就會(huì)有問題,所以我們在計(jì)算起點(diǎn)終點(diǎn)的時(shí)候做了判斷 progress >= maxPro 時(shí)畫整圓
當(dāng)前效果
動(dòng)畫實(shí)現(xiàn)let currentProgress = 1 const timer = setInterval(() => { if (currentProgress >= progress) { currentProgress = progress clearInterval(timer) } ctx.beginPath() ctx.lineCap = "round" // 下面是漸變的代碼不需要的可以換成純色 let grd = ctx.createLinearGradient(0, 0, 220, 220) grd.addColorStop(0, "red") grd.addColorStop(1, "blue") ctx.strokeStyle = grd const startRadian = currentProgress >= maxPro ? 0 : Math.PI * 1.5 const rate = currentProgress / maxPro const endRadian = currentProgress >= maxPro ? 2 * Math.PI : 2 * Math.PI * rate - Math.PI / 2 ctx.arc(r + 10, r + 10, r, startRadian, endRadian) ctx.stroke() currentProgress++ }, 10)
動(dòng)畫的實(shí)現(xiàn)也非常的簡單,我們只需定義一個(gè)臨時(shí)的進(jìn)度 currentProgress 通過定時(shí)器每次累加這個(gè)進(jìn)度知道與progress相等停止計(jì)時(shí),期間每次繪制
完整的代碼我用react 寫的所以直接把react的整個(gè)代碼粘過來了,如果不需要的可以只拿繪圖的那一部分
import React from "react" export default class Test extends React.Component { componentDidMount () { this.renderProgress(30) } renderProgress (progress) { const cvsWitdh = 220 const cvsHeight = 220 const maxPro = 100 // 定義總進(jìn)度為100 const r = 100 // 定義圓的半徑為100 this.cvs.width = cvsWitdh this.cvs.height = cvsHeight const ctx = this.cvs.getContext("2d") ctx.lineWidth = 10 ctx.strokeStyle = "#15496B" ctx.arc(r + 10, r + 10, r, 0, 2 * Math.PI) // 2 * Math.PI === 360 度 最后一個(gè)參數(shù)代表的是圓的弧度 ctx.stroke() // 至此大圓畫完 if (progress === 0) { return } let currentProgress = 1 const timer = setInterval(() => { if (currentProgress >= progress) { currentProgress = progress clearInterval(timer) } ctx.beginPath() ctx.lineCap = "round" // 下面是漸變的代碼不需要的可以換成純色 let grd = ctx.createLinearGradient(0, 0, 220, 220) grd.addColorStop(0, "red") grd.addColorStop(1, "blue") ctx.strokeStyle = grd const startRadian = currentProgress >= maxPro ? 0 : Math.PI * 1.5 const rate = currentProgress / maxPro const endRadian = currentProgress >= maxPro ? 2 * Math.PI : 2 * Math.PI * rate - Math.PI / 2 ctx.arc(r + 10, r + 10, r, startRadian, endRadian) ctx.stroke() currentProgress++ }, 10) } render () { return () } }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/104702.html
摘要:將當(dāng)前狀態(tài)保存在堆棧,之后可以調(diào)用的平移旋轉(zhuǎn)錯(cuò)切剪裁等操作。恢復(fù)為之前堆棧保存的狀態(tài),防止后對執(zhí)行的操作對后續(xù)的繪制有影響。 目錄介紹 1.Paint畫筆介紹 1.1 圖形繪制 1.2 文本繪制 2.Canvas畫布介紹 2.1 設(shè)置屬性 2.2 畫圖【重點(diǎn)】 2.3 Canvas對象的獲取方式 2.4 Canvas的作用 2.5 Canvas繪制圓和橢圓 2.6 Can...
摘要:一個(gè)沒什么特別的日子,你接到了一個(gè)沒什么特別的設(shè)計(jì)圖,準(zhǔn)備寫個(gè)沒什么特別的活動(dòng)頁,然后,看到了一個(gè)效果唔,射雞獅啊,你這個(gè)圓是不是沒畫好啊,缺了個(gè)角。唔,那個(gè)是不是可以畫畫作為一個(gè)熟練操作和的前端工程師,那就去看看有沒有提供什么讓我們的吧。 一個(gè)沒什么特別的日子,你接到了一個(gè)沒什么特別的設(shè)計(jì)圖,準(zhǔn)備寫個(gè)沒什么特別的活動(dòng)頁,然后,看到了一個(gè)效果:showImg(https://segme...
摘要:一個(gè)沒什么特別的日子,你接到了一個(gè)沒什么特別的設(shè)計(jì)圖,準(zhǔn)備寫個(gè)沒什么特別的活動(dòng)頁,然后,看到了一個(gè)效果唔,射雞獅啊,你這個(gè)圓是不是沒畫好啊,缺了個(gè)角。唔,那個(gè)是不是可以畫畫作為一個(gè)熟練操作和的前端工程師,那就去看看有沒有提供什么讓我們的吧。 一個(gè)沒什么特別的日子,你接到了一個(gè)沒什么特別的設(shè)計(jì)圖,準(zhǔn)備寫個(gè)沒什么特別的活動(dòng)頁,然后,看到了一個(gè)效果:showImg(https://segme...
閱讀 3063·2021-11-25 09:43
閱讀 1040·2021-11-24 10:22
閱讀 1370·2021-09-22 15:26
閱讀 695·2019-08-30 15:44
閱讀 2472·2019-08-29 16:33
閱讀 3712·2019-08-26 18:42
閱讀 924·2019-08-23 18:07
閱讀 1842·2019-08-23 17:55