SVG generate conical gradient

Source: https://stackoverflow.com/a/54594553/2142071

by PhilQ

HTML

<svg viewBox="0 0 200 200" version="1.1" id="color-wheel"></svg>

CSS

#color-wheel {
  width: 200px;
  height: 200px;
}

JavaScript

const resolution = 1;
const outerRadius = 100;
const innerRadius = 0;

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);