On Sun, 1 Sep 2024 12:31:06 GMT, Michael Strauß <mstra...@openjdk.org> wrote:

>> This PR completes the CSS Transitions story (see #870) by adding 
>> interpolation support for backgrounds and borders, making them targetable by 
>> transitions.
>> 
>> `Background` and `Border` objects are deeply immutable, but not 
>> interpolatable. Consider the following `Background`, which describes the 
>> background of a `Region`:
>> 
>> 
>> Background {
>>     fills = [
>>         BackgroundFill {
>>             fill = Color.RED
>>         }
>>     ]
>> }
>> 
>> 
>> Since backgrounds are deeply immutable, changing the region's background to 
>> another color requires the construction of a new `Background`, containing a 
>> new `BackgroundFill`, containing the new `Color`.
>> 
>> 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 subclasses
>> - `Margins` (internal type)
>> - `BorderImageSlices` (internal type)
>> 
>> ## Interpolation of composite objects
>> 
>> As of now, only `Color`, `Point2D`, and `Point3D` are interpolatable. Each 
>> of these classes is an aggregate of `double` values, which are combined 
>> using linear interpolation. However, many of the new interpolatable classes 
>> comprise of not only `double` 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:
>> 
>> | Interpolation type | Description |
>> |---|---|
>> | default | Component types that implement `Interpolatable` are interpolated 
>> by calling the `interpolate(Object, double)}` method. |
>> | linear | Two components are combined by linear interpolation such that `t 
>> = 0` produces the start value, and `t = 1` produces the end value. This 
>> interpolation type is usually applicable for numeric components. |
>> | discrete | If two components cannot be meaningfully combined, the 
>> intermediate component value is equal to the start value for `t < 0.5` and 
>> equal to the end value for `t >= 0.5`. |
>> | pairwise | Two lists are combined by pairwise interpolation. If the start 
>> list has fewer elements than the target list, the...
>
> Michael Strauß has updated the pull request with a new target base due to a 
> merge or a rebase. The incremental webrev excludes the unrelated changes 
> brought in by the merge/rebase. The pull request contains 48 additional 
> commits since the last revision:
> 
>  - Merge branch 'master' into feature/interpolatable
>  - remove StyleConverter.WithReconstructionSupport
>  - fix line separators
>  - StyleableStringProperty should be transitionable
>  - non-interpolatable values should always transition discretely
>  - only call get() when necessary
>  - add more documentation
>  - replace reconstruction annotation with interface
>  - interpolate integers in real number space
>  - replace StyleConverter.SupportsDeconstruction interface with annotation
>  - ... and 38 more: https://git.openjdk.org/jfx/compare/37c6136d...2337ca98

Q1: I see a lot of work in the code to handle reverse transitions.  Is this 
actually part of the CSS specification?

Q2: Reversal detection seems very limited.  If I change a value multiple times 
within the duration of the animation, then reset it to its original value, then 
I think the reversal code will not trigger.  As an example, let's say I'm 
animating scrolling.  I'm at the top.  I press page down once and then press 
home.  The value changes for example from 0 -> 20 -> 0 -- this triggers the 
reversal code,  and the animated scrolling will quickly return to its top 
position.  However, if I do 0 -> 20 -> 40 -> 0 (page down, page down, home), 
then I think the reversal is not detected and I'm left with a very slow return 
to the top position.

Q3: How does the user do calculations for properties that are being 
interpolated?  Let's say I have a simple system where the `+` and `-` change a 
value by +10 and -10.  So I press `+`; I read the current value, add 10 and set 
it (say from 0 to 10).  Now I press `+` again.  Reading the current value would 
get me some intermediate animated value.  Adding 10 to this is not what the 
user would expect (they would expect to go to 20, not to 15 if the animation 
was only halfway completed).

As an example, I've implemented (without CSS transitions) a smooth scrolling 
system; this system tracks the target value to do the scrolling.  Pressing 3x 
page down in a row will go 3 pages down, no matter what the state of the 
animation.  With CSS transitions, should the programmer be aware of the 
interpolation (which may be added later in CSS) and track their own "target" 
value to make this work as you'd expect?

-------------

PR Comment: https://git.openjdk.org/jfx/pull/1522#issuecomment-2325001849

Reply via email to