CanCirPro 使用canvas标签绘制 圆环进度条 有渐变和动画

CanCirPro 使用canvas标签绘制 圆环进度条 有渐变和动画

  1. import React, { Component } from "react";
    import PropTypes from "prop-types";
    
    export default class CanCirPro extends Component {
    
       constructor(props) {
           super(props);
           this.state = {
               percent: 0,
           };
       }
    
       static defaultProps = {
           radius: 45,
           percent: 47.7,
           borderWidth: 6,
           startcolor: '#ffd460',
           centercolor: '#fcc241',
           endColor: '#f79d00',
           textStyle: { fontSize: 11, color: "#fa9a22", textAlign: 'center' },
           openAnimation: true
       }
       static propTypes = {
           radius: PropTypes.number,
           percent: PropTypes.number,
           borderWidth: PropTypes.number,
           startcolor: PropTypes.string,
           centercolor: PropTypes.string,
           endColor: PropTypes.string,
           textStyle: PropTypes.object,
           openAnimation: PropTypes.bool,
       }
       render() {
           return (
    "cancirproOut" style={{ width: (this.props.radius + this.props.borderWidth) * 2, height: (this.props.radius + this.props.borderWidth) * 2, }} > "cancirproIn" ref={cancirpro => { this.onDraw(cancirpro);//ref时开始绘制 }} width={(this.props.radius + this.props.borderWidth) * 2} height={(this.props.radius + this.props.borderWidth) * 2} />
    "cancirproContent" style={{ width: (this.props.radius + this.props.borderWidth) * 2, height: (this.props.radius + this.props.borderWidth) * 2, marginTop: - (this.props.radius + this.props.borderWidth) * 2 - this.props.borderWidth/2 }} > {this.props.children ? this.props.children :
    this.props.textStyle}>{this.props.openAnimation ? this.state.percent : this.props.percent}%
    }
    ); } componentWillReceiveProps(newprops) { this.setState({ percent: 0 }); this.time = setTimeout(() => { this.componentDidMount(); }, 1); } componentDidMount() { if (this.props.openAnimation) { this.startAnimation(); } } startAnimation() { if (this.state.percent < this.props.percent - 2) { this.time = setTimeout(() => { this.setState({ percent: this.state.percent + 2 }); this.startAnimation(); }, 11); } else { this.setState({ percent: this.props.percent }); } } onDraw(cancirpro) { if (cancirpro) {//如果cancirpro存在 let canvas = cancirpro; let ctx = canvas.getContext("2d"); ctx.clearRect(0, 0, (this.props.radius + this.props.borderWidth) * 2, (this.props.radius + this.props.borderWidth) * 2);//清空绘画区域 if (this.props.percent !== 0) { let percent = this.props.openAnimation ? this.state.percent : this.props.percent; let width = (this.props.radius + this.props.borderWidth) * 2; if (window.devicePixelRatio) { canvas.style.width = width + "px"; canvas.style.height = width + "px"; canvas.height = width * window.devicePixelRatio; canvas.width = width * window.devicePixelRatio; ctx.scale(window.devicePixelRatio, window.devicePixelRatio); }//使用ctx.scale,解决锯齿严重问题 ctx.beginPath(); let grd1 = ctx.createLinearGradient(0, 0, 0, this.props.radius * 2); grd1.addColorStop(0, this.props.startcolor); grd1.addColorStop(1, this.props.centercolor);//线性渐变定义 ctx.lineCap = 'round';//连接处圆头 ctx.strokeStyle = grd1;//设置strokeStyle为渐变色 ctx.lineWidth = this.props.borderWidth;//圆环宽度 if (percent < 50) {//小于50,绘制前半部分的部分半圆 ctx.arc(this.props.radius + this.props.borderWidth, this.props.radius + this.props.borderWidth, this.props.radius, Math.PI * (1.4), Math.PI * (1.4 + percent / 50), false); } else {//大于50,绘制前半部分的完整半圆 ctx.arc(this.props.radius + this.props.borderWidth, this.props.radius + this.props.borderWidth, this.props.radius, Math.PI * (1.4), Math.PI * (1.4 + 1), false); } ctx.stroke(); if (percent > 50) {//大于50,才绘制后半部分需要的半圆 ctx.beginPath(); let grd2 = ctx.createLinearGradient(0, this.props.radius * 2, 0, 0); grd2.addColorStop(0, this.props.centercolor); grd2.addColorStop(1, this.props.endColor); ctx.lineCap = 'round'; ctx.strokeStyle = grd2; ctx.lineWidth = this.props.borderWidth; ctx.arc(this.props.radius + this.props.borderWidth, this.props.radius + this.props.borderWidth, this.props.radius, Math.PI * (2.4), Math.PI * (2.4 + ((percent - 50) / 50)), false); ctx.stroke(); } } } } }
  2. .cancirproOut {
       overflow: hidden;
     }
    .cancirproContent {
       display: flex;
       display: -webkit-flex;
       justify-content: center;
       -webkit-justify-content: center;
       align-items: center;
       -webkit-align-items: center;
     }

qq交流群

​ 179916551 欢迎进群交流前端各种问题

github

​ https://github.com/1cao2mu/react-circle-progress 如果只是参考思路,也请给个star 谢谢

你可能感兴趣的:(react)