all files / ol/renderer/canvas/ intermediatecanvas.js

63.16% Statements 36/57
52.94% Branches 9/17
28.57% Functions 2/7
63.16% Lines 36/57
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148                     102×           102×           102×                 102×   102× 102×     101× 101×     101×     101×       101× 101×       101× 101× 101× 101× 101×   101×   101×       102×                                                                                                                                    
goog.provide('ol.renderer.canvas.IntermediateCanvas');
 
goog.require('ol');
goog.require('ol.coordinate');
goog.require('ol.dom');
goog.require('ol.extent');
goog.require('ol.renderer.canvas.Layer');
goog.require('ol.transform');
 
 
/**
 * @constructor
 * @abstract
 * @extends {ol.renderer.canvas.Layer}
 * @param {ol.layer.Layer} layer Layer.
 */
ol.renderer.canvas.IntermediateCanvas = function(layer) {
 
  ol.renderer.canvas.Layer.call(this, layer);
 
  /**
   * @protected
   * @type {ol.Transform}
   */
  this.coordinateToCanvasPixelTransform = ol.transform.create();
 
  /**
   * @private
   * @type {CanvasRenderingContext2D}
   */
  this.hitCanvasContext_ = null;
 
};
ol.inherits(ol.renderer.canvas.IntermediateCanvas, ol.renderer.canvas.Layer);
 
 
/**
 * @inheritDoc
 */
ol.renderer.canvas.IntermediateCanvas.prototype.composeFrame = function(frameState, layerState, context) {
 
  this.preCompose(context, frameState);
 
  var image = this.getImage();
  if (image) {
 
    // clipped rendering if layer extent is set
    var extent = layerState.extent;
    var clipped = extent !== undefined &&
        !ol.extent.containsExtent(extent, frameState.extent) &&
        ol.extent.intersects(extent, frameState.extent);
    if (clipped) {
      this.clip(context, frameState, /** @type {ol.Extent} */ (extent));
    }
 
    var imageTransform = this.getImageTransform();
    // for performance reasons, context.save / context.restore is not used
    // to save and restore the transformation matrix and the opacity.
    // see http://jsperf.com/context-save-restore-versus-variable
    var alpha = context.globalAlpha;
    context.globalAlpha = layerState.opacity;
 
    // for performance reasons, context.setTransform is only used
    // when the view is rotated. see http://jsperf.com/canvas-transform
    var dx = imageTransform[4];
    var dy = imageTransform[5];
    var dw = image.width * imageTransform[0];
    var dh = image.height * imageTransform[3];
    context.drawImage(image, 0, 0, +image.width, +image.height,
        Math.round(dx), Math.round(dy), Math.round(dw), Math.round(dh));
    context.globalAlpha = alpha;
 
    if (clipped) {
      context.restore();
    }
  }
 
  this.postCompose(context, frameState, layerState);
};
 
 
/**
 * @abstract
 * @return {HTMLCanvasElement|HTMLVideoElement|Image} Canvas.
 */
ol.renderer.canvas.IntermediateCanvas.prototype.getImage = function() {};
 
 
/**
 * @abstract
 * @return {!ol.Transform} Image transform.
 */
ol.renderer.canvas.IntermediateCanvas.prototype.getImageTransform = function() {};
 
 
/**
 * @inheritDoc
 */
ol.renderer.canvas.IntermediateCanvas.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, hitTolerance, callback, thisArg) {
  var layer = this.getLayer();
  var source = layer.getSource();
  var resolution = frameState.viewState.resolution;
  var rotation = frameState.viewState.rotation;
  var skippedFeatureUids = frameState.skippedFeatureUids;
  return source.forEachFeatureAtCoordinate(
      coordinate, resolution, rotation, hitTolerance, skippedFeatureUids,
      /**
       * @param {ol.Feature|ol.render.Feature} feature Feature.
       * @return {?} Callback result.
       */
      function(feature) {
        return callback.call(thisArg, feature, layer);
      });
};
 
 
/**
 * @inheritDoc
 */
ol.renderer.canvas.IntermediateCanvas.prototype.forEachLayerAtCoordinate = function(coordinate, frameState, callback, thisArg) {
  if (!this.getImage()) {
    return undefined;
  }
 
  if (this.getLayer().getSource().forEachFeatureAtCoordinate !== ol.nullFunction) {
    // for ImageVector sources use the original hit-detection logic,
    // so that for example also transparent polygons are detected
    return ol.renderer.canvas.Layer.prototype.forEachLayerAtCoordinate.apply(this, arguments);
  } else {
    var pixel = ol.transform.apply(this.coordinateToCanvasPixelTransform, coordinate.slice());
    ol.coordinate.scale(pixel, frameState.viewState.resolution / this.renderedResolution);
 
    if (!this.hitCanvasContext_) {
      this.hitCanvasContext_ = ol.dom.createCanvasContext2D(1, 1);
    }
 
    this.hitCanvasContext_.clearRect(0, 0, 1, 1);
    this.hitCanvasContext_.drawImage(this.getImage(), pixel[0], pixel[1], 1, 1, 0, 0, 1, 1);
 
    var imageData = this.hitCanvasContext_.getImageData(0, 0, 1, 1).data;
    if (imageData[3] > 0) {
      return callback.call(thisArg, this.getLayer(),  imageData);
    } else {
      return undefined;
    }
  }
};