Events

The HTML file:

<html>
<head>

<script id="vertex-shader" type="x-shader/x-vertex" >
attribute vec4 vPosition;
uniform float percent;

varying vec4 f_Color;

void main() {
    float scale = 1.0+percent;

    gl_Position = vec4(vPosition.x, vPosition.y,0.0,1.0/scale);
    f_Color = vec4(1.0, 0.0, 0.0, 1.0);
}
</script>

<script id="fragment-shader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 f_Color;

void main() {
    gl_FragColor = f_Color;
}
</script>

<script type="text/javascript" src="../Common/webgl-utils.js"></script>
<script type="text/javascript" src="../Common/initShaders.js"></script>
<script type="text/javascript" src="../Common/MV.js"></script>
<script type="text/javascript" src="hb1.js"></script>
<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>

<style>
canvas{
    display:block;
    border:2px solid #0094ff;
}
</style>
</head>

<body>
<h1>Events</h1>

<script>
    var canvas1 = new Canvas(500, 500);
    canvas1.Redisplay();
</script>

<button type="button" onclick="canvas1.ChangeAnimation()">Thump BIG</button>
<script>
    var canvas2 = new Canvas(200, 200);
    canvas2.Redisplay();
</script>

</body>

The Javascript file:

function MakeCanvas(width, height, locID) {

    if (width == undefined || width < 0) {
       width = 300;
    }

    if (height == undefined || height < 0) {
       height = 300;
    }

    var canvas = document.createElement('canvas')
        // allow the canvas to take a focus.
        canvas.tabIndex = 0;
        canvas.height = height;
        canvas.width = width;

    if(locID == undefined) {
        document.body.appendChild(canvas);
    } else {
        div = document.getElementById(locID);
        if (null == div) {
            document.body.appendChild(canvas);
        } else {
            div.appendChild(canvas);
        }
    }

    document.body.appendChild(canvas);
    return canvas;
}

function InitGL(canvas) {
    var gl = WebGLUtils.setupWebGL(canvas);
    if (!gl) {
        alert ("WebGL isn't available");
    }

    return gl;
}

function Canvas(width, height, locID) {
    var canvas = MakeCanvas(width, height, locID);

    this.canvas = canvas;
    this.gl = InitGL(canvas);

    var gl = this.gl;

    // I need to pass this to events, but it will have a different value when
    // I actually call it, so save this.
    var tmpCanvas = this;

    // where am I in relationship to the main window.  
    this.x = canvas.offsetLeft;
    this.y = canvas.offsetTop;

    // new in this code, register event handlers that can take parameters
    window.addEventListener("focus",FocusFunc);

    canvas.addEventListener("focus",
         function( evnt) {
	    tmpCanvas.FocusFun(tmpCanvas, evnt)
	 }
    );

    canvas.addEventListener("click", 
         function(evnt) {
	    tmpCanvas.ClickFunc(tmpCanvas, evnt);
	 }
    );

    canvas.addEventListener("keypress",
         function(evnt) {
	    tmpCanvas.KeyFunc(tmpCanvas, evnt);
	 }
    );

    gl.viewport(0,0, width, height);

    program = initShaders(gl, "vertex-shader","fragment-shader");
    gl.useProgram(program);

    this.vBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, this.vBuffer);

    var vPosition = gl.getAttribLocation(program, "vPosition");
    gl.vertexAttribPointer(vPosition,2,gl.FLOAT, false,0,0);
    gl.enableVertexAttribArray(vPosition);

    this.k = 5;
    this.MakePoints();
    gl.bufferData(gl.ARRAY_BUFFER,flatten(this.vertex),gl.STATIC_DRAW);

    this.pctLoc = gl.getUniformLocation(program, "percent");
    this.pct = 0;
    this.pctStep = 0.05;
    gl.uniform1f(this.pctLoc, this.pct);

    this.animationState = false;
    this.gl.clearColor(1.0, 1.0, 1.0, 1.0);

    this._Listener();

    return this;
}

Canvas.prototype = {

    MakePoints: function(){
        var theta, r = .6;
	
        var data = [];
	i = 0;
	for(theta = 0; theta < 2*Math.PI;  theta += Math.PI/100) {
	    var x = r*Math.cos(this.k*theta)*Math.cos(theta)
	    var y = r*Math.cos(this.k*theta)*Math.sin(theta);
	    vertex = [x,y];
	    data.push(vertex);
	}
	this.vertex = data;

	return;
    },

    ChangeAnimation: function() {
	this.animationState = !this.animationState; 
	if (this.animationState) {
	   this.timerID = setInterval(this.AutomatedAnimationStep,1,this);
	} else {
	   clearInterval(this.timerID);
	}
    },

    AutomatedAnimationStep: function(me) {
        me.AnimationStep();
    },

    AnimationStep: function() {
        this.pct += this.pctStep;

	if (this.pct >= 1.0) {
	   this.pct = 1.0;
	   this.pctStep *= -1;
	}

	if (this.pct <= 0.0) {
	   this.pct = 0.0;
	   this.pctStep *= -1;
	}

	if (this.pct == 0) {
	   this.ChangeAnimation();
	}

        this.gl.uniform1f(this.pctLoc, this.pct);
	this.Redisplay();
    },

    Redisplay: function() {
        this.gl.clear(this.gl.COLOR_BUFFER_BIT);

	this.gl.drawArrays(this.gl.LINE_LOOP, 0, this.vertex.length);
        return;
    },

    // callbacks
    FocusFun: function(me, evnt) {
        console.log("Canvas got focus and pctStep is ", me.pctStep);
	console.log("\t the event type is ", evnt.type);
    },

    ClickFunc: function (me, evnt) {
      var x = evnt.clientX-me.x;
      var y = evnt.clientY-me.y
      console.log("In mousepress, Real", x, y);
      console.log("\t\t raw", evnt.clientX, evnt.clientY);

      me.ChangeAnimation();
    },

    _Listener: function(evnt) {
       if (typeof arguments.callee.me == 'undefined') {
          arguments.callee.me = this;
       } 

       if (typeof evnt != "undefined") {
          arguments.callee.me.MouseFunc(arguments.callee.me, evnt);
       }
    },

    MouseFunc: function(me, evnt) {
      var x = evnt.clientX-me.x;
      var y = evnt.clientY-me.y
      console.log("Mickey Says ",x, y);
    },

    KeyFunc: function(me, evnt) {
          console.log("A Keydown '"+ evnt.key + "'");

          if(evnt.altKey) {
             console.log("\tThe alt key was pressed");
          }

          if(evnt.shiftKey) {
             console.log("\tThe shift key was pressed");
          }

          switch(evnt.key) {
              case 'a':
              case 'A': me.ChangeAnimation();
                   break;
	      case 'M':
                  me.canvas.addEventListener("mousemove",this._Listener);
                  break;
	      case 'm':
                  me.canvas.removeEventListener("mousemove",this._Listener);
                  break;
	      default:
                  console.log("\tKeydown not handeled "+ evnt.key);
          }
    },

};

function FocusFunc(event) {
    console.log("I have focus!, Window");
};