forked from organicmaps/organicmaps
fixed flickering during animation and two-fingers scaling.
This commit is contained in:
parent
877f0234a4
commit
5080d7ccfe
6 changed files with 76 additions and 22 deletions
|
@ -1,6 +1,7 @@
|
|||
#include "animator.hpp"
|
||||
#include "rotate_screen_task.hpp"
|
||||
#include "change_viewport_task.hpp"
|
||||
#include "move_screen_task.hpp"
|
||||
#include "framework.hpp"
|
||||
|
||||
#include "../anim/controller.hpp"
|
||||
|
@ -67,6 +68,43 @@ void Animator::StopRotation()
|
|||
m_rotateScreenTask.reset();
|
||||
}
|
||||
|
||||
shared_ptr<MoveScreenTask> const & Animator::MoveScreen(m2::PointD const & startPt,
|
||||
m2::PointD const & endPt,
|
||||
double speed)
|
||||
{
|
||||
StopMoveScreen();
|
||||
|
||||
m_moveScreenTask.reset(new MoveScreenTask(m_framework,
|
||||
startPt,
|
||||
endPt,
|
||||
speed));
|
||||
|
||||
m_framework->GetAnimController()->AddTask(m_moveScreenTask);
|
||||
|
||||
return m_moveScreenTask;
|
||||
}
|
||||
|
||||
void Animator::StopMoveScreen()
|
||||
{
|
||||
if (m_moveScreenTask)
|
||||
m_moveScreenTask->Lock();
|
||||
|
||||
if (m_moveScreenTask
|
||||
&& !m_moveScreenTask->IsEnded()
|
||||
&& !m_moveScreenTask->IsCancelled())
|
||||
{
|
||||
m_moveScreenTask->Cancel();
|
||||
m_moveScreenTask->Unlock();
|
||||
m_moveScreenTask.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_moveScreenTask)
|
||||
m_moveScreenTask->Unlock();
|
||||
|
||||
m_moveScreenTask.reset();
|
||||
}
|
||||
|
||||
shared_ptr<ChangeViewportTask> const & Animator::ChangeViewport(m2::AnyRectD const & start,
|
||||
m2::AnyRectD const & end,
|
||||
double rotationSpeed)
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
class Framework;
|
||||
class RotateScreenTask;
|
||||
class ChangeViewportTask;
|
||||
class MoveScreenTask;
|
||||
/// Class, which is responsible for
|
||||
/// tracking all map animations.
|
||||
class Animator
|
||||
|
@ -18,6 +19,7 @@ private:
|
|||
|
||||
shared_ptr<RotateScreenTask> m_rotateScreenTask;
|
||||
shared_ptr<ChangeViewportTask> m_changeViewportTask;
|
||||
shared_ptr<MoveScreenTask> m_moveScreenTask;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -36,4 +38,10 @@ public:
|
|||
void StopChangeViewport();
|
||||
/// get screen rotation speed
|
||||
double GetRotationSpeed() const;
|
||||
/// move screen from one point to another
|
||||
shared_ptr<MoveScreenTask> const & MoveScreen(m2::PointD const & startPt,
|
||||
m2::PointD const & endPt,
|
||||
double speed);
|
||||
/// stopping screen movement
|
||||
void StopMoveScreen();
|
||||
};
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "framework.hpp"
|
||||
#include "compass_filter.hpp"
|
||||
#include "change_viewport_task.hpp"
|
||||
#include "move_screen_task.hpp"
|
||||
|
||||
#include "../yg/display_list.hpp"
|
||||
#include "../yg/skin.hpp"
|
||||
|
@ -502,12 +503,13 @@ namespace location
|
|||
|
||||
controller->Lock();
|
||||
|
||||
m2::AnyRectD startRect = m_framework->GetNavigator().Screen().GlobalRect();
|
||||
m2::AnyRectD endRect = m2::AnyRectD(Position(),
|
||||
startRect.Angle().val(),
|
||||
m2::RectD(startRect.GetLocalRect()));
|
||||
m2::PointD startPt = m_framework->GetNavigator().Screen().GetOrg();
|
||||
m2::PointD endPt = Position();
|
||||
|
||||
m_framework->GetAnimator().ChangeViewport(startRect, endRect, 2);
|
||||
ScreenBase const & s = m_framework->GetNavigator().Screen();
|
||||
double speed = min(0.5, 0.5 * s.GtoP(startPt).Length(s.GtoP(endPt)) / 50.0);
|
||||
|
||||
m_framework->GetAnimator().MoveScreen(startPt, endPt, speed);
|
||||
|
||||
controller->Unlock();
|
||||
}
|
||||
|
@ -518,12 +520,12 @@ namespace location
|
|||
|
||||
controller->Lock();
|
||||
|
||||
m2::AnyRectD startRect = m_framework->GetNavigator().Screen().GlobalRect();
|
||||
m2::AnyRectD endRect = m2::AnyRectD(Position(),
|
||||
-m_compassFilter.GetHeadingRad(),
|
||||
m2::RectD(startRect.GetLocalRect()));
|
||||
m2::PointD startPt = m_framework->GetNavigator().Screen().GetOrg();
|
||||
m2::PointD endPt = Position();
|
||||
ScreenBase const & s = m_framework->GetNavigator().Screen();
|
||||
double speed = min(0.5,0.5 * s.GtoP(startPt).Length(s.GtoP(endPt)) / 50.0);
|
||||
|
||||
shared_ptr<ChangeViewportTask> const & t = m_framework->GetAnimator().ChangeViewport(startRect, endRect, 2);
|
||||
shared_ptr<MoveScreenTask> const & t = m_framework->GetAnimator().MoveScreen(startPt, endPt, speed);
|
||||
|
||||
t->Lock();
|
||||
t->AddCallback(anim::Task::EEnded, bind(&State::SetIsCentered, this, true));
|
||||
|
@ -547,6 +549,7 @@ namespace location
|
|||
SetCompassProcessMode(ECompassDoNothing);
|
||||
m_framework->GetAnimator().StopRotation();
|
||||
m_framework->GetAnimator().StopChangeViewport();
|
||||
m_framework->GetAnimator().StopMoveScreen();
|
||||
setState(EActive);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,14 +15,17 @@ MoveScreenTask::MoveScreenTask(Framework * framework,
|
|||
|
||||
void MoveScreenTask::OnStep(double ts)
|
||||
{
|
||||
m2::PointD oldPt = m_outPt;
|
||||
anim::SegmentInterpolation::OnStep(ts);
|
||||
m_framework->GetNavigator().SetOrg(m_outPt);
|
||||
Navigator & nav = m_framework->GetNavigator();
|
||||
nav.SetOrg(nav.Screen().GetOrg() + m_outPt - oldPt);
|
||||
}
|
||||
|
||||
void MoveScreenTask::OnEnd(double ts)
|
||||
{
|
||||
anim::SegmentInterpolation::OnEnd(ts);
|
||||
m_framework->GetNavigator().SetOrg(m_outPt);
|
||||
Navigator & nav = m_framework->GetNavigator();
|
||||
nav.SetOrg(m_outPt);
|
||||
}
|
||||
|
||||
bool MoveScreenTask::IsVisual() const
|
||||
|
|
|
@ -398,8 +398,8 @@ void Navigator::StartScale(m2::PointD const & pt1, m2::PointD const & pt2, doubl
|
|||
{
|
||||
//LOG(LDEBUG, (pt1.x, pt1.y, pt2.x, pt2.y));
|
||||
m_StartScreen = m_Screen;
|
||||
m_StartPt1 = pt1;
|
||||
m_StartPt2 = pt2;
|
||||
m_StartPt1 = m_LastPt1 = pt1;
|
||||
m_StartPt2 = m_LastPt2 = pt2;
|
||||
m_DoCheckRotationThreshold = m_DoSupportRotation;
|
||||
m_IsRotatingDuringScale = false;
|
||||
|
||||
|
@ -518,9 +518,9 @@ void Navigator::DoScale(m2::PointD const & pt1, m2::PointD const & pt2, double /
|
|||
|
||||
m_Screen = m_StartScreen;
|
||||
|
||||
/// Checking for rotation threshold.
|
||||
if (m_DoCheckRotationThreshold)
|
||||
{
|
||||
//LOG(LINFO, ("checking the rotation threshold"));
|
||||
double s = pt1.Length(pt2) / m_StartPt1.Length(m_StartPt2);
|
||||
double a = ang::AngleTo(pt1, pt2) - ang::AngleTo(m_StartPt1, m_StartPt2);
|
||||
|
||||
|
@ -534,22 +534,22 @@ void Navigator::DoScale(m2::PointD const & pt1, m2::PointD const & pt2, double /
|
|||
{
|
||||
if (isRotationOutBounds)
|
||||
{
|
||||
//LOG(LINFO, ("rotating during scale"));
|
||||
m_IsRotatingDuringScale = true;
|
||||
m_DoCheckRotationThreshold = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//LOG(LINFO, ("not rotating during scale"));
|
||||
m_IsRotatingDuringScale = false;
|
||||
m_DoCheckRotationThreshold = false;
|
||||
}
|
||||
}
|
||||
|
||||
m_Screen = PrevScreen;
|
||||
|
||||
if (!ScaleImpl(pt1, pt2,
|
||||
m_StartPt1, m_StartPt2,
|
||||
pt1.Length(pt2) / m_StartPt1.Length(m_StartPt2) > 1,
|
||||
m_LastPt1, m_LastPt2,
|
||||
pt1.Length(pt2) / m_LastPt1.Length(m_LastPt2) > 1,
|
||||
m_IsRotatingDuringScale))
|
||||
m_Screen = PrevScreen;
|
||||
|
||||
|
@ -559,7 +559,6 @@ void Navigator::DoScale(m2::PointD const & pt1, m2::PointD const & pt2, double /
|
|||
|
||||
void Navigator::StopScale(m2::PointD const & pt1, m2::PointD const & pt2, double timeInSec)
|
||||
{
|
||||
// Ensure that final pos is reached.
|
||||
DoScale(pt1, pt2, timeInSec);
|
||||
ASSERT(m_LastPt1 == pt1, (m_LastPt1.x, m_LastPt1.y, pt1.x, pt1.y));
|
||||
ASSERT(m_LastPt2 == pt2, (m_LastPt2.x, m_LastPt2.y, pt2.x, pt2.y));
|
||||
|
|
|
@ -15,14 +15,17 @@ RotateScreenTask::RotateScreenTask(Framework * framework,
|
|||
|
||||
void RotateScreenTask::OnStep(double ts)
|
||||
{
|
||||
double prevAngle = m_outAngle;
|
||||
anim::AngleInterpolation::OnStep(ts);
|
||||
m_framework->GetNavigator().SetAngle(m_outAngle);
|
||||
Navigator & nav = m_framework->GetNavigator();
|
||||
nav.SetAngle(nav.Screen().GetAngle() + m_outAngle - prevAngle);
|
||||
}
|
||||
|
||||
void RotateScreenTask::OnEnd(double ts)
|
||||
{
|
||||
anim::AngleInterpolation::OnEnd(ts);
|
||||
m_framework->GetNavigator().SetAngle(m_outAngle);
|
||||
Navigator & nav = m_framework->GetNavigator();
|
||||
nav.SetAngle(m_outAngle);
|
||||
}
|
||||
|
||||
bool RotateScreenTask::IsVisual() const
|
||||
|
|
Loading…
Add table
Reference in a new issue