canvas绘制双圆环进度池

1 篇文章 0 订阅
1 篇文章 0 订阅

vue绘制canvas绘制双圆环进度池组件

canvas绘制双圆环进度池

组件代码

<template>
    <canvas
        ref="circle"
        moz-opaque
        :width="width"
        :height="height"
        :BigColor="BigColor"
        :contentData="contentData"
        :allData="allData"
        :contentStyle="contentStyle"
        :SmallColor="SmallColor"
        :SmallRadius="SmallRadius"
        :InsideRadius="InsideRadius"
        :lineGrad="lineGrad"
        :contentGrad="contentGrad"
        :title="title"
    ></canvas>
</template>
<script>
export default {
    name: 'CanvasCircle',
    props:{
        width:  {
            type: Number,
            require: true
        },
        height:  {
            type: Number,
            require: true
        },
        BigColor: {
            type: String,
            default: '#013967'
        },
        contentData: {
            type: Number,
            require: true
        },
        allData: {
            type: Number,
            default: 100
        },
        contentStyle: {
            type: Object,
            default(){
                return {
                    0: '#01D9FE',
                    1: '#0477D5'
                }
            }
        },
        SmallColor: {
            type: String,
            default: '#013967'
        },
        SmallRadius: {
            type: Number,
            require: true
        },
        InsideRadius: {
            type: Number,
            require: true
        },
        lineGrad: {
            type: Object,
            default(){
                return {
                    direction: 'ToRight',
                    style: {
                        0: '#03D5FB',
                        1: '#2068C0'
                    }
                }
            }
        },
        contentGrad: {
            type: Object,
            default(){
                return {
                    direction: 'ToTop',
                    style: {
                        0: '#025289',
                        1: '#02193F'
                    }
                }
            }
        },
        title: {
            type: Object,
            default(){
                return {

                }
            }
        }
    },
    methods: {
        AngleFn(data){
            let startAngle = Math.PI / 180 * (90 - (data / this.allData * 360 / 2));
            let endAngle = Math.PI / 180 * (90 + (data / this.allData * 360 / 2));
            return {
                startAngle,
                endAngle
            }
        }
    },
    mounted(){
        let canvasBox = this.$refs.circle;
        let ctx = canvasBox.getContext('2d');
        //fillRect(x, y, width, height)绘制一个填充的矩形
        //strokeRect(x, y, width, height)绘制一个矩形的边框
        //clearRect(x, y, width, height)清除指定矩形区域
        //beginPath() 新建一条路径
        //closePath() 闭合路径
        //stroke() 通过该线条来绘制图形轮廓
        //fill()通过填充路径的内容区域生成实心的图形
        //moveTo(x, y) 将笔触移动到指定的坐标x,y上
        //lineTo(x, y) 绘制从当前位置到指定x,y 的直线
        /*+++++++++++++++++++++++++++++++++++++++++++++++++++++
        @params
        	width-----------canvas宽度
        	height----------canvas高度
            BigColor-------最外层圆颜色
            allData--------总数量
            contentData----内容大小(进度池容量)
            contentStyle----进度池样式
            SmallColor------中层圆样式
            SmallRadius----中层圆半径
            InsideRadius-----最里层圆的半径
            lineGrad----------最里层圆边框样式
            contentGrad----最里层圆样式
            title----------------文本
        +++++++++++++++++++++++++++++++++++++++++++++++++++++*/
        let bigCircle = new Path2D();
        bigCircle.arc(this.width / 2, this.height / 2, this.width / 2, 0, Math.PI * 2);
        let contentCircle = new Path2D();
        contentCircle.arc(this.width / 2, this.height / 2, this.width / 2, this.AngleFn(this.contentData).startAngle, this.AngleFn(this.contentData).endAngle);
        // let leftX, leftY, rightX, rightY;
        // let percentage = this.contentData / this.allData;
        // let contentY = this.height * percentage;
        // if( this.height / 2 - this.SmallRadius < contentY < this.height - (this.height / 2 - this.SmallRadius) ){
        //     if(percentage < 0.5){
        //         leftY = rightY = this.height * (1 - percentage);
        //         let x = Math.sqrt(this.SmallRadius ** 2 - (this.height / 2 - this.height * percentage) ** 2);
        //         leftX = this.width / 2 - x;
        //         rightX = this.width / 2 + x;
        //         //contentCircle.moveTo(leftX, leftY);
        //         contentCircle.arc(this.width / 2, this.height / 2, this.SmallRadius, this.AngleFn(this.contentData).endAngle, this.AngleFn(this.contentData).startAngle, true);
        //         console.log(rightY, rightX, leftY, leftX)
        //     }
        // }
        let smallCircle = new Path2D();
        smallCircle.arc(this.width / 2, this.height / 2, this.SmallRadius, 0, Math.PI * 2);
        ctx.strokeStyle = this.BigColor;
        ctx.stroke(bigCircle);
        let contentColor = ctx.createLinearGradient(this.width / 2, this.height, this.width / 2, this.height * (1 - this.contentData / this.allData));
        for(let key in this.contentStyle){
            contentColor.addColorStop(key, this.contentStyle[key]);
        }
        ctx.fillStyle = contentColor;
        ctx.fill(contentCircle);
        ctx.fillStyle = '#000A3B';
        ctx.fill(smallCircle);
        ctx.strokeStyle = this.SmallColor;
        ctx.stroke(smallCircle);
        let insideCircle = new Path2D();
        insideCircle.arc(this.width/ 2, this.height / 2, this.InsideRadius, 0, Math.PI * 2);
        let lineGrad = this.lineGrad.direction == 'ToTop'
                        ?
                        ctx.createLinearGradient(this.width / 2, this.height / 2 + this.InsideRadius, this.width / 2, this.height / 2 - this.InsideRadius)
                        :
                        ctx.createLinearGradient(this.width / 2 - this.InsideRadius, this.height / 2, this.width / 2 + this.InsideRadius, this.height / 2);
        for(let key in this.lineGrad.style){
            lineGrad.addColorStop(key, this.lineGrad.style[key]);
        }
        let gradColor = this.contentGrad.direction == 'ToTop'
                        ?
                        ctx.createLinearGradient(this.width / 2, this.height / 2 + this.InsideRadius, this.width / 2, this.height / 2 - this.InsideRadius)
                        :
                        ctx.createLinearGradient(this.width / 2 - this.InsideRadius, this.height / 2, this.width / 2 + this.InsideRadius, this.height / 2);
        for(let key in this.contentGrad.style){
            gradColor.addColorStop(key, this.contentGrad.style[key]);
        }
        ctx.fillStyle = gradColor;
        ctx.fill(insideCircle);
        ctx.strokeStyle = lineGrad;
        ctx.stroke(insideCircle);
        ctx.font = this.title.font;
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.fillStyle = this.title.color;
        ctx.fillText(this.title.text, this.width / 2, this.height / 2);
    }
}
</script>

##父组件代码

<canvas-circle
  :width="120"
  :height="120"
  :contentData="30"
  :allData="100"
  :SmallRadius="55"
  :InsideRadius="50"
  :title="{text: '352.33亿', font : '0.2rem SourceHanSansCN-Bold', color: '#02D9FD'}"
/>

render-result

效果

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值