Closed smfr closed 5 years ago
This seems to be the key suggestion from the linked thread.
I wonder if we could take this a bit further - rather than just removing identical prefixes (where both the functions and arguments match), we could find the prefix that just has functions matching, with potentially different arguments. Then we can interpolate that common prefix normally, and run the rest of the two states back through the list again as you describe, either matching the remainder up with identity transforms or mashing the remainder up into a matrix.
My interpretation of this is that translateX(100px) scaleX(2) rotateX(90deg)
interpolating with translateY(100px) scaleY(2) rotateY(90deg)
would use pairwise function interpolation for translate
and scale
and use post multiplied matrix interpolation for rotate
.
Propose moving to level 2.
The CSS Working Group just discussed Smarter interpolation of truncated lists, and agreed to the following resolutions:
RESOLVED: Accept the issue as written.
That resolution wording is obtuse, but I think means that we resolved to make the behavior change in transforms-1.
We started implementing this in Firefox but I'm a little unclear about the intention of this change. In the IRC log I see the comment:
smfr: it's saying that it uses the common prefix for as much as possible, then smoosh together the rest into a matrix
but in the spec change we seem to only handle mismatched lists where the functions of the shorter one match primitives of the longer.
i.e. it seemed like we were initially looking at allowing rotate(0deg) translate(10px)
→ rotate(720deg) scale(2)
to interpolate the rotate()
component directly and then use matrix interpolation for the remainder but the spec change would make the whole thing use matrix interpolation.
It may well be that the spec change deliberately doesn't allow the "common prefix" behavior due to compatibility concerns but I'd like to confirm we've understood the intention here since it's not clear to me from the IRC log what the outcome was.
@birtles From the proposal and the discussion, the spec change does not fully support the requested "smoosh". According to the discussion above this could either be by:
Both do not sound ideal to me. The latter mostly because we need to define an algorithm where and when to add neutral transformations. At the first glance this might sound intuitive but really isn't.
I wasn't in the discussion but what @smfr added seems to be logical and matching the behavior of other CSS properties:
Yeah, it seems to be reasonable. I just wanted to check if the spec change was intentionally different from what the discussion seemed to conclude.
My interpretation of the discussion was that both of Dirk's suggestions should be used:
matrix()
or matrix3d()
and transitioning appropriately.So @birtles' example should work as they expect - rotate(0deg) translate(10px)
→ rotate(720deg) scale(2)
will do two full rotations (as rotate()
is the compatible prefix) and then do a matrix-interpolation between translate(10px)
and scale(2)
.
@tabatkins Yes, phrased it wrong. I am just suspicious about
- adding neutral transform functions where needed.
Where should missing/differing functions be added?
Simple example:
rotate(720deg)
→ translate(100px, 100px)
A translate needs to get added to the former and a rotate to the latter transform function list. But in which order? After all the order matters a lot from the visual perspective.
translate
, rotate
and scale
properties in Level 2. So translate has precedence over rotate which has precedence over scale. Independent of the lists length we add the pendant function as needed. This potentially doubles the number of transform functions if they all differ. More thoughts are needed for skewX
, skewY
, skew
, matrix
and the 3D transform functions.Potentially both algorithms would replace matrix decomposition for the majority of cases. However, quite often there would be a solution that could have been smarter from a human eye perspective but wasn't used. Sometimes, even the first solution does not give the most pleasant result.
The complex algorithm needs to get implemented in an interoperable way in all UAs as well. Given how long even smaller changes in the spec took, it might be a while and I expect that we will see some additional feedback from UAs after implementing.
Like I just outlined, you fix length mismatches by adding neutral transforms to the end of the shorter list.
In your example, no fixup is possible. They're the same length, and have no common prefix, so you still just go straight to matrix interpolation.
@tabatkins Oh got it. The common transform function primitive is there already and adding neutral transform functions at the end of the list was added recently.
The proposal in https://github.com/w3c/csswg-drafts/issues/927#issue-200763204 and the question from @birtles https://github.com/w3c/csswg-drafts/issues/927#issuecomment-392390666 goes adds an additional step:
If there is a mismatch between 2 transform function pairs (no common primitive): Instead of multiplying all transform functions into one matrix before decomposing the suggestion is to do the matrix interpolation part only between not matching transform function pairs.
An additional question I have for that proposal: rotate(180deg) translate(120px) scale(2)
-> rotate(180deg) scale(2) skewX(45deg)
. According to the proposal, rotate
uses normal interpolation for rotate:
I think the simplest thing is to collapse the rest once you have a mismatch. That's also the minimal change from the current behavior for things that differ early; they can't accidentally get "back on track" and change behavior.
The Working Group just discussed Smarter interpolation of truncated transform lists
.
The Working Group just discussed [css-transforms] Smarter interpolation of truncated transform lists
, and agreed to the following:
RESOLVED: pad the shorter one with identity functions, find the common prefix, interpolate common prefix pairwise, interpolate the rest matrix-wise.
One different idea, possibly bad, but figured I'd throw it out there just in case: Matrix interpolation looks far worse for angle-based (rotate and skew) transforms than the rest. What if we try to match those up and interpolate the rest via matrix interpolation?
It turns out this change breaks the header on Channel News Asia. See https://github.com/webcompat/web-bugs/issues/23687
https://www.w3.org/mid/CALXxKfCKZd+P0mH2oFyDkBgps56WqwQnLSMpKk1nrqiFXScqVA@mail.gmail.com https://www.w3.org/mid/CAAWBYDBPafEbiXNy=Mw4a9w1jmvK6dUJzq28PPjN7APgtjqAEw@mail.gmail.com
Need to decide what goes into Level 1, and what to call the new identify functions. Related to https://github.com/w3c/csswg-drafts/issues/898