HTML Canvas Animation mechanical gears

Description

HTML Canvas Animation mechanical gears

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 w w.  j av a 2s  . c  o  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.getTime = function() {
    return this.t;
  };


  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 Gear(config){
                this.x = config.x;
                this.y = config.y;
                this.outerRadius = config.outerRadius;
                this.innerRadius = config.innerRadius;
                this.holeRadius = config.holeRadius;
                this.numTeeth = config.numTeeth;
                this.theta = config.theta;
                this.thetaSpeed = config.thetaSpeed;
                this.lightColor = config.lightColor;
                this.darkColor = config.darkColor;
                this.clockwise = config.clockwise;
                this.midRadius = config.outerRadius - 10;
            }
            
            Gear.prototype.draw = function(context){
                context.save();
                context.translate(this.x, this.y);
                context.rotate(this.theta);
                
                // draw gear teeth
                context.beginPath();

                context.lineJoin = "bevel";
                
                // loop through the number of points to create the gear shape
                var numPoints = this.numTeeth * 2;
                for (var n = 0; n < numPoints; n++) {
                    var radius = null;
                    
                    if (n % 2 == 0) {
                        radius = this.outerRadius;
                    }

                    else {
                        radius = this.innerRadius;
                    }
                    
                    var theta = ((Math.PI * 2) / numPoints) * (n + 1);
                    var x = (radius * Math.sin(theta));
                    var y = (radius * Math.cos(theta));
                    
                    if (n == 0) {
                        context.moveTo(x, y);
                    }
                    // if any other iteration, use lineTo() to connect sub paths
                    else {
                        context.lineTo(x, y);
                    }
                }
                
                context.closePath();
                
                // define the line width and stroke color
                context.lineWidth = 5;
                context.strokeStyle = this.darkColor;
                context.stroke();
                
                // draw gear body
                context.beginPath();
                context.arc(0, 0, this.midRadius, 0, 2 * Math.PI, false);
                
                // create a linear gradient
                var grd = context.createLinearGradient(-1 * this.outerRadius / 2, -1 * this.outerRadius / 2, this.outerRadius / 2, this.outerRadius / 2);
                grd.addColorStop(0, this.lightColor); 
                grd.addColorStop(1, this.darkColor); 
                context.fillStyle = grd;
                context.fill();
                context.lineWidth = 5;
                context.strokeStyle = this.darkColor;
                context.stroke();
                
                // draw gear hole
                context.beginPath();
                context.arc(0, 0, this.holeRadius, 0, 2 * Math.PI, false);
                context.fillStyle = "white";
                context.fill();
                context.strokeStyle = this.darkColor;
                context.stroke();
                context.restore();
            };
            
            window.onload = function(){
                var anim = new Animation("myCanvas");
                var canvas = anim.getCanvas();
                var context = anim.getContext();
                
                var gears = [];
                
                // add blue gear
                gears.push(new Gear({
                    x: 270,
                    y: 105,
                    outerRadius: 90,
                    innerRadius: 50,
                    holeRadius: 10,
                    numTeeth: 24,
                    theta: 0,
                    thetaSpeed: 1 / 1000,
                    lightColor: "yellow",
                    darkColor: "pink",
                    clockwise: false
                }));
                
                // add red gear
                gears.push(new Gear({
                    x: 372,
                    y: 190,
                    outerRadius: 50,
                    innerRadius: 15,
                    holeRadius: 10,
                    numTeeth: 12,
                    theta: 0.14,
                    thetaSpeed: 2 / 1000,
                    lightColor: "red",
                    darkColor: "blue",
                    clockwise: true
                }));
                
                anim.setDrawStage(function(){
                    // update
                    for (var i = 0; i < gears.length; i++) {
                        var gear = gears[i];
                        var thetaIncrement = gear.thetaSpeed * this.getTimeInterval();
                        gear.theta += gear.clockwise ? thetaIncrement : -1 * thetaIncrement;
                    }
                    
                    // clear
                    this.clear();
                    
                    // draw
                    for (var i = 0; i < gears.length; i++) {
                        gears[i].draw(context);
                    }
                });
                
                anim.start();
            };
</script>
</head>
<body>
  <canvas id="myCanvas" width="600" height="350"
    style="border: 1px solid black;">
        </canvas>
</body>
</html>



PreviousNext

Related