OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 | 6 |
7 #include "CCPageScaleAnimation.h" | 7 #include "CCPageScaleAnimation.h" |
8 | 8 |
9 #include "FloatRect.h" | 9 #include "FloatRect.h" |
10 #include "FloatSize.h" | 10 #include "FloatSize.h" |
11 | 11 |
12 #include <math.h> | 12 #include <math.h> |
13 | 13 |
14 namespace cc { | 14 namespace cc { |
15 | 15 |
16 scoped_ptr<CCPageScaleAnimation> CCPageScaleAnimation::create(const IntSize& scr
ollStart, float pageScaleStart, const IntSize& windowSize, const IntSize& conten
tSize, double startTime) | 16 scoped_ptr<PageScaleAnimation> PageScaleAnimation::create(const IntSize& scrollS
tart, float pageScaleStart, const IntSize& windowSize, const IntSize& contentSiz
e, double startTime) |
17 { | 17 { |
18 return make_scoped_ptr(new CCPageScaleAnimation(scrollStart, pageScaleStart,
windowSize, contentSize, startTime)); | 18 return make_scoped_ptr(new PageScaleAnimation(scrollStart, pageScaleStart, w
indowSize, contentSize, startTime)); |
19 } | 19 } |
20 | 20 |
21 CCPageScaleAnimation::CCPageScaleAnimation(const IntSize& scrollStart, float pag
eScaleStart, const IntSize& windowSize, const IntSize& contentSize, double start
Time) | 21 PageScaleAnimation::PageScaleAnimation(const IntSize& scrollStart, float pageSca
leStart, const IntSize& windowSize, const IntSize& contentSize, double startTime
) |
22 : m_scrollStart(scrollStart) | 22 : m_scrollStart(scrollStart) |
23 , m_pageScaleStart(pageScaleStart) | 23 , m_pageScaleStart(pageScaleStart) |
24 , m_windowSize(windowSize) | 24 , m_windowSize(windowSize) |
25 , m_contentSize(contentSize) | 25 , m_contentSize(contentSize) |
26 , m_anchorMode(false) | 26 , m_anchorMode(false) |
27 , m_scrollEnd(scrollStart) | 27 , m_scrollEnd(scrollStart) |
28 , m_pageScaleEnd(pageScaleStart) | 28 , m_pageScaleEnd(pageScaleStart) |
29 , m_startTime(startTime) | 29 , m_startTime(startTime) |
30 , m_duration(0) | 30 , m_duration(0) |
31 { | 31 { |
32 } | 32 } |
33 | 33 |
34 void CCPageScaleAnimation::zoomTo(const IntSize& finalScroll, float finalPageSca
le, double duration) | 34 void PageScaleAnimation::zoomTo(const IntSize& finalScroll, float finalPageScale
, double duration) |
35 { | 35 { |
36 if (m_pageScaleStart != finalPageScale) { | 36 if (m_pageScaleStart != finalPageScale) { |
37 // For uniform-looking zooming, infer the anchor (point that remains in | 37 // For uniform-looking zooming, infer the anchor (point that remains in |
38 // place throughout the zoom) from the start and end rects. | 38 // place throughout the zoom) from the start and end rects. |
39 FloatRect startRect(IntPoint(m_scrollStart), m_windowSize); | 39 FloatRect startRect(IntPoint(m_scrollStart), m_windowSize); |
40 FloatRect endRect(IntPoint(finalScroll), m_windowSize); | 40 FloatRect endRect(IntPoint(finalScroll), m_windowSize); |
41 endRect.scale(m_pageScaleStart / finalPageScale); | 41 endRect.scale(m_pageScaleStart / finalPageScale); |
42 | 42 |
43 // The anchor is the point which is at the same ratio of the sides of | 43 // The anchor is the point which is at the same ratio of the sides of |
44 // both startRect and endRect. For example, a zoom-in double-tap to a | 44 // both startRect and endRect. For example, a zoom-in double-tap to a |
(...skipping 14 matching lines...) Expand all Loading... |
59 } else { | 59 } else { |
60 // If this is a pure translation, then there exists no anchor. Linearly | 60 // If this is a pure translation, then there exists no anchor. Linearly |
61 // interpolate the scroll offset instead. | 61 // interpolate the scroll offset instead. |
62 m_scrollEnd = finalScroll; | 62 m_scrollEnd = finalScroll; |
63 m_pageScaleEnd = finalPageScale; | 63 m_pageScaleEnd = finalPageScale; |
64 m_duration = duration; | 64 m_duration = duration; |
65 m_anchorMode = false; | 65 m_anchorMode = false; |
66 } | 66 } |
67 } | 67 } |
68 | 68 |
69 void CCPageScaleAnimation::zoomWithAnchor(const IntSize& anchor, float finalPage
Scale, double duration) | 69 void PageScaleAnimation::zoomWithAnchor(const IntSize& anchor, float finalPageSc
ale, double duration) |
70 { | 70 { |
71 m_scrollEnd = m_scrollStart + anchor; | 71 m_scrollEnd = m_scrollStart + anchor; |
72 m_scrollEnd.scale(finalPageScale / m_pageScaleStart); | 72 m_scrollEnd.scale(finalPageScale / m_pageScaleStart); |
73 m_scrollEnd -= anchor; | 73 m_scrollEnd -= anchor; |
74 | 74 |
75 m_scrollEnd.clampNegativeToZero(); | 75 m_scrollEnd.clampNegativeToZero(); |
76 FloatSize scaledContentSize(m_contentSize); | 76 FloatSize scaledContentSize(m_contentSize); |
77 scaledContentSize.scale(finalPageScale / m_pageScaleStart); | 77 scaledContentSize.scale(finalPageScale / m_pageScaleStart); |
78 IntSize maxScrollPosition = roundedIntSize(scaledContentSize - m_windowSize)
; | 78 IntSize maxScrollPosition = roundedIntSize(scaledContentSize - m_windowSize)
; |
79 m_scrollEnd = m_scrollEnd.shrunkTo(maxScrollPosition); | 79 m_scrollEnd = m_scrollEnd.shrunkTo(maxScrollPosition); |
80 | 80 |
81 m_anchor = anchor; | 81 m_anchor = anchor; |
82 m_pageScaleEnd = finalPageScale; | 82 m_pageScaleEnd = finalPageScale; |
83 m_duration = duration; | 83 m_duration = duration; |
84 m_anchorMode = true; | 84 m_anchorMode = true; |
85 } | 85 } |
86 | 86 |
87 IntSize CCPageScaleAnimation::scrollOffsetAtTime(double time) const | 87 IntSize PageScaleAnimation::scrollOffsetAtTime(double time) const |
88 { | 88 { |
89 return scrollOffsetAtRatio(progressRatioForTime(time)); | 89 return scrollOffsetAtRatio(progressRatioForTime(time)); |
90 } | 90 } |
91 | 91 |
92 float CCPageScaleAnimation::pageScaleAtTime(double time) const | 92 float PageScaleAnimation::pageScaleAtTime(double time) const |
93 { | 93 { |
94 return pageScaleAtRatio(progressRatioForTime(time)); | 94 return pageScaleAtRatio(progressRatioForTime(time)); |
95 } | 95 } |
96 | 96 |
97 bool CCPageScaleAnimation::isAnimationCompleteAtTime(double time) const | 97 bool PageScaleAnimation::isAnimationCompleteAtTime(double time) const |
98 { | 98 { |
99 return time >= endTime(); | 99 return time >= endTime(); |
100 } | 100 } |
101 | 101 |
102 float CCPageScaleAnimation::progressRatioForTime(double time) const | 102 float PageScaleAnimation::progressRatioForTime(double time) const |
103 { | 103 { |
104 if (isAnimationCompleteAtTime(time)) | 104 if (isAnimationCompleteAtTime(time)) |
105 return 1; | 105 return 1; |
106 | 106 |
107 return (time - m_startTime) / m_duration; | 107 return (time - m_startTime) / m_duration; |
108 } | 108 } |
109 | 109 |
110 IntSize CCPageScaleAnimation::scrollOffsetAtRatio(float ratio) const | 110 IntSize PageScaleAnimation::scrollOffsetAtRatio(float ratio) const |
111 { | 111 { |
112 if (ratio <= 0) | 112 if (ratio <= 0) |
113 return m_scrollStart; | 113 return m_scrollStart; |
114 if (ratio >= 1) | 114 if (ratio >= 1) |
115 return m_scrollEnd; | 115 return m_scrollEnd; |
116 | 116 |
117 float currentPageScale = pageScaleAtRatio(ratio); | 117 float currentPageScale = pageScaleAtRatio(ratio); |
118 IntSize currentScrollOffset; | 118 IntSize currentScrollOffset; |
119 if (m_anchorMode) { | 119 if (m_anchorMode) { |
120 // Keep the anchor stable on the screen at the current scale. | 120 // Keep the anchor stable on the screen at the current scale. |
121 IntSize documentAnchor = m_scrollStart + m_anchor; | 121 IntSize documentAnchor = m_scrollStart + m_anchor; |
122 documentAnchor.scale(currentPageScale / m_pageScaleStart); | 122 documentAnchor.scale(currentPageScale / m_pageScaleStart); |
123 currentScrollOffset = documentAnchor - m_anchor; | 123 currentScrollOffset = documentAnchor - m_anchor; |
124 } else { | 124 } else { |
125 // First move both scroll offsets to the current coordinate space. | 125 // First move both scroll offsets to the current coordinate space. |
126 FloatSize scaledStartScroll(m_scrollStart); | 126 FloatSize scaledStartScroll(m_scrollStart); |
127 scaledStartScroll.scale(currentPageScale / m_pageScaleStart); | 127 scaledStartScroll.scale(currentPageScale / m_pageScaleStart); |
128 FloatSize scaledEndScroll(m_scrollEnd); | 128 FloatSize scaledEndScroll(m_scrollEnd); |
129 scaledEndScroll.scale(currentPageScale / m_pageScaleEnd); | 129 scaledEndScroll.scale(currentPageScale / m_pageScaleEnd); |
130 | 130 |
131 // Linearly interpolate between them. | 131 // Linearly interpolate between them. |
132 FloatSize delta = scaledEndScroll - scaledStartScroll; | 132 FloatSize delta = scaledEndScroll - scaledStartScroll; |
133 delta.scale(ratio); | 133 delta.scale(ratio); |
134 currentScrollOffset = roundedIntSize(scaledStartScroll + delta); | 134 currentScrollOffset = roundedIntSize(scaledStartScroll + delta); |
135 } | 135 } |
136 | 136 |
137 return currentScrollOffset; | 137 return currentScrollOffset; |
138 } | 138 } |
139 | 139 |
140 float CCPageScaleAnimation::pageScaleAtRatio(float ratio) const | 140 float PageScaleAnimation::pageScaleAtRatio(float ratio) const |
141 { | 141 { |
142 if (ratio <= 0) | 142 if (ratio <= 0) |
143 return m_pageScaleStart; | 143 return m_pageScaleStart; |
144 if (ratio >= 1) | 144 if (ratio >= 1) |
145 return m_pageScaleEnd; | 145 return m_pageScaleEnd; |
146 | 146 |
147 // Linearly interpolate the magnitude in log scale. | 147 // Linearly interpolate the magnitude in log scale. |
148 // Log scale is needed to maintain the appearance of uniform zoom. For | 148 // Log scale is needed to maintain the appearance of uniform zoom. For |
149 // example, if we zoom from 0.5 to 4.0 in 3 seconds, then we should | 149 // example, if we zoom from 0.5 to 4.0 in 3 seconds, then we should |
150 // be zooming by 2x every second. | 150 // be zooming by 2x every second. |
151 float diff = m_pageScaleEnd / m_pageScaleStart; | 151 float diff = m_pageScaleEnd / m_pageScaleStart; |
152 float logDiff = log(diff); | 152 float logDiff = log(diff); |
153 logDiff *= ratio; | 153 logDiff *= ratio; |
154 diff = exp(logDiff); | 154 diff = exp(logDiff); |
155 return m_pageScaleStart * diff; | 155 return m_pageScaleStart * diff; |
156 } | 156 } |
157 | 157 |
158 } // namespace cc | 158 } // namespace cc |
OLD | NEW |