all files / ol/ kinetic.js

50% Statements 18/36
12.5% Branches 1/8
50% Functions 3/6
50% Lines 18/36
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                                       310×           310×           310×           310×           310×           310×             76× 76× 76×                             74×     74×                                                                                        
goog.provide('ol.Kinetic');
 
 
/**
 * @classdesc
 * Implementation of inertial deceleration for map movement.
 *
 * @constructor
 * @param {number} decay Rate of decay (must be negative).
 * @param {number} minVelocity Minimum velocity (pixels/millisecond).
 * @param {number} delay Delay to consider to calculate the kinetic
 *     initial values (milliseconds).
 * @struct
 * @api
 */
ol.Kinetic = function(decay, minVelocity, delay) {
 
  /**
   * @private
   * @type {number}
   */
  this.decay_ = decay;
 
  /**
   * @private
   * @type {number}
   */
  this.minVelocity_ = minVelocity;
 
  /**
   * @private
   * @type {number}
   */
  this.delay_ = delay;
 
  /**
   * @private
   * @type {Array.<number>}
   */
  this.points_ = [];
 
  /**
   * @private
   * @type {number}
   */
  this.angle_ = 0;
 
  /**
   * @private
   * @type {number}
   */
  this.initialVelocity_ = 0;
};
 
 
/**
 * FIXME empty description for jsdoc
 */
ol.Kinetic.prototype.begin = function() {
  this.points_.length = 0;
  this.angle_ = 0;
  this.initialVelocity_ = 0;
};
 
 
/**
 * @param {number} x X.
 * @param {number} y Y.
 */
ol.Kinetic.prototype.update = function(x, y) {
  this.points_.push(x, y, Date.now());
};
 
 
/**
 * @return {boolean} Whether we should do kinetic animation.
 */
ol.Kinetic.prototype.end = function() {
  Eif (this.points_.length < 6) {
    // at least 2 points are required (i.e. there must be at least 6 elements
    // in the array)
    return false;
  }
  var delay = Date.now() - this.delay_;
  var lastIndex = this.points_.length - 3;
  if (this.points_[lastIndex + 2] < delay) {
    // the last tracked point is too old, which means that the user stopped
    // panning before releasing the map
    return false;
  }
 
  // get the first point which still falls into the delay time
  var firstIndex = lastIndex - 3;
  while (firstIndex > 0 && this.points_[firstIndex + 2] > delay) {
    firstIndex -= 3;
  }
 
  var duration = this.points_[lastIndex + 2] - this.points_[firstIndex + 2];
  // we don't want a duration of 0 (divide by zero)
  // we also make sure the user panned for a duration of at least one frame
  // (1/60s) to compute sane displacement values
  if (duration < 1000 / 60) {
    return false;
  }
 
  var dx = this.points_[lastIndex] - this.points_[firstIndex];
  var dy = this.points_[lastIndex + 1] - this.points_[firstIndex + 1];
  this.angle_ = Math.atan2(dy, dx);
  this.initialVelocity_ = Math.sqrt(dx * dx + dy * dy) / duration;
  return this.initialVelocity_ > this.minVelocity_;
};
 
 
/**
 * @return {number} Total distance travelled (pixels).
 */
ol.Kinetic.prototype.getDistance = function() {
  return (this.minVelocity_ - this.initialVelocity_) / this.decay_;
};
 
 
/**
 * @return {number} Angle of the kinetic panning animation (radians).
 */
ol.Kinetic.prototype.getAngle = function() {
  return this.angle_;
};