Tuesday Feb 21, 2012

CSS Animations - Slide Out Panel

In this second the detailed articles on the animation prototype I'm going to look at the animation of a whole group of components at once in the form of a slide out panel menu effect. This animation combines two effects (if you look closely),  The actual slide-out, and, in parallel, a shadow around the panel.  Just like the first example, no Java or JavaScript code is required for this example, we can just use default CSS hover functionality to trigger the animation.

Again, just a warning.  This prototype was only set up for the WebKit based browsers (Safari and Chrome). So where I talk about -webkit* styles below be aware that these will have different names on FireFox (usually -moz*) and IE. A stylesheet that handles more browsers will have to include these versions as well. 

The start point for this article assumes that your style sheet (via a custom skin) already exists (go back to the first article if you've not read this yet).

However, before we get too excited about the animations we need to think a little about layout.  The last thing we want to do with these funky effects is to mess up the rest of the screen, and so at this stage, where we've not got any scripting involved, we need to make sure that space is available in the UI for the slide out. To do this I started out by laying out my components thus:

<af:panelGroupLayout (Horizontal)>
  <af:panelGroupLayout (Vertical)> - will be animated
    [Menu] 
  </af:panelGroupLayout> 
  <af:spacer .../>  
  <af:panelGroupLayout (Vertical)>
    [Decorative Box etc.] 
  </af:panelGroupLayout>  
</af:panelGroupLayout> 

So basically the panelGroupLayout that will be animated already has space "reserved" for it on the screen and, at design time, it occupies that slot. At this stage you also need to work out how wide the panel that you are animating will be once populated. This is so you can push it off screen, but still expose enough for the mouse to hover over. In my case the pgl comes out at around 100px once populated.

Hint: To keep things simple with these "container" animations I recommend that you attach effects to a vertical panelGroupLayout. In HTML terms these components get rendered as a simple html <div> which is perfect and makes things much easier to debug if the styles don't seem to be working.

On to the animation. When I started this animation I was not sure what components I would be animating so, rather than defining a specific sub-type as I did for the button in the last article, I'm defining a generic styleClass that could be used with any components. Again we need the base class(.slideout) and the :hover selector for it.

.slideout
{
}
.slideout:hover
{
} 

Again concentrating on the base selector first, let's look at the transitions. This time I'm kicking it up a notch (to coin a phrase) by desiring two concurrent animations, the slide out and the shadow.  Just like the last example with the commandButton we want to pair effects so that any effect I put on the hover needs to be mirrored and reversed by the base selector. This way, both the mouse-over and mouse-out will be smoothly animated.

So here's the base selector.  This "parks" the panel off screen with a little bit hanging out for the mouse to hover over and start the animation:

.slideout
{
  position: relative;
  -webkit-transition-property: left, -webkit-box-shadow; ;  
  -webkit-transition-timing-function: linear, ease-out;
  -webkit-transition-duration: 1s, 1s;  
  -webkit-box-shadow: 0px 0px 0px;
  left: -80px; 
} 

The story here is going to be similar to the simple button scaling discussed in part 1, but there are some differences worthy of mention.  First of all the position property. As part of this animation we're actually moving a <div> and all it's contents around the screen. I want to do that in relation to it's initial position (remember that we started out with the panel in a conventional layout). So the relative keyword is used for this. The other option here is absolute. Try setting this to absolute if you give this a go, you'll notice that the results can be, shall we say unpredictable. You need to be really careful if you're trying to move things around out of context and could end up fighting with the ADF layout algorythms. So stick to relative for now!

Next the -webkit-transition-property - this time it contains two properties, separated by a comma: left and -webkit-box-shadow. So I'm declaring here that those are the two properties I'll be animating the change in. As I'm now dealing with two properties the other -webkit-transition* properties also contain two values separated by a comma and those refer to each property transition. Thus if you look at the timing function, you'll see how the animation in the change of the left value will be linear whereas the shadow will use the ease-in-out rate of change just like the button did.  Again have a play with this and see what the difference is between the timing effects, you have total control. 

Both animations take place concurrently and take place over the same 1s duration although they could be of different durations.  In the next article I'll be looking at how animations can be queued up to provide more complex effects. 

Finally we have the endpoints for  the shadow (basically no shadow) and left. Notice with the left property, it is set to -80px. Recall that the positioning for this style is relative, so this really just tells the panel to shift 80px to the left from its starting position, which happens, in this case, to place it mostly, but not quite all, off screen.

Next the hover selector, it is, as you would expect pretty similar except that we move the pgl back to where it belongs at 0px (relative) and introduces some shadow:

.slideout:hover
{
  position: relative;
  -webkit-transition-property: left, -webkit-box-shadow;  
  -webkit-transition-timing-function: linear, ease-in;
  -webkit-transition-duration: 1s, 1s;  
  -webkit-box-shadow: 10px 10px 5px #888;
  left: 0px;
}

The final step is, of course, to assign this style to the pgl itself. Again this is done with the styleClass property 

<af:panelGroupLayout id="pglmenu" layout="vertical" styleClass="slideout"> 
... 

There you have it.  In the final article in this series I'll be investigating a more complex animation involving JavaScript and other goodies - stay tuned! 

About

Hawaii, Yes! Duncan has been around Oracle technology way too long but occasionally has interesting things to say. He works in the Development Tools Division at Oracle, but you guessed that right? In his spare time he contributes to the Hudson CI Server Project at Eclipse
Follow DuncanMills on Twitter

Note that comments on this blog are moderated so (1) There may be a delay before it gets published (2) I reserve the right to ignore silly questions and comment spam is not tolerated - it gets deleted so don't even bother, we all have better things to do with our lives.
However, don't be put off, I want to hear what you have to say!

Search

Archives
« April 2014
MonTueWedThuFriSatSun
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    
       
Today