Merge pull request #1975 from fredj/rotation-anchor

Rotate around arbitrary coordinate
This commit is contained in:
Frédéric Junod
2014-04-10 14:22:08 +02:00
8 changed files with 65 additions and 11 deletions
+1
View File
@@ -32,6 +32,7 @@
<div class="span12"> <div class="span12">
<button id="rotate-left"><i class="icon-arrow-left"></i></button> <button id="rotate-left"><i class="icon-arrow-left"></i></button>
<button id="rotate-right"><i class="icon-arrow-right"></i></button> <button id="rotate-right"><i class="icon-arrow-right"></i></button>
<button id="rotate-around-rome">Rotate around Rome</button>
<button id="pan-to-london">Pan to London</button> <button id="pan-to-london">Pan to London</button>
<button id="elastic-to-moscow">Elastic to Moscow</button> <button id="elastic-to-moscow">Elastic to Moscow</button>
<button id="bounce-to-istanbul">Bounce to Istanbul</button> <button id="bounce-to-istanbul">Bounce to Istanbul</button>
+11
View File
@@ -49,6 +49,17 @@ rotateRight.addEventListener('click', function() {
map.beforeRender(rotateRight); map.beforeRender(rotateRight);
}, false); }, false);
var rotateAroundRome = document.getElementById('rotate-around-rome');
rotateAroundRome.addEventListener('click', function() {
var currentRotation = view.getRotation();
var rotateAroundRome = ol.animation.rotate({
anchor: rome,
duration: 1000,
rotation: currentRotation
});
map.beforeRender(rotateAroundRome);
view.rotate(currentRotation + (Math.PI / 2), rome);
}, false);
var panToLondon = document.getElementById('pan-to-london'); var panToLondon = document.getElementById('pan-to-london');
panToLondon.addEventListener('click', function() { panToLondon.addEventListener('click', function() {
+13 -3
View File
@@ -544,7 +544,8 @@ olx.animation.PanOptions.prototype.easing;
/** /**
* @typedef {{rotation: number, * @typedef {{rotation: (number|undefined),
* anchor: (ol.Coordinate|undefined),
* start: (number|undefined), * start: (number|undefined),
* duration: (number|undefined), * duration: (number|undefined),
* easing: (function(number):number|undefined)}} * easing: (function(number):number|undefined)}}
@@ -554,12 +555,21 @@ olx.animation.RotateOptions;
/** /**
* The rotation to apply, in radians. * The rotation value (in radians) to begin rotating from, typically
* @type {number} * `map.getView().getRotation()`. If `undefined` then `0` is assumed.
* @type {number|undefined}
*/ */
olx.animation.RotateOptions.prototype.rotation; olx.animation.RotateOptions.prototype.rotation;
/**
* The rotation center/anchor. The map rotates around the center of the view
* if unspecified.
* @type {ol.Coordinate|undefined}
*/
olx.animation.RotateOptions.prototype.anchor;
/** /**
* The start time of the animation. Default is immediately. * The start time of the animation. Default is immediately.
* @type {number|undefined} * @type {number|undefined}
+12 -3
View File
@@ -4,6 +4,7 @@ goog.provide('ol.animation');
goog.require('ol.PreRenderFunction'); goog.require('ol.PreRenderFunction');
goog.require('ol.ViewHint'); goog.require('ol.ViewHint');
goog.require('ol.coordinate');
goog.require('ol.easing'); goog.require('ol.easing');
@@ -87,11 +88,13 @@ ol.animation.pan = function(options) {
* @todo stability experimental * @todo stability experimental
*/ */
ol.animation.rotate = function(options) { ol.animation.rotate = function(options) {
var sourceRotation = options.rotation; var sourceRotation = goog.isDef(options.rotation) ? options.rotation : 0;
var start = goog.isDef(options.start) ? options.start : goog.now(); var start = goog.isDef(options.start) ? options.start : goog.now();
var duration = goog.isDef(options.duration) ? options.duration : 1000; var duration = goog.isDef(options.duration) ? options.duration : 1000;
var easing = goog.isDef(options.easing) ? var easing = goog.isDef(options.easing) ?
options.easing : ol.easing.inAndOut; options.easing : ol.easing.inAndOut;
var anchor = goog.isDef(options.anchor) ?
options.anchor : null;
return ( return (
/** /**
@@ -106,9 +109,15 @@ ol.animation.rotate = function(options) {
} else if (frameState.time < start + duration) { } else if (frameState.time < start + duration) {
var delta = 1 - easing((frameState.time - start) / duration); var delta = 1 - easing((frameState.time - start) / duration);
var deltaRotation = var deltaRotation =
sourceRotation - frameState.view2DState.rotation; (sourceRotation - frameState.view2DState.rotation) * delta;
frameState.animate = true; frameState.animate = true;
frameState.view2DState.rotation += delta * deltaRotation; frameState.view2DState.rotation += deltaRotation;
if (!goog.isNull(anchor)) {
var center = frameState.view2DState.center;
ol.coordinate.sub(center, anchor);
ol.coordinate.rotate(center, deltaRotation);
ol.coordinate.add(center, anchor);
}
frameState.viewHints[ol.ViewHint.ANIMATING] += 1; frameState.viewHints[ol.ViewHint.ANIMATING] += 1;
return true; return true;
} else { } else {
+12
View File
@@ -182,6 +182,18 @@ ol.coordinate.scale = function(coordinate, s) {
}; };
/**
* @param {ol.Coordinate} coordinate Coordinate.
* @param {ol.Coordinate} delta Delta.
* @return {ol.Coordinate} Coordinate.
*/
ol.coordinate.sub = function(coordinate, delta) {
coordinate[0] -= delta[0];
coordinate[1] -= delta[1];
return coordinate;
};
/** /**
* @param {ol.Coordinate} coord1 First coordinate. * @param {ol.Coordinate} coord1 First coordinate.
* @param {ol.Coordinate} coord2 Second coordinate. * @param {ol.Coordinate} coord2 Second coordinate.
+1 -5
View File
@@ -128,11 +128,7 @@ ol.interaction.Interaction.rotateWithoutConstraints =
} }
} }
goog.asserts.assertInstanceof(view, ol.View2D); goog.asserts.assertInstanceof(view, ol.View2D);
if (goog.isDefAndNotNull(opt_anchor)) { view.rotate(rotation, opt_anchor);
var center = view.calculateCenterRotate(rotation, opt_anchor);
view.setCenter(center);
}
view.setRotation(rotation);
} }
}; };
+1
View File
@@ -7,4 +7,5 @@
@exportProperty ol.View2D.prototype.centerOn @exportProperty ol.View2D.prototype.centerOn
@exportProperty ol.View2D.prototype.getView2D @exportProperty ol.View2D.prototype.getView2D
@exportProperty ol.View2D.prototype.getZoom @exportProperty ol.View2D.prototype.getZoom
@exportProperty ol.View2D.prototype.rotate
@exportProperty ol.View2D.prototype.setZoom @exportProperty ol.View2D.prototype.setZoom
+14
View File
@@ -534,6 +534,20 @@ ol.View2D.prototype.isDef = function() {
}; };
/**
* Rotate the view around a given coordinate.
* @param {number} rotation New rotation value for the view.
* @param {ol.Coordinate=} opt_anchor The rotation center.
*/
ol.View2D.prototype.rotate = function(rotation, opt_anchor) {
if (goog.isDef(opt_anchor)) {
var center = this.calculateCenterRotate(rotation, opt_anchor);
this.setCenter(center);
}
this.setRotation(rotation);
};
/** /**
* Set the center of the current view. * Set the center of the current view.
* @param {ol.Coordinate|undefined} center Center. * @param {ol.Coordinate|undefined} center Center.