html5 canvas 弧形线条由中间向两边渐变

252 阅读1分钟

fd.png

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<canvas id="canvas" width="700" height="500" style="background: black"></canvas>
<script>
    let canvas = document.querySelector('#canvas');
    let ctx = canvas.getContext('2d');
    let x = canvas.width / 5;
    let y = canvas.height / 8;
    let num = 0;

    /**
     * 弧形线条由中间向两边渐变
     * @param {Array} translate - 重新映射画布的位置
     * @param {Array}  gradient - 放射状/圆形渐变
     * @param {Array}       arc - 圆形
     * @param {Number}  opacity - 渐变色透明度
     * @param {Boolean}  stroke - 是否使用线条
     **/
    function aperture({translate = [], gradient = [], arc = [],opacity = 0 ,stroke = false}) {
        ctx.save();
        ctx.translate(...translate);
        ctx.beginPath();
        ctx.lineWidth = 2;
        ctx.arc(...arc);
        let grd = ctx.createRadialGradient(...gradient);
        grd.addColorStop(0, `rgba(1,174,229,${opacity})`);
        grd.addColorStop(1, "rgba(1,174,229,1)");
        if(!stroke){
            ctx.fillStyle = grd;
            ctx.fill();
        }else {
            ctx.strokeStyle = grd;
            ctx.stroke();
        }
        ctx.restore();
    }

    aperture({translate:[x, y + 50], gradient:[0, 0, 80, 0, 0, 20], arc:[0, 0, 82, 0, Math.PI],opacity:0.5});
    aperture({translate:[x, y + 50], gradient:[0, 0, 80, 0, 0, 20], arc:[0, 0, 82, Math.PI, Math.PI * 2],opacity:0.5});

    aperture({translate:[x + 200, y + 50], gradient:[0, 50, 80, 0, 80, 20], arc:[0, 0, 82, 0, Math.PI],opacity:0.1});
    aperture({translate:[x + 200, y + 50], gradient:[0, -50, 80, 0, -80, 20], arc:[0, 0, 82, Math.PI, Math.PI * 2],opacity:0.1});

    aperture({translate:[x, y + 250], gradient:[0, 40, 80, 0, 80, 20], arc:[0, 0, 82, 0, Math.PI]});
    aperture({translate:[x, y + 250], gradient:[0, -50, 80, 0, -80, 20], arc:[0, 0, 82, Math.PI, Math.PI * 2]});

    aperture({translate:[x + 200, y + 250], gradient:[0, 40, 80, 0, 80, 20], arc:[0, 0, 82, 0, Math.PI],stroke:true});
    aperture({translate:[x + 200, y + 250], gradient:[0, -50, 80, 0, -80, 20], arc:[0, 0, 82, Math.PI, Math.PI * 2],stroke:true});

    
    /**
     *  实现旋转
     **/
    function f({translate = [], gradient = [], arc = [],opacity = 0 ,stroke = false}) {
        ctx.save();
        ctx.translate(...translate);
        ctx.beginPath();
        ctx.rotate(num * Math.PI / 180);
        ctx.lineWidth = 2;
        ctx.arc(...arc);
        let grd = ctx.createRadialGradient(...gradient);
        grd.addColorStop(0, `rgba(1,174,229,${opacity})`);
        grd.addColorStop(1, "rgba(1,174,229,1)");
        if(!stroke){
            ctx.fillStyle = grd;
            ctx.fill();
        }else {
            ctx.strokeStyle = grd;
            ctx.stroke();
        }
        ctx.restore();
        num++;
    }
    (function drawFrame() {
        window.requestAnimationFrame(drawFrame);
        ctx.clearRect(x + 310, y, 240, 400);
        f({translate:[x + 400, y + 150], gradient:[0, 40, 80, 0, 80, 20], arc:[0, 0, 82, 0, Math.PI],stroke:true});
        f({translate:[x + 400, y + 150], gradient:[0, -50, 80, 0, -80, 20], arc:[0, 0, 82, Math.PI, Math.PI * 2],stroke:true});
    })();
</script>
</body>
</html>