| Index: cc/page_scale_animation.cc
|
| diff --git a/cc/page_scale_animation.cc b/cc/page_scale_animation.cc
|
| index e5b1fec043ed1977c3eaac6dfb4f015c57b9f688..e1d5f45436eeae4a27b6e37378c776e2d5ff654e 100644
|
| --- a/cc/page_scale_animation.cc
|
| +++ b/cc/page_scale_animation.cc
|
| @@ -4,19 +4,16 @@
|
|
|
| #include "cc/page_scale_animation.h"
|
|
|
| +#include "base/logging.h"
|
| #include "cc/geometry.h"
|
| #include "ui/gfx/point_f.h"
|
| #include "ui/gfx/rect_f.h"
|
| +#include "ui/gfx/vector2d_conversions.h"
|
|
|
| #include <math.h>
|
|
|
| namespace {
|
|
|
| -gfx::PointF toPointF(const gfx::Vector2dF& vector)
|
| -{
|
| - return gfx::PointF(vector.x(), vector.y());
|
| -}
|
| -
|
| // This takes a viewport-relative vector and returns a vector whose values are
|
| // between 0 and 1, representing the percentage position within the viewport.
|
| gfx::Vector2dF normalizeFromViewport(const gfx::Vector2dF& denormalized, const gfx::SizeF& viewportSize)
|
| @@ -31,10 +28,7 @@ gfx::Vector2dF denormalizeToViewport(const gfx::Vector2dF& normalized, const gfx
|
|
|
| gfx::Vector2dF interpolateBetween(const gfx::Vector2dF& start, const gfx::Vector2dF end, float interp)
|
| {
|
| - gfx::Vector2dF result;
|
| - result.set_x(start.x() + interp * (end.x() - start.x()));
|
| - result.set_y(start.y() + interp * (end.y() - start.y()));
|
| - return result;
|
| + return start + gfx::ScaleVector2d(end - start, interp);
|
| }
|
|
|
| }
|
| @@ -97,47 +91,52 @@ void PageScaleAnimation::zoomWithAnchor(const gfx::Vector2dF& anchor, float targ
|
| inferTargetAnchorFromScrollOffsets();
|
| }
|
|
|
| -gfx::SizeF PageScaleAnimation::viewportSizeAtScale(float pageScaleFactor) const
|
| -{
|
| - return gfx::ScaleSize(m_viewportSize, 1 / pageScaleFactor);
|
| -}
|
| -
|
| void PageScaleAnimation::inferTargetScrollOffsetFromStartAnchor()
|
| {
|
| - gfx::Vector2dF anchorRelativeToStartViewport = m_startAnchor - m_startScrollOffset;
|
| - gfx::Vector2dF normalized = normalizeFromViewport(anchorRelativeToStartViewport, viewportSizeAtScale(m_startPageScaleFactor));
|
| - m_targetScrollOffset = m_startAnchor - denormalizeToViewport(normalized, viewportSizeAtScale(m_targetPageScaleFactor));
|
| + gfx::Vector2dF normalized = normalizeFromViewport(m_startAnchor - m_startScrollOffset, startViewportSize());
|
| + m_targetScrollOffset = m_startAnchor - denormalizeToViewport(normalized, targetViewportSize());
|
| }
|
|
|
| void PageScaleAnimation::inferTargetAnchorFromScrollOffsets()
|
| {
|
| - gfx::RectF startRect(toPointF(m_startScrollOffset), viewportSizeAtScale(m_startPageScaleFactor));
|
| - gfx::RectF targetRect(toPointF(m_targetScrollOffset), viewportSizeAtScale(m_targetPageScaleFactor));
|
| -
|
| // The anchor is the point which is at the same normalized relative position
|
| - // within both startRect and endRect. For example, a zoom-in double-tap to a
|
| - // perfectly centered rect will have normalized anchor (0.5, 0.5), while one
|
| - // to a rect touching the bottom-right of the screen will have normalized
|
| - // anchor (1.0, 1.0). In other words, it obeys the equations:
|
| - // anchorX = start_width * normalizedX + start_x
|
| - // anchorX = target_width * normalizedX + target_x
|
| - // anchorY = start_height * normalizedY + start_y
|
| - // anchorY = target_height * normalizedY + target_y
|
| - // where both anchor{x,y} and normalized{x,y} begin as unknowns. Solving
|
| - // for the normalized, we get the following formulas:
|
| - gfx::Vector2dF normalized;
|
| - normalized.set_x((startRect.x() - targetRect.x()) / (targetRect.width() - startRect.width()));
|
| - normalized.set_y((startRect.y() - targetRect.y()) / (targetRect.height() - startRect.height()));
|
| - m_targetAnchor = m_targetScrollOffset + denormalizeToViewport(normalized, viewportSizeAtScale(m_targetPageScaleFactor));
|
| + // within both start viewport rect and target viewport rect. For example, a
|
| + // zoom-in double-tap to a perfectly centered rect will have normalized
|
| + // anchor (0.5, 0.5), while one to a rect touching the bottom-right of the
|
| + // screen will have normalized anchor (1.0, 1.0). In other words, it obeys
|
| + // the equations:
|
| + // anchor = start_size * normalized + start_offset
|
| + // anchor = target_size * normalized + target_offset
|
| + // where both anchor and normalized begin as unknowns. Solving
|
| + // for the normalized, we get the following:
|
| + float widthScale = 1 / (targetViewportSize().width() - startViewportSize().width());
|
| + float heightScale = 1 / (targetViewportSize().height() - startViewportSize().height());
|
| + gfx::Vector2dF normalized = gfx::ScaleVector2d(m_startScrollOffset - m_targetScrollOffset, widthScale, heightScale);
|
| + m_targetAnchor = m_targetScrollOffset + denormalizeToViewport(normalized, targetViewportSize());
|
| }
|
|
|
| void PageScaleAnimation::clampTargetScrollOffset()
|
| {
|
| - gfx::Vector2dF maxScrollOffset = BottomRight(gfx::RectF(m_rootLayerSize)) - BottomRight(gfx::RectF(viewportSizeAtScale(m_targetPageScaleFactor)));
|
| + gfx::Vector2dF maxScrollOffset = BottomRight(gfx::RectF(m_rootLayerSize)) - BottomRight(gfx::RectF(targetViewportSize()));
|
| m_targetScrollOffset.ClampToMin(gfx::Vector2dF());
|
| m_targetScrollOffset.ClampToMax(maxScrollOffset);
|
| }
|
|
|
| +gfx::SizeF PageScaleAnimation::startViewportSize() const
|
| +{
|
| + return gfx::ScaleSize(m_viewportSize, 1 / m_startPageScaleFactor);
|
| +}
|
| +
|
| +gfx::SizeF PageScaleAnimation::targetViewportSize() const
|
| +{
|
| + return gfx::ScaleSize(m_viewportSize, 1 / m_targetPageScaleFactor);
|
| +}
|
| +
|
| +gfx::SizeF PageScaleAnimation::viewportSizeAt(float interp) const
|
| +{
|
| + return gfx::ScaleSize(m_viewportSize, 1 / pageScaleFactorAt(interp));
|
| +}
|
| +
|
| gfx::Vector2dF PageScaleAnimation::scrollOffsetAtTime(double time) const
|
| {
|
| return scrollOffsetAt(interpAtTime(time));
|
| @@ -155,6 +154,7 @@ bool PageScaleAnimation::isAnimationCompleteAtTime(double time) const
|
|
|
| float PageScaleAnimation::interpAtTime(double time) const
|
| {
|
| + DCHECK_GE(time, m_startTime);
|
| if (isAnimationCompleteAtTime(time))
|
| return 1;
|
|
|
| @@ -174,23 +174,17 @@ gfx::Vector2dF PageScaleAnimation::scrollOffsetAt(float interp) const
|
| gfx::Vector2dF PageScaleAnimation::anchorAt(float interp) const
|
| {
|
| // Interpolate from start to target anchor in absolute space.
|
| - gfx::Vector2dF delta = gfx::ScaleVector2d(m_targetAnchor - m_startAnchor, interp);
|
| - return m_startAnchor + delta;
|
| + return interpolateBetween(m_startAnchor, m_targetAnchor, interp);
|
| }
|
|
|
| gfx::Vector2dF PageScaleAnimation::viewportRelativeAnchorAt(float interp) const
|
| {
|
| - // Interpolate from start to target anchor in the space relative to the
|
| - // viewport at its current scale level.
|
| - gfx::Vector2dF anchorRelativeToStartViewport = m_startAnchor - m_startScrollOffset;
|
| - gfx::Vector2dF anchorRelativeToTargetViewport = m_targetAnchor - m_targetScrollOffset;
|
| -
|
| - gfx::Vector2dF startNormalized = normalizeFromViewport(anchorRelativeToStartViewport, viewportSizeAtScale(m_startPageScaleFactor));
|
| - gfx::Vector2dF targetNormalized = normalizeFromViewport(anchorRelativeToTargetViewport, viewportSizeAtScale(m_targetPageScaleFactor));
|
| + // Interpolate from start to target anchor in normalized space.
|
| + gfx::Vector2dF startNormalized = normalizeFromViewport(m_startAnchor - m_startScrollOffset, startViewportSize());
|
| + gfx::Vector2dF targetNormalized = normalizeFromViewport(m_targetAnchor - m_targetScrollOffset, targetViewportSize());
|
| gfx::Vector2dF interpNormalized = interpolateBetween(startNormalized, targetNormalized, interp);
|
|
|
| - gfx::SizeF currentViewportSize = viewportSizeAtScale(pageScaleFactorAt(interp));
|
| - return denormalizeToViewport(interpNormalized, currentViewportSize);
|
| + return denormalizeToViewport(interpNormalized, viewportSizeAt(interp));
|
| }
|
|
|
| float PageScaleAnimation::pageScaleFactorAt(float interp) const
|
|
|