JSFiddle - React, Tailwind, and code Playground

by nilloc

HTML

<svg height=800 width=800>
    <pattern id="hatch" patternUnits="userSpaceOnUse" width="20" height="20">
        <path stroke="green" d="M 5,0 l 20,10" />
    </pattern>
    <g fill-rule="evenodd" id="paths">
        <path fill="url(#hatch)" stroke="black" d="M 50,50 C500,100 300,200 300,400 Z
                    M240,180 h-35 a 35,35, 0 1 0 35,-35 Z" />
        <path d="M 200,100 h-35 a 35,35, 0 1 0 35,-35 Z" />
    </g>
    <g id="arcs" fill="none">
        <!-- Arc test-->
        <path stroke="blue" d="M 0,200 A 50,50 0 0 1 100,200"/>
        <path stroke="blue" d="M 0,250 A 62.5,62.5 0 0 1 100,250"></path>
        <path stroke="blue" d="M 0,300 A 50,50 0 0 1 50,250"></path>
        <rect stroke="purple" x="120" y="250" width="20" height="20" />
        <circle stroke="purple" cx="120" cy="250" r="20"/>
    </g>
</svg>

JavaScript

$(function () {
    var lineLength = function (x, y, x0, y0) {
        return Math.sqrt((x -= x0) * x + (y -= y0) * y);
    };
    var lineAngle = function(x1,y1,x2,y2){
        return Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;
    };

    var curveToArc = function (x1, y1, x2, y2, curve) {
        curve = parseInt(curve);
        curve = Math.min(curve, 180); // Doesn't work for curves past 180 degress.
        curve = Math.max(-180, curve);
        
        console.log('curve:', curve);
        var arc = 'M ' + x1 + ',' + y1 + ' A ';
        var xAxisRotation = 0; // unsupported
        var largeArcFlag = 0; // unneeded, we used sweep flag for curve direction
        var sweepFlag = (parseFloat(curve) >= 0) ? 0 : 1; // flips the curve direction for negative curves.
        
        // 180 -> 2
        // 135 -> 
        // 360/(360 - 180) =2 //GOOD
        //360/(360-135) = 1.6 //FAILS
        //var radius = lineLength(x1, y1, x2, y2) / (360 / curve);
        
        //(360 - 180)/360 = .5
        //(360-135)/360 = .625 
        // still probably not right, because angle of end points matters...
        
        var radius = lineLength(x1, y1, x2, y2) * ((360-Math.abs(curve))/360);
        
        arc += radius + ',' + radius;
        arc += ' ' + xAxisRotation;
        arc += ' ' + largeArcFlag;
        arc += ' ' + sweepFlag;
        arc += ' ' + x2 + ',' + y2;
        // rx, ry, x-axis-rotation, large-arc-flag, sweep-flag, x, y
        return arc;
    };
    
    console.log(lineLength(0, 300, 50, 250));
    
    $('#arcs').append('<path stroke="blue" d="' + 
                      curveToArc(0, 300, 50, 250, -90)+ '" />');

    console.log($('#arcs').html());
});