- From: Tab Atkins Jr. <jackalmage@gmail.com>
- Date: Fri, 15 Nov 2013 15:15:44 -0800
- To: Jon Rimmer <jon.rimmer@gmail.com>
- Cc: www-style list <www-style@w3.org>
On Thu, Nov 14, 2013 at 5:45 PM, Jon Rimmer <jon.rimmer@gmail.com> wrote: > Hi all, > > Apologies if this has been asked before, but I'm wondering if the position > of items in a grid layout are intended to be animatable? The properties in > the spec do not specify one way or the other. > > I ask because I contend that the ability to animate elements from one layout > position to another is an important use case, and one where the web > struggles to match the UI experiences provided by native apps. Right now the > only way to do this is through JS layout libraries [1] and impressive hacks > like Steve Sanderson's use of generated nth-child specific transforms [2]. > If grid positions were able to be transitioned, particularly for > automatically placed items, it would make it very easy to build lists and > grids that responded nicely to insertions, removals, reorderings, etc. As Daniel said, yes, they're probably interpolable (though we haven't defined that, and you can't just assume since the value space is non-trivial), but that won't help you as it wont' do the smooth flying-around that you want. The fundamental issue is that CSS Transitions and Animations all act on property values, and property values only. They work well when the thing you're animating has intermediate states that can be expressed with CSS properties as a linear combination of the start and end values, but are completely worthless outside of that. There is no way to use Grid to write that something is halfway between cell A and cell B, so you can't do what you're asking for with T/A. I've been working on this problem for a while internally in Blink. We came up with a declarative solution to this, but it was a bit heavyweight and didn't actually work for a lot of reasonable cases, so we scrapped it. Instead, we're first focusing on a basic JS API to make this easier to do manually. Basically, current approaches revolve around either doing all layout in JS (which is then easy to animate), or doing complicated things to measure the position/size at the endpoint (usually involving cloning an element into an off-screen container and duplicating styles as well as you can) and then animating it in JS. Our approach is to make this easier to do: 1. Have an API to completely turn off painting for an element. Turning off painting is identical to setting "visibility:hidden", except children can't opt out; it's a separate API to keep from screwing with the page's styles. The element still takes up space/etc. 2. Have an API to take "snapshots" of an element, regardless of whether its painting is turned on or off. (If it's off, it paints for the snapshot, but not for the screen.) This function call returns an opaque object that can't be directly inspected, but *can* be assigned to the element() map <http://dev.w3.org/csswg/css-images/#elementsources> and used as a CSS image. This is all you need. Doing fancy grid animations is still some work in JS, but all the hard/hacky stuff has been taken out. You just: 1. Turn off painting for the grid container. 2. Snapshot all the grid children, and insert dummy <div>s using the snapshots as background-images over the top of each of the elements. (Measuring and positioning should be relatively easy with the new Geometry APIs <http://dev.w3.org/FXTF/geometry/>.) 3. Switch the style to the end-state. 4. Snapshot all the children again, and measure any relevant size/positions you need. 5. Do the animation you want on the dummy <div>s - cross-fade() the images or whatever, animate the positions, etc. 6. When finished, turn painting back on and delete all the dummy <div>s. Done. It's still something that you'll want a library to do for you, but it's much more performant and reliable than the existing methods.
Received on Friday, 15 November 2013 23:16:30 UTC