diff --git a/src/ol/interaction/dragpaninteraction.js b/src/ol/interaction/dragpaninteraction.js index 3fcc4d4157..4598cabec1 100644 --- a/src/ol/interaction/dragpaninteraction.js +++ b/src/ol/interaction/dragpaninteraction.js @@ -7,6 +7,7 @@ goog.require('ol.Coordinate'); goog.require('ol.MapBrowserEvent'); goog.require('ol.View2D'); goog.require('ol.ViewHint'); +goog.require('ol.animation'); goog.require('ol.interaction.ConditionType'); goog.require('ol.interaction.Drag'); @@ -16,8 +17,9 @@ goog.require('ol.interaction.Drag'); * @constructor * @extends {ol.interaction.Drag} * @param {ol.interaction.ConditionType} condition Condition. + * @param {ol.Kinetic=} opt_kinetic Kinetic object. */ -ol.interaction.DragPan = function(condition) { +ol.interaction.DragPan = function(condition, opt_kinetic) { goog.base(this); @@ -27,6 +29,12 @@ ol.interaction.DragPan = function(condition) { */ this.condition_ = condition; + /** + * @private + * @type {ol.Kinetic|undefined} + */ + this.kinetic_ = opt_kinetic; + }; goog.inherits(ol.interaction.DragPan, ol.interaction.Drag); @@ -35,6 +43,9 @@ goog.inherits(ol.interaction.DragPan, ol.interaction.Drag); * @inheritDoc */ ol.interaction.DragPan.prototype.handleDrag = function(mapBrowserEvent) { + if (this.kinetic_) { + this.kinetic_.update(mapBrowserEvent.browserEvent); + } var map = mapBrowserEvent.map; // FIXME works for View2D only var view = map.getView(); @@ -55,9 +66,31 @@ ol.interaction.DragPan.prototype.handleDrag = function(mapBrowserEvent) { * @inheritDoc */ ol.interaction.DragPan.prototype.handleDragEnd = function(mapBrowserEvent) { + + // FIXME works for View2D only + var map = mapBrowserEvent.map; - map.requestRenderFrame(); - map.getView().setHint(ol.ViewHint.PANNING, -1); + var view = map.getView(); + view.setHint(ol.ViewHint.PANNING, -1); + + if (this.kinetic_ && this.kinetic_.end()) { + var distance = this.kinetic_.getDistance(); + var angle = this.kinetic_.getAngle(); + var center = view.getCenter(); + var kineticPanFrom = ol.animation.createPanFrom({ + source: center, + duration: this.kinetic_.getDuration(), + easing: this.kinetic_.getEasingFn() + }); + map.addPreRenderFunction(kineticPanFrom); + + var centerpx = map.getPixelFromCoordinate(center); + var destpx = new ol.Pixel( + centerpx.x - distance * Math.cos(angle), + centerpx.y - distance * Math.sin(angle)); + var dest = map.getCoordinateFromPixel(destpx); + view.setCenter(dest); + } }; @@ -67,6 +100,9 @@ ol.interaction.DragPan.prototype.handleDragEnd = function(mapBrowserEvent) { ol.interaction.DragPan.prototype.handleDragStart = function(mapBrowserEvent) { var browserEvent = mapBrowserEvent.browserEvent; if (this.condition_(browserEvent)) { + if (this.kinetic_) { + this.kinetic_.begin(browserEvent); + } var map = mapBrowserEvent.map; map.requestRenderFrame(); map.getView().setHint(ol.ViewHint.PANNING, 1); diff --git a/src/ol/kinetic.js b/src/ol/kinetic.js new file mode 100644 index 0000000000..909fbb4936 --- /dev/null +++ b/src/ol/kinetic.js @@ -0,0 +1,143 @@ + +goog.provide('ol.Kinetic'); + +goog.require('goog.array'); +goog.require('ol.Pixel'); + + +/** + * @typedef {{x: number, + * y: number, + * t: number}} + */ +ol.KineticPoint; + + + +/** + * @constructor + * @param {number} decay Rate of decay (must be negative). + * @param {number} v_min Minimum velocity (pixels/millisecond). + * @param {number} delay Delay to consider to calculate the kinetic + * initial values (milliseconds). + */ +ol.Kinetic = function(decay, v_min, delay) { + + /** + * @private + * @type {number} + */ + this.decay_ = decay; + + /** + * @private + * @type {number} + */ + this.v_min_ = v_min; + + /** + * @private + * @type {number} + */ + this.delay_ = delay; + + /** + * @private + * @type {Array.