summaryrefslogtreecommitdiffstats
path: root/cc/page_scale_animation.h
blob: fe09d5b55f9c0b4c7d7e8d3fa97335847f92bce4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// Copyright 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CC_PAGE_SCALE_ANIMATION_H_
#define CC_PAGE_SCALE_ANIMATION_H_

#include "base/memory/scoped_ptr.h"
#include "ui/gfx/size.h"
#include "ui/gfx/vector2d_f.h"

namespace cc {

// A small helper class that does the math for zoom animations, primarily for
// double-tap zoom. Initialize it with starting and ending scroll/page scale
// positions and an animation length time, then call ...AtTime() at every frame
// to obtain the current interpolated position.
//
// All sizes and vectors in this class's public methods are in the root scroll
// layer's coordinate space.
class PageScaleAnimation {
public:
    // Construct with the state at the beginning of the animation.
    static scoped_ptr<PageScaleAnimation> create(const gfx::Vector2dF& startScrollOffset, float startPageScaleFactor, const gfx::SizeF& viewportSize, const gfx::SizeF& rootLayerSize, double startTime);

    ~PageScaleAnimation();

    // The following methods initialize the animation. Call one of them
    // immediately after construction to set the final scroll and page scale.

    // Zoom while explicitly specifying the top-left scroll position.
    void zoomTo(const gfx::Vector2dF& targetScrollOffset, float targetPageScaleFactor, double duration);

    // Zoom based on a specified anchor. The animator will attempt to keep it
    // at the same position on the physical display throughout the animation,
    // unless the edges of the root layer are hit. The anchor is specified
    // as an offset from the content layer.
    void zoomWithAnchor(const gfx::Vector2dF& anchor, float targetPageScaleFactor, double duration);

    // Call these functions while the animation is in progress to output the
    // current state.
    gfx::Vector2dF scrollOffsetAtTime(double time) const;
    float pageScaleFactorAtTime(double time) const;
    bool isAnimationCompleteAtTime(double time) const;

    // The following methods return state which is invariant throughout the
    // course of the animation.
    double startTime() const { return m_startTime; }
    double duration() const { return m_duration; }
    double endTime() const { return m_startTime + m_duration; }
    const gfx::Vector2dF& targetScrollOffset() const { return m_targetScrollOffset; }
    float targetPageScaleFactor() const { return m_targetPageScaleFactor; }

protected:
    PageScaleAnimation(const gfx::Vector2dF& startScrollOffset, float startPageScaleFactor, const gfx::SizeF& viewportSize, const gfx::SizeF& rootLayerSize, double startTime);

private:
    void clampTargetScrollOffset();
    void inferTargetScrollOffsetFromStartAnchor();
    void inferTargetAnchorFromScrollOffsets();

    gfx::SizeF startViewportSize() const;
    gfx::SizeF targetViewportSize() const;
    float interpAtTime(double time) const;
    gfx::SizeF viewportSizeAt(float interp) const;
    gfx::Vector2dF scrollOffsetAt(float interp) const;
    gfx::Vector2dF anchorAt(float interp) const;
    gfx::Vector2dF viewportRelativeAnchorAt(float interp) const;
    float pageScaleFactorAt(float interp) const;

    float m_startPageScaleFactor;
    float m_targetPageScaleFactor;
    gfx::Vector2dF m_startScrollOffset;
    gfx::Vector2dF m_targetScrollOffset;

    gfx::Vector2dF m_startAnchor;
    gfx::Vector2dF m_targetAnchor;

    gfx::SizeF m_viewportSize;
    gfx::SizeF m_rootLayerSize;

    double m_startTime;
    double m_duration;
};

}  // namespace cc

#endif  // CC_PAGE_SCALE_ANIMATION_H_