Skip to content

Conversation

@gnprice
Copy link
Member

@gnprice gnprice commented Jun 24, 2024

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.

gnprice added 2 commits June 24, 2024 13:30
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.
@gnprice gnprice requested a review from Hixie June 24, 2024 20:33
@github-actions github-actions bot added framework flutter/packages/flutter repository. See also f: labels. a: animation Animation APIs labels Jun 24, 2024
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.
Copy link
Member

@loic-sharma loic-sharma Jul 3, 2024

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:

Suggested change
/// A value which may change over time, moving forward or backward.
/// A value that can change over time, moving forwards or backwards.

Copy link
Contributor

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 :)

Copy link
Member Author

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.

Comment on lines 79 to 86
/// 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.).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// 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.).

Copy link
Member Author

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.)

Comment on lines 98 to 101
/// 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).
Copy link
Member

@loic-sharma loic-sharma Jul 3, 2024

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:

Suggested change
/// 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.

Copy link
Member Author

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.

Comment on lines 103 to 107
/// 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].
Copy link
Member

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:

Suggested change
/// 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].

Copy link
Member Author

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,
Copy link
Member

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?

Suggested change
/// Because the [Animation] keeps the same identity as the animation proceeds,
/// ## Performance
///
/// Because the [Animation] keeps the same identity as the animation proceeds,

Copy link
Member Author

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// 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

Copy link
Contributor

@nate-thegrate nate-thegrate left a 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.
Copy link
Contributor

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 :)

Comment on lines +51 to +53
/// Calls its callback once per animation frame, when enabled.
///
/// To obtain a ticker, consider [TickerProvider].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// 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.

Copy link
Member Author

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.

Copy link
Contributor

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.

Suggested change
/// 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").

Copy link
Member Author

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.

Copy link
Member Author

@gnprice gnprice left a 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.
Copy link
Member Author

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.

Comment on lines 98 to 101
/// 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).
Copy link
Member Author

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.

Comment on lines 79 to 86
/// 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.).
Copy link
Member Author

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.)

Comment on lines +51 to +53
/// Calls its callback once per animation frame, when enabled.
///
/// To obtain a ticker, consider [TickerProvider].
Copy link
Member Author

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.

Copy link
Contributor

@nate-thegrate nate-thegrate left a 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!

Comment on lines +51 to +53
/// Calls its callback once per animation frame, when enabled.
///
/// To obtain a ticker, consider [TickerProvider].
Copy link
Contributor

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.

Suggested change
/// 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").

Copy link
Member Author

@gnprice gnprice left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Comment on lines +51 to +53
/// Calls its callback once per animation frame, when enabled.
///
/// To obtain a ticker, consider [TickerProvider].
Copy link
Member Author

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 gnprice added the autosubmit Merge PR when tree becomes green via auto submit App label Aug 2, 2024
@auto-submit auto-submit bot merged commit 1dcc1b1 into flutter:master Aug 2, 2024
@gnprice gnprice deleted the pr-animation-docs branch August 2, 2024 21:49
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Aug 4, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Aug 4, 2024
auto-submit bot pushed a commit to flutter/packages that referenced this pull request Aug 4, 2024
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
TytaniumDev pushed a commit to TytaniumDev/flutter that referenced this pull request Aug 7, 2024
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.
@nate-thegrate nate-thegrate mentioned this pull request Aug 11, 2024
8 tasks
Buchimi pushed a commit to Buchimi/flutter that referenced this pull request Sep 2, 2024
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.
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 11, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a: animation Animation APIs autosubmit Merge PR when tree becomes green via auto submit App framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants