I've previously proposed to add implicit CSS transitions to JavaFX. Compared to the previous proposal, this new and refined proposal is a "minimally invasive" version that requires almost no new API. The previous proposal did get some reactions on GitHub, and I hope that this new proposal can attract enough support within the OpenJFX community to move it forward:
Goals ----- Support CSS Transitions [1] in JavaFX. Non-Goals --------- It is not a goal to * change the semantics of explicit transitions and animations of the `javafx.animation` framework * provide a programmatic API for implicit transitions (i.e. implicit tansitions can only be defined in stylesheets) * support CSS Animations [2] Motivation ---------- CSS Transitions [1] is a universally supported web standard that allows developers to specify how a CSS property changes its value smoothly from one value to another. Here's how an implicit transition is defined in a stylesheet: .button { transition-property: -fx-opacity; transition-duration: 1s; } CSS Transitions makes it easy to define animated transitions and create rich and fluid user experiences. CSS Transitions also nicely complements control skins: while skins define the structure and semantics of a control, implicit transitions define its dynamic appearance. Alternatives ------------ Applications that want to offer animated user experiences can use the existing `javafx.animation` framework. Animated controls can be created by subclassing existing skins and hooking into different kinds of input events and property change events to trigger animations. However, this is very cumbersome compared to using CSS Transitions. Description ----------- The `transition` pseudo-property is added to styleable nodes. It is special and distinct from all other CSS properties for three reasons: 1. There is no API to access this property in Java code. 2. It is not returned from `Node.getClassCssMetaData`. 3. It is guaranteed to be applied before all other properties. When a property value is changed by the CSS subsystem, we look whether a transition has been specified for the given property. If it has, the value change is animated over time. This works for all primitive property types, as well as object properties with `javafx.animation.Interpolatable` values. Note that in order for this to work, we must apply the `transition` pseudo-property before all other properties, as otherwise the CSS subsystem might not know that a transition was specified for a given property by the time the property value is changed. It is important to note that an implicit transition is only started when the property value is changed by the CSS subsystem, but not when it is changed programmatically by calling Property.setValue(T) or via a binding. This maximizes compatibility with code that assumes that programmatic value changes happen instantly. Applications don't need to keep track of running transitions, as they are automatically cancelled when their associated control is removed from the scene graph, becomes invisible, or is eligible for garbage collection. TransitionEvent --------------- The new event `javafx.css.TransitionEvent` signals the creation, beginning, completion and cancellation of implicit CSS transitions [3]. Applications can use this event to react to running transitions, for example by allowing a running transition to complete before reconfiguring the user interface or switching to a new page. Easing Functions ---------------- CSS Transitions specifies the `transition-timing-function` sub-property to define easing functions (see CSS Easing Functions [4]). Here is a list of all easing functions available in CSS Easing Functions: * linear * ease, ease-in, ease-out, ease-in-out, cubic-bezier(x1, y1, x2, y2) * step-start, step-end, steps(intervals, step-position) Easing functions are implemented using `javafx.animation.Interpolator` in JavaFX. While it may seem straightforward to re-use existing interpolator implementations like `Interpolator.EASE_IN`, `Interpolator.EASE_OUT`, etc., the definitions of those interpolators don't match the definitions of CSS Easing Functions. In order to maximize compatibility with CSS Transitions, implicit transitions use the CSS definitions, not the SMIL 3.0 definitions of the existing interpolator implementations. Note that step-wise interpolators are only available for CSS Transitions, they are not exposed as new public API in the `javafx.animation` framework. The reason for this is that step-wise interpolators accept negative input values and can produce different results depending on their `step-position` parameter (for details on that, see "2.3.1. Output of a step easing function" [5]). Since the `javafx.animation` framework does not provide negative input values to interpolators, step-wise interpolators don't work with explicit transitions and animations. This could be a future enhancement. Future enhancements ------------------- * In a follow-up enhancement, `Insets`, `Background`, `BackgroundFill`, and `CornerRadii` will implement the `Interpolatable` interface to allow more types to be implicitly animated. * CSS Animations [2] might also be implemented, which is another CSS-based animation framework. * An API to programmatically define CSS transitions might be added. Not doing this right away allows the implementation to move around a bit (which it might do if we choose to also do CSS Animations). * Expose step-wise interpolators as public API in the `javafx.animation` framework. [1] https://www.w3.org/TR/css-transitions-1/ [2] https://www.w3.org/TR/css-animations-1/ [3] https://www.w3.org/TR/css-transitions-1/#transition-events [4] https://www.w3.org/TR/css-easing-1/ [5] https://www.w3.org/TR/css-easing-1/#step-easing-algo