-
Notifications
You must be signed in to change notification settings - Fork 472
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
8332895: Support interpolation for backgrounds and borders #1522
Conversation
👋 Welcome back mstrauss! A progress list of the required criteria for merging this PR into |
@mstr2 This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 4 new commits pushed to the
Please see this link for an up-to-date comparison between the source branch of this pull request and the ➡️ To integrate this PR with the above commit message to the |
I note that PR #1471 was originally proposed to address this. Can you highlight the differences? Are any of the comments added to that PR still relevant? I also note that JDK-8226911 was added as an issue to the original PR? Should it also be added here? I'd like a review by at least two with a "Reviewer" role in addition to the CSR. /reviewers 2 reviewers |
@kevinrushforth |
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.
Approving from the perspective of the API with the remark that there is a theoretical API break for TransitionEvent
.
Thanks for the review! I added the changed |
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.
latest changes are an improvement, thank you
# Conflicts: # modules/javafx.graphics/src/test/java/test/javafx/geometry/InsetsTest.java # modules/javafx.graphics/src/test/java/test/javafx/scene/layout/BackgroundFillTest.java # modules/javafx.graphics/src/test/java/test/javafx/scene/layout/BackgroundImageTest.java # modules/javafx.graphics/src/test/java/test/javafx/scene/layout/BackgroundPositionTest.java # modules/javafx.graphics/src/test/java/test/javafx/scene/layout/BackgroundSizeTest.java # modules/javafx.graphics/src/test/java/test/javafx/scene/layout/BackgroundTest.java # modules/javafx.graphics/src/test/java/test/javafx/scene/layout/BorderStrokeTest.java # modules/javafx.graphics/src/test/java/test/javafx/scene/layout/BorderTest.java # modules/javafx.graphics/src/test/java/test/javafx/scene/layout/BorderWidthsTest.java # modules/javafx.graphics/src/test/java/test/javafx/scene/paint/ColorTest.java # modules/javafx.graphics/src/test/java/test/javafx/scene/paint/ImagePatternTest.java # modules/javafx.graphics/src/test/java/test/javafx/scene/paint/LinearGradientTest.java # modules/javafx.graphics/src/test/java/test/javafx/scene/paint/RadialGradientTest.java # modules/javafx.graphics/src/test/java/test/javafx/scene/paint/StopListTest.java # modules/javafx.graphics/src/test/java/test/javafx/scene/paint/StopTest.java
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 really good and is almost ready to go in. Since the implementation has been heavily reviewed already, I'll limit my review to the API and do some light testing.
I left a few comments on the API and docs inline. In addition, should ImagePattern::getImage
specify an interpolation type of "discrete"? The docs for that method weren't updated.
As soon as these issues are addressed, I'll re-review and also Review the CSR.
* @return the Paint to use for filling the background of the {@link Region} | ||
* @interpolationType see {@link BackgroundFill} |
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 isn't any mention of how interpolation is done in the class docs of this class. Did you mean to add something to the class docs, or should it link to Paint
instead?
* </tr> | ||
* <tr><td style="vertical-align: top"><a id="linear" style="white-space: nowrap">linear</a></td> | ||
* <td>Two components are combined by linear interpolation such that {@code t = 0} produces | ||
* the start value, and {@code t = 1} produces the end value. This interpolation type |
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.
Minor: I might add something like: and {@code 0 < t < 1} produces {@code (1 - t) * start + t * end}
, to clearly define what linear means. This would be OK to add in a follow-up.
* @param elapsedTime the time that has elapsed since the transition has entered its active period | ||
* @throws NullPointerException if {@code eventType}, {@code property} or {@code elapsedTime} is {@code null} | ||
*/ | ||
public TransitionEvent(EventType<? extends Event> eventType, | ||
StyleableProperty<?> property, | ||
String propertyName, |
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.
It might be best to leave the original constructor, deprecate it for removal, and set the default value of name
to the empty string. We could then remove it in JavaFX 25.
Either way, this new constructor will need an @since 24
tag.
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 updates. Looks good with a couple more comments on the deprecated-for-removal constructor.
* @param elapsedTime the time that has elapsed since the transition has entered its active period | ||
* @throws NullPointerException if {@code eventType}, {@code property} or {@code elapsedTime} is {@code null} | ||
*/ | ||
@Deprecated(forRemoval = true) |
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.
Can you add since = 24,
before the forRemoval
?
Also please add an @deprecated
javadoc tag referring to the new constructor.
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, it looks good now. I have also Reviewed the CSR. You can Finalize it when ready.
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.
Re-approving the API.
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.
re-approving
/integrate |
Going to push as commit 01e9e7e.
Your commit was automatically rebased without conflicts. |
This PR completes the CSS Transitions story (see #870) by adding interpolation support for backgrounds and borders, making them targetable by transitions.
Background
andBorder
objects are deeply immutable, but not interpolatable. Consider the followingBackground
, which describes the background of aRegion
:Since backgrounds are deeply immutable, changing the region's background to another color requires the construction of a new
Background
, containing a newBackgroundFill
, containing the newColor
.Animating the background color using a CSS transition therefore requires the entire Background object graph to be interpolatable in order to generate intermediate backgrounds.
More specifically, the following types will now implement
Interpolatable
.Insets
Background
BackgroundFill
BackgroundImage
BackgroundPosition
BackgroundSize
Border
BorderImage
BorderStroke
BorderWidths
CornerRadii
Stop
Paint
and all of its subclassesMargins
(internal type)BorderImageSlices
(internal type)Interpolation of composite objects
As of now, only
Color
,Point2D
, andPoint3D
are interpolatable. Each of these classes is an aggregate ofdouble
values, which are combined using linear interpolation. However, many of the new interpolatable classes comprise of not onlydouble
values, but a whole range of other types. This requires us to more precisely define what we mean by "interpolation".Mirroring the CSS specification, the
Interpolatable
interface defines several types of component interpolation:Interpolatable
are interpolated by calling theinterpolate(Object, double)}
method.t = 0
produces the start value, andt = 1
produces the end value. This interpolation type is usually applicable for numeric components.t < 0.5
and equal to the end value fort >= 0.5
.Every component of an interpolatable class specifies its interpolation type with the new
@interpolationType
javadoc tag. For example, this is the specification of theCornerRadii.topLeftHorizontalRadius
component:In the generated documentation, this javadoc tag shows up as a new entry in the specification list:
Independent transitions of sub-properties
CSS allows developers to specify independent transitions for sub-properties. Consider the following example:
We have two independent transitions (each with a different duration and easing function) that target two sub-properties of the same
Border
. We can't use normal interpolation between the before-change style and the after-change style of the border, as theInterpolatable
interface doesn't allow us to specify separate transitions per sub-property.Instead, we add a new interface (internal for now) that is implemented by
BorderConverter
andBackgroundConverter
:This allows us to use
BorderConverter
andBackgroundConverter
to decompose solid objects into their CSS-addressable component parts, animate each of the components, and then reconstruct a new solid object that incorporates the effects of several independent transitions.More specifically, if the CSS subsystem applies a new value via
StyleableProperty.applyStyle(newValue)
:newValue
implementsSubPropertyConverter
:a. Deconstruct
oldValue
andnewValue
into their components.b. For each component, determine if a transition was specified; if so, start a transition from
oldValue.componentN
tonewValue.componentN
with rules as described in "Interpolation of composite objects".c. For each frame, collect the effects of all component transitions, and reconstruct the current value as a solid object.
newValue
implementsInterpolatable
:Start a regular transition using
Interpolatable.interpolate()
.Limitations
Implementations usually fall back to discrete interpolation when the start value is an absolute value, and the end value is a percentage (see the example of
CornerRadii.topLeftHorizontalRadius
above). However, we can often solve these scenarios by first canonicalizing the values before interpolation (i.e. converting percentages to absolute values). This will be a future enhancement./reviewers 2
/csr
Progress
Issues
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jfx.git pull/1522/head:pull/1522
$ git checkout pull/1522
Update a local copy of the PR:
$ git checkout pull/1522
$ git pull https://git.openjdk.org/jfx.git pull/1522/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 1522
View PR using the GUI difftool:
$ git pr show -t 1522
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jfx/pull/1522.diff
Webrev
Link to Webrev Comment