Пример #1
0
drape_ptr<MapLinearAnimation> GetRectAnimation(ScreenBase const & startScreen, ScreenBase const & endScreen)
{
  auto anim = make_unique_dp<MapLinearAnimation>();

  anim->SetRotate(startScreen.GetAngle(), endScreen.GetAngle());
  anim->SetMove(startScreen.GetOrg(), endScreen.GetOrg(),
                startScreen.PixelRectIn3d(), (startScreen.GetScale() + endScreen.GetScale()) / 2.0);
  anim->SetScale(startScreen.GetScale(), endScreen.GetScale());
  anim->SetMaxScaleDuration(kMaxAnimationTimeSec);

  return anim;
}
Пример #2
0
drape_ptr<SequenceAnimation> GetPrettyFollowAnimation(ScreenBase const & startScreen, m2::PointD const & userPos, double targetScale,
                                                      double targetAngle, m2::PointD const & endPixelPos)
{
  auto sequenceAnim = make_unique_dp<SequenceAnimation>();
  sequenceAnim->SetCustomType(kPrettyFollowAnim);

  m2::RectD const viewportRect = startScreen.PixelRectIn3d();

  ScreenBase tmp = startScreen;
  tmp.SetAngle(targetAngle);
  tmp.MatchGandP3d(userPos, viewportRect.Center());

  double const moveDuration = PositionInterpolator::GetMoveDuration(startScreen.GetOrg(), tmp.GetOrg(), startScreen);
  ASSERT_GREATER(moveDuration, 0.0, ());

  double const scaleFactor = moveDuration / kMaxAnimationTimeSec * 2.0;

  tmp = startScreen;

  if (moveDuration > 0.0)
  {
    tmp.SetScale(startScreen.GetScale() * scaleFactor);

    auto zoomOutAnim = make_unique_dp<MapLinearAnimation>();
    zoomOutAnim->SetScale(startScreen.GetScale(), tmp.GetScale());
    zoomOutAnim->SetMaxDuration(kMaxAnimationTimeSec * 0.5);
    sequenceAnim->AddAnimation(move(zoomOutAnim));

    tmp.MatchGandP3d(userPos, viewportRect.Center());

    auto moveAnim = make_unique_dp<MapLinearAnimation>();
    moveAnim->SetMove(startScreen.GetOrg(), tmp.GetOrg(), viewportRect, tmp.GetScale());
    moveAnim->SetMaxDuration(kMaxAnimationTimeSec);
    sequenceAnim->AddAnimation(move(moveAnim));
  }

  auto followAnim = make_unique_dp<MapFollowAnimation>(tmp, userPos, endPixelPos,
                                                       tmp.GetScale(), targetScale,
                                                       tmp.GetAngle(), targetAngle,
                                                       false /* isAutoZoom */);
  followAnim->SetMaxDuration(kMaxAnimationTimeSec * 0.5);
  sequenceAnim->AddAnimation(move(followAnim));
  return sequenceAnim;
}
Пример #3
0
void Navigator::SetFromScreen(ScreenBase const & screen, uint32_t tileSize, double visualScale)
{
  ScreenBase tmp = ScaleInto(screen, df::GetWorldRect());

  if (!CheckMaxScale(tmp, tileSize, visualScale))
  {
    int const scale = scales::GetUpperStyleScale() - 1;
    m2::RectD newRect = df::GetRectForDrawScale(scale, screen.GetOrg());
    newRect.Scale(m_Screen.GetScale3d());
    CheckMinMaxVisibleScale(newRect, scale, m_Screen.GetScale3d());
    tmp = m_Screen;
    tmp.SetFromRect(m2::AnyRectD(newRect));

    ASSERT(CheckMaxScale(tmp, tileSize, visualScale), ());
  }
Пример #4
0
bool MapFollowAnimation::GetProperty(TObject object, TProperty property, bool targetValue, PropertyValue & value) const
{
  if (property == Animation::Position)
  {
    ScreenBase tmp = AnimationSystem::Instance().GetLastScreen();
    if (targetValue)
    {
      tmp.SetFromParams(m_globalPosition, m_angleInterpolator.GetTargetAngle(), m_isAutoZoom ? m_scaleInterpolator.GetScale()
                                                                                             : m_scaleInterpolator.GetTargetScale());
      tmp.MatchGandP3d(m_globalPosition, m_endPixelPosition);
    }
    else
    {
      double const scale = m_scaleInterpolator.GetScale() / m_scaleInterpolator.GetStartScale();
      double const angle = m_angleInterpolator.GetAngle() - m_angleInterpolator.GetStartAngle();
      m2::PointD offset = m_offsetInterpolator.GetPosition() * scale;
      offset.Rotate(angle);
      m2::PointD pos = m_globalPosition + offset;

      tmp.SetFromParams(m_globalPosition, m_angleInterpolator.GetAngle(), m_scaleInterpolator.GetScale());
      tmp.MatchGandP3d(pos, m_endPixelPosition);
    }
    value = PropertyValue(tmp.GetOrg());
    return true;
  }
  if (property == Animation::Angle)
  {
    value = PropertyValue(targetValue ? m_angleInterpolator.GetTargetAngle() : m_angleInterpolator.GetAngle());
    return true;
  }
  if (property == Animation::Scale)
  {
    value = PropertyValue((targetValue && !m_isAutoZoom) ? m_scaleInterpolator.GetTargetScale()
                                                         : m_scaleInterpolator.GetScale());
    return true;
  }
  ASSERT(false, ("Wrong property:", property));
  return false;
}
Пример #5
0
ScreenBase const ShrinkAndScaleInto(ScreenBase const & screen, m2::RectD boundRect)
{
  ReduceRectHack(boundRect);

  ScreenBase res = screen;

  m2::RectD globalRect = res.ClipRect();

  m2::PointD newOrg = res.GetOrg();
  double scale = 1;
  double offs = 0;

  if (globalRect.minX() < boundRect.minX())
  {
    offs = boundRect.minX() - globalRect.minX();
    globalRect.Offset(offs, 0);
    newOrg.x += offs;

    if (globalRect.maxX() > boundRect.maxX())
    {
      double k = boundRect.SizeX() / globalRect.SizeX();
      scale /= k;
      /// scaling always occur pinpointed to the rect center...
      globalRect.Scale(k);
      /// ...so we should shift a rect after scale
      globalRect.Offset(boundRect.minX() - globalRect.minX(), 0);
    }
  }

  if (globalRect.maxX() > boundRect.maxX())
  {
    offs = boundRect.maxX() - globalRect.maxX();
    globalRect.Offset(offs, 0);
    newOrg.x += offs;

    if (globalRect.minX() < boundRect.minX())
    {
      double k = boundRect.SizeX() / globalRect.SizeX();
      scale /= k;
      globalRect.Scale(k);
      globalRect.Offset(boundRect.maxX() - globalRect.maxX(), 0);
    }
  }

  if (globalRect.minY() < boundRect.minY())
  {
    offs = boundRect.minY() - globalRect.minY();
    globalRect.Offset(0, offs);
    newOrg.y += offs;

    if (globalRect.maxY() > boundRect.maxY())
    {
      double k = boundRect.SizeY() / globalRect.SizeY();
      scale /= k;
      globalRect.Scale(k);
      globalRect.Offset(0, boundRect.minY() - globalRect.minY());
    }
  }

  if (globalRect.maxY() > boundRect.maxY())
  {
    offs = boundRect.maxY() - globalRect.maxY();
    globalRect.Offset(0, offs);
    newOrg.y += offs;

    if (globalRect.minY() < boundRect.minY())
    {
      double k = boundRect.SizeY() / globalRect.SizeY();
      scale /= k;
      globalRect.Scale(k);
      globalRect.Offset(0, boundRect.maxY() - globalRect.maxY());
    }
  }

  res.SetOrg(globalRect.Center());
  res.Scale(scale);

  return res;
}