OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of $LIBRARYNAME; | 5 part of $LIBRARYNAME; |
6 | 6 |
7 typedef void RemoveFrameRequestMapping(int id); | |
8 | |
9 /** | |
10 * The task object representing animation-frame requests. | |
11 * | |
12 * For historical reasons, [Window.requestAnimationFrame] returns an integer | |
13 * to users. However, zone tasks must be unique objects, and an integer can | |
14 * therefore not be used as task object. The [Window] class thus keeps a mapping | |
15 * from the integer ID to the corresponding task object. All zone related | |
16 * operations work on this task object, whereas users of | |
17 * [Window.requestAnimationFrame] only see the integer ID. | |
18 * | |
19 * Since this mapping takes up space, it must be removed as soon as the | |
20 * animation-frame task has triggered. The default implementation does this | |
21 * automatically, but intercepted implementations of `requestAnimationFrame` | |
22 * must ensure to call the [AnimationFrameTask.removeMapping] | |
23 * function that is provided in the task specification. | |
24 */ | |
25 abstract class AnimationFrameTask { | |
26 /** The ID that is returned to users. */ | |
27 int get id; | |
28 | |
29 /** The function that is invoked when the user cancels the request. */ | |
Lasse Reichstein Nielsen
2016/06/29 09:22:12
-> A function which
and consider: when -> if
May
floitsch
2016/06/30 19:42:49
Done.
| |
30 void cancel(Window window); | |
31 | |
32 /** The zone in which the task should run. */ | |
Lasse Reichstein Nielsen
2016/06/29 09:22:12
should -> will
floitsch
2016/06/30 19:42:49
Done.
| |
33 Zone get zone; | |
34 | |
35 /** | |
36 * Maps animation-frame request IDs to their task objects. | |
37 */ | |
38 static final Map<int, _AnimationFrameTask> _tasks = {}; | |
39 | |
40 /** | |
41 * The function that should be invoked by user-implemented animation-frame | |
Lasse Reichstein Nielsen
2016/06/29 09:22:12
-> A function which must ...
floitsch
2016/06/30 19:42:49
Reworded.
| |
42 * tasks, before running [callback]. | |
43 * | |
44 * See [AnimationFrameTask]. | |
45 */ | |
46 static void removeMapping(int id) { | |
47 _tasks.remove(id); | |
48 } | |
49 } | |
50 | |
51 class _AnimationFrameTask implements AnimationFrameTask { | |
52 final int id; | |
53 final Zone zone; | |
54 final FrameRequestCallback _callback; | |
55 | |
56 _AnimationFrameTask(this.id, this.zone, this._callback); | |
57 | |
58 void cancel(Window window) { | |
59 window._cancelAnimationFrame(this.id); | |
60 } | |
61 } | |
62 | |
63 /** | |
64 * The task specification for an animation-frame request. | |
Lasse Reichstein Nielsen
2016/06/29 09:22:12
Is there anything more to say about this class? Pe
floitsch
2016/06/30 19:42:49
I added an "experimental" note.
| |
65 */ | |
66 class AnimationFrameRequestSpecification implements TaskSpecification { | |
67 /** | |
68 * The window on which [Window.requestAnimationFrame] was invoked. | |
69 */ | |
70 final Window window; | |
71 | |
72 /** | |
73 * The callback that should be executed when the animation-frame is ready. | |
Lasse Reichstein Nielsen
2016/06/29 09:22:12
should -> will
floitsch
2016/06/30 19:42:49
-> is.
done.
| |
74 * | |
75 * Note that the callback hasn't been registered in any zone yet. | |
Lasse Reichstein Nielsen
2016/06/29 09:22:12
"yet" isn't a good word for a final property which
floitsch
2016/06/30 19:42:49
Reworded. The important thing is, that the create
| |
76 */ | |
77 final FrameRequestCallback callback; | |
78 | |
79 AnimationFrameRequestSpecification(this.window, this.callback); | |
80 | |
81 String get name => "dart.html.request-animation-frame"; | |
82 bool get isOneShot => true; | |
83 } | |
84 | |
7 @DocsEditable() | 85 @DocsEditable() |
8 $if DART2JS | 86 $if DART2JS |
9 $(ANNOTATIONS)@Native("Window,DOMWindow") | 87 $(ANNOTATIONS)@Native("Window,DOMWindow") |
10 $(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS { | 88 $(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS { |
11 $else | 89 $else |
12 $(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS { | 90 $(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS { |
13 $endif | 91 $endif |
14 | 92 |
15 /** | 93 /** |
16 * Returns a Future that completes just before the window is about to | 94 * Returns a Future that completes just before the window is about to |
17 * repaint so the user can draw an animation frame. | 95 * repaint so the user can draw an animation frame. |
18 * | 96 * |
19 * If you need to later cancel this animation, use [requestAnimationFrame] | 97 * If you need to later cancel this animation, use [requestAnimationFrame] |
20 * instead. | 98 * instead. |
21 * | 99 * |
22 * The [Future] completes to a timestamp that represents a floating | 100 * The [Future] completes to a timestamp that represents a floating |
23 * point value of the number of milliseconds that have elapsed since the page | 101 * point value of the number of milliseconds that have elapsed since the page |
24 * started to load (which is also the timestamp at this call to | 102 * started to load (which is also the timestamp at this call to |
25 * animationFrame). | 103 * animationFrame). |
26 * | 104 * |
27 * Note: The code that runs when the future completes should call | 105 * Note: The code that runs when the future completes should call |
28 * [animationFrame] again for the animation to continue. | 106 * [animationFrame] again for the animation to continue. |
29 */ | 107 */ |
30 Future<num> get animationFrame { | 108 Future<num> get animationFrame { |
31 var completer = new Completer<num>.sync(); | 109 var completer = new Completer<num>.sync(); |
32 requestAnimationFrame((time) { | 110 requestAnimationFrame(completer.complete); |
33 completer.complete(time); | |
34 }); | |
35 return completer.future; | 111 return completer.future; |
36 } | 112 } |
37 | 113 |
38 $if DART2JS | 114 $if DART2JS |
39 /** | 115 /** |
40 * The newest document in this window. | 116 * The newest document in this window. |
41 * | 117 * |
42 * ## Other resources | 118 * ## Other resources |
43 * | 119 * |
44 * * [Loading web | 120 * * [Loading web |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
108 * request. This value only needs to be saved if you intend to call | 184 * request. This value only needs to be saved if you intend to call |
109 * [cancelAnimationFrame] so you can specify the particular animation to | 185 * [cancelAnimationFrame] so you can specify the particular animation to |
110 * cancel. | 186 * cancel. |
111 * | 187 * |
112 * Note: The supplied [callback] needs to call [requestAnimationFrame] again | 188 * Note: The supplied [callback] needs to call [requestAnimationFrame] again |
113 * for the animation to continue. | 189 * for the animation to continue. |
114 */ | 190 */ |
115 @DomName('Window.requestAnimationFrame') | 191 @DomName('Window.requestAnimationFrame') |
116 int requestAnimationFrame(FrameRequestCallback callback) { | 192 int requestAnimationFrame(FrameRequestCallback callback) { |
117 _ensureRequestAnimationFrame(); | 193 _ensureRequestAnimationFrame(); |
118 return _requestAnimationFrame(_wrapZone/*<dynamic, num>*/(callback)); | 194 if (identical(Zone.current, Zone.ROOT)) { |
195 return _requestAnimationFrame(callback); | |
196 } | |
197 var spec = new AnimationFrameRequestSpecification(this, callback); | |
198 var task = Zone.current.createTask/*<AnimationFrameTask>*/( | |
199 _createAnimationFrameTask, spec); | |
200 AnimationFrameTask._tasks[task.id] = task; | |
201 return task.id; | |
202 } | |
203 | |
204 static _AnimationFrameTask _createAnimationFrameTask( | |
205 AnimationFrameRequestSpecification spec, Zone zone) { | |
206 var task; | |
207 var id = spec.window._requestAnimationFrame((num time) { | |
208 AnimationFrameTask.removeMapping(task.id); | |
209 zone.runTask(_runAnimationFrame, task, time); | |
210 }); | |
211 var callback = zone.registerUnaryCallback(spec.callback); | |
212 task = new _AnimationFrameTask(id, zone, callback); | |
213 return task; | |
214 } | |
215 | |
216 static void _runAnimationFrame(_AnimationFrameTask task, num time) { | |
217 task._callback(time); | |
119 } | 218 } |
120 | 219 |
121 /** | 220 /** |
122 * Cancels an animation frame request. | 221 * Cancels an animation frame request. |
123 * | 222 * |
124 * ## Other resources | 223 * ## Other resources |
125 * | 224 * |
126 * * [Window.cancelAnimationFrame](https://developer.mozilla.org/en-US/docs/We b/API/Window.cancelAnimationFrame) | 225 * * [Window.cancelAnimationFrame](https://developer.mozilla.org/en-US/docs/We b/API/Window.cancelAnimationFrame) |
127 * from MDN. | 226 * from MDN. |
128 */ | 227 */ |
129 void cancelAnimationFrame(int id) { | 228 void cancelAnimationFrame(int id) { |
130 _ensureRequestAnimationFrame(); | 229 _ensureRequestAnimationFrame(); |
131 _cancelAnimationFrame(id); | 230 var task = AnimationFrameTask._tasks.remove(id); |
231 if (task == null) { | |
232 // Assume that the animation frame request wasn't intercepted by a zone. | |
233 _cancelAnimationFrame(id); | |
234 return; | |
235 } | |
236 task.cancel(this); | |
132 } | 237 } |
133 | 238 |
134 @JSName('requestAnimationFrame') | 239 @JSName('requestAnimationFrame') |
135 int _requestAnimationFrame(FrameRequestCallback callback) native; | 240 int _requestAnimationFrame(FrameRequestCallback callback) native; |
136 | 241 |
137 @JSName('cancelAnimationFrame') | 242 @JSName('cancelAnimationFrame') |
138 void _cancelAnimationFrame(int id) native; | 243 void _cancelAnimationFrame(int id) native; |
139 | 244 |
140 _ensureRequestAnimationFrame() { | 245 _ensureRequestAnimationFrame() { |
141 if (JS('bool', | 246 if (JS('bool', |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
375 {bool useCapture: false}) { | 480 {bool useCapture: false}) { |
376 $if DART2JS | 481 $if DART2JS |
377 // Specify the generic type for _ElementEventStreamImpl only in dart2js to | 482 // Specify the generic type for _ElementEventStreamImpl only in dart2js to |
378 // avoid checked mode errors in dartium. | 483 // avoid checked mode errors in dartium. |
379 return new _ElementListEventStreamImpl<BeforeUnloadEvent>(e, _eventType, use Capture); | 484 return new _ElementListEventStreamImpl<BeforeUnloadEvent>(e, _eventType, use Capture); |
380 $else | 485 $else |
381 return new _ElementListEventStreamImpl(e, _eventType, useCapture); | 486 return new _ElementListEventStreamImpl(e, _eventType, useCapture); |
382 $endif | 487 $endif |
383 } | 488 } |
384 } | 489 } |
OLD | NEW |