-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Write more on Animation and related docs #150727
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
A few days ago I started reading up on how animations work, in preparation for starting to use them in a more complex way than I'd done before. I found it a bit difficult to get my head around; in particular the many different classes involved, how they relate to each other, and how to fit them together. So once I had worked that out, I sat down to express it in the form of documentation. The largest change here is an expansion of the docs on [Animation] itself, including a new section "Using animations" with several paragraphs laying out how one typically fits together AnimationController, TickerProvider, CurvedAnimation and/or Tween, and AnimatedWidget subclasses. [Animation] also gets an expanded "See also" list, a revised conceptual intro, and a new summary line. There are also revisions on [TickerProvider], [AnimatedController], and elsewhere; some new exposition, some revisions for clarity, and various small fixes.
| typedef ValueListenableTransformer<T> = T Function(T); | ||
|
|
||
| /// An animation with a value of type `T`. | ||
| /// A value which may change over time, moving forward or backward. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Google developer doc style guide recommends using may for legal contexts only: https://developers.google.com/style/word-list#may
Consider:
| /// A value which may change over time, moving forward or backward. | |
| /// A value that can change over time, moving forwards or backwards. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to the advice for may.
As far as "forward" vs "forwards", after a bit of Googling I found one good article about it. The TL;DR is that "forward" is generally better, but "forwards" is more common in British English.
American spelling suggests "colors" and "gray", while Brits would use "colours" and "grey". The fact that Flutter uses Colors.grey indicates that it's probably not a big deal :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to "might".
To my eye, saying "can" here suggests the wrong meaning — it sounds more like it's saying the code that holds one of these objects can cause the value to change (i.e. it sounds like what an AnimationController is), rather than that the value might change while that code isn't looking.
| /// An animation may move forward or backward on its own as time passes | ||
| /// (like the opacity of a button that fades over a fixed duration | ||
| /// once the user touches it), | ||
| /// or it may be driven by the user | ||
| /// (like the position of a slider that the user can drag back and forth), | ||
| /// or it may do both | ||
| /// (like a switch that snaps into place when releaseed, | ||
| /// or a [Dismissible] that responds to drag and fling gestures, etc.). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| /// An animation may move forward or backward on its own as time passes | |
| /// (like the opacity of a button that fades over a fixed duration | |
| /// once the user touches it), | |
| /// or it may be driven by the user | |
| /// (like the position of a slider that the user can drag back and forth), | |
| /// or it may do both | |
| /// (like a switch that snaps into place when releaseed, | |
| /// or a [Dismissible] that responds to drag and fling gestures, etc.). | |
| /// An animation can move forward or backward on its own as time passes | |
| /// (like the opacity of a button that fades over a fixed duration | |
| /// once the user touches it), | |
| /// or it can be driven by the user | |
| /// (like the position of a slider that the user can drag back and forth), | |
| /// or it can do both | |
| /// (like a switch that snaps into place when releaseed, | |
| /// or a [Dismissible] that responds to drag and fling gestures, etc.). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Changed these to "might", for the same reason as above.)
| /// When an [ImplicitlyAnimatedWidget] suffices, there is | ||
| /// no need to work with [Animation], [AnimationController], or [Tween], | ||
| /// or even to have a [State] to manage the animation (though all of those are | ||
| /// involved in the implementation of the [ImplicitlyAnimatedWidget] itself). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For folks that want simple animation effects, this might be too much context and might be overwhelming. Perhaps we should simplify this section?
Maybe:
| /// When an [ImplicitlyAnimatedWidget] suffices, there is | |
| /// no need to work with [Animation], [AnimationController], or [Tween], | |
| /// or even to have a [State] to manage the animation (though all of those are | |
| /// involved in the implementation of the [ImplicitlyAnimatedWidget] itself). | |
| /// Widgets of this type animate when their inputs change. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, that's useful feedback. How about this?
/// When an [ImplicitlyAnimatedWidget] suffices, there is
/// no need to work with [Animation] or the rest of the classes
/// discussed in this section.The intended point here is to help people confidently stop reading and ignore the rest of the complexity of this API, when what they want is a simple animation effect that AnimatedScale and friends can handle for them.
| /// Otherwise, typically an animation originates with an [AnimationController] | ||
| /// (which is itself an [Animation<double>]) | ||
| /// created by a [State] that implements [TickerProvider], | ||
| /// and then further animations may be derived from it using | ||
| /// e.g. [Tween] or [CurvedAnimation]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sentence introduces quite a few concepts. Maybe consider splitting it in two:
| /// Otherwise, typically an animation originates with an [AnimationController] | |
| /// (which is itself an [Animation<double>]) | |
| /// created by a [State] that implements [TickerProvider], | |
| /// and then further animations may be derived from it using | |
| /// e.g. [Tween] or [CurvedAnimation]. | |
| /// Otherwise, typically an animation originates with an [AnimationController] | |
| /// (which is itself an [Animation<double>]) | |
| /// created by a [State] that implements [TickerProvider]. | |
| /// Further animations can be derived from it using | |
| /// e.g. [Tween] or [CurvedAnimation]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, thanks. Split like this:
/// Otherwise, typically an animation originates with an [AnimationController]
/// (which is itself an [Animation<double>])
/// created by a [State] that implements [TickerProvider].
/// Further animations might be derived from that animation
/// by using e.g. [Tween] or [CurvedAnimation].(I think the referent of "it" is a bit less clear when it's no longer the same sentence, so expanded to "that animation".)
| /// to produce an [Animation<Size>] and an [Animation<Color>] that control | ||
| /// a widget shrinking and changing color as the animation proceeds. | ||
| /// | ||
| /// Because the [Animation] keeps the same identity as the animation proceeds, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an excellent tip. Do you think it deserves its own section?
| /// Because the [Animation] keeps the same identity as the animation proceeds, | |
| /// ## Performance | |
| /// | |
| /// Because the [Animation] keeps the same identity as the animation proceeds, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, good idea.
I expanded the heading slightly to "Performance considerations", following other examples in the codebase.
| /// even while the animation is active. | ||
| /// If the leaf widgets also ignore [value] and pass the whole | ||
| /// [Animation] object to a render object (like [FadeTransition] does), | ||
| /// they too may be able to avoid rebuild and even relayout, so that the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| /// they too may be able to avoid rebuild and even relayout, so that the | |
| /// they too might be able to avoid rebuild and even relayout, so that the |
nate-thegrate
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks fantastic overall; thanks for putting the work in here.
| typedef ValueListenableTransformer<T> = T Function(T); | ||
|
|
||
| /// An animation with a value of type `T`. | ||
| /// A value which may change over time, moving forward or backward. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to the advice for may.
As far as "forward" vs "forwards", after a bit of Googling I found one good article about it. The TL;DR is that "forward" is generally better, but "forwards" is more common in British English.
American spelling suggests "colors" and "gray", while Brits would use "colours" and "grey". The fact that Flutter uses Colors.grey indicates that it's probably not a big deal :)
| /// Calls its callback once per animation frame, when enabled. | ||
| /// | ||
| /// To obtain a ticker, consider [TickerProvider]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| /// Calls its callback once per animation frame, when enabled. | |
| /// | |
| /// To obtain a ticker, consider [TickerProvider]. | |
| /// Calls its [TickerCallback] once per animation frame, when enabled. |
The TickerProvider reference could be moved to a "See also" section at the bottom, for consistency with other docs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think mentioning TickerProvider up at the top is helpful here because when someone's just trying to get an animation working and finding their way around the API, that's the reader who can most benefit from an early signpost helping them redirect toward what they're looking for.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair point!
I still do think it'd be nice to link to the typedef here.
| /// Calls its callback once per animation frame, when enabled. | |
| /// | |
| /// To obtain a ticker, consider [TickerProvider]. | |
| /// Calls its [TickerCallback] once per animation frame, when enabled. | |
| /// | |
| /// To obtain a ticker, consider using a [TickerProvider]. |
And this is very pedantic, but I also feel that a sentence flows better when adding an "-ing" verb after "consider" (other alternatives: "consider the" or "consider who/what/when/where/how").
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the summary line, I think the style I typically see in the Flutter docs tends to keep that summary line in plain English prose (no identifiers) except where an identifier reference is critical to understanding the meaning.
So for example [TickerCallback] itself says in its summary:
/// Signature for the callback passed to the [Ticker] class's constructor.which fits because that type is really all about the Ticker class.
But here, I think the exact signature of the callback isn't critical to a summary-level understanding of what Ticker is about. So that detail is best left for later, past the summary. (In the docs page, it'll appear right after the class's doc comment, in the signature of the constructor.)
On "consider", I feel like I see the terser form a lot in the Flutter docs, and I think it works well when the object of it is short, like here.
Looking in the Git history confirms that that wording is often from Hixie (who wrote much of Flutter's documentation in general and set its style):
$ git log -p --author hixie -G 'consider\b'
# or even, filtering to some of the most core docs:
$ git log -p --author hixie -G 'consider\b' lib/src/widgets/framework.dart
consider the [AppLifecycleListener] API.
consider a single [CustomPaint] widget.
consider an expression such as the following: [… a one-line code block …]
consider [SelectionArea].
and so on. Certainly plenty of "-ing" gerund forms too, but usually when there's more to say about it.
gnprice
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the reviews! Revision pushed; PTAL.
| typedef ValueListenableTransformer<T> = T Function(T); | ||
|
|
||
| /// An animation with a value of type `T`. | ||
| /// A value which may change over time, moving forward or backward. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to "might".
To my eye, saying "can" here suggests the wrong meaning — it sounds more like it's saying the code that holds one of these objects can cause the value to change (i.e. it sounds like what an AnimationController is), rather than that the value might change while that code isn't looking.
| /// When an [ImplicitlyAnimatedWidget] suffices, there is | ||
| /// no need to work with [Animation], [AnimationController], or [Tween], | ||
| /// or even to have a [State] to manage the animation (though all of those are | ||
| /// involved in the implementation of the [ImplicitlyAnimatedWidget] itself). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, that's useful feedback. How about this?
/// When an [ImplicitlyAnimatedWidget] suffices, there is
/// no need to work with [Animation] or the rest of the classes
/// discussed in this section.The intended point here is to help people confidently stop reading and ignore the rest of the complexity of this API, when what they want is a simple animation effect that AnimatedScale and friends can handle for them.
| /// An animation may move forward or backward on its own as time passes | ||
| /// (like the opacity of a button that fades over a fixed duration | ||
| /// once the user touches it), | ||
| /// or it may be driven by the user | ||
| /// (like the position of a slider that the user can drag back and forth), | ||
| /// or it may do both | ||
| /// (like a switch that snaps into place when releaseed, | ||
| /// or a [Dismissible] that responds to drag and fling gestures, etc.). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Changed these to "might", for the same reason as above.)
| /// Calls its callback once per animation frame, when enabled. | ||
| /// | ||
| /// To obtain a ticker, consider [TickerProvider]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think mentioning TickerProvider up at the top is helpful here because when someone's just trying to get an animation working and finding their way around the API, that's the reader who can most benefit from an early signpost helping them redirect toward what they're looking for.
nate-thegrate
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with 1 small nit.
Thanks again for doing this!
| /// Calls its callback once per animation frame, when enabled. | ||
| /// | ||
| /// To obtain a ticker, consider [TickerProvider]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair point!
I still do think it'd be nice to link to the typedef here.
| /// Calls its callback once per animation frame, when enabled. | |
| /// | |
| /// To obtain a ticker, consider [TickerProvider]. | |
| /// Calls its [TickerCallback] once per animation frame, when enabled. | |
| /// | |
| /// To obtain a ticker, consider using a [TickerProvider]. |
And this is very pedantic, but I also feel that a sentence flows better when adding an "-ing" verb after "consider" (other alternatives: "consider the" or "consider who/what/when/where/how").
gnprice
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
| /// Calls its callback once per animation frame, when enabled. | ||
| /// | ||
| /// To obtain a ticker, consider [TickerProvider]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the summary line, I think the style I typically see in the Flutter docs tends to keep that summary line in plain English prose (no identifiers) except where an identifier reference is critical to understanding the meaning.
So for example [TickerCallback] itself says in its summary:
/// Signature for the callback passed to the [Ticker] class's constructor.which fits because that type is really all about the Ticker class.
But here, I think the exact signature of the callback isn't critical to a summary-level understanding of what Ticker is about. So that detail is best left for later, past the summary. (In the docs page, it'll appear right after the class's doc comment, in the signature of the constructor.)
On "consider", I feel like I see the terser form a lot in the Flutter docs, and I think it works well when the object of it is short, like here.
Looking in the Git history confirms that that wording is often from Hixie (who wrote much of Flutter's documentation in general and set its style):
$ git log -p --author hixie -G 'consider\b'
# or even, filtering to some of the most core docs:
$ git log -p --author hixie -G 'consider\b' lib/src/widgets/framework.dart
consider the [AppLifecycleListener] API.
consider a single [CustomPaint] widget.
consider an expression such as the following: [… a one-line code block …]
consider [SelectionArea].
and so on. Certainly plenty of "-ing" gerund forms too, but usually when there's more to say about it.
Manual roll requested by [email protected] flutter/flutter@f10a497...cbfb222 2024-08-04 [email protected] Roll Flutter Engine from 980577996f38 to 16012e2f8ccd (1 revision) (flutter/flutter#152824) 2024-08-03 [email protected] Roll Flutter Engine from 2a51c687fd40 to 980577996f38 (1 revision) (flutter/flutter#152821) 2024-08-03 [email protected] Roll Flutter Engine from 4c868ee85616 to 2a51c687fd40 (2 revisions) (flutter/flutter#152818) 2024-08-03 [email protected] Roll Flutter Engine from afb7007298cc to 4c868ee85616 (2 revisions) (flutter/flutter#152814) 2024-08-03 [email protected] Fix device_os requested in linux_build_test tests (flutter/flutter#152808) 2024-08-03 [email protected] Roll Flutter Engine from 516235e4456b to afb7007298cc (3 revisions) (flutter/flutter#152804) 2024-08-03 [email protected] Fix misunderstanding of properties vs. drone_dimensions in Linux_build_tests (flutter/flutter#152796) 2024-08-03 [email protected] Roll Flutter Engine from 3c9d7e3f7c02 to 516235e4456b (3 revisions) (flutter/flutter#152790) 2024-08-03 [email protected] Improve `CupertinoRadio` fidelity (flutter/flutter#149703) 2024-08-03 [email protected] Roll Flutter Engine from 353c6b237b78 to 3c9d7e3f7c02 (3 revisions) (flutter/flutter#152777) 2024-08-02 [email protected] Fix handling of `iconSize` and `iconColor` defaults for `ButtonStyleButton` subclasses. (flutter/flutter#143501) 2024-08-02 [email protected] Use print logging on LUCI. (flutter/flutter#152776) 2024-08-02 [email protected] Reland: Shift Linux_build_test tests from MotoG4 to mokey (flutter/flutter#152756) 2024-08-02 [email protected] Write more on Animation and related docs (flutter/flutter#150727) 2024-08-02 [email protected] Quick Grammar Fixes (flutter/flutter#152744) 2024-08-02 [email protected] Roll Flutter Engine from 077b6f057b69 to 353c6b237b78 (3 revisions) (flutter/flutter#152762) 2024-08-02 [email protected] [SliderTheme] Fix markdown links for api doc images (flutter/flutter#152748) 2024-08-02 [email protected] Make the App's title optional on web (flutter/flutter#152003) 2024-08-02 [email protected] Add tests for scaffold messenger state (flutter/flutter#152735) 2024-08-02 [email protected] Ignore both unused_element and unused_element_parameter (flutter/flutter#152689) 2024-08-02 [email protected] Update dartdoc to 8.0.12 to fix focusing search field (flutter/flutter#151576) 2024-08-02 [email protected] [wiki] Remove outdated warning about stale coverage data (flutter/flutter#152560) 2024-08-02 [email protected] Roll Packages from 27896d1 to cc9ff47 (8 revisions) (flutter/flutter#152754) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC [email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
A few days ago I started reading up on how animations work, in preparation for starting to use them in a more complex way than I'd done before. I found it a bit difficult to get my head around; in particular the many different classes involved, how they relate to each other, and how to fit them together. So once I had worked that out, I sat down to express it in the form of documentation. The largest change here is an expansion of the docs on [Animation] itself, including a new section "Using animations" with several paragraphs laying out how one typically fits together AnimationController, TickerProvider, CurvedAnimation and/or Tween, and AnimatedWidget subclasses. [Animation] also gets an expanded "See also" list, a revised conceptual intro, and a new summary line. There are also revisions on [TickerProvider], [AnimatedController], and elsewhere; some new exposition, some revisions for clarity, and various small fixes.
A few days ago I started reading up on how animations work, in preparation for starting to use them in a more complex way than I'd done before. I found it a bit difficult to get my head around; in particular the many different classes involved, how they relate to each other, and how to fit them together. So once I had worked that out, I sat down to express it in the form of documentation. The largest change here is an expansion of the docs on [Animation] itself, including a new section "Using animations" with several paragraphs laying out how one typically fits together AnimationController, TickerProvider, CurvedAnimation and/or Tween, and AnimatedWidget subclasses. [Animation] also gets an expanded "See also" list, a revised conceptual intro, and a new summary line. There are also revisions on [TickerProvider], [AnimatedController], and elsewhere; some new exposition, some revisions for clarity, and various small fixes.
A few days ago I started reading up on how animations work, in
preparation for starting to use them in a more complex way than
I'd done before. I found it a bit difficult to get my head around;
in particular the many different classes involved, how they relate
to each other, and how to fit them together.
So once I had worked that out, I sat down to express it in the form
of documentation.
The largest change here is an expansion of the docs on [Animation]
itself, including a new section "Using animations" with several
paragraphs laying out how one typically fits together
AnimationController, TickerProvider, CurvedAnimation and/or Tween,
and AnimatedWidget subclasses. [Animation] also gets an expanded
"See also" list, a revised conceptual intro, and a new summary line.
There are also revisions on [TickerProvider], [AnimatedController],
and elsewhere; some new exposition, some revisions for clarity, and
various small fixes.
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.