Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(238)

Side by Side Diff: third_party/WebKit/Source/core/animation/ScrollTimeline.cpp

Issue 2873493002: Basic ScrollTimeline implementation for Animation Worklet (Closed)
Patch Set: Make document reference non-const Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "core/animation/ScrollTimeline.h"
6
7 #include "core/dom/ExceptionCode.h"
8 #include "core/layout/LayoutBox.h"
9 #include "core/paint/PaintLayerScrollableArea.h"
10
11 namespace blink {
12
13 namespace {
14 bool StringToScrollDirection(String scroll_direction,
15 ScrollTimeline::ScrollDirection* result) {
16 if (scroll_direction == "auto") {
17 *result = ScrollTimeline::Auto;
18 return true;
19 }
20 if (scroll_direction == "block") {
21 *result = ScrollTimeline::Block;
22 return true;
23 }
24 if (scroll_direction == "inline") {
25 *result = ScrollTimeline::Inline;
26 return true;
27 }
28 return false;
29 }
30 } // namespace
31
32 ScrollTimeline* ScrollTimeline::Create(Document& document,
33 ScrollTimelineOptions options,
34 ExceptionState& exception_state) {
35 Element* scroll_source = options.scrollSource() ? options.scrollSource()
36 : document.scrollingElement();
37
38 ScrollDirection orientation;
39 if (!StringToScrollDirection(options.orientation(), &orientation)) {
40 exception_state.ThrowDOMException(kNotSupportedError,
41 "Invalid orientation");
42 return nullptr;
43 }
44
45 // TODO(smcgruer): Support 'auto' value.
46 if (options.timeRange().isScrollTimelineAutoKeyword()) {
47 exception_state.ThrowDOMException(
48 kNotSupportedError, "'auto' value for timeRange not yet supported");
49 return nullptr;
50 }
51
52 return new ScrollTimeline(document, scroll_source, orientation,
53 options.timeRange().getAsDouble());
54 }
55
56 ScrollTimeline::ScrollTimeline(const Document& document,
57 Element* scroll_source,
58 ScrollDirection orientation,
59 double time_range)
60 : AnimationTimeline(const_cast<Document*>(&document), nullptr),
61 scroll_source_(scroll_source),
62 orientation_(orientation),
63 time_range_(time_range) {}
64
65 double ScrollTimeline::currentTime(bool& is_null) {
66 // 1. If scrollSource does not currently have a CSS layout box, or if its
67 // layout box is not a scroll container, return an unresolved time value.
68 LayoutBox* layout_box = scroll_source_->GetLayoutBox();
69 if (!layout_box || !layout_box->HasOverflowClip()) {
70 is_null = true;
71 return std::numeric_limits<double>::quiet_NaN();
72 }
73
74 // 2. Otherwise, let current scroll offset be the current scroll offset of
75 // scrollSource in the direction specified by orientation.
76
77 // 'auto' ScrollDirection is specified as: If only one direction is
78 // scrollable, selects that direction. Otherwise selects the direction along
79 // the block axis.
80 ScrollDirection local_orientation = orientation_;
81 bool is_horizontal = layout_box->IsHorizontalWritingMode();
82 if (local_orientation == Auto) {
83 if (layout_box->HasScrollableOverflowX() &&
84 !layout_box->HasScrollableOverflowY()) {
85 local_orientation = is_horizontal ? Inline : Block;
86 } else if (!layout_box->HasScrollableOverflowX() &&
87 layout_box->HasScrollableOverflowY()) {
88 local_orientation = is_horizontal ? Block : Inline;
89 } else {
90 // Either neither or both axes are scrollable, so select the block
91 // direction.
92 local_orientation = Block;
93 }
94 }
95
96 // Depending on the writing-mode and direction, the scroll origin shifts and
97 // the scroll offset may be negative. The easiest way to deal with this is to
98 // use only the magnitude of the scroll offset, and compare it to (max-offset
99 // - min_offset).
flackr 2017/05/18 15:11:50 There is always the risk that the max or min may n
smcgruer 2017/05/18 15:42:57 Added a DCHECK, since this is a pre-requisite of t
100 PaintLayerScrollableArea* scrollable_area = layout_box->GetScrollableArea();
101 ScrollOffset scroll_offset = scrollable_area->GetScrollOffset();
102 ScrollOffset scroll_dimensions = scrollable_area->MaximumScrollOffset() -
103 scrollable_area->MinimumScrollOffset();
104
105 double current_offset;
106 double max_offset;
107 DCHECK(local_orientation == Block || local_orientation == Inline);
108 if (local_orientation == Block) {
109 current_offset =
110 is_horizontal ? scroll_offset.Height() : scroll_offset.Width();
111 max_offset =
112 is_horizontal ? scroll_dimensions.Height() : scroll_dimensions.Width();
113 } else {
114 current_offset =
115 is_horizontal ? scroll_offset.Width() : scroll_offset.Height();
116 max_offset =
117 is_horizontal ? scroll_dimensions.Width() : scroll_dimensions.Height();
118 }
119
120 // 3. If current scroll offset is less than startScrollOffset, return an
121 // unresolved time value if fill is none or forwards, or 0 otherwise.
122 // TODO(smcgruer): Implement |startScrollOffset| and |fill|.
123
124 // 4. If current scroll offset is greater than or equal to endScrollOffset,
125 // return an unresolved time value if fill is none or backwards, or the
126 // effective time range otherwise.
127 // TODO(smcgruer): Implement |endScrollOffset| and |fill|.
128
129 // 5. Return the result of evaluating the following expression:
130 // ((current scroll offset - startScrollOffset) /
131 // (endScrollOffset - startScrollOffset)) * effective time range
132
133 is_null = false;
134 return (std::abs(current_offset) / max_offset) * time_range_;
135 }
136
137 double ScrollTimeline::currentTime() {
138 bool ignored;
139 return currentTime(ignored);
140 }
141
142 double ScrollTimeline::CurrentTimeInternal(bool& is_null) {
143 return currentTime(is_null);
144 }
145
146 double ScrollTimeline::CurrentTimeInternal() {
147 bool ignored;
148 return currentTime(ignored);
149 }
150
151 Element* ScrollTimeline::scrollSource() {
152 return scroll_source_.Get();
153 }
154
155 String ScrollTimeline::orientation() {
156 switch (orientation_) {
157 case Auto:
158 return "auto";
159 case Block:
160 return "block";
161 case Inline:
162 return "inline";
163 }
164 }
165
166 void ScrollTimeline::timeRange(DoubleOrScrollTimelineAutoKeyword& result) {
167 result.setDouble(time_range_);
168 }
169
170 DEFINE_TRACE(ScrollTimeline) {
171 visitor->Trace(scroll_source_);
172 AnimationTimeline::Trace(visitor);
173 }
174
175 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/animation/ScrollTimeline.h ('k') | third_party/WebKit/Source/core/animation/ScrollTimeline.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698