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

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

Issue 2873493002: Basic ScrollTimeline implementation for Animation Worklet (Closed)
Patch Set: Add helper method in tests for creating options 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(const Document& document,
33 ScrollTimelineOptions options,
34 ExceptionState& exception_state) {
35 Element* scroll_source =
36 options.scrollSource()
37 ? options.scrollSource()
38 : const_cast<Document&>(document).scrollingElement();
majidvp 2017/05/17 20:39:45 I believe this should instead use |ScrollingElemen
majidvp 2017/05/17 20:39:45 It is odd that this method is not |const| requirin
smcgruer 2017/05/18 13:58:56 My only concern here is that |scrollingElement()|
smcgruer 2017/05/18 14:17:21 Turns out that the Document& doesnt have to be con
39
40 ScrollDirection orientation;
41 if (!StringToScrollDirection(options.orientation(), &orientation)) {
42 exception_state.ThrowDOMException(kNotSupportedError,
43 "Invalid orientation");
44 return nullptr;
45 }
46
47 // TODO(smcgruer): Support 'auto' value.
48 if (options.timeRange().isScrollTimelineAutoKeyword()) {
49 exception_state.ThrowDOMException(
50 kNotSupportedError, "'auto' value for timeRange not yet supported");
51 return nullptr;
52 }
53
54 return new ScrollTimeline(document, scroll_source, orientation,
55 options.timeRange().getAsDouble());
56 }
57
58 ScrollTimeline::ScrollTimeline(const Document& document,
59 Element* scroll_source,
60 ScrollDirection orientation,
61 double time_range)
62 : AnimationTimeline(const_cast<Document*>(&document), nullptr),
63 scroll_source_(scroll_source),
64 orientation_(orientation),
65 time_range_(time_range) {}
66
67 double ScrollTimeline::currentTime(bool& is_null) {
68 // 1. If scrollSource does not currently have a CSS layout box, or if its
69 // layout box is not a scroll container, return an unresolved time value.
70 LayoutBox* layout_box = scroll_source_->GetLayoutBox();
71 if (!layout_box || !layout_box->HasOverflowClip()) {
72 is_null = true;
73 return std::numeric_limits<double>::quiet_NaN();
74 }
75
76 // 2. Otherwise, let current scroll offset be the current scroll offset of
77 // scrollSource in the direction specified by orientation.
78
79 // 'auto' ScrollDirection is specified as: If only one direction is
80 // scrollable, selects that direction. Otherwise selects the direction along
81 // the block axis.
82 ScrollDirection local_orientation = orientation_;
83 bool is_horizontal = layout_box->IsHorizontalWritingMode();
84 if (local_orientation == Auto) {
85 if (layout_box->HasScrollableOverflowX() &&
86 !layout_box->HasScrollableOverflowY()) {
87 local_orientation = is_horizontal ? Inline : Block;
88 } else if (!layout_box->HasScrollableOverflowX() &&
89 layout_box->HasScrollableOverflowY()) {
90 local_orientation = is_horizontal ? Block : Inline;
91 } else {
92 // Either neither or both axes are scrollable, so select the block
93 // direction.
94 local_orientation = Block;
95 }
96 }
majidvp 2017/05/17 20:39:45 Should this decision be made every time we query c
smcgruer 2017/05/18 13:58:56 Filed https://github.com/WICG/scroll-animations/is
smcgruer 2017/05/23 14:47:27 https://github.com/WICG/scroll-animations/issues/1
97
98 // Depending on the writing-mode and direction, the scroll origin shifts and
99 // the scroll offset may be negative. The easiest way to deal with this is to
100 // use only the magnitude of the scroll offset, and compare it to (max-offset
101 // - min_offset).
102 PaintLayerScrollableArea* scrollable_area = layout_box->GetScrollableArea();
103 ScrollOffset abs_scroll_offset =
104 ScrollOffset(std::abs(scrollable_area->GetScrollOffset().Width()),
105 std::abs(scrollable_area->GetScrollOffset().Height()));
106 ScrollOffset max_abs_scroll_offset = scrollable_area->MaximumScrollOffset() -
majidvp 2017/05/17 20:39:45 nit: s/max_abs_scroll_offset/scroll_dimensions/ (
smcgruer 2017/05/18 13:58:56 Done.
107 scrollable_area->MinimumScrollOffset();
108
109 double current_offset;
110 double max_offset;
111 DCHECK(local_orientation == Block || local_orientation == Inline);
112 if (local_orientation == Block) {
113 current_offset =
114 is_horizontal ? abs_scroll_offset.Height() : abs_scroll_offset.Width();
115 max_offset = is_horizontal ? max_abs_scroll_offset.Height()
116 : max_abs_scroll_offset.Width();
117 } else {
118 current_offset =
119 is_horizontal ? abs_scroll_offset.Width() : abs_scroll_offset.Height();
120 max_offset = is_horizontal ? max_abs_scroll_offset.Width()
121 : max_abs_scroll_offset.Height();
122 }
123
124 // 3. If current scroll offset is less than startScrollOffset, return an
125 // unresolved time value if fill is none or forwards, or 0 otherwise.
126 // TODO(smcgruer): Implement |startScrollOffset| and |fill|.
127
128 // 4. If current scroll offset is greater than or equal to endScrollOffset,
129 // return an unresolved time value if fill is none or backwards, or the
130 // effective time range otherwise.
131 // TODO(smcgruer): Implement |endScrollOffset| and |fill|.
132
133 // 5. Return the result of evaluating the following expression:
134 // ((current scroll offset - startScrollOffset) /
135 // (endScrollOffset - startScrollOffset)) * effective time range
136
137 is_null = false;
138 return (current_offset / max_offset) * time_range_;
majidvp 2017/05/17 20:39:44 may be cleaner if we just move std::abs operation
smcgruer 2017/05/18 13:58:56 Done.
139 }
140
141 double ScrollTimeline::currentTime() {
142 bool ignored;
143 return currentTime(ignored);
144 }
145
146 double ScrollTimeline::CurrentTimeInternal(bool& is_null) {
147 return currentTime(is_null);
148 }
149
150 double ScrollTimeline::CurrentTimeInternal() {
151 bool ignored;
152 return currentTime(ignored);
153 }
154
155 Element* ScrollTimeline::scrollSource() {
156 return scroll_source_.Get();
157 }
158
159 String ScrollTimeline::orientation() {
160 switch (orientation_) {
161 case Auto:
162 return "auto";
majidvp 2017/05/17 20:39:45 If we decide to resolve "auto" value on constructi
163 case Block:
164 return "block";
165 case Inline:
166 return "inline";
167 }
168 }
169
170 void ScrollTimeline::timeRange(DoubleOrScrollTimelineAutoKeyword& result) {
171 result.setDouble(time_range_);
172 }
173
174 DEFINE_TRACE(ScrollTimeline) {
175 visitor->Trace(scroll_source_);
176 AnimationTimeline::Trace(visitor);
177 }
178
179 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698