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
89
90
91
92
93
94
95
96
97
98
99
100
101
|
// Copyright 2014 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.
#include "content/child/fling_animator_impl_android.h"
#include "base/logging.h"
#include "third_party/WebKit/public/platform/WebFloatSize.h"
#include "third_party/WebKit/public/platform/WebGestureCurveTarget.h"
#include "ui/gfx/frame_time.h"
#include "ui/gfx/vector2d.h"
namespace content {
namespace {
// Value taken directly from Android's ViewConfiguration. As the value has not
// changed in 4+ years, and does not depend on any device-specific configuration
// parameters, copy it directly to avoid potential JNI interop issues in the
// render process (see crbug.com/362614).
const float kDefaultAndroidPlatformScrollFriction = 0.015f;
gfx::Scroller::Config GetScrollerConfig() {
gfx::Scroller::Config config;
config.flywheel_enabled = false;
config.fling_friction = kDefaultAndroidPlatformScrollFriction;
return config;
}
} // namespace
FlingAnimatorImpl::FlingAnimatorImpl()
: is_active_(false),
scroller_(GetScrollerConfig()) {}
FlingAnimatorImpl::~FlingAnimatorImpl() {}
void FlingAnimatorImpl::StartFling(const gfx::PointF& velocity) {
// No bounds on the fling. See http://webkit.org/b/96403
// Instead, use the largest possible bounds for minX/maxX/minY/maxY. The
// compositor will ignore any attempt to scroll beyond the end of the page.
DCHECK(velocity.x() || velocity.y());
if (is_active_)
CancelFling();
is_active_ = true;
scroller_.Fling(0,
0,
velocity.x(),
velocity.y(),
INT_MIN,
INT_MAX,
INT_MIN,
INT_MAX,
base::TimeTicks());
}
void FlingAnimatorImpl::CancelFling() {
if (!is_active_)
return;
is_active_ = false;
scroller_.AbortAnimation();
}
bool FlingAnimatorImpl::apply(double time,
blink::WebGestureCurveTarget* target) {
// If the fling has yet to start, simply return and report true to prevent
// fling termination.
if (time <= 0)
return true;
const base::TimeTicks time_ticks =
base::TimeTicks() + base::TimeDelta::FromMicroseconds(
time * base::Time::kMicrosecondsPerSecond);
if (!scroller_.ComputeScrollOffset(time_ticks)) {
is_active_ = false;
return false;
}
gfx::PointF current_position(scroller_.GetCurrX(), scroller_.GetCurrY());
gfx::Vector2dF scroll_amount(current_position - last_position_);
last_position_ = current_position;
// scrollBy() could delete this curve if the animation is over, so don't touch
// any member variables after making that call.
return target->scrollBy(blink::WebFloatSize(scroll_amount),
blink::WebFloatSize(scroller_.GetCurrVelocityX(),
scroller_.GetCurrVelocityY()));
}
FlingAnimatorImpl* FlingAnimatorImpl::CreateAndroidGestureCurve(
const blink::WebFloatPoint& velocity,
const blink::WebSize&) {
FlingAnimatorImpl* gesture_curve = new FlingAnimatorImpl();
gesture_curve->StartFling(velocity);
return gesture_curve;
}
} // namespace content
|