JSFiddle - React, Tailwind, and code Playground

by apimenov93

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.16/d3.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/css/bootstrap.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/js/bootstrap.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-beta1/jquery.js"></script>
<title>
  Bouncing Balls</title>
<body style="background-color:#111">

  <div class="row">
    <div class="btn-group">
      <label class="btn btn-primary" onclick="onGroup()" id="group-button">
        Group
      </label>
      <label class="btn btn-primary" onClick="OnNumberOfBallsChanged()">
        Add
      </label>
    </div>
  </div>

  <div id="mainDiv" style="width:1400px; height:710px">
    <div id="drawAreaOuter" style="width:100%; height:100%;  ">
      <div id="drawArea" style="width:100%; height:100%; background-color:#222; border:5px solid #333;">
      </div>
    </div>
  </div>


</body>

CSS

body {
   background-color: black;
   padding-left: 30px;
 }
 
 circle {
   stroke: white;
   stroke-width: 0px;
   opacity: .8;
 }
 
 .btn-group {
   margin: 20px;
 }
 
 .btn-group label {
   width: 80px;
 }
 
 .label {
   fill: white;
   font-size: 16px;
 }

JavaScript

// Ball object - multiple balls can be created by instantiating new objects

function Ball(svg, x, y, id, color, aoa, weight) {
    this.x = x; // cx
    this.y = y; // cy
    this.color = color;
    this.radius = weight; // radius and weight same
    this.jumpSize = 1.5; // equivalent of speed default to 1
    this.svg = svg; // parent SVG
    this.id = id; // id of ball
    this.aoa = aoa; // initial angle of attack
    this.weight = weight;

    if (!this.aoa)
        this.aoa = Math.PI / 7;
    if (!this.weight)
        this.weight = 10;
    this.radius = this.weight;

    var circle_data = {};
    // circle_data.id = this.id;
    // circle_data.x = this.x;
    // circle_data.y = this.y;
    // circle_data.radius = this.radius;
    circle_data = this;

    var data_arr = new Array();
    data_arr.push(circle_data);

    //this.data = [this.id]; // allow us to use d3.enter()
    this.data = data_arr;

    var thisobj = this; // i like to use thisobj instead of this. this many times not reliable particularly handling evnet

    // **** aoa is used only here -- earlier I was using to next move position.
    // Now aoa and speed together is velocity
    this.vx = Math.cos(thisobj.aoa) * thisobj.jumpSize; // velocity x
    this.vy = Math.sin(thisobj.aoa) * thisobj.jumpSize; // velocity y
    this.initialVx = this.vx;
    this.initialVy = this.vy;
    this.initialx = this.x;
    this.initialy = this.y;

    // when speed changes, go to initial setting
    this.GoToInitialSettings = function(newjumpSize) {
        thisobj.x = thisobj.initialx;
        thisobj.y = thisobj.initialy;
        thisobj.vx = Math.cos(thisobj.aoa) * newjumpSize; // velocity x
        thisobj.vy = Math.sin(thisobj.aoa) * newjumpSize; // velocity y
        thisobj.Draw();
    }

    this.Draw = function() {
        var svg = thisobj.svg;
        var ball = svg.selectAll('#' + thisobj.id)
            .data(thisobj.data);
        ball.enter()
            .append("circle")
            .attr({
  ...