JSFiddle - React, Tailwind, and code Playground

by yahyaKACEM

HTML

<div ng-app="balls" ng-controller="bounce">
  <div class="balls">
      <div ng-repeat="ball in balls"
           ball-position="ball"></div>
  </div>
  <div>
    <div class="fps-bar"><div class="fps" ng-style="{width:fps*4 + 'px'}"></div></div>
  </div>      
  {{fps | number:1}} fps. ({{balls.length}} balls) <br>
  <a href ng-click="changeCount(1)">+1</a> 
  <a href ng-click="changeCount(10)">+10</a> 
  <a href ng-click="changeCount(100)">+100</a> 
  <br>
  <a href ng-click="changeCount(-1)">-1</a> 
  <a href ng-click="changeCount(-10)">-10</a> 
  <a href ng-click="changeCount(-100)">-100</a> 
</div>

CSS

.balls {
  border: 1px solid black;
  width: 420px;
  height: 420px;
  margin: 5px;
}

.ball {
    display: inline-block;
    position: absolute;
    width: 20px;
    height: 20px;
    border: 1px solid black;
    -webkit-border-radius: 10px;
    -moz-border-radius: 10px;
    border-radius: 10px;
}

.fps-bar {
  width: 200px;
  height: 10px;
  border: 1px solid black;
  display: inline-block;
  margin-left: 5px;
}

.fps {
  height: 10px;
  width: 60px;
  background-color: green;
}

JavaScript

angular.module('balls', []).
    directive('ballPosition', function() {
        return function(scope, element, attrs) {
            element.addClass('ball');
            var ball = scope[attrs.ballPosition];
            element.css('backgroundColor', ball.color);
            scope.$watch(function() {
                element.css({
                    left: (ball.x + 5) + 'px',
                    top: (ball.y + 5) + 'px'
                });
            });
        };
    }).
    factory('animFrame', function($rootScope) {
      var animFrame = 
              window.requestAnimationFrame       || 
              window.webkitRequestAnimationFrame || 
              window.mozRequestAnimationFrame    || 
              window.oRequestAnimationFrame      || 
              window.msRequestAnimationFrame     || 
              function( callback ){
                window.setTimeout(callback, 1000 / 60);
              };
        return function(fn) {
          animFrame(function(){
            $rootScope.$apply(fn);
          });
        }
    }).
    controller('bounce', function($scope, animFrame) {
        var width = 400;
        var height = 400;
        var speed = .5;
        var lastTime = new Date().getTime();
        
        function color() {
          var color = '#',
              i = 6;
      
          while(i--) {
            color += Number(Math.floor(16 * Math.random())).toString(16);
          }
          return color;
        }
        
        $scope.balls = [];
        
        $scope.changeCount = function(count) {
            while(count>0) {
                $scope.balls.push({
                    x: width * Math.random(),
                    y: height * Math.random(),
                    velX: 2*speed * Math.random() - speed,
                    velY: 2*speed * Math.random() - speed,
                    color: color()
                });
                count--;
            }
            while(count<0) {
                $scope.balls.pop();
       ...