From 3ae58c53a22a613cb70755c18a9396fb44f39a0a Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Wed, 5 Feb 2014 15:16:05 -0500 Subject: [PATCH] refs #30: animated scaleBy * add duration argument to scaleBy & setScale * add scale center arguments to setScale * add animation to Transform::setScale --- include/llmr/map/map.hpp | 4 ++-- include/llmr/map/transform.hpp | 4 ++-- src/map/map.cpp | 8 ++++---- src/map/transform.cpp | 27 +++++++++++++++------------ 4 files changed, 23 insertions(+), 20 deletions(-) diff --git a/include/llmr/map/map.hpp b/include/llmr/map/map.hpp index 46b7dfb3c37..dcabc1338df 100644 --- a/include/llmr/map/map.hpp +++ b/include/llmr/map/map.hpp @@ -43,8 +43,8 @@ class Map { void resetPosition(); /* scale */ - void scaleBy(double ds, double cx, double cy); - void setScale(double scale); + void scaleBy(double ds, double cx = -1, double cy = -1, double duration = 0); + void setScale(double scale, double cx = -1, double cy = -1, double duration = 0); double getScale() const; // void setZoom(double zoom); // void setLonLatZoom(double lon, double lat, double zoom); diff --git a/include/llmr/map/transform.hpp b/include/llmr/map/transform.hpp index 9b39aa149a4..38fe7af863e 100644 --- a/include/llmr/map/transform.hpp +++ b/include/llmr/map/transform.hpp @@ -27,11 +27,11 @@ class Transform { // Relative changes void moveBy(double dx, double dy); - void scaleBy(double ds, double cx, double cy); + void scaleBy(double ds, double cx = -1, double cy = -1, double duration = 0); void rotateBy(double cx, double cy, double sx, double sy, double ex, double ey); // Absolute changes - void setScale(double scale); + void setScale(double scale, double cx = -1, double cy = -1, double duration = 0); void setAngle(double angle, double duration = 0); void setZoom(double zoom); void setLonLat(double lon, double lat); diff --git a/src/map/map.cpp b/src/map/map.cpp index 2828b9d9b9b..146a86bab08 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -65,8 +65,8 @@ void Map::moveBy(double dx, double dy) { settings.save(); } -void Map::scaleBy(double ds, double cx, double cy) { - transform.scaleBy(ds, cx, cy); +void Map::scaleBy(double ds, double cx, double cy, double duration) { + transform.scaleBy(ds, cx, cy, duration); style.cascade(transform.getZoom()); update(); @@ -83,8 +83,8 @@ void Map::rotateBy(double cx, double cy, double sx, double sy, double ex, double settings.save(); } -void Map::setScale(double scale) { - transform.setScale(scale); +void Map::setScale(double scale, double cx, double cy, double duration) { + transform.setScale(scale, cx, cy, duration); style.cascade(transform.getZoom()); update(); diff --git a/src/map/transform.cpp b/src/map/transform.cpp index 98fb0ba206c..f2857195217 100644 --- a/src/map/transform.cpp +++ b/src/map/transform.cpp @@ -33,7 +33,7 @@ void Transform::moveBy(double dx, double dy) { y += cos(angle) * dy + sin(-angle) * dx; } -void Transform::scaleBy(double ds, double cx, double cy) { +void Transform::scaleBy(double ds, double cx, double cy, double duration) { // clamp scale to min/max values double new_scale = scale * ds; if (new_scale < min_scale) { @@ -44,13 +44,7 @@ void Transform::scaleBy(double ds, double cx, double cy) { new_scale = max_scale; } - setScale(new_scale); - - // Correct for non-center scaling location. - const double dx = (cx - width / 2) * (1.0 - ds); - const double dy = (cy - height / 2) * (1.0 - ds); - x += cos(angle) * dx + sin(angle) * dy; - y += cos(angle) * dy + sin(-angle) * dx; + setScale(new_scale, cx, cy, duration); } @@ -92,7 +86,7 @@ void Transform::setAngle(double new_angle, double duration) { } } -void Transform::setScale(double new_scale) { +void Transform::setScale(double new_scale, double cx, double cy, double duration) { if (new_scale < min_scale) { new_scale = min_scale; } else if (new_scale > max_scale) { @@ -100,9 +94,18 @@ void Transform::setScale(double new_scale) { } const double factor = new_scale / scale; - x *= factor; - y *= factor; - scale = new_scale; + const double dx = (cx - width / 2) * (1.0 - factor); + const double dy = (cy - height / 2) * (1.0 - factor); + + if (duration == 0) { + x = x * factor + dx; + y = y * factor + dy; + scale = new_scale; + } else { + animations.emplace_front(x, x * factor + dx, x, duration); + animations.emplace_front(y, y * factor + dy, y, duration); + animations.emplace_front(scale, new_scale, scale, duration); + } const double s = scale * size; zc = s / 2;