heli-agri
Version:
HeliAgri is a high-performance, feature-packed library for creating interactive maps on the web. It can display map tiles, vector data and markers loaded from any source on any web page. OpenLayers has been developed to further the use of geographic infor
127 lines (111 loc) • 3.02 kB
JavaScript
/**
* @module ol/Kinetic
*/
/**
* @classdesc
* Implementation of inertial deceleration for map movement.
*
* @api
*/
class Kinetic {
/**
* @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).
*/
constructor(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
*/
begin() {
this.points_.length = 0;
this.angle_ = 0;
this.initialVelocity_ = 0;
}
/**
* @param {number} x X.
* @param {number} y Y.
*/
update(x, y) {
this.points_.push(x, y, Date.now());
}
/**
* @return {boolean} Whether we should do kinetic animation.
*/
end() {
if (this.points_.length < 6) {
// at least 2 points are required (i.e. there must be at least 6 elements
// in the array)
return false;
}
const delay = Date.now() - this.delay_;
const 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
let firstIndex = lastIndex - 3;
while (firstIndex > 0 && this.points_[firstIndex + 2] > delay) {
firstIndex -= 3;
}
const 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;
}
const dx = this.points_[lastIndex] - this.points_[firstIndex];
const 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).
*/
getDistance() {
return (this.minVelocity_ - this.initialVelocity_) / this.decay_;
}
/**
* @return {number} Angle of the kinetic panning animation (radians).
*/
getAngle() {
return this.angle_;
}
}
export default Kinetic;