svg multiple color on circle stroke

后端 未结 2 1273
梦谈多话
梦谈多话 2020-12-02 13:59

i want to create a rainbow circle

like the picture below:

but how can i draw the curved and multiple color stop gradient?

here\'s my current

2条回答
  •  北荒
    北荒 (楼主)
    2020-12-02 14:16

    You can use the conic-gradient to solve it:

    .color-wheel {
      display: inline-block;
      padding: 25px;
      border-radius: 100%;
      background: conic-gradient(red, yellow, lime, aqua, blue, magenta, red);
      background-repeat: no-repeat;
      background-size: cover;
      background-position: center center;
      background-size: auto;
    }
    
    .color-wheel::after {
      content: '';
      display: block;
      padding: 75px;
      border-radius: 100%;
      background: #ffffff;
    }

    But this is currently only supported in Chrome. Take a look here for more information: https://caniuse.com/#feat=css-conic-gradients

    I also built javascript/svg solution which can solve it easily:

    const resolution = 1;
    const outerRadius = 100;
    const innerRadius = 75;
    
    function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
        const angleInRadians = (angleInDegrees - 90) * Math.PI / 180.0;
    
        return {
            x: centerX + radius * Math.cos(angleInRadians),
            y: centerY + radius * Math.sin(angleInRadians)
        };
    }
    
    function describeArc(x, y, radius, startAngle, endAngle) {
        const start = polarToCartesian(x, y, radius, endAngle);
        const end = polarToCartesian(x, y, radius, startAngle);
    
        const arcSweep = endAngle - startAngle <= 180 ? '0' : '1';
    
        const d = [
            'M', start.x, start.y,
            'A', radius, radius, 0, arcSweep, 0, end.x, end.y,
            'L', x, y,
            'L', start.x, start.y
        ].join(' ');
    
        return d;
    }
    
    function generateConicGradiant(radius, resolution, target) {
        for (var i = 0; i < 360 * resolution; i++) {
            const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
    
            path.setAttribute(
                "d",
                describeArc(
                    radius,
                    radius,
                    radius,
                    i / resolution,
                    (i + 2) / resolution
                )
            );
            path.setAttribute('fill', 'hsl(' + (i / resolution) + ', 100%, 50%)');
    
            target.appendChild(path);
        } 
    }
    
    function generateOverlay(outerRadius, innerRadius, target) {
        const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
    
        circle.setAttribute('cx', outerRadius);
        circle.setAttribute('cy', outerRadius);
        circle.setAttribute('r', innerRadius);
        circle.setAttribute('fill', 'white');
    
        target.appendChild(circle);
    }
    
    var root = document.getElementById('color-wheel');
    
    generateConicGradiant(outerRadius, resolution, root);
    generateOverlay(outerRadius, innerRadius, root);
    #color-wheel {
      width: 200px;
      height: 200px;
    }

提交回复
热议问题