function Layer(options) {
  options = options || {};
  /**
   * @property {HTMLElement} canvas
   *   The canvas backing the Layer.
   * @readonly
   */
  this.canvas = options.canvas || document.createElement('canvas');
  /**
   * @property {CanvasRenderingContext2D} context
   *   The Layer's graphics context. Use this to draw onto the Layer.
   * @readonly
   */
  this.context = this.canvas.getContext('2d');
  this.context.__layer = this;
  /**
   * @property {Number} width
   *   The width of the Layer.
   * @readonly
   */
  this.width = options.width || (options.canvas ? options.canvas.width : 0) || (options.relative == 'canvas' ? canvas.width : world.width);
  /**
   * @property {Number} height
   *   The height of the Layer.
   * @readonly
   */
  this.height = options.height || (options.canvas ? options.canvas.height : 0) || (options.relative == 'canvas' ? canvas.height : world.height);
  /**
   * @property {Number} x
   *   The x-coordinate on the {@link global#canvas global canvas} of the
   *   upper-left corner of the Layer.
   */
  this.x = options.x || 0;
  /**
   * @property {Number} y
   *   The y-coordinate on the {@link global#canvas global canvas} of the
   *   upper-left corner of the Layer.
   */
  this.y = options.y || 0;
  /**
   * @property {"world"/"canvas"} relative
   *   What to draw the Layer relative to.
   */
  this.relative = options.relative || 'world';
  /**
   * @property {Number} opacity
   *   A fractional percentage [0, 1] indicating the opacity of the Layer.
   *   0 (zero) means fully transparent; 1 means fully opaque. This value is
   *   applied when {@link Layer#draw drawing} the layer.
   */
  this.opacity = options.opacity || 1;
  /**
   * @property {Number} parallax
   *   A fractional percentage indicating how much to
   *   {@link Layer#scroll scroll} the Layer relative to the viewport's
   *   movement.
   */
  this.parallax = options.parallax || 1;
  if (this.canvas.width != this.width) {
    this.canvas.width = this.width;
  }
  if (this.canvas.height != this.height) {
    this.canvas.height = this.height;
  }
  /**
   * @property {Number} xOffset
   *   The horizontal distance in pixels that the Layer has
   *   {@link Layer#scroll scrolled}.
   */
  this.xOffset = 0;
  /**
   * @property {Number} yOffset
   *   The vertical distance in pixels that the Layer has
   *   {@link Layer#scroll scrolled}.
   */
  this.yOffset = 0;
  if (options.src) {
    this.context.drawImage(options.src, 0, 0, this.width, this.height);
  }
  /**
   * Draw the Layer.
   *
   * This method can be invoked in two ways:
   *
   * - `draw(x, y)`
   * - `draw(ctx, x, y)`
   *
   * All parameters are optional either way.
   *
   * @param {CanvasRenderingContext2D} [ctx]
   *   A canvas graphics context onto which this Layer should be drawn. This is
   *   useful for drawing onto other Layers. If not specified, defaults to the
   *   {@link global#context global context} for the default canvas.
   * @param {Number} [x]
   *   An x-coordinate on the canvas specifying where to draw the upper-left
   *   corner of the Layer. The actual position that the coordinate equates to
   *   depends on the value of the
   *   {@link Layer#relative Layer's "relative" property}. Defaults to the
   *   {@link Layer#x Layer's "x" property} (which defaults to 0 [zero]).
   * @param {Number} [y]
   *   A y-coordinate on the canvas specifying where to draw the upper-left
   *   corner of the Layer. The actual position that the coordinate equates to
   *   depends on the value of the
   *   {@link Layer#relative Layer's "relative" property}. Defaults to the
   *   {@link Layer#y Layer's "y" property} (which defaults to 0 [zero]).
   */
  this.draw = function(ctx, x, y) {
    if (!(ctx instanceof CanvasRenderingContext2D)) {
      y = x;
      x = ctx;
      ctx = context;
    }
    x = typeof x === 'undefined' ? this.x : x;
    y = typeof y === 'undefined' ? this.y : y;
    ctx.save();
    ctx.globalAlpha = this.opacity;
    if (this.relative == 'canvas') {
      ctx.translate(world.xOffset, world.yOffset);
    }
    if (this.xOffset || this.yOffset) {
      ctx.translate(this.xOffset, this.yOffset);
    }
    ctx.drawImage(this.canvas, x, y);
    ctx.restore();
    return this;
  };
  /**
   * Clear the layer, optionally by filling it with a given style.
   *
   * @param {Mixed} [fillStyle]
   *   A canvas graphics context fill style. If not passed, the Layer will
   *   simply be cleared. If passed, the Layer will be filled with the given
   *   style.
   */
  this.clear = function(fillStyle) {
    this.context.clear(fillStyle);
    return this;
  };
  /**
   * Scroll the Layer.
   *
   * @param {Number} x
   *   The horizontal distance the target has shifted.
   * @param {Number} y
   *   The vertical distance the target has shifted.
   * @param {Number} [p]
   *   The parallax factor. Defaults to {@link Layer#parallax this.parallax}.
   */
  this.scroll = function(x, y, p) {
    p = p || this.parallax;
    this.xOffset += -x*p;
    this.yOffset += -y*p;
    return this;
  };
  /**
   * Position the Layer's canvas over the primary canvas.
   *
   * This is an alternative to drawing the Layer directly onto the primary
   * canvas. It is mostly useful when the `relative` property is `"canvas"`.
   * It is also useful when the primary canvas is scaled with
   * World#scaleResolution but this Layer should stay a consistent size.
   * However, since it is literally in front of the primary canvas, any other
   * Layers that need to be drawn in front of this one must also be positioned
   * over the primary canvas instead of drawn directly onto it.
   *
   * @return {HTMLElement}
   *   A jQuery representation of a div containing the Layer's canvas.
   */
  this.positionOverCanvas = function() {
    var $d = jQuery('<div></div>');
    var o = $canvas.offset();
    $d.css({
      left: o.left,
      pointerEvents: 'none',
      position: 'absolute',
      top: o.top,
    });
    var $c = jQuery(this.canvas);
    $c.css({
      backgroundColor: 'transparent',
      margin: '0 auto',
      overflow: 'hidden',
      pointerEvents: 'none',
      position: 'absolute',
      'z-index': 50,
    });
    $d.append($c);
    jQuery('body').append($d);
    return $d;
  };
  /**
   * Display this Layer's canvas in an overlay (for debugging purposes).
   *
   * Clicking the overlay will remove it.
   *
   * @return {HTMLElement}
   *   A jQuery representation of a div containing the Layer's canvas.
   */
  this.showCanvasOverlay = function() {
    stopAnimating();
    var $d = jQuery('<div></div>');
    $d.css({
      cursor: 'pointer',
      display: 'block',
      height: '100%',
      left: 0,
      position: 'absolute',
      top: 0,
      width: '100%',
    });
    var $c = jQuery(this.canvas);
    $c.css({
      border: '1px solid black',
      display: 'block',
      margin: '0 auto',
      position: 'absolute',
      'z-index': 100,
    }).click(function() {
      $d.remove();
      startAnimating();
    });
    $d.append($c);
    jQuery('body').append($d);
    $d.click(function(e) {
      if (e.which != 3) { // Don't intercept right-click events
        $d.remove();
      }
    });
    return $d;
  };
}
/**
 * The Layer object (basically a new, utility canvas).
 *
 * Layers allow efficient rendering of complex scenes by acting as caches for
 * parts of the scene that are grouped together. For example, it is recommended
 * to create a Layer for your canvas's background so that you can render the
 * background once and then draw the completely rendered background onto the
 * main canvas in each frame instead of re-computing the background for each
 * frame. This can significantly speed up animation.
 *
 * In general you should create a layer for any significant grouping of items
 * if that grouping moves together when animated. It is more memory-efficient
 * to specify a smaller layer size if possible; otherwise the layer will
 * default to the size of the whole canvas.
 *
 * Draw onto a Layer by using its "context" property, which is a
 * {@link CanvasRenderingContext2D canvas graphics context}.
 *
 * @param {Object} [options]
 *   A set of options.
 * @param {Number} [options.x=0]
 *   The x-coordinate of the top-left corner of the Layer.
 * @param {Number} [options.y=0]
 *   The y-coordinate of the top-left corner of the Layer.
 * @param {Number} [options.width]
 *   The width of the Layer.
 * @param {Number} [options.height]
 *   The height of the Layer.
 * @param {"world"/"canvas"} [options.relative="world"]
 *   Indicates what to draw the Layer relative to:
 *
 *   - 'world': Draw the layer relative to the world so that it will appear
 *     to be in one specific place as the player or viewport moves.
 *   - 'canvas': Draw the layer relative to the canvas so that it stays fixed
 *     as the player moves. This is useful for a HUD, for example.
 *
 *   This option is irrelevant if the world is the same size as the canvas.
 * @param {Number} [options.opacity=1]
 *   A fractional percentage [0, 1] indicating the opacity of the Layer.
 *   0 (zero) means fully transparent; 1 means fully opaque. This value is
 *   applied when {@link Layer#draw drawing} the layer.
 * @param {Number} [options.parallax=1]
 *   A fractional percentage indicating how much to {@link Layer#scroll scroll}
 *   the Layer relative to the viewport's movement.
 * @param {Mixed} [options.src]
 *   Anything that can be passed to the `src` parameter of
 *   {@link CanvasRenderingContext2D#drawImage drawImage()}. This will be used
 *   to draw an image stretched over the whole Layer as a convenience.
 * @param {HTMLElement} [options.canvas]
 *   A Canvas element in which to hold the Layer. If not specified, a new,
 *   invisible canvas is created. Careful; if width and height are specified,
 *   the canvas will be resized (and therefore cleared). This is mainly for
 *   internal use.
 */
The Layer object (basically a new, utility canvas).
Layers allow efficient rendering of complex scenes by acting as caches for
parts of the scene that are grouped together. For example, it is recommended
to create a Layer for your canvas's background so that you can render the
background once and then draw the completely rendered background onto the
main canvas in each frame instead of re-computing the background for each
frame. This can significantly speed up animation.

In general you should create a layer for any significant grouping of items
if that grouping moves together when animated. It is more memory-efficient
to specify a smaller layer size if possible; otherwise the layer will
default to the size of the whole canvas.

Draw onto a Layer by using its "context" property, which is a
CanvasRenderingContext2D canvas graphics context.

@param {Object} [options]
A set of options.
@param {Number} [options.x=0]
The x-coordinate of the top-left corner of the Layer.
@param {Number} [options.y=0]
The y-coordinate of the top-left corner of the Layer.
@param {Number} [options.width]
The width of the Layer.
@param {Number} [options.height]
The height of the Layer.

- 'world': Draw the layer relative to the world so that it will appear
to be in one specific place as the player or viewport moves.
- 'canvas': Draw the layer relative to the canvas so that it stays fixed
as the player moves. This is useful for a HUD, for example.

This option is irrelevant if the world is the same size as the canvas.
@param {Number} [options.opacity=1]
A fractional percentage [0, 1] indicating the opacity of the Layer.
0 (zero) means fully transparent; 1 means fully opaque. This value is
applied when  Layer#draw drawing the layer.
@param {Number} [options.parallax=1]
A fractional percentage indicating how much to  Layer#scroll scroll
the Layer relative to the viewport's movement.
@param {Mixed} [options.src]
Anything that can be passed to the `src` parameter of
CanvasRenderingContext2D#drawImage drawImage(). This will be used
to draw an image stretched over the whole Layer as a convenience.
@param {HTMLElement} [options.canvas]
A Canvas element in which to hold the Layer. If not specified, a new,
invisible canvas is created. Careful; if width and height are specified,
the canvas will be resized (and therefore cleared). This is mainly for
internal use.
The Layer object ( basically a new utility canvas ) . Layers allow efficient rendering of complex scenes by acting as caches for parts of the scene that are grouped together . For example it is recommended to create a Layer for your canvas ' s background so that you can render the background once and then draw the completely rendered background onto the main canvas in each frame instead of re - computing the background for each frame . This can significantly speed up animation . In general you should create a layer for any significant grouping of items if that grouping moves together when animated . It is more memory - efficient to specify a smaller layer size if possible ; otherwise the layer will default to the size of the whole canvas . Draw onto a Layer by using its " context " property which is a CanvasRenderingContext2D canvas graphics context . @param { Object } [ options ] A set of options . @param { Number } [ options . x = 0 ] The x - coordinate of the top - left corner of the Layer . @param { Number } [ options . y = 0 ] The y - coordinate of the top - left corner of the Layer . @param { Number } [ options . width ] The width of the Layer . @param { Number } [ options . height ] The height of the Layer . - ' world ' : Draw the layer relative to the world so that it will appear to be in one specific place as the player or viewport moves . - ' canvas ' : Draw the layer relative to the canvas so that it stays fixed as the player moves . This is useful for a HUD for example . This option is irrelevant if the world is the same size as the canvas . @param { Number } [ options . opacity = 1 ] A fractional percentage [ 0 1 ] indicating the opacity of the Layer . 0 ( zero ) means fully transparent ; 1 means fully opaque . This value is applied when Layer#draw drawing the layer . @param { Number } [ options . parallax = 1 ] A fractional percentage indicating how much to Layer#scroll scroll the Layer relative to the viewport ' s movement . @param { Mixed } [ options . src ] Anything that can be passed to the ` src ` parameter of CanvasRenderingContext2D#drawImage drawImage () . This will be used to draw an image stretched over the whole Layer as a convenience . @param { HTMLElement } [ options . canvas ] A Canvas element in which to hold the Layer . If not specified a new invisible canvas is created . Careful ; if width and height are specified the canvas will be resized ( and therefore cleared ) . This is mainly for internal use .
function Layer(options) {
  options = options || {};
  this.canvas = options.canvas || document.createElement('canvas');
  this.context = this.canvas.getContext('2d');
  this.context.__layer = this;
  this.width = options.width || (options.canvas ? options.canvas.width : 0) || (options.relative == 'canvas' ? canvas.width : world.width);
  this.height = options.height || (options.canvas ? options.canvas.height : 0) || (options.relative == 'canvas' ? canvas.height : world.height);
  this.x = options.x || 0;
  this.y = options.y || 0;
  this.relative = options.relative || 'world';
  this.opacity = options.opacity || 1;
  this.parallax = options.parallax || 1;
  if (this.canvas.width != this.width) {
    this.canvas.width = this.width;
  }
  if (this.canvas.height != this.height) {
    this.canvas.height = this.height;
  }
  this.xOffset = 0;
  this.yOffset = 0;
  if (options.src) {
    this.context.drawImage(options.src, 0, 0, this.width, this.height);
  }
  this.draw = function(ctx, x, y) {
    if (!(ctx instanceof CanvasRenderingContext2D)) {
      y = x;
      x = ctx;
      ctx = context;
    }
    x = typeof x === 'undefined' ? this.x : x;
    y = typeof y === 'undefined' ? this.y : y;
    ctx.save();
    ctx.globalAlpha = this.opacity;
    if (this.relative == 'canvas') {
      ctx.translate(world.xOffset, world.yOffset);
    }
    if (this.xOffset || this.yOffset) {
      ctx.translate(this.xOffset, this.yOffset);
    }
    ctx.drawImage(this.canvas, x, y);
    ctx.restore();
    return this;
  };
  this.clear = function(fillStyle) {
    this.context.clear(fillStyle);
    return this;
  };
  this.scroll = function(x, y, p) {
    p = p || this.parallax;
    this.xOffset += -x*p;
    this.yOffset += -y*p;
    return this;
  };
  this.positionOverCanvas = function() {
    var $d = jQuery('<div></div>');
    var o = $canvas.offset();
    $d.css({
      left: o.left,
      pointerEvents: 'none',
      position: 'absolute',
      top: o.top,
    });
    var $c = jQuery(this.canvas);
    $c.css({
      backgroundColor: 'transparent',
      margin: '0 auto',
      overflow: 'hidden',
      pointerEvents: 'none',
      position: 'absolute',
      'z-index': 50,
    });
    $d.append($c);
    jQuery('body').append($d);
    return $d;
  };
  this.showCanvasOverlay = function() {
    stopAnimating();
    var $d = jQuery('<div></div>');
    $d.css({
      cursor: 'pointer',
      display: 'block',
      height: '100%',
      left: 0,
      position: 'absolute',
      top: 0,
      width: '100%',
    });
    var $c = jQuery(this.canvas);
    $c.css({
      border: '1px solid black',
      display: 'block',
      margin: '0 auto',
      position: 'absolute',
      'z-index': 100,
    }).click(function() {
      $d.remove();
      startAnimating();
    });
    $d.append($c);
    jQuery('body').append($d);
    $d.click(function(e) {
      if (e.which != 3) { 
        $d.remove();
      }
    });
    return $d;
  };
}
function Layer ( options ) { options = options || { } ; this . canvas = options . canvas || document . createElement ( 'canvas' ) ; this . context = this . canvas . getContext ( '2d' ) ; this . context . __layer = this ; this . width = options . width || ( options . canvas ? options . canvas . width : 0 ) || ( options . relative == 'canvas' ? canvas . width : world . width ) ; this . height = options . height || ( options . canvas ? options . canvas . height : 0 ) || ( options . relative == 'canvas' ? canvas . height : world . height ) ; this . x = options . x || 0 ; this . y = options . y || 0 ; this . relative = options . relative || 'world' ; this . opacity = options . opacity || 1 ; this . parallax = options . parallax || 1 ; if ( this . canvas . width != this . width ) { this . canvas . width = this . width ; } if ( this . canvas . height != this . height ) { this . canvas . height = this . height ; } this . xOffset = 0 ; this . yOffset = 0 ; if ( options . src ) { this . context . drawImage ( options . src , 0 , 0 , this . width , this . height ) ; } this . draw = function ( ctx , x , y ) { if ( ! ( ctx instanceof CanvasRenderingContext2D ) ) { y = x ; x = ctx ; ctx = context ; } x = typeof x === 'undefined' ? this . x : x ; y = typeof y === 'undefined' ? this . y : y ; ctx . save ( ) ; ctx . globalAlpha = this . opacity ; if ( this . relative == 'canvas' ) { ctx . translate ( world . xOffset , world . yOffset ) ; } if ( this . xOffset || this . yOffset ) { ctx . translate ( this . xOffset , this . yOffset ) ; } ctx . drawImage ( this . canvas , x , y ) ; ctx . restore ( ) ; return this ; } ; this . clear = function ( fillStyle ) { this . context . clear ( fillStyle ) ; return this ; } ; this . scroll = function ( x , y , p ) { p = p || this . parallax ; this . xOffset += - x * p ; this . yOffset += - y * p ; return this ; } ; this . positionOverCanvas = function ( ) { var $d = jQuery ( '<div></div>' ) ; var o = $canvas . offset ( ) ; $d . css ( { left : o . left , pointerEvents : 'none' , position : 'absolute' , top : o . top , } ) ; var $c = jQuery ( this . canvas ) ; $c . css ( { backgroundColor : 'transparent' , margin : '0 auto' , overflow : 'hidden' , pointerEvents : 'none' , position : 'absolute' , 'z-index' : 50 , } ) ; $d . append ( $c ) ; jQuery ( 'body' ) . append ( $d ) ; return $d ; } ; this . showCanvasOverlay = function ( ) { stopAnimating ( ) ; var $d = jQuery ( '<div></div>' ) ; $d . css ( { cursor : 'pointer' , display : 'block' , height : '100%' , left : 0 , position : 'absolute' , top : 0 , width : '100%' , } ) ; var $c = jQuery ( this . canvas ) ; $c . css ( { border : '1px solid black' , display : 'block' , margin : '0 auto' , position : 'absolute' , 'z-index' : 100 , } ) . click ( function ( ) { $d . remove ( ) ; startAnimating ( ) ; } ) ; $d . append ( $c ) ; jQuery ( 'body' ) . append ( $d ) ; $d . click ( function ( e ) { if ( e . which != 3 ) { $d . remove ( ) ; } } ) ; return $d ; } ; }
The Layer object (basically a new, utility canvas).
The Layer object ( basically a new utility canvas ) .
/**
   * @property {HTMLElement} canvas
   *   The canvas backing the Layer.
   * @readonly
   */ /**
   * @property {CanvasRenderingContext2D} context
   *   The Layer's graphics context. Use this to draw onto the Layer.
   * @readonly
   */ /**
   * @property {Number} width
   *   The width of the Layer.
   * @readonly
   */ /**
   * @property {Number} height
   *   The height of the Layer.
   * @readonly
   */ /**
   * @property {Number} x
   *   The x-coordinate on the {@link global#canvas global canvas} of the
   *   upper-left corner of the Layer.
   */ /**
   * @property {Number} y
   *   The y-coordinate on the {@link global#canvas global canvas} of the
   *   upper-left corner of the Layer.
   */ /**
   * @property {"world"/"canvas"} relative
   *   What to draw the Layer relative to.
   */ /**
   * @property {Number} opacity
   *   A fractional percentage [0, 1] indicating the opacity of the Layer.
   *   0 (zero) means fully transparent; 1 means fully opaque. This value is
   *   applied when {@link Layer#draw drawing} the layer.
   */ /**
   * @property {Number} parallax
   *   A fractional percentage indicating how much to
   *   {@link Layer#scroll scroll} the Layer relative to the viewport's
   *   movement.
   */ /**
   * @property {Number} xOffset
   *   The horizontal distance in pixels that the Layer has
   *   {@link Layer#scroll scrolled}.
   */ /**
   * @property {Number} yOffset
   *   The vertical distance in pixels that the Layer has
   *   {@link Layer#scroll scrolled}.
   */ /**
   * Draw the Layer.
   *
   * This method can be invoked in two ways:
   *
   * - `draw(x, y)`
   * - `draw(ctx, x, y)`
   *
   * All parameters are optional either way.
   *
   * @param {CanvasRenderingContext2D} [ctx]
   *   A canvas graphics context onto which this Layer should be drawn. This is
   *   useful for drawing onto other Layers. If not specified, defaults to the
   *   {@link global#context global context} for the default canvas.
   * @param {Number} [x]
   *   An x-coordinate on the canvas specifying where to draw the upper-left
   *   corner of the Layer. The actual position that the coordinate equates to
   *   depends on the value of the
   *   {@link Layer#relative Layer's "relative" property}. Defaults to the
   *   {@link Layer#x Layer's "x" property} (which defaults to 0 [zero]).
   * @param {Number} [y]
   *   A y-coordinate on the canvas specifying where to draw the upper-left
   *   corner of the Layer. The actual position that the coordinate equates to
   *   depends on the value of the
   *   {@link Layer#relative Layer's "relative" property}. Defaults to the
   *   {@link Layer#y Layer's "y" property} (which defaults to 0 [zero]).
   */ /**
   * Clear the layer, optionally by filling it with a given style.
   *
   * @param {Mixed} [fillStyle]
   *   A canvas graphics context fill style. If not passed, the Layer will
   *   simply be cleared. If passed, the Layer will be filled with the given
   *   style.
   */ /**
   * Scroll the Layer.
   *
   * @param {Number} x
   *   The horizontal distance the target has shifted.
   * @param {Number} y
   *   The vertical distance the target has shifted.
   * @param {Number} [p]
   *   The parallax factor. Defaults to {@link Layer#parallax this.parallax}.
   */ /**
   * Position the Layer's canvas over the primary canvas.
   *
   * This is an alternative to drawing the Layer directly onto the primary
   * canvas. It is mostly useful when the `relative` property is `"canvas"`.
   * It is also useful when the primary canvas is scaled with
   * World#scaleResolution but this Layer should stay a consistent size.
   * However, since it is literally in front of the primary canvas, any other
   * Layers that need to be drawn in front of this one must also be positioned
   * over the primary canvas instead of drawn directly onto it.
   *
   * @return {HTMLElement}
   *   A jQuery representation of a div containing the Layer's canvas.
   */ /**
   * Display this Layer's canvas in an overlay (for debugging purposes).
   *
   * Clicking the overlay will remove it.
   *
   * @return {HTMLElement}
   *   A jQuery representation of a div containing the Layer's canvas.
   */ // Don't intercept right-click events