iris: drive animation from painter frame time
This commit is contained in:
1 parent
9fe6aca1f1
commit
b1416d86bf
19 files changed
+171
-133
No files matched your search
+15
-7
@@ -15,7 +15,7 @@ that struct (`scrollable.rs`); there is exactly one `Flinger` and one
|
||||
`DragGesture` implementation in the crate's widgets. A widget with one
|
||||
implements `Scrollable`, whose one required pair of methods hands the
|
||||
controller back, and gets `scroll`, `fling`, `drag`, `amt`,
|
||||
`is_scrolling`, `tick_fling` and the pin as default methods.
|
||||
`is_scrolling` and the pin as default methods.
|
||||
|
||||
Two widgets have one, and they differ only in how they spend a delta:
|
||||
|
||||
@@ -30,6 +30,14 @@ Two widgets have one, and they differ only in how they spend a delta:
|
||||
Do not give a widget its own fling, scroll amount, or platform wake
|
||||
handle, and do not add scrolling methods to the general `Widget` trait.
|
||||
|
||||
There is no animation registry or animation callback on `Widget`. The
|
||||
platform passes the frame's presentation time through `Painter`; a scrolling
|
||||
widget advances its controller at the beginning of `draw` and calls
|
||||
`Painter::request_next_frame` while the fling remains active. That request is
|
||||
staged until the current retained redraw finishes, then dirties the requesting
|
||||
widget for the following frame. Staging matters because the ordinary dirty set
|
||||
is drained to completion within one frame.
|
||||
|
||||
## One convention for a delta
|
||||
|
||||
**Positive scrolls the reader up or left; negative down or right.** The
|
||||
@@ -60,14 +68,14 @@ means "the end is not in sight". That last is not a placeholder — a lazy
|
||||
layout genuinely cannot say how far its content runs without walking
|
||||
there, and `clamp` takes the answer with no branch of its own.
|
||||
|
||||
**Why the delta is banked rather than applied where it arrives.** A wheel
|
||||
event, a drag frame and a fling tick all land between draws, and none of
|
||||
them can know whether there is content to move into. Applying them at the
|
||||
layout that follows is also what keeps layout a pure function of the state
|
||||
(Iris, 2026-09-08). The visible consequence, and the thing that catches a
|
||||
**Why the delta is banked rather than applied where it arrives.** A wheel or
|
||||
drag lands between draws, and advancing a fling happens at the top of a draw;
|
||||
none of them can know whether there is content to move into until layout runs.
|
||||
Applying them in that layout is also what keeps layout a pure function of the
|
||||
state (Iris, 2026-09-08). The visible consequence, and the thing that catches a
|
||||
test out: **`amt` does not move until the next draw.**
|
||||
|
||||
**Which clock a fling is ticked on.** The vsync the frame callback
|
||||
**Which clock advances a fling.** The vsync the frame callback
|
||||
carries, not `Instant::now()` -- on Android `do_frame`'s
|
||||
`frame_time_nanos`, converted through the view's one `DeviceClock`
|
||||
(`sense.rs`), which also dates every touch sample, so a fling is advanced
|
||||
|
||||
Reference in new issue
Block a user