JSFiddle - React, Tailwind, and code Playground

HTML

<body class="yui3-skin-sam">
        <div id="leftLine"></div>        
        <div id="topLine"></div>
        <div id="bottomLine"></div>
        <div id="rightLine"></div>
        Number of Cards: <span id="numCards" class="slider"></span><span id="numCardsValue">13</span><br>
        Card Spacing: <span id="cardSpacing" class="slider"></span><span id="cardSpacingValue">0.20</span><br>
        Arc Radius: <span id="arcRadius" class="slider"></span><span id="arcRadiusValue">400</span><br>
        <input type="button" value="N">
        <input type="button" value="W">
        <input type="button" value="S">
        <input type="button" value="E">
        <script src="http://yui.yahooapis.com/3.4.1/build/yui/yui-min.js"></script>
    </body>

CSS

img { position: absolute; z-index: 2; }
body { background-color: #6395EC; }
.slider {  }
input { padding: 1.0em; }
#leftLine { display: none; width: 3px; background-color: red; height: 2000px; position: absolute; top: 0; }
#topLine { display: none; height: 3px; background-color: red; width: 2000px; position: absolute; left:0; }
#bottomLine { display: none; height: 3px; background-color: red; width: 2000px; position: absolute; left:0;; }
#rightLine { display: none; width: 3px; background-color: red; height: 2000px; position: absolute; top: 0; }
.baseLine { display: block !important; background-color: yellow !important; z-index: 3; }

JavaScript

var RENDER_OFFSET_X = 200;
var RENDER_OFFSET_Y = 200;

var CARD_URL = "http://staticworldofsolitaire.com/decks/paris/4/1s.png";
var CARD_WIDTH = 128;
var CARD_HEIGHT = 199;

// Number of cards to show
var NUM_CARDS = 13;

// How much to show between cards, expressed as percentage of textureWidth
var CARD_SPACING = 0.20;

// This is the radius of the circle under the fan of cards and thus controls the overall curvature of the fan. Small values means higher curvature
var ARC_RADIUS = 400;

var DIRECTION = "N";

function calculateCoords(numCards, arcRadius, cardWidth, cardHeight, direction, cardSpacing)
{
    // The separation between the cards, in terms of rotation around the circle's origin
    var anglePerCard = Math.radiansToDegrees(Math.atan(((cardWidth*cardSpacing)/arcRadius)));

    var angleOffset = ({"N" : 270, "S" : 90, "E" : 0, "W" : 180})[direction];    
    
    var startAngle = angleOffset-0.5*anglePerCard*(numCards-1);
        
    var coords = [];
    var i;
    var minX = 99999;
    var minY = 99999;
    var maxX = -minX;
    var maxY = -minY;
    for(i=0;i<numCards;i++)
    {
        var degrees = startAngle + anglePerCard*i;
        
        var radians= Math.degreesToRadians(degrees);
        var x = cardWidth / 2 + Math.cos(radians) * arcRadius;
        var y = cardHeight / 2 + Math.sin(radians) * arcRadius;
        
        minX = Math.min(minX, x);
        minY = Math.min(minY, y);
        maxX = Math.max(maxX, x);
        maxY = Math.max(maxY, y);
        
        coords.push({x:x, y:y, angle:degrees+90});
    }
    
    var rotatedDimensions = Math.getRotatedDimensions(coords[0].angle, cardWidth, cardHeight);

    var offsetX = 0;
    var offsetY = 0;
    
    if(direction==="N")
    {
        offsetX = (minX*-1);
        offsetX += ((rotatedDimensions[0]-cardWidth)/2);
        
        offsetY = (minY*-1);
    }
    else if(direction==="S")
    {
        offsetX = (minX*-1);
        offsetX += ((rotatedDimensions[0]-cardWidth)/2);
        
...