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