[{"name":"Animator","comment":"\n\n@docs Animation, transition\n\n@docs Attribute, opacity\n\n@docs rotation, x, y, scale, scaleX, scaleY\n\n@docs color, px, int, float\n\n@docs withBezier, withImpulse\n\n@docs Duration, ms, delay\n\n\n# Premade\n\nHere are some premade animations.\n\nThere's nothing special about them, they're just convenient!\n\nCheck out how they're defined if you want to make your own.\n\n@docs spinning, pulsing, bouncing, pinging\n\n\n# Sequences\n\nYou may want something more involved than a single step transition.\n\nHere's an element that's blinking.\n\n    import Animator as Anim\n    import Html\n    import Html.Attributes\n\n\n    Anim.div\n        (Anim.loop\n            [ Anim.step (Anim.ms 200)\n                [ Anim.opacity 1\n                ]\n            , Anim.wait (Anim.ms 200)\n            , Anim.step (Anim.ms 200)\n                [ Anim.opacity 0\n                ]\n            ]\n        )\n        [ Html.Attributes.id \"my-element\" ]\n        [ Html.text \"Hello!\" ]\n\n@docs Step, set, wait, step\n\n@docs keyframes, loop, loopFor\n\n\n# On a Timeline\n\n@docs onTimeline, onTimelineWith\n\n\n# Rendering\n\n@docs div, node\n\n@docs Css, css\n\n","unions":[{"name":"Animation","comment":" ","args":[],"cases":[]},{"name":"Step","comment":" ","args":[],"cases":[]}],"aliases":[{"name":"Attribute","comment":" ","args":[],"type":"Internal.Css.Prop"},{"name":"Css","comment":" ","args":[],"type":"{ hash : String.String, keyframes : String.String, props : List.List ( String.String, String.String ) }"},{"name":"Duration","comment":" Choosing a nice duration can depend on:\n\n  - The size of the thing moving\n  - The type of movement\n  - The distance it's traveling.\n\nSo, start with a nice default and adjust it as you start to understand your specific needs.\n\n**Note** — Here's [a very good overview on animation durations and speeds](https://uxdesign.cc/the-ultimate-guide-to-proper-use-of-animation-in-ux-10bd98614fa9).\n\n","args":[],"type":"Internal.Time.Duration"}],"values":[{"name":"bouncing","comment":" ","type":"Animator.Duration -> Basics.Float -> Animator.Animation"},{"name":"color","comment":" ","type":"String.String -> Color.Color -> Animator.Attribute"},{"name":"css","comment":" ","type":"Animator.Timeline.Timeline state -> (state -> ( List.List Animator.Attribute, List.List Animator.Step )) -> Animator.Css"},{"name":"delay","comment":" ","type":"Animator.Duration -> Animator.Animation -> Animator.Animation"},{"name":"div","comment":" ","type":"Animator.Animation -> List.List (Html.Styled.Attribute msg) -> List.List (Html.Styled.Html msg) -> Html.Styled.Html msg"},{"name":"float","comment":" ","type":"String.String -> Basics.Float -> Animator.Attribute"},{"name":"int","comment":" ","type":"String.String -> Basics.Float -> Animator.Attribute"},{"name":"keyframes","comment":" ","type":"List.List Animator.Step -> Animator.Animation"},{"name":"loop","comment":" ","type":"List.List Animator.Step -> Animator.Step"},{"name":"loopFor","comment":" ","type":"Basics.Int -> List.List Animator.Step -> Animator.Step"},{"name":"ms","comment":" ","type":"Basics.Float -> Animator.Duration"},{"name":"node","comment":" ","type":"String.String -> Animator.Animation -> List.List (Html.Styled.Attribute msg) -> List.List (Html.Styled.Html msg) -> Html.Styled.Html msg"},{"name":"onTimeline","comment":" Animate an element on a specific timeline. Check out [`Animator.Timeline`](#Animator/Timeline) for more details.\n\nThis will\n\n1.  Give you smooth transitions when an animation is interrupted.\n2.  Allow you to syncronize multiple elements.\n\n```\nimport Animator as Anim\nimport Html\nimport Html.Attributes\n\n\nAnim.div\n    (Anim.onTimeline model.timeline\n        (\\state ->\n            if state.open\n                [ Anim.opacity 1\n                ]\n\n            else\n                [ Anim.opacity 0\n                , Anim.x -200\n                ]\n        )\n    )\n    [ Html.Attributes.id \"my-element\" ]\n    [ Html.text \"Hello!\" ]\n```\n\n","type":"Animator.Timeline.Timeline state -> (state -> List.List Animator.Attribute) -> Animator.Animation"},{"name":"onTimelineWith","comment":" ","type":"Animator.Timeline.Timeline state -> (state -> ( List.List Animator.Attribute, List.List Animator.Step )) -> Animator.Animation"},{"name":"opacity","comment":" ","type":"Basics.Float -> Animator.Attribute"},{"name":"pinging","comment":" ","type":"Animator.Duration -> Animator.Animation"},{"name":"pulsing","comment":" ","type":"Animator.Duration -> Animator.Animation"},{"name":"px","comment":" ","type":"String.String -> Basics.Float -> Animator.Attribute"},{"name":"rotation","comment":" ","type":"Basics.Float -> Animator.Attribute"},{"name":"scale","comment":" ","type":"Basics.Float -> Animator.Attribute"},{"name":"scaleX","comment":" ","type":"Basics.Float -> Animator.Attribute"},{"name":"scaleY","comment":" ","type":"Basics.Float -> Animator.Attribute"},{"name":"set","comment":" ","type":"List.List Animator.Attribute -> Animator.Step"},{"name":"spinning","comment":" ","type":"Animator.Duration -> Animator.Animation"},{"name":"step","comment":" ","type":"Animator.Duration -> List.List Animator.Attribute -> Animator.Step"},{"name":"transition","comment":"\n\n    import Animator as Anim\n    import Html\n    import Html.Attributes\n\n\n    Anim.div\n        (Anim.transition (Anim.ms 200)\n            [ Anim.opacity <|\n                if model.visible then\n                    1\n                else\n                    0\n            ]\n        )\n        [ Html.Attributes.id \"my-element\" ]\n        [ Html.text \"Hello!\" ]\n\n","type":"Animator.Duration -> List.List Animator.Attribute -> Animator.Animation"},{"name":"wait","comment":" ","type":"Animator.Duration -> Animator.Step"},{"name":"withBezier","comment":" ","type":"Basics.Float -> Basics.Float -> Basics.Float -> Basics.Float -> Animator.Attribute -> Animator.Attribute"},{"name":"withImpulse","comment":" When transitioning to this state, start with a little extra velocity!\n\nThis takes a number from 0-1.\n\n","type":"Basics.Float -> Animator.Attribute -> Animator.Attribute"},{"name":"x","comment":" ","type":"Basics.Float -> Animator.Attribute"},{"name":"y","comment":" ","type":"Basics.Float -> Animator.Attribute"}],"binops":[]},{"name":"Animator.Timeline","comment":"\n\n\n# Getting started\n\n@docs Timeline, init\n\n\n# Transitioning to a new state\n\nNow that we have a `Timeline` set up, we likely want to set a new **value**.\n\nIn order to do that we need to specify both —\n\n  - the new state we want to be in\n  - a `Duration` for how long this transition should take.\n\n@docs to\n\n@docs update, isRunning\n\n\n# Interruptions and Queueing\n\nIn some more **advanced** cases you might want to define a _series_ of states to animate through instead of just going to one directly.\n\n    Timeline.interrupt\n        [ Timeline.wait (Timeline.millis 300)\n\n        -- after waiting 300 milliseconds,\n        -- start transitioning to a new state, Griffyndor\n        -- Take 1 whole second to make the transition\n        , Timeline.transitionTo (Timeline.seconds 1) Griffyndor\n\n        -- Once we've arrived at Griffyndor,\n        -- immediately start transitioning to Slytherin\n        -- and take half a second to make the transition\n        , Timeline.transitionTo (Timeline.seconds 0.5) Slytherin\n        ]\n\n@docs interrupt, queue\n\n@docs Step, wait, transitionTo\n\n@docs scale, delay\n\n\n# Reading the timeline\n\nYou might be wondering, 'How do we get our value \"out\" of a `Timeline`?'\n\nWell, we can ask the `Timeline` all sorts of questions.\n\n@docs current, previous, upcoming, upcomingWith, arrived, arrivedAt, arrivedAtWith\n\n","unions":[{"name":"Step","comment":" ","args":["state"],"cases":[]}],"aliases":[{"name":"Timeline","comment":" A timeline of `state` values.\n\nBehind the scenes this is roughly a list of states and the times that they should occur!\n\n","args":["state"],"type":"Internal.Timeline.Timeline state"}],"values":[{"name":"arrived","comment":" Subtley different than [`current`](#current), this will provide the new state as soon as the transition has _finished_.\n\n```ascii\n          A---------B---------C\n               ^    ^    ^    ^\narrived:       A    B    B    C\n```\n\n","type":"Animator.Timeline.Timeline state -> state"},{"name":"arrivedAt","comment":" Sometimes we want to know when we've arrived at a state so we can trigger some other work.\n\nYou can use `arrivedAt` in the `Tick` branch of your update to see if you will arrive at an event on this tick.\n\n    Tick time ->\n        if Animator.arrivedAt MyState time model.timeline then\n            --...do something special\n\n","type":"state -> Time.Posix -> Animator.Timeline.Timeline state -> Basics.Bool"},{"name":"arrivedAtWith","comment":" Again, sometimes you'll want to supply your own equality function!\n","type":"(state -> Basics.Bool) -> Time.Posix -> Animator.Timeline.Timeline state -> Basics.Bool"},{"name":"current","comment":" Get the current `state` of the timeline.\n\nThis value will switch to a new value when a transition begins.\n\nIf you had a timeline that went from A to B to C, here's what `current` would be at various points on the timeline.\n\n```ascii\n          A---------B---------C\n               ^    ^    ^    ^\ncurrent:       B    B    C    C\n```\n\n**Note** — If you want to detect the moment when you arrive at a new state, try using [`arrivedAt`](#arrivedAt)\n\n","type":"Animator.Timeline.Timeline state -> state"},{"name":"delay","comment":" Delay the events of a timeline.\n\nThis is generally used in your view function to add a bit of variety when animating multiple elements.\n\n        Animator.move (Animator.delay (Animator.millis 200) timeline) <|\n            \\state ->\n                if state then\n                    Animator.at 0\n\n                else\n                    Animator.at 1\n\nThis has a maximum value of 5 seconds.\n\nIf you need a longer delay, it's likely you want to create a separate timeline.\n\n","type":"Animator.Timeline.Duration -> Animator.Timeline.Timeline state -> Animator.Timeline.Timeline state"},{"name":"init","comment":" Create a timeline with an initial `state`.\n\nSo, if you previously had a `Bool` in your model:\n\n    type alias Model = { checked : Bool }\n\n    -- created via\n    { checked = False }\n\nYou could replace that with an `Animator.Timeline Bool`\n\n    type alias Model = { checked : Animator.Timeline Bool }\n\n    -- created via\n    { checked = Animator.init False }\n\n","type":"state -> Animator.Timeline.Timeline state"},{"name":"interrupt","comment":" Interrupt what's currently happening with a new list.\n","type":"List.List (Animator.Timeline.Step state) -> Animator.Timeline.Timeline state -> Animator.Timeline.Timeline state"},{"name":"isRunning","comment":" Does this timeline have upcoming events?\n\n**Note** this is only useful if you're not using a `Animator.Watcher`\n\n","type":"Animator.Timeline.Timeline state -> Basics.Bool"},{"name":"previous","comment":" Get the previous `state` on this timeline.\n\nAs you'll see in the [Loading example](https://github.com/mdgriffith/elm-animator/blob/master/examples/Loading.elm), it means we can use `previous` to refer to data that we've already \"deleted\" or set to `Nothing`.\n\nHow cool!\n\n```ascii\n          A---------B---------C\n               ^    ^    ^\nprevious:      A    A    B\n```\n\n","type":"Animator.Timeline.Timeline state -> state"},{"name":"queue","comment":" Wait until the current timeline is **finished** and then continue with these new steps.\n","type":"List.List (Animator.Timeline.Step state) -> Animator.Timeline.Timeline state -> Animator.Timeline.Timeline state"},{"name":"scale","comment":" Scale timeline durations.\n\n    0.5 -> Animations take half as much time\n    1.0 -> normal\n    2.0 -> Animations take twice as long\n\n**Note** - 0.1 is the lowest number allowed, and 5 is the highest.\n\nThis is generally used in your view function to add a bit of variety when animating multiple elements.\n\n","type":"Basics.Float -> Animator.Timeline.Timeline state -> Animator.Timeline.Timeline state"},{"name":"to","comment":" Go to a new state!\n","type":"Animator.Timeline.Duration -> state -> Animator.Timeline.Timeline state -> Animator.Timeline.Timeline state"},{"name":"transitionTo","comment":" ","type":"Animator.Timeline.Duration -> state -> Animator.Timeline.Step state"},{"name":"upcoming","comment":" Check to see if a `state` is upcoming on a timeline.\n\n**Note** — This can be used to ensure a set of states can only be [`queued`](#queue) if they aren't already running.\n\n**Note 2** — This only checks if an event is in the _future_, but does not check the value you're currently at. You might need to use [`arrived`](#arrived) as well if you also care about the current state.\n\n","type":"state -> Animator.Timeline.Timeline state -> Basics.Bool"},{"name":"upcomingWith","comment":" For complicated values it can be computationally expensive to use `==`.\n\n`upcomingWith` allows you to specify your own equality function, so you can be smarter in checking how two value are equal.\n\n","type":"(state -> Basics.Bool) -> Animator.Timeline.Timeline state -> Basics.Bool"},{"name":"update","comment":" If you're creating something like a game, you might want to update your `Timelines` manually instead of using an `Animator`.\n\nThis will allow you to do whatever calculations you need while updating each `Timeline`.\n\n**Note** — You'll have to take care of subscribing to `Browser.Events.onAnimationFrame`.\n\n","type":"Time.Posix -> Animator.Timeline.Timeline state -> Animator.Timeline.Timeline state"},{"name":"wait","comment":" ","type":"Animator.Timeline.Duration -> Animator.Timeline.Step state"}],"binops":[]},{"name":"Animator.Value","comment":" You may want to animate a value manually, without generating any CSS.\n\nThis module is for you!\n\nYou'll need to track a `Timeline` in your model and update it using `AnimationFrame`.\n\n@docs color\n\n@docs float, velocity, movement, Movement, to, xy, xyz\n\n\n# Transition personality\n\n@docs withWobble\n\n","unions":[],"aliases":[{"name":"Movement","comment":" ","args":[],"type":"Internal.Move.Move Basics.Float"}],"values":[{"name":"color","comment":" ","type":"Animator.Timeline.Timeline state -> (state -> Color.Color) -> Color.Color"},{"name":"float","comment":" ","type":"Animator.Timeline.Timeline state -> (state -> Animator.Value.Movement) -> Basics.Float"},{"name":"movement","comment":" ","type":"Animator.Timeline.Timeline state -> (state -> Animator.Value.Movement) -> { position : Basics.Float, velocity : Basics.Float }"},{"name":"to","comment":" ","type":"Basics.Float -> Animator.Value.Movement"},{"name":"velocity","comment":" ","type":"Animator.Timeline.Timeline state -> (state -> Animator.Value.Movement) -> Basics.Float"},{"name":"withWobble","comment":" This will make the transition use a spring!\n\n  - `withWobble 0` - absolutely no wobble\n  - `withWobble 1` - all the wobble\n\n","type":"Basics.Float -> Animator.Value.Movement -> Animator.Value.Movement"},{"name":"xy","comment":" ","type":"Animator.Timeline.Timeline state -> (state -> { x : Animator.Value.Movement, y : Animator.Value.Movement }) -> { x : Basics.Float, y : Basics.Float }"},{"name":"xyz","comment":" ","type":"Animator.Timeline.Timeline state -> (state -> { x : Animator.Value.Movement, y : Animator.Value.Movement, z : Animator.Value.Movement }) -> { x : Basics.Float, y : Basics.Float, z : Basics.Float }"}],"binops":[]},{"name":"Animator.Watcher","comment":" If you're tracking a number of timelines in your model, you may decide to use a `Watching` to simplify adding new timelines.\n\n@docs Watching\n\n@docs init, watching, list\n\n@docs update, toSubscription\n\n","unions":[],"aliases":[{"name":"Watching","comment":" An `Animator` knows how to read and write all the `Timelines` within your `Model`.\n\nHere's an animator from the [Checkbox.elm example](https://github.com/mdgriffith/elm-animator/blob/master/examples/Checkbox.elm),\n\n    import Animator.Watcher as Watcher\n\n    animator : Watcher.Watching Model\n    animator =\n        Watcher.init\n            |> Watcher.watching\n                -- we tell the animator how\n                -- to get the checked timeline using .checked\n                .checked\n                -- and we tell the animator how\n                -- to update that timeline as well\n                (\\newChecked model ->\n                    { model | checked = newChecked }\n                )\n\nNotice you could add any number of timelines to this animator:\n\n    animator : Watcher.Watching Model\n    animator =\n        Watcher.init\n            |> Watcher.watching\n                .checked\n                (\\newChecked model ->\n                    { model | checked = newChecked }\n                )\n            |> Watcher.watching\n                .anotherChecked\n                (\\anotherCheckboxState ->\n                    { model | anotherChecked = anotherCheckboxState }\n                )\n\n**Note** — You likely only need one animator for a given project.\n\n**Note 2** — Once we have an `Animator Model`, we have two more steps in order to set things up:\n\n  - [create a _subscription_](#toSubscription)\n  - [_update_ our model](#update)\n\n","args":["model"],"type":"Internal.Timeline.Animator model"}],"values":[{"name":"init","comment":" ","type":"Animator.Watcher.Watching model"},{"name":"list","comment":" ","type":"(model -> List.List item) -> (List.List item -> model -> model) -> Animator.Watcher.Watching item -> Animator.Watcher.Watching model -> Animator.Watcher.Watching model"},{"name":"toSubscription","comment":" Convert an `Animator` to a subscription.\n\nThis is where the animator will decide if a running animation needs another frame or not.\n\n    subscriptions model =\n        Animator.toSubscription Tick model animator\n\n","type":"(Time.Posix -> msg) -> model -> Animator.Watcher.Watching model -> Platform.Sub.Sub msg"},{"name":"update","comment":" When new messages come in, we then need to update our model. This looks something like this:\n\n    type Msg\n        = Tick Time.Posix\n\n    update msg model =\n        case msg of\n            Tick newTime ->\n                ( Animator.update newTime animator model\n                , Cmd.none\n                )\n\nAnd voilà, we can begin animating!\n\n**Note** — To animate more things, all you need to do is add a new `with` to your `Animator`.\n\n","type":"Time.Posix -> Animator.Watcher.Watching model -> model -> model"},{"name":"watching","comment":" ","type":"(model -> Animator.Timeline.Timeline state) -> (Animator.Timeline.Timeline state -> model -> model) -> Animator.Watcher.Watching model -> Animator.Watcher.Watching model"}],"binops":[]}]