diff --git a/src/ol/interaction/dragrotateandzoominteraction.js b/src/ol/interaction/dragrotateandzoominteraction.js index 9cc3ab89ca..7cf2f7ffa1 100644 --- a/src/ol/interaction/dragrotateandzoominteraction.js +++ b/src/ol/interaction/dragrotateandzoominteraction.js @@ -26,15 +26,15 @@ ol.interaction.DragRotateAndZoom = function(condition) { /** * @private - * @type {number} + * @type {number|undefined} */ - this.startRatio_ = 0; + this.lastAngle_; /** * @private - * @type {number} + * @type {number|undefined} */ - this.startRotation_ = 0; + this.lastMagnitude_; }; goog.inherits(ol.interaction.DragRotateAndZoom, ol.interaction.Drag); @@ -52,15 +52,23 @@ ol.interaction.DragRotateAndZoom.prototype.handleDrag = browserEvent.offsetX - size.width / 2, size.height / 2 - browserEvent.offsetY); var theta = Math.atan2(delta.y, delta.x); - var resolution = this.startRatio_ * delta.magnitude(); + var magnitude = delta.magnitude(); // FIXME works for View2D only var view = map.getView(); goog.asserts.assert(view instanceof ol.View2D); map.requestRenderFrame(); // FIXME the calls to map.rotate and map.zoomToResolution should use // map.withFrozenRendering but an assertion fails :-( - view.rotate(map, this.startRotation_, -theta); - view.zoomToResolution(map, resolution); + if (goog.isDef(this.lastAngle_)) { + var angleDelta = theta - this.lastAngle_; + view.rotate(map, view.getRotation() - angleDelta); + } + this.lastAngle_ = theta; + if (goog.isDef(this.lastMagnitude_)) { + var resolution = this.lastMagnitude_ * (view.getResolution() / magnitude); + view.zoomToResolution(map, resolution); + } + this.lastMagnitude_ = magnitude; }; @@ -70,18 +78,9 @@ ol.interaction.DragRotateAndZoom.prototype.handleDrag = ol.interaction.DragRotateAndZoom.prototype.handleDragStart = function(mapBrowserEvent) { var browserEvent = mapBrowserEvent.browserEvent; - var map = mapBrowserEvent.map; - var view = map.getView().getView2D(); if (this.condition_(browserEvent)) { - var resolution = view.getResolution(); - var size = map.getSize(); - var delta = new goog.math.Vec2( - browserEvent.offsetX - size.width / 2, - size.height / 2 - browserEvent.offsetY); - var theta = Math.atan2(delta.y, delta.x); - this.startRotation_ = view.getRotation() + theta; - this.startRatio_ = resolution / delta.magnitude(); - map.requestRenderFrame(); + this.lastAngle_ = undefined; + this.lastMagnitude_ = undefined; return true; } else { return false; diff --git a/src/ol/interaction/dragrotateinteraction.js b/src/ol/interaction/dragrotateinteraction.js index 048a847957..276fb15c56 100644 --- a/src/ol/interaction/dragrotateinteraction.js +++ b/src/ol/interaction/dragrotateinteraction.js @@ -23,9 +23,9 @@ ol.interaction.DragRotate = function(condition) { /** * @private - * @type {number} + * @type {number|undefined} */ - this.startRotation_ = 0; + this.lastAngle_; }; goog.inherits(ol.interaction.DragRotate, ol.interaction.Drag); @@ -39,14 +39,16 @@ ol.interaction.DragRotate.prototype.handleDrag = function(mapBrowserEvent) { var map = mapBrowserEvent.map; var size = map.getSize(); var offset = mapBrowserEvent.getPixel(); - var theta = Math.atan2( - size.height / 2 - offset.y, - offset.x - size.width / 2); - // FIXME supports View2D only - var view = map.getView(); - goog.asserts.assert(view instanceof ol.View2D); - map.requestRenderFrame(); - view.rotate(map, this.startRotation_, -theta); + var theta = Math.atan2(size.height / 2 - offset.y, offset.x - size.width / 2); + if (goog.isDef(this.lastAngle_)) { + var delta = theta - this.lastAngle_; + var view = map.getView(); + // FIXME supports View2D only + goog.asserts.assert(view instanceof ol.View2D); + map.requestRenderFrame(); + view.rotate(map, view.getRotation() - delta); + } + this.lastAngle_ = theta; }; @@ -56,18 +58,13 @@ ol.interaction.DragRotate.prototype.handleDrag = function(mapBrowserEvent) { ol.interaction.DragRotate.prototype.handleDragStart = function(mapBrowserEvent) { var browserEvent = mapBrowserEvent.browserEvent; - var map = mapBrowserEvent.map; - // FIXME supports View2D only - var view = map.getView(); - goog.asserts.assert(view instanceof ol.View2D); if (browserEvent.isMouseActionButton() && this.condition_(browserEvent)) { + var map = mapBrowserEvent.map; + // FIXME supports View2D only + var view = map.getView(); + goog.asserts.assert(view instanceof ol.View2D); map.requestRenderFrame(); - var size = map.getSize(); - var offset = mapBrowserEvent.getPixel(); - var theta = Math.atan2( - size.height / 2 - offset.y, - offset.x - size.width / 2); - this.startRotation_ = view.getRotation() + theta; + this.lastAngle_ = undefined; return true; } else { return false; diff --git a/src/ol/view2d.js b/src/ol/view2d.js index ca726b99f4..ed707f2e74 100644 --- a/src/ol/view2d.js +++ b/src/ol/view2d.js @@ -256,11 +256,26 @@ goog.exportProperty( /** * @param {ol.Map} map Map. * @param {number|undefined} rotation Rotation. - * @param {number} delta Delta. + * @param {ol.Coordinate=} opt_anchor Anchor coordinate. */ -ol.View2D.prototype.rotate = function(map, rotation, delta) { - rotation = this.constraints_.rotation(rotation, delta); - this.setRotation(rotation); +ol.View2D.prototype.rotate = function(map, rotation, opt_anchor) { + rotation = this.constraints_.rotation(rotation, 0); + if (goog.isDefAndNotNull(opt_anchor)) { + var anchor = opt_anchor; + var oldCenter = /** @type {!ol.Coordinate} */ (this.getCenter()); + var center = new ol.Coordinate( + oldCenter.x - anchor.x, + oldCenter.y - anchor.y); + center.rotate(rotation - this.getRotation()); + center.x += anchor.x; + center.y += anchor.y; + map.withFrozenRendering(function() { + this.setCenter(center); + this.setRotation(rotation); + }, this); + } else { + this.setRotation(rotation); + } };