canvas円形アニメーションの円角進捗バーを描きます.

4786 ワード

手順を見たくないなら、一番後ろを直接見てもいいです.完全なコードがあります.
最近は円形の進捗状況を作っていますが、ネットでいくつかの例を見ました.
最後の効果を先にします.
まず丸を描きます.
    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() //       
上のコードで注意したいのは、arcメソッドの最後の側のパラメータです. (2π)は角度ではなく、円を描く起点は 3 12 次に進行の弧を描きます.
円弧を描くには、主に を計算する必要があります.
    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'これは最終的に描いた線を設定したもので、円角があるものです.
始点のラジアン計算方式const startRadian = progess >= maxPro ? 0 : Math.PI * 1.5私達の希望点の起点位置は時計12 の位置で、丸の弧度は2π==360°と推定され、12時の位置は1.5π==270°である.
終点のラジアン計算方式
  const rate = progress / maxPro
  const endRadian = progress >= maxPro ? 2 * Math.PI : 2 * Math.PI * rate - Math.PI / 2
const rate = progress / maxProoの値は、進行比2π * rateであり、進捗に必要なラジアンである.arcの方法で円を描く 3 のために、 12 の値を得るために、私たちのMath.PI / 2を減らす必要がある.progress maxProの時に計算した終点は私達の起点の最終画のに等しいので、起点の終点を計算する時に判断しました. progress >= maxProの時に丸を描きます.
現在の効果
アニメーション

    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)
アニメーションの実現も非常に簡単で、私達は1つの臨時の進捗度を定義するだけでcurrentProgressがタイマーを通してこの進捗度をアキュムレータによって知ることができます.progressと同じように時間を停止します.毎回描画します.
完全なコード
reactで書いたので、reactのコードを全部貼り付けました.必要でないなら、絵の一部だけを持ってきてもいいです.
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)
      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 (
      


{ this.cvs = ref }} />

) } }