Unexpected behaviour when trying to use elm-animator for a game
w0rm opened this issue · comments
Hi! I am working on a game and trying to use elm-animator for it. The package is really great and API looks easy to use.
I faced three unexpected issues though:
- Interpolation to 0. I am queueing the striking animation, and then back to the resting position, however the animated value seems to jump to 0. Inserting
Animator.millis 1
seems to fix it.
eel.timeline
|> Animator.queue
[ Animator.event Animator.quickly (Eel.Striking mouse)
-- uncommenting this fixes the interpolation issue:
--, Animator.wait (Animator.millis 1)
, Animator.event Animator.quickly Eel.Resting
]
- Queuing return animation in the middle of existing animation causes overshooting of values. Can be reproduced by clicking near eel's head when its moving up.
- Queuing animation in the middle of existing animation sometimes jumps to the final state. Can sometimes be reproduced by clicking near eel's head when it is biting the mouse.
I captured these issues in the branch as we discussed on slack.
SSCCEE for item 2:
module Main exposing (main)
import Animator exposing (Animator, Timeline)
import Browser
import Browser.Events
import Html exposing (Html)
import Html.Attributes
import Html.Events
import Time
type Msg
= Click
| Tick Time.Posix
main : Program () (Timeline Float) Msg
main =
Browser.element
{ init =
\_ ->
( Animator.init 0
|> Animator.go (Animator.seconds 2) 1
, Cmd.none
)
, view = view
, update = update
, subscriptions = \_ -> Browser.Events.onAnimationFrame Tick
}
update : Msg -> Timeline Float -> ( Timeline Float, Cmd Msg )
update msg timeline =
case msg of
Click ->
( Animator.queue
[ Animator.event (Animator.seconds 1) 0
, Animator.wait (Animator.seconds 5)
, Animator.event (Animator.seconds 2) 1
]
timeline
, Cmd.none
)
Tick time ->
( Animator.update time animator timeline
, Cmd.none
)
view : Timeline Float -> Html Msg
view timeline =
let
width =
Animator.linear timeline Animator.at * 500
in
Html.div
[ Html.Attributes.style "margin" "20px"
, Html.Attributes.style "width" "500px"
, Html.Attributes.style "height" "8px"
, Html.Attributes.style "background-color" "black"
, Html.Attributes.style "padding" "1px"
]
[ Html.div
[ Html.Attributes.style "width" (String.fromFloat width ++ "px")
, Html.Attributes.style "height" "8px"
, Html.Attributes.style "background-color" "white"
]
[]
, Html.button
[ Html.Attributes.style "margin" "10px 0 0", Html.Events.onClick Click ]
[ Html.text "Click during animation to see the jump" ]
]
animator : Animator (Timeline any)
animator =
Animator.watching identity always Animator.animator
Expected behaviour: When clicking the button during animation, I expect the bar to go until the end, and then return back.
This can be a test case that shows that queuing during animation breaks the animated value. Using the linear scale here, so the value should be a bit more than 0.5. However, with the new event queued, it becomes more than 0.6.
val : ( Float, Float )
val =
let
animator =
Animator.watching identity always Animator.animator
init =
Animator.init 0
|> Animator.update (Time.millisToPosix 0) animator
|> Animator.go (Animator.seconds 2) 1
-- count 1 second (not sure why I need to call update twice here to work?)
|> Animator.update (Time.millisToPosix 0) animator
|> Animator.update (Time.millisToPosix 1000) animator
withoutQueue =
init
|> Animator.update (Time.millisToPosix 1001) animator
withQueue =
init
|> Animator.queue [ Animator.event (Animator.seconds 1) 0 ]
|> Animator.update (Time.millisToPosix 1001) animator
in
( Debug.log "without queue" (Animator.linear withoutQueue Animator.at)
-- without queue: 0.5007324216421694
, Debug.log "with queue" (Animator.linear withQueue Animator.at)
-- with queue: 0.6258543726289645
)
Ok! So, I fixed a queuing bug as well as a few other issues in 4461b4f
It does fix the loading bar example you posted. I'm hoping it fixes all of these!
Will publish a patch release shortly.
Published as 1.0.2
!
@mdgriffith thanks a lot! I confirm that this fixed all 3 issues I had in the game.
🙌 wonderful!