HTML Canvas Animation Microscopic life

Description

HTML Canvas Animation Microscopic life

View in separate window

<!DOCTYPE HTML>
<html>
<head>
<script>
  var Animation = function(canvasId) {
    this.canvas = document.getElementById(canvasId);
    this.context = this.canvas.getContext("2d");
    this.t = 0;/*from  w  ww. j a  va  2 s .co  m*/
    this.timeInterval = 0;
    this.startTime = 0;
    this.lastTime = 0;
    this.frame = 0;
    this.animating = false;

    // provided by Paul Irish
    window.requestAnimFrame = (function(callback) {
      return window.requestAnimationFrame
          || window.webkitRequestAnimationFrame
          || window.mozRequestAnimationFrame
          || window.oRequestAnimationFrame
          || window.msRequestAnimationFrame || function(callback) {
            window.setTimeout(callback, 1000 / 60);
          };
    })();
  };

  Animation.prototype.getContext = function() {
    return this.context;
  };

  Animation.prototype.getCanvas = function() {
    return this.canvas;
  };

  Animation.prototype.clear = function() {
    this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
  };

  Animation.prototype.setDrawStage = function(func) {
    this.drawStage = func;
  };

  Animation.prototype.getFrame = function() {
    return this.frame;
  };

  Animation.prototype.start = function() {
    this.animating = true;
    var date = new Date();
    this.startTime = date.getTime();
    this.lastTime = this.startTime;

    if (this.drawStage !== undefined) {
      this.drawStage();
    }

    this.animationLoop();
  };

  Animation.prototype.stop = function() {
    this.animating = false;
  };
  Animation.prototype.getTimeInterval = function() {
    return this.timeInterval;
  };
    Animation.prototype.getFps = function(){
        return this.timeInterval > 0 ? 1000 / this.timeInterval : 0;
    };

  Animation.prototype.animationLoop = function() {
    var that = this;

    this.frame++;
    var date = new Date();
    var thisTime = date.getTime();
    this.timeInterval = thisTime - this.lastTime;
    this.t += this.timeInterval;
    this.lastTime = thisTime;

    if (this.drawStage !== undefined) {
      this.drawStage();
    }

    if (this.animating) {
      requestAnimFrame(function() {
        that.animationLoop();
      });
    }
  };
            
            function getRandTheta(){
                return Math.random() * 2 * Math.PI;
            }
            
            function updateMicrobes(anim, microbes){
                var canvas = anim.getCanvas();
                var angleVariance = 0.2;
                
                for (var i = 0; i < microbes.length; i++) {
                    var microbe = microbes[i];
                    var angles = microbe.angles;
                    
                    var numNewSegmentsPerFrame = 10;
                    
                    for (var n = 0; n < numNewSegmentsPerFrame; n++) {
                        // create first angle if no angles
                        if (angles.length == 0) {
                            microbe.headX = canvas.width / 2;
                            microbe.headY = canvas.height / 2;
                            angles.push(getRandTheta());
                        }
                        
                        var headX = microbe.headX;
                        var headY = microbe.headY;
                        var headAngle = angles[angles.length - 1];
                        
                        // create new head angle
                        var dist = anim.getTimeInterval() / (10 * numNewSegmentsPerFrame);
                        // increase new head angle by an amount equal to

                        var newHeadAngle = headAngle + ((angleVariance / 2) - Math.random() * angleVariance);
                        var newHeadX = headX + dist * Math.cos(newHeadAngle);
                        var newHeadY = headY + dist * Math.sin(newHeadAngle);
                        
                        if (newHeadX >= canvas.width || newHeadX <= 0 || newHeadY >= canvas.height || newHeadY <= 0) {
                            newHeadAngle += Math.PI / 2;
                            newHeadX = headX + dist * Math.cos(newHeadAngle);
                            newHeadY = headY + dist * Math.sin(newHeadAngle);
                        }
                        
                        microbe.headX = newHeadX;
                        microbe.headY = newHeadY;
                        angles.push(newHeadAngle);
                        
                        if (angles.length > 20) {
                            angles.shift();
                        }
                    }
                }
            }
            
            function drawMicrobes(anim, microbes){
                var segmentLength = 2; // px
                var context = anim.getContext();
                
                for (var i = 0; i < microbes.length; i++) {
                    var microbe = microbes[i];
                    
                    var angles = microbe.angles;
                    context.beginPath();
                    context.moveTo(microbe.headX, microbe.headY);
                    
                    var x = microbe.headX;
                    var y = microbe.headY;
                    
                    // start with the head and end with the tail
                    for (var n = angles.length - 1; n >= 0; n--) {
                        var angle = angles[n];
                        
                        x -= segmentLength * Math.cos(angle);
                        y -= segmentLength * Math.sin(angle);
                        context.lineTo(x, y);
                    }
                    
                    context.lineWidth = 20;
                    context.lineCap = "round";
                    context.lineJoin = "round";
                    context.strokeStyle = microbe.color;
                    context.stroke();
                }
            }
            
            window.onload = function(){
                var anim = new Animation("myCanvas");
                var canvas = anim.getCanvas();
                var context = anim.getContext();
                
                // init microbes
                var microbes = [];
                for (var n = 0; n < 10; n++) {
                    microbes[n] = {
                        headX: 300,
                        headY: 40,
                        angles: [],
                        color: "blue"
                    };
                }
                
                anim.setDrawStage(function(){
                    // update
                    updateMicrobes(this, microbes);
                    
                    // clear
                    this.clear();
                    
                    // draw
                    drawMicrobes(this, microbes);
                });
                
                anim.start();
            };

</script>
</head>
<body>
  <canvas id="myCanvas" width="600" height="350"
    style="border: 1px solid black;">
        </canvas>
</body>
</html>



PreviousNext

Related