mdgriffith / elm-style-animation

The style animation library for Elm!
http://package.elm-lang.org/packages/mdgriffith/elm-style-animation/latest
BSD 3-Clause "New" or "Revised" License
440 stars 40 forks source link

How to animate with auto height ? #9

Closed vankeisb closed 8 years ago

vankeisb commented 8 years ago

Hello,

I'm evaluating this library and I am new to Elm in general... apologies in advance if I ask a silly question !

Is there a way to animate an element without knowing its target height ? Stuff like a title pane that can be collapsed/expanded and contains arbitrary HTML.

I'd have done this like :

expanded : { height: auto } // or height : 100%
collapsed: { height: 0 }

But the API doesn't allow me to do this. Any idea ?

Thanks !

mdgriffith commented 8 years ago

Hi!

Definitely not a silly question. Using this library you can animate to height: 100%, but not to height: auto.

Style.to 
    [Height 100 Percent
    ]

The auto value is interesting because it requires values that are calculated by the browser. Due to the strong guarantees of Elm code, we have to bring those external values in via a port if we want to use them (unlike javascript where we can just do some magic behind the scenes).

So, if you wanted to animate to height:auto, you'd need to write some javascript to find that value in px, and send it in via a port.

Looking at it, I realize the README doesn't cover other units besides Px and Turn. Whoops :)

All units that you can use for length, rotation, or display mode are defined in this file.

vankeisb commented 8 years ago

Hi, thanks for the prompt response !

I've tried it with percents, but I have another problem with this.

I'm trying to create a TreeView component, with expand/collapse capabilities. It works fine without animations, and now I'd like to animate it (have children appear/disappear animated). Problem with the percent approach is that I have multiple child elements under the main "wrapper" and therefore 100% is too much in some cases, and the inner elements overflow...

I have found a trick though (after googling a bit) : using max-height seems to work better. In order to "hide" the children of a node, I animate to MaxHeight 0 Px. To expand, MaxHeight 99999999 Px. It's a bit ugly this hard-coded max constant, but I guess no html element should ever be higher than this :P

Now I noticed another issue : when expanding, the animation is faster than when collapsing... Any idea why it should behave like this ?

Here below is the code that updates the tree node state (style, and expansion flag) :

expandCollapse: TreeNodeId -> Bool -> TreeNode a -> TreeNode a
expandCollapse nodeId expanded n =
  let
    newProp = case expanded of
      True ->
        MaxHeight 99999999 Px
      False ->
        MaxHeight 0 Px

    newStyle =
      Style.animate
        |> Style.duration (1*second)
        |> Style.easing (\x -> x^10)
        |> Style.to [ newProp ]
        |> Style.on n.style
  in

  if n.id == nodeId then
    { n | expanded = expanded
        , style = newStyle }
  else
    n

I don't see why it should be different when increasing or decreasing the value of the style. Is it a known bug or something ?

I'll try to isolate a test just to see if it's my code or a problem in the interpolation.

Thanks again for your response, and have a nice day !

mdgriffith commented 8 years ago

That's a clever way of animating to auto. Does animating MaxHeight work as MaxHeight 100 Percent?

The difference in times for expanding vs collapsing is probably due to using MaxHeight. The library is animating from 0 to 99999999, but only values 0 to however big the child element is are affecting what you're seeing.

vankeisb commented 8 years ago

I haven't tried MaxHeight 100%, only setting a "way too high" value. And yes, I also think that explains the time difference. I read posts from people with similar problems while Googling for it.

Maybe one can provide its own function in order to minimize that problem ? Like by skipping part of the too high values, and easing out only starting from a given treshold ?

vankeisb commented 8 years ago

Maybe MaxHeight in Percent is better actually... This way you wouldn't have to set a hardcoded constant, and your anim would actually use the browser's computed heights... Mmmhmhhh... I have to try it !