code: function CanvasControl(canvas, elements, callbackFunc) {
    this._canvas = canvas;
    this._elements = elements;
    this._callbackFunc = callbackFunc;
  
    this._context = this._canvas.getContext('2d');
    this._cursorDown = false;
  
    this._selected = {
      index: -1,
      xOffset: 0,
      yOffset: 0,
    };
  
    this._lastMoveEventTime = 0;
    this._minimumThreshold = 16;
    let that = this;
    canvas.addEventListener('touchstart', function(event) {
      that._cursorDownFunc(event);
    });
  
    canvas.addEventListener('mousedown', function(event) {
      that._cursorDownFunc(event);
    });
  
    canvas.addEventListener('touchmove', function(event) {
      let currentEventTime = Date.now();
      if (currentEventTime - that._lastMoveEventTime > that._minimumThreshold) {
        that._lastMoveEventTime = currentEventTime;
        if (that._cursorMoveFunc(event)) {
          event.preventDefault();
        }
      }
    }, true);
  
    canvas.addEventListener('mousemove', function(event) {
      let currentEventTime = Date.now();
      if (currentEventTime - that._lastMoveEventTime > that._minimumThreshold) {
        that._lastMoveEventTime = currentEventTime;
        that._cursorMoveFunc(event);
      }
    });
  
    document.addEventListener('touchend', function(event) {
      that._cursorUpFunc(event);
    });
  
    document.addEventListener('mouseup', function(event) {
      that._cursorUpFunc(event);
    });
  
    window.addEventListener('resize', function(event) {
      that.resize();
      that.draw();
    }, false);
  
    this.invokeCallback();
    this.resize();
    this.draw();
  }
docs: Class for managing 2D visualization/interaction for audio demos.
  @param {Object} canvas
  @param {Object} elements
  @param {Function} callbackFunc