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
Gradient transform #42484
Gradient transform #42484
Conversation
/// // Calculate the point to rotate about. | ||
/// final double sinRadians = math.sin(radians); | ||
/// final double oneMinusCosRadians = 1 - math.cos(radians); | ||
/// final Offset center = rect.center; | ||
/// final double originX = sinRadians * center.dy + oneMinusCosRadians * center.dx; | ||
/// final double originY = -sinRadians * center.dx + oneMinusCosRadians * center.dy; | ||
/// | ||
/// final Matrix4 transform = Matrix4.identity() | ||
/// ..translate(originX, originY) | ||
/// ..rotateZ(radians); |
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 suspect having amethod like this in the framework might be helpful to people, but I'm not sure where it would go. MatrixUtils?
@goderbauer wdyt?
Would it make more sense for the matrix to be a property rather than something you pass to createShader? The shader is created pretty low-down, most people don't use that API. |
The thing is, you're generally going to need to know the It would be nice but I'm not sure how we'd really abstract the rect away properly. |
We could maybe give it a callback where you're given a rect and you give back a transform, like: typdef MatrixBuilder = Matrix4 Function(Rect rect); And then |
We could also take a new kind of class that represents a matrix transform. That class would have a method on it that takes a rect to do the actual transform computation. This is analogous to what we do wiht |
d1cdc44
to
13d7f99
Compare
I've added a We could trivially implement things like |
/// | ||
/// For example, a [SweepGradient] normally starts its gradation at 3 o'clock | ||
/// and draws clockwise. To have the sweep appear to start at 6 o'clock, supply | ||
/// a [GradientRotation] of `0.785398` radians (i.e. `45` degrees). |
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.
trivial nit: I think our style is to not use backticks for literals.
/// a [GradientRotation] of `0.785398` radians (i.e. `45` degrees). | ||
@immutable | ||
abstract class GradientTransform { | ||
/// A const constructor that allows subclasses to be const. |
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.
there's a boilerplate paragraph we use for this kind of thing.
/// colors: colors, | ||
/// transform: GradientRotation(0.785398), | ||
/// ); | ||
/// ``` |
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.
we should use the sample code logic for this
/// ``` | ||
@immutable | ||
class GradientRotation extends GradientTransform { | ||
/// Constructs a `GradientRotation` for the specified angle. |
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.
use []
for identifiers
/// The angle is in radians in the clockwise direction. | ||
const GradientRotation(this.radians); | ||
|
||
/// The angle of rotation. |
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 needs more detail, e.g. direction of rotation (clockwise, counter-clockwise), the units (though it's pretty obvious from the name).
/// | ||
/// The [transform] argument can be applied to transform _only_ the gradient, | ||
/// without rotating the canvas itself or other geometry on the canvas. For | ||
/// example, a `GradientRotation(0.785398)` will result in a [SweepGradient] |
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.
here and elsewhere, rather than 0.785398 we should say pi/4
In case it's not obvious - I've rev'd goldens a few times in this because I've made very minor changes to the tests that are resulting in miniscule pixel differences. |
Description
Exposes the
transform
parameter for gradients into the framework via aGradientTransform
class, which is akin toAlignment
orEdgeInsets
in that it resolves an actualMatrix4
by means of aRect
(and potentially aTextDirection
). This enables more easily creating rotated gradient effects without having to rotate the entire canvas.Fixes #23648
Related Issues
#23648
Tests
I added the following tests:
Golden tests for transformed gradients.
Checklist
Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes (
[x]
). This will ensure a smooth and quick review process.///
).flutter analyze --flutter-repo
) does not report any problems on my PR.Breaking Change
Does your PR require Flutter developers to manually update their apps to accommodate your change?