canvas绘制多边形进度展示图,水波浪效果

参考:
多边形函数:https://www.cnblogs.com/anxia...
canvas画波浪进度球:https://www.cnblogs.com/pagod...

最近项目中需要一个六边形的水波纹进度,在网上只找到了一个进度球的绘制方法,然后结合了一下多边形的绘制方法,代码如下
案例1:
代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<style>
    body{
        position: relative;
        width:100vw;
        height: 100vh;
        margin: 0;
    }
    canvas{
        position: absolute;
        left: 50%;
        top: 50%;
        margin-left: -150px;
        margin-top: -150px;
        border: 1px dashed rgba(0,0,0,0.1)
    }
</style>
<body>
<canvas id="c"></canvas>
<input type="range" id="r" min="0" max="100" step="1">
</body>
<script>
    var canvas = document.getElementById('c');
    var ctx = canvas.getContext('2d');
    var range = document.getElementById('r');

    //range控件信息
    var rangeValue = range.value;
    var nowRange = 40;   //用于做一个临时的range

    //画布属性
    var mW = canvas.width = 350;
    var mH = canvas.height = 350;
    var lineWidth = 1;

    //圆属性
    var r = mH / 2; //圆心
    var cR = r - 32 * lineWidth; //圆半径

    //Sin 曲线属性
    var sX = 0;
    var axisLength = mW; //轴长
    var waveWidth = 0.008 ;   //波浪宽度,数越小越宽
    var waveHeight = 6; //波浪高度,数越大越高
    var speed = 0.09; //波浪速度,数越大速度越快
    var xOffset = 0; //波浪x偏移量

    ctx.lineWidth = lineWidth;

    //画圈函数
    var IsdrawCircled = false;
    var drawCircle = function(){
        // 画多边形函数
        function drawPath(x, y, n, r)
        {
            var i,ang;
            ang = Math.PI*2/n //旋转的角度
            ctx.save();//保存状态
            ctx.fillStyle ='rgba(255,0,0,.3)';//填充红色,半透明
            ctx.strokeStyle ='#000)';//填充绿色
            ctx.lineWidth = 2;//设置线宽
            ctx.translate(x, y);//原点移到x,y处,即要画的多边形中心
            ctx.moveTo(0, -r);//据中心r距离处画点
            ctx.beginPath();
            for(i = 0;i < n; i ++)
            {
                ctx.rotate(ang)//旋转
                ctx.lineTo(0, -r);//据中心r距离处连线
            }
            ctx.closePath();
            ctx.stroke();
            ctx.fill();
            ctx.restore();//返回原始状态
        }
        drawPath(r, r, 6, cR+1)
        drawPath(r, r, 6, cR)
        ctx.clip();
        IsdrawCircled = true;
    }

    //画sin 曲线函数
    var drawSin = function(xOffset, color, waveHeight){
        ctx.save();

        var points=[];  //用于存放绘制Sin曲线的点

        ctx.beginPath();
        //在整个轴长上取点
        for(var x = sX; x < sX + axisLength; x += 20 / axisLength){
            //此处坐标(x,y)的取点,依靠公式 “振幅高*sin(x*振幅宽 + 振幅偏移量)”
            var y = Math.sin((-sX - x) * waveWidth + xOffset) * 0.8 + 0.1;

            var dY = mH * (1 - nowRange / 100 );

            points.push([x, dY + y * waveHeight]);
            ctx.lineTo(x, dY + y * waveHeight);
        }

        //封闭路径
        ctx.lineTo(axisLength, mH);
        ctx.lineTo(sX, mH);
        ctx.lineTo(points[0][0],points[0][1]);
        ctx.fillStyle = color;
        ctx.fill();

        ctx.restore();
    };

    var render = function(){
        ctx.clearRect(0, 0, mW, mH);

        rangeValue = range.value;
        console.log(rangeValue);
        if(IsdrawCircled == false){
            drawCircle();
        }

        if(nowRange <= rangeValue){
            var tmp = 1;
            nowRange += tmp;
        }

        if(nowRange > rangeValue){
            var tmp = 1;
            nowRange -= tmp;
        }

        drawSin(xOffset+Math.PI*0.7, 'rgba(28, 134, 209, 0.5)', 18);
        drawSin(xOffset, '#1c86d1', 18);
        drawText();

        xOffset += speed;
        requestAnimationFrame(render);
    }
    //写百分比文本函数
    var drawText = function(){
        ctx.save();

        var size = 0.4*cR;
        ctx.font = size + 'px Microsoft Yahei';
        ctx.textAlign = 'center';
        ctx.fillStyle = "rgba(06, 85, 128, 0.5)";
        ctx.fillText(~~nowRange + '%', r, r + size / 2);

        ctx.restore();
    };

    render();


</script>
</html>

canvas绘制多边形进度展示图,水波浪效果
效果图


案例2:
代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<style>
    body{
        position: relative;
        width:100vw;
        height: 100vh;
        margin: 0;
    }
    canvas{
        position: absolute;
        left: 50%;
        top: 50%;
        margin-left: -150px;
        margin-top: -150px;
        border: 1px dashed rgba(0,0,0,0.1)
    }
</style>
<body>
<canvas id="c"></canvas>
</body>
<script>

    var canvas = document.getElementById('c');
    var ctx = canvas.getContext('2d');

    // 初始化参数
    let oW = 236,
        oH = 267,
        lineWidth = 1,
        bOffset = 2,
        border = 3, //X轴偏移量
        r,
        cR,
        axisLength,
        unit, // 浪宽
        range = .3, // 浪高
        nowrange = .3,
        sp = 0,     // 周期偏移量
        nowdata = 0,
        value = 0.5, // 百分比
        waveupsp = 0.002; // 水波上涨速度

    canvas.width = oW;
    canvas.height = oH;
    ctx.lineWidth = lineWidth;
    var triangleH = Math.ceil(oH/4);
    // 外六边形
    var arcStack = [
        [oW/2, 0],
        [oW-bOffset, triangleH],
        [oW-bOffset,oH-triangleH],
        [oW/2, oH],
        [bOffset, oH-triangleH],
        [bOffset, triangleH]
    ];
    var cStartPoint = arcStack.shift();
    // 内六边形
    var arcStackInner = [
      [oW/2, border],
      [oW-border, triangleH + border/2],
      [oW-border, oH-triangleH-border/2],
      [oW/2, oH-border],
      [border, oH - triangleH - border/2],
      [border,triangleH + border/2]
    ];
    var cStartPointInner = arcStackInner.shift();
    r = oW / 2;
    cR = oH/2 - border - lineWidth;

    ctx.beginPath();
    axisLength = oW - 2*border;
    unit = axisLength / 20;
    ctx.beginPath();
    renderBorder();
    render();
    function renderBorder() {
        ctx.beginPath();
        ctx.strokeStyle = "#000000";
        ctx.fillStyle = "#000000";
        ctx.moveTo(cStartPoint[0], cStartPoint[1]);
        while (arcStack.length) {
            var temp = arcStack.shift();
            this.ctx.lineTo(temp[0], temp[1]);
            ctx.stroke();
        }
        ctx.lineTo(cStartPoint[0], cStartPoint[1]);
        ctx.stroke();
        ctx.fill();
        ctx.globalCompositeOperation = 'source-over';

        ctx.beginPath();
        ctx.fillStyle = '#fff'
        ctx.strokeStyle = '#fff';
        ctx.moveTo(cStartPointInner[0], cStartPointInner[1]);
        while (arcStackInner.length) {
            var temp = arcStackInner.shift();
            this.ctx.lineTo(temp[0], temp[1]);
            ctx.stroke();
        }
        ctx.lineTo(cStartPointInner[0], cStartPointInner[1]);
        ctx.stroke();
        ctx.fill();
        ctx.restore();
        ctx.clip();
        ctx.save();
        ctx.globalCompositeOperation = 'source-over';
    }

    function render() {
        ctx.clearRect(0,0,oW,oH);
        if (value >= 0.85) {
            if (nowrange > range/4) {
                var t = range * 0.01;
                nowrange -= t;
            }
        } else if (value <= 0.1) {
            if (nowrange < range*1.5) {
                var t = range * 0.01;
                nowrange += t;
            }
        } else {
            if (nowrange <= range) {
                var t = range * 0.01;
                nowrange += t;
            }

            if (nowrange >= range) {
                var t = range * 0.01;
                nowrange -= t;
            }
        }

        if((value - nowdata) > 0) {
            nowdata += waveupsp;
        }

        if((value - nowdata) < 0){
            nowdata -= waveupsp
        }

        sp += 0.07;
        if(value){
            drawSine();
        }
        requestAnimationFrame(render)
    }

    function drawSine() {
        ctx.beginPath();
        ctx.save();
        var Stack = [];
        for (let i = border; i <= border+axisLength; i+=20/axisLength) {
            var x = sp + (border + i) / unit;
            var y = Math.sin(x) * nowrange;
            var dx = i;

            var dy = 2*cR*(1-nowdata) + border - (unit * y);
            ctx.lineTo(dx, dy);
            Stack.push([dx,dy]);
        }
        var startP = Stack[0]
        ctx.lineTo(border + axisLength,oH + border);
        ctx.lineTo(border,oH+border);
        ctx.lineTo(startP[0], startP[1])
        ctx.fillStyle = "#50bff7";
        ctx.fill();
        ctx.restore();
    }
     function drawText() {
        ctx.save();

        var size = 0.4*cR;
        ctx.font = size + 'px Microsoft Yahei';
        ctx.textAlign = 'center';
        ctx.fillStyle = "rgba(06, 85, 128, 0.5)";
        let txt = (nowdata.toFixed(2)*100).toFixed(0) + '%';
        ctx.fillText(txt, r, r + size / 2);

        ctx.restore();
    }
</script>
</html>

canvas绘制多边形进度展示图,水波浪效果

效果图

相关推荐