Dot.Animator

Settings

51 x 51

100 ms

Random Dots

This animation draws randomly dots to the canvas.

Start | Stop | Clear

Game Of Life

Rules

For a space that is 'populated':

  • Each cell with one or no neighbors dies, as if by loneliness.
  • Each cell with four or more neighbors dies, as if by overpopulation.
  • Each cell with two or three neighbors survives.
For a space that is 'empty' or 'unpopulated'
  • Each cell with three neighbors becomes populated.
Wiki Page

0

Next | Start | Stop | Reset

Langton's Ant

Rules

Squares on a plane are colored variously either black or white. We arbitrarily identify one square as the "ant". The ant can travel in any of the four cardinal directions at each step it takes. The ant moves according to the rules below:

  • At a white square, turn 90° right, flip the color of the square, move forward one unit
  • At a black square, turn 90° left, flip the color of the square, move forward one unit
Wiki Page

0

Next | Start | Stop | Reset

Current Animation: none

Source Code (download)

di-gui.js

GUI script handles current selected animation, redraws the dot matrix, handles mouse input for dot matrix, handles settings panel actions and initializes animations.

  1. var lastDotX;
  2. var lastDotY;
  3. var isMouseDown = false
  4.  
  5. $(document).ready(function() {
  6.     init();
  7.  
  8.     $('.accordion#programms').accordion({
  9.         header: 'h3',
  10.         autoHeight: false
  11.     });
  12.  
  13.     $('#slider-grid-size').slider({
  14.         value: 10,
  15.         min: 5,
  16.         max: 15,
  17.         step: 5,
  18.         slide: function(event, ui) {
  19.             stopAnimation();
  20.             ctxGrid.clearRect(0, 0, cvsWidth, cvsHeight);
  21.             clear();
  22.  
  23.             cellSize = ui.value;
  24.             createGrid();
  25.  
  26.             $('#grid-size-label').html(510 / ui.value + ' x ' + 510 / ui.value);
  27.         }
  28.     });
  29.  
  30.     $('#slider-interval').slider({
  31.         value: 100,
  32.         min: 10,
  33.         max: 500,
  34.         step: 10,
  35.         slide: function(event, ui) {
  36.             stopAnimation();
  37.             clear();
  38.             interval = ui.value;
  39.  
  40.             $('#interval-label').html(ui.value + ' ms');
  41.         }
  42.     });
  43.  
  44.     $('#canvas-area').mousedown(function(e) {
  45.         isMouseDown = true;
  46.  
  47.         var x = Math.floor((e.pageX - this.offsetLeft) / cellSize);
  48.         var y = Math.floor((e.pageY - this.offsetTop) / cellSize);
  49.         canvasClickedAt(x, y);
  50.  
  51.     }).mouseup(function() {
  52.         isMouseDown = false;
  53.     }).mousemove(function(e) {
  54.         if (isMouseDown) {
  55.             var x = Math.floor((e.pageX - this.offsetLeft) / cellSize);
  56.             var y = Math.floor((e.pageY - this.offsetTop) / cellSize);
  57.  
  58.             if (lastDotX != x || lastDotY != y) {
  59.                 canvasClickedAt(x, y);
  60.                 lastDotX = x;
  61.                 lastDotY = y;
  62.             }
  63.         }
  64.     });
  65.  
  66.     function canvasClickedAt(x, y) {
  67.         if (isDot(x, y))
  68.             clearDot(x, y);
  69.         else
  70.             setDot(x, y);
  71.     }
  72.  
  73.     $('.stop-animation').click(function() {
  74.         $('#current-animation').html('none');
  75.         stopAnimation();
  76.     });
  77.  
  78.     $('.clear-grid').click(function() {
  79.         clear();
  80.     });
  81.  
  82.     // init animation guis
  83.     initRandomAnimationGui();
  84.     initGameOfLifeGui();
  85.     initLangtonsAntGui();
  86. });

di-lib.js

Dot Matrix Library script handles the drawing of the dots int the matrix; it runs animations. It provides functions like clearing the matrix, drawing dots, checking if dots are set on specific coordinates and so on. To do this the script uses HTML 5 canvas tag.

  1. var cellSize = 10;    // px
  2. var interval = 100;   // miliseconds
  3.  
  4. var ctxDots;
  5. var ctxGrid;
  6. var gridWidth;
  7. var gridHeight;
  8. var cvsWidth;
  9. var cvsHeight;
  10. var dots;
  11. var intervalId = null;
  12.  
  13. const dirUp = 0;
  14. const dirRight = 1;
  15. const dirDown = 2;
  16. const dirLeft = 3;
  17.  
  18. function init() {
  19.     ctxDots = $('#canvas-dots')[0].getContext("2d");
  20.     ctxGrid = $('#canvas-grid')[0].getContext("2d");
  21.    
  22.     cvsWidth = $("#canvas-dots").width();
  23.     cvsHeight = $("#canvas-dots").height();
  24.    
  25.     createGrid();
  26. }
  27.  
  28. function createGrid() {
  29.     gridWidth = cvsWidth / cellSize;
  30.     gridHeight = cvsHeight / cellSize;
  31.  
  32.     dots = new Array(gridWidth);
  33.     for (var x = 0; x < gridWidth; x++) {
  34.         dots[x] = new Array(gridHeight);
  35.         for (var y = 0; y < gridHeight; y++) {
  36.             dots[x][y] = false;
  37.         }
  38.     }
  39.  
  40.     drawGrid();
  41. }
  42.  
  43. function stopAnimation() {
  44.     clearInterval(intervalId);
  45.     intervalId = null;
  46. }
  47.  
  48. function runAnimation(a) {
  49.     if (intervalId != null) {
  50.         stopAnimation();
  51.     }
  52.     //clear();
  53.     intervalId = setInterval(a, interval);
  54. }
  55.  
  56. function clear() {
  57.     ctxDots.clearRect(0, 0, cvsWidth, cvsHeight);
  58.  
  59.     for(var x = 0; x < gridWidth; x++) {
  60.         for (var y = 0; y < gridHeight; y++) {
  61.             dots[x][y] = false;
  62.         }
  63.     }
  64. }
  65.    
  66. function setDot(x, y) {
  67.     ctxDots.fillRect(x * cellSize, y * cellSize, cellSize, cellSize);
  68.     dots[x][y] = true;
  69. }
  70.  
  71. function clearDot(x, y) {
  72.     ctxDots.clearRect(x * cellSize, y * cellSize, cellSize, cellSize);
  73.     dots[x][y] = false;
  74. }
  75.  
  76. function getDotCoordsByDir(x, y, d) {
  77.     if (d == 0) y--;
  78.     else if (d == 1) x++;
  79.     else if (d == 2) y++;
  80.     else x--;
  81.  
  82.     if (x < 0) x = 0;
  83.     if (x >= gridWidth) x = gridWidth - 1;
  84.     if (y < 0) y = 0;
  85.     if (y >= gridHeight) y = gridHeight - 1;
  86.  
  87.     return new Array(x, y);
  88. }
  89.  
  90. function isDot(x, y) {
  91.     if (x < 0 || x >= gridWidth || y < 0 || y >= gridHeight)
  92.         return false;
  93.        
  94.     return dots[x][y];
  95. }
  96.  
  97. function drawGrid() {
  98.     ctxGrid.strokeStyle = '#ccc';
  99.     ctxGrid.lineWidth = 0.5;
  100.          
  101.     for (var x = 0; x <= cvsWidth; x += cellSize) {
  102.         drawLine(x, 0, x, cvsHeight);
  103.     }
  104.    
  105.     for (var y = 0; y <= cvsHeight; y += cellSize) {
  106.         drawLine(0, y, cvsWidth, y);
  107.     }
  108. }
  109.  
  110. function drawLine(xStart, yStart, xEnd, yEnd) {
  111.     ctxGrid.beginPath();
  112.     ctxGrid.moveTo(xStart, yStart);
  113.     ctxGrid.lineTo(xEnd, yEnd);
  114.     ctxGrid.closePath();
  115.     ctxGrid.stroke();
  116. }

di-random.js

Simple script drawing random dots in the dot matrix

  1. function initRandomAnimationGui() {
  2.     $('#start-random').click(function() {
  3.         $('#current-animation').html('Random Dots');
  4.         runAnimation(drawRandomAnimation);
  5.     });
  6. }
  7.  
  8. function drawRandomAnimationInit() {
  9.     alert('drawRandomAnimation begin to run!');
  10. }
  11.  
  12. function drawRandomAnimation() {
  13.     setDot(Math.floor(Math.random() * gridWidth), Math.floor(Math.random() * gridHeight));
  14.     clearDot(Math.floor(Math.random() * gridWidth), Math.floor(Math.random() * gridHeight));
  15. }

di-game-of-life.js

This script provides Conway's Game of Life animation (Wiki Entry)

  1. function initGameOfLifeGui() {
  2.     $('select#gol-start-shape').change(function() {
  3.         var centerX = Math.floor(gridWidth / 2);
  4.         var centerY = Math.floor(gridHeight / 2);
  5.         clear();
  6.  
  7.         switch (this.value) {
  8.             case '1': // glider
  9.                 setDot(centerX, centerY - 1);
  10.                 setDot(centerX + 1, centerY);
  11.                 setDot(centerX - 1, centerY + 1);
  12.                 setDot(centerX, centerY + 1);
  13.                 setDot(centerX + 1, centerY + 1);
  14.                 break;
  15.             case '2': // small exploder
  16.                 setDot(centerX, centerY - 1);
  17.                 setDot(centerX, centerY);
  18.                 setDot(centerX - 1, centerY);
  19.                 setDot(centerX + 1, centerY);
  20.                 setDot(centerX - 1, centerY + 1);
  21.                 setDot(centerX + 1, centerY + 1);
  22.                 setDot(centerX, centerY + 2);
  23.                 break;
  24.             case '3': // exploder
  25.                 setDot(centerX, centerY - 2);
  26.                 setDot(centerX, centerY + 2);
  27.                 setDot(centerX - 2, centerY - 2);
  28.                 setDot(centerX - 2, centerY - 1);
  29.                 setDot(centerX - 2, centerY);
  30.                 setDot(centerX - 2, centerY + 1);
  31.                 setDot(centerX - 2, centerY + 2);
  32.                 setDot(centerX + 2, centerY - 2);
  33.                 setDot(centerX + 2, centerY - 1);
  34.                 setDot(centerX + 2, centerY);
  35.                 setDot(centerX + 2, centerY + 1);
  36.                 setDot(centerX + 2, centerY + 2);
  37.                 break;
  38.             case '4': // 10 cell row
  39.                 setDot(centerX - 4, centerY);
  40.                 setDot(centerX - 3, centerY);
  41.                 setDot(centerX - 2, centerY);
  42.                 setDot(centerX - 1, centerY);
  43.                 setDot(centerX, centerY);
  44.                 setDot(centerX + 1, centerY);
  45.                 setDot(centerX + 2, centerY);
  46.                 setDot(centerX + 3, centerY)
  47.                 setDot(centerX + 4, centerY);
  48.                 setDot(centerX + 5, centerY);
  49.                 break;
  50.             case '5': // lightweight spaceship
  51.                 setDot(centerX - 1, centerY - 2);
  52.                 setDot(centerX, centerY - 2);
  53.                 setDot(centerX + 1, centerY - 2);
  54.                 setDot(centerX + 2, centerY - 2);
  55.                 setDot(centerX + 2, centerY - 1);
  56.                 setDot(centerX + 2, centerY);
  57.                 setDot(centerX - 2, centerY - 1);
  58.                 setDot(centerX - 2, centerY + 1);
  59.                 setDot(centerX + 1, centerY + 1);
  60.                 break;
  61.             case '6': // tumbler
  62.                 setDot(centerX - 2, centerY - 2);
  63.                 setDot(centerX - 2, centerY - 1);
  64.                 setDot(centerX - 1, centerY - 2);
  65.                 setDot(centerX - 1, centerY - 1);
  66.                 setDot(centerX - 1, centerY);
  67.                 setDot(centerX - 1, centerY + 1);
  68.                 setDot(centerX - 1, centerY + 2);
  69.                 setDot(centerX - 2, centerY + 3);
  70.                 setDot(centerX - 3, centerY + 3);
  71.                 setDot(centerX - 3, centerY + 2);
  72.                 setDot(centerX - 3, centerY + 1);
  73.                 setDot(centerX + 2, centerY - 2);
  74.                 setDot(centerX + 2, centerY - 1);
  75.                 setDot(centerX + 1, centerY - 2);
  76.                 setDot(centerX + 1, centerY - 1);
  77.                 setDot(centerX + 1, centerY);
  78.                 setDot(centerX + 1, centerY + 1);
  79.                 setDot(centerX + 1, centerY + 2);
  80.                 setDot(centerX + 2, centerY + 3);
  81.                 setDot(centerX + 3, centerY + 3);
  82.                 setDot(centerX + 3, centerY + 2);
  83.                 setDot(centerX + 3, centerY + 1);
  84.                 break;
  85.             case '7': // gosper glider gun
  86.                 setDot(centerX - 17, centerY - 4);
  87.                 setDot(centerX - 17, centerY - 5);
  88.                 setDot(centerX - 18, centerY - 4);
  89.                 setDot(centerX - 18, centerY - 5);
  90.                 setDot(centerX - 10, centerY - 4);
  91.                 setDot(centerX - 10, centerY - 3);
  92.                 setDot(centerX - 9, centerY - 3);
  93.                 setDot(centerX - 9, centerY - 5);
  94.                 setDot(centerX - 8, centerY - 5);
  95.                 setDot(centerX - 8, centerY - 4);
  96.                 setDot(centerX - 2, centerY - 3);
  97.                 setDot(centerX - 2, centerY - 2);
  98.                 setDot(centerX - 2, centerY - 1);
  99.                 setDot(centerX - 1, centerY - 3);
  100.                 setDot(centerX, centerY - 2);
  101.                 setDot(centerX + 4, centerY - 5);
  102.                 setDot(centerX + 4, centerY - 6);
  103.                 setDot(centerX + 5, centerY - 5);
  104.                 setDot(centerX + 5, centerY - 7);
  105.                 setDot(centerX + 6, centerY - 7);
  106.                 setDot(centerX + 6, centerY - 6);
  107.                 setDot(centerX + 16, centerY - 7);
  108.                 setDot(centerX + 17, centerY - 7);
  109.                 setDot(centerX + 16, centerY - 6);
  110.                 setDot(centerX + 17, centerY - 6);
  111.  
  112.                 setDot(centerX + 17, centerY + 0);
  113.                 setDot(centerX + 17, centerY + 1);
  114.                 setDot(centerX + 17, centerY + 2);
  115.                 setDot(centerX + 18, centerY);
  116.                 setDot(centerX + 19, centerY + 1);
  117.  
  118.                 setDot(centerX + 6, centerY + 5);
  119.                 setDot(centerX + 7, centerY + 5);
  120.                 setDot(centerX + 8, centerY + 5);
  121.                 setDot(centerX + 6, centerY + 6);
  122.                 setDot(centerX + 7, centerY + 7);
  123.  
  124.                 break;
  125.             default: // nop                    
  126.         }
  127.     });
  128.  
  129.     $('#gol-next').click(function() {
  130.         $('#current-animation').html('Game Of Life');
  131.         initGameOfLifeAnimation();
  132.         drawGameOfLifeAnimation();
  133.     });
  134.  
  135.     $('#gol-start').click(function() {
  136.         $('#current-animation').html('Game Of Life');
  137.         initGameOfLifeAnimation();
  138.         runAnimation(drawGameOfLifeAnimation);
  139.     });
  140.  
  141.     $('#gol-reset').click(function() {
  142.         $('#current-animation').html('Game Of Life');
  143.         golInit = false;
  144.         stopAnimation();
  145.         clear();
  146.     });
  147. }
  148.  
  149. var golGenerations = 0;
  150. var golInit = false;
  151.  
  152. function initGameOfLifeAnimation() {
  153.     if (golInit == true) {
  154.         return;
  155.     }
  156.  
  157.     golGenerations = 0;
  158.     golInit = true;
  159. }
  160.  
  161. function drawGameOfLifeAnimation() {
  162.     newGrid = new Array(gridWidth);
  163.     for (var x = 0; x < gridWidth; x++) {
  164.         newGrid[x] = new Array(gridHeight);
  165.         for (var y = 0; y < gridHeight; y++) {
  166.             newGrid[x][y] = false;
  167.         }
  168.     }
  169.  
  170.     for (var x = 0; x < gridWidth; x++) {
  171.         for (var y = 0; y < gridHeight; y++) {
  172.             var neighbors = getNeighborCount(x, y);
  173.  
  174.             if (dots[x][y] == true) {
  175.                 newGrid[x][y] = (neighbors == 2 || neighbors == 3);
  176.             }
  177.             else {
  178.                 newGrid[x][y] = (neighbors == 3);
  179.             }
  180.         }
  181.     }
  182.  
  183.     clear();
  184.     for (var x = 0; x < gridWidth; x++) {
  185.         for (var y = 0; y < gridHeight; y++) {
  186.             if (newGrid[x][y] == true) {
  187.                 setDot(x, y);
  188.             }
  189.         }
  190.     }
  191.  
  192.     $('#gol-generations').html(golGenerations.toString());
  193.     golGenerations++;
  194.  
  195.     if (golGenerations > 10000)
  196.         stopAnimation();
  197. }
  198.  
  199. function getNeighborCount(x, y) {
  200.     var count = 0;
  201.  
  202.     if (isDot(x - 1, y - 1)) count++;
  203.     if (isDot(x, y - 1)) count++;
  204.     if (isDot(x + 1, y - 1)) count++;
  205.     if (isDot(x + 1, y)) count++;
  206.     if (isDot(x + 1, y + 1)) count++;
  207.     if (isDot(x, y + 1)) count++;
  208.     if (isDot(x - 1, y + 1)) count++;
  209.     if (isDot(x - 1, y)) count++;
  210.  
  211.     return count;
  212. }

di-langtons-ant.js

This script provides Langton's ant animation (Wiki Entry)

  1. function initLangtonsAntGui() {
  2.     $('#ant-next').click(function() {
  3.         $('#current-animation').html("Langton's Ant");
  4.         initLangtonsAntAnimation();
  5.         drawLangtonsAntAnimation();
  6.     });
  7.  
  8.     $('#ant-start').click(function() {
  9.         $('#current-animation').html("Langton's Ant");
  10.         initLangtonsAntAnimation();
  11.         runAnimation(drawLangtonsAntAnimation);
  12.     });
  13.  
  14.     $('#ant-reset').click(function() {
  15.         $('#current-animation').html("Langton's Ant");
  16.         antInit = false;
  17.         stopAnimation();
  18.         clear();
  19.     });
  20. }
  21.  
  22. var antSteps = 0;
  23. var antInit = false;
  24. var antPos;
  25. var antDir;
  26.  
  27. function initLangtonsAntAnimation() {
  28.     if (antInit == true) {
  29.         return;
  30.     }
  31.  
  32.     antSteps = 0;
  33.     antDir = $('#ant-direction').val();
  34.     antPos = new Array(Math.floor(gridWidth / 2), Math.floor(gridHeight / 2));
  35.     antInit = true;
  36. }
  37.  
  38. function getAntDirection(dir, toRight) {
  39.     var rtn = dir;
  40.  
  41.     if (toRight) {
  42.         rtn++
  43.         if (rtn > 3) rtn = 0;
  44.     }
  45.     else {
  46.         rtn--
  47.         if (rtn < 0) rtn = 3;
  48.     }
  49.  
  50.     return rtn;
  51. }
  52.  
  53. function drawLangtonsAntAnimation() {
  54.     antPos = getDotCoordsByDir(antPos[0], antPos[1], antDir);
  55.  
  56.     if (isDot(antPos[0], antPos[1])) {
  57.         clearDot(antPos[0], antPos[1]);
  58.         antDir = getAntDirection(antDir, false);
  59.     }
  60.     else {
  61.         setDot(antPos[0], antPos[1]);
  62.         antDir = getAntDirection(antDir, true);
  63.     }
  64.  
  65.     $('#ant-steps').html(antSteps.toString());
  66.     antSteps++;
  67.  
  68.     if (antSteps > 13000)
  69.         stopAnimation();
  70. }