Animations for lustre, utilizing JS requestAnimationFrame and setTimeout
  • JavaScript 88.9%
  • Gleam 8.1%
  • HTML 2.3%
  • CSS 0.7%
Find a file
2025-06-04 21:51:43 +02:00
src simplify + doc 2025-05-28 23:39:25 +02:00
test Upgrade test to use assert (gleam 1.11) 2025-06-04 21:49:12 +02:00
.gitignore Documentation with both examples running! 2023-03-30 21:31:39 +02:00
gleam.toml Require gleam 1.11 and upgarde to gleeunit 1.4.0 2025-06-04 21:51:43 +02:00
highlight.js Documentation with both examples running! 2023-03-30 21:31:39 +02:00
index.html upgrade deps; release v0.4 2025-04-26 14:31:00 +02:00
lustre_animation.css Documentation with both examples running! 2023-03-30 21:31:39 +02:00
manifest.toml Require gleam 1.11 and upgarde to gleeunit 1.4.0 2025-06-04 21:51:43 +02:00
package-lock.json Documentation with both examples running! 2023-03-30 21:31:39 +02:00
package.json Documentation with both examples running! 2023-03-30 21:31:39 +02:00
README.md Pass a function that evaluates between start and stop value; provide helper to construct that function 2025-05-26 21:46:35 +02:00
run_highlight.js Documentation with both examples running! 2023-03-30 21:31:39 +02:00

Lustre Animation

The basic usage is

  • keep 1 Animations value
  • add animations by some trigger
  • call animation.effect() on your value and let your lustre update() return it. This will cause a dispatch on the next JS animation frame, unless all animations have finished (and auto-removed)
  • update the animations with the new time.
  • evaluate for each animation you are interested in.

e.g. like this:

import lustre/animation as a

pub type Msg {
    Trigger
    Tick(Float)
}

pub fn update(model: Model, msg: Msg) {
    let m = case msg of {
        Trigger -> {
            let new_anim = a.add(model.animations, "id", 1.0, 2.0, 0.250)
            Model(1.0, animations: new_anim)
        }
        Tick(t) -> {
            let new_anim = a.tick(model.animations, t)
            let new_value = a.value(new_anim, "id", model.value)
            Model(new_value, new_anim)
        }
    }
    #(m, animation.effect(m.animations, Tick))
}

In the above type Model, init and render have been omitted.

Running Examples

There are fully functional examples animations in the test/ directory, which you can build by

gleam test
npx vite

and then pointing your browser to the URL that vite indicates.

TODO

  • every(Minute), etc
  • quadratic, cubic, etc interpolators
  • Compose animations from("anim", 1.0) |> after(0.250) |> cubic(3.0, 0.250) |> after(0.250) |> quadr(2.0, 0.250)