JSFiddle - React, Tailwind, and code Playground

by Spero Koulouras

HTML

<script src="http://fancyapps.com/fancybox/source/jquery.fancybox.js"></script>
<link rel="stylesheet" href="http://fancyapps.com/fancybox/source/jquery.fancybox.css">
<!-- This loads the YouTube IFrame Player API code -->
<title>Field Calibration</title>

<script src="http://www.youtube.com/player_api"></script>
<script src="http://code.jquery.com/jquery-1.8.2.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>

<!--
  <a class="fancybox fancybox.iframe" 
     href="https://www.youtube.com/embed/nCWveeg0gPA?wmode=opaque&enablejsapi=1&autoplay=1">LGHS JV
  </a>
  <iframe class="fancybox fancybox.iframe" type="text/html"
          src="http://www.youtube.com/embed/nCWveeg0gPA?wmode=opaque&enablejsapi=1&autoplay=1"
          frameborder="0">
  </iframe>
-->
<div id="fixedBar">
  <nav>
    <ul>
      <li>Camera Setup</li>
      <li>Game Schedule</li>
      <li>This Game</li>
    </ul>
  </nav>
</div>

<div id="field">
  <iframe id="ytVideo" class="fancybox fancybox.iframe" type="text/html"
          src="http://www.youtube.com/embed/nCWveeg0gPA?wmode=opaque&enablejsapi=1&autoplay=1"
          frameborder="0">
  </iframe>

  <div id="overlay">
    <div id="alignment">
    </div>
  </div>
</div>

CSS

body {
  background: black;
  font-family: Verdana, Geneva, "sans-serif";
}

#fixedBar {
  position: fixed;
}

nav {
  background: #303030;
  color: white;
  display: table;
  width: 100%;
  border-collapse: collapse;
  border: none;
}
nav ul {
  display: table-row;
}
nav li {
  display: table-cell;
  text-align: center;
  font-weight: bold;
  padding: .75em;
  border: 4px solid black;
  background: linear-gradient(to bottom, #4c4c4c 0%,#595959 12%,#666666 25%,#474747 35%,#2c2c2c 43%,#000000 53%,#111111 63%,#2b2b2b 76%,#1c1c1c 91%,#131313 100%); 
}


.menu {
  position: fixed;
  background: #202020;
  width: 100%
  opacity: 1;
}

button {
  background: Blue;
  color: White;
  border: none;
  font-size: medium;
  margin: .5em;
  padding: .5em;
}

.fancybox-nav {
    width: 60px;       
}

.fancybox-nav span {
    visibility: visible;
}

.fancybox-next {
    right: -60px;
}

.fancybox-prev {
    left: -60px;
}


.fancybox {
  position: relative;
  left: 200px;
  top: 200px;
  height: 720px;
  width: 1280px;
}


svg {
  position: relative;
}

h1 {
  font-size: 20pt;
  font-weight: bold;
  margin:1em;
}

#field {
  position: relative;
  width: 1680px;
  height: 1120px;
  top: 0;
}


.template {
  display: none;
}

#overlay {
  position: fixed;
  top: 60px;
  left:0;
}

#alignment {
}

.foulLine {
  stroke: white;
  stroke-width: 4;
}

.foulPole {
  stroke: yellow;
  fill: yellow;
  opacity: .5;
}

.fence {
  stroke: yellow;
  stroke-dasharray: 5 5;
  stroke-width: 3;
  fill: none;
}

.homePlate {
  stroke: yellow;
  fill: yellow;
  opacity: .5;
}

.centerField {
  stroke: yellow;
  fill: yellow;
  opacity: .5;
}

.hppr2b {
  stroke: white;
  stroke-dasharray: 5 5;
  stroke-width: 3;
  fill: none;
  opacity: .5;
}

.first {
  stroke: none;
  fill: red;
  opacity: .3;
}

.second {
  stroke: none;
  fill: red;
  opacity: .3;
}

.third {
  stroke: none;
  fill: red;
  opacity: .3;
}

.firstToThird {
  stroke: white;
  fill: none;
  stroke-width: 5;
  opacity: .3;
}

JavaScript

function line(ox,oy,dx,dy) {
	console.log("M" + ox + "," + oy + " L" + dx + "," + dy)
	return("M" + ox + "," + oy + " L" + dx + "," + dy)
}

function line2(p1,p2,p3) {
  console.log("M" + p1.x + "," + p1.y + "L" + p2.x + "," + p2.y + "L" + p3.x + "," + p3.y)
	return("M" + p1.x + "," + p1.y + "L" + p2.x + "," + p2.y + "L" + p3.x + "," + p3.y)
}

function curveQ(ox,oy,dx,dy,cx,cy) {
  console.log("M" + ox + "," + oy + " Q" + cx + "," + cy + " " + dx + "," + dy)
	return("M" + ox + "," + oy + " Q" + cx + "," + cy + " " + dx + "," + dy)
}

// Calculate a new point on a line that is xp% of the X distance from m1.x to m2.x

function findPoint(m1, m2, xp) {
  if (Math.abs(m1.attr("cx") - m2.attr("cx")) < .01) { // Vertical Line
  	return ({ "x": m1.attr("cx"), "y": (xp * (m2.attr("cy") - m1.attr("cy"))) + m1.attr("cy")})
  }
  
  var xNew = m1.attr("cx") - (m1.attr("cx") - m2.attr("cx")) * xp;
  var slope = (m1.attr("cy") - m2.attr("cy")) / (m1.attr("cx") - m2.attr("cx"));
  var intcpt = m1.attr("cy") - (slope * m1.attr("cx"));
  var yNew = slope * xNew + intcpt;
  console.log("(" + xNew + "," + yNew + ")")
  return ({"x": xNew, "y": yNew})
}

// Corner drag functions (start, move, up)
var start = function() {
    // storing original coordinates
    this.ox = this.attr("cx");
    this.oy = this.attr("cy");
  },
  move = function(dx, dy) {
    // move will be called with dx and dy
    this.attr({
      cx: this.ox + dx,
      cy: this.oy + dy
    });
    updatebases();
    updatelines();
  },
  up = function() {
    // restoring state
  };
  
function updatebases(){
  var base = findPoint(hpm, lfpm, .8)
  $(tbm.node).attr({ cx: base.x , cy: base.y } );

  base = findPoint(hpm, rfpm, .8)
  $(fbm.node).attr({ cx: base.x , cy: base.y } );

  base = findPoint(hpm, cfm, .78)
  $(sbm.node).attr({ cx: base.x , cy: base.y } );
}  

// Function updates lines between corner circles
function updatelines() {
  $(lfp.node).attr({
    d: "M" + lfpm.attr("cx") + "," + lfpm.attr("cy") +...