# canvas绘制圆形动画圆角进度条

### 首先画一整个圆

```const cvsWitdh = 220
const cvsHeight = 220

const progess = 50 // 定义进度为50
const maxPro = 100  // 定义总进度为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() // 至此大圆画完```

### 然后是画一个进度的圆弧

```ctx.beginPath()
ctx.lineCap = 'round'
// 下面是渐变的代码不需要的可以换成纯色
let grd = ctx.createLinearGradient(0, 0, 220, 220)
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.stroke()```

#### 起点的弧度计算方式

`const startRadian = progess >= maxPro ? 0 : Math.PI * 1.5`

#### 终点的弧度计算方式

```const rate = progress / maxPro
const endRadian = progress >= maxPro ? 2 * Math.PI : 2 * Math.PI * rate - Math.PI / 2```

`const rate = progress / maxProo` 得值为进度占圆的比率

`2π * rate` 就是进度所需要的弧度

### 动画实现

```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)
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.stroke()
currentProgress++
}, 10)```

### 完整的代码

```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  // 定义总进度为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 度 最后一个参数代表的是圆的弧度
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)
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.stroke()
currentProgress++
}, 10)
}

render () {
return (
<div>
<br />
<br />
<canvas
ref={ref => {
this.cvs = ref
}}
/>

<br />

<br />
<button onClick={() => {
this.renderProgress(60)
</div>
)
}
}```