| 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 |