aboutsummaryrefslogtreecommitdiff
path: root/compat/lustre_animation/test
diff options
context:
space:
mode:
Diffstat (limited to 'compat/lustre_animation/test')
-rw-r--r--compat/lustre_animation/test/example_drops.gleam120
-rw-r--r--compat/lustre_animation/test/example_two_independent.gleam103
-rw-r--r--compat/lustre_animation/test/info.mjs2
-rw-r--r--compat/lustre_animation/test/lustre/animation_test.gleam39
-rw-r--r--compat/lustre_animation/test/lustre_animation_test.gleam5
-rw-r--r--compat/lustre_animation/test/start_examples.mjs5
6 files changed, 274 insertions, 0 deletions
diff --git a/compat/lustre_animation/test/example_drops.gleam b/compat/lustre_animation/test/example_drops.gleam
new file mode 100644
index 0000000..dd69f5c
--- /dev/null
+++ b/compat/lustre_animation/test/example_drops.gleam
@@ -0,0 +1,120 @@
+import lustre
+import lustre/animation.{Animations}
+import lustre/attribute.{id, style}
+import lustre/effect.{Effect}
+import lustre/element.{Element, text}
+import lustre/element/html.{div, h3}
+import lustre/event.{on}
+import gleam/float
+import gleam/int
+import gleam/list.{filter, map}
+import gleam/dynamic.{Dynamic} as d
+import gleam/option.{Some}
+
+pub type Msg {
+ Click(x: Float, y: Float)
+ Tick(time_offset: Float)
+}
+
+pub type Drop {
+ Drop(id: String, x: Float, y: Float, r: Float)
+}
+
+pub type Model {
+ Model(counter: Int, drops: List(Drop), animations: Animations)
+}
+
+pub fn main() {
+ lustre.application(init, update, render)
+ |> lustre.start("#drops", Nil)
+}
+
+fn init(_) {
+ #(Model(0, [], animation.new()), effect.none())
+}
+
+const to_s = int.to_string
+
+pub fn update(model: Model, msg: Msg) -> #(Model, Effect(Msg)) {
+ let m = case msg {
+ Click(x, y) -> {
+ let id = "drop" <> to_s(model.counter)
+ let new_animations = animation.add(model.animations, id, 0.0, 1.0, 1.5)
+ let new_drop = Drop(id, x, y, 0.0)
+ Model(model.counter + 1, [new_drop, ..model.drops], new_animations)
+ }
+ Tick(time_offset) -> {
+ let new_animations = animation.tick(model.animations, time_offset)
+ let new_drops =
+ model.drops
+ |> filter(fn(drop) { drop.r != 1.0 })
+ |> map(fn(drop) {
+ let r = animation.value(new_animations, drop.id, drop.r)
+ Drop(..drop, r: r)
+ })
+ Model(..model, drops: new_drops, animations: new_animations)
+ }
+ }
+ #(m, animation.effect(m.animations, Tick))
+}
+
+pub fn render(model: Model) -> Element(Msg) {
+ div(
+ [
+ style([
+ #("width", "100%"),
+ #("height", "100%"),
+ #("display", "grid"),
+ #("grid-template-rows", "auto 1fr"),
+ ]),
+ ],
+ [
+ h3([style([#("text-align", "center")])], [text("Click to make drops")]),
+ div(
+ [
+ id("pond"),
+ style([#("position", "relative")]),
+ on(
+ "mouseDown",
+ fn(event) {
+ let assert Ok(x) = d.field("clientX", d.float)(event)
+ let assert Ok(y) = d.field("clientY", d.float)(event)
+ let rect = bounding_client_rect("pond")
+ let assert Ok(top) = d.field("top", d.float)(rect)
+ let assert Ok(left) = d.field("left", d.float)(rect)
+
+ Some(Click(x -. left, y -. top))
+ },
+ ),
+ ],
+ map(model.drops, render_drop),
+ ),
+ ],
+ )
+}
+
+fn render_drop(drop: Drop) {
+ let r = drop.r *. 50.0
+ let rad = float.to_string(r *. 2.0)
+ let rw = float.to_string(drop.r *. 2.5)
+ let alpha =
+ 1.0 -. drop.r
+ |> float.to_string
+ div(
+ [
+ style([
+ #("position", "absolute"),
+ #("left", float.to_string(drop.x -. r) <> "px"),
+ #("top", float.to_string(drop.y -. r) <> "px"),
+ #("width", rad <> "px"),
+ #("height", rad <> "px"),
+ #("border", rw <> "px solid rgba(0, 0, 0, " <> alpha <> ")"),
+ #("border-radius", "50%"),
+ ]),
+ ],
+ [],
+ )
+}
+
+external fn bounding_client_rect(String) -> Dynamic =
+ "./info.mjs" "bounding_client_rect"
diff --git a/compat/lustre_animation/test/example_two_independent.gleam b/compat/lustre_animation/test/example_two_independent.gleam
new file mode 100644
index 0000000..61e687d
--- /dev/null
+++ b/compat/lustre_animation/test/example_two_independent.gleam
@@ -0,0 +1,103 @@
+import lustre
+import lustre/animation.{Animations}
+import lustre/attribute.{style}
+import lustre/effect.{Effect}
+import lustre/element.{text}
+import lustre/element/html.{button, div, h3, span}
+import lustre/event.{on_click}
+import gleam/float
+
+pub type Msg {
+ Left
+ Right
+ Top
+ Bottom
+ Tick(time_offset: Float)
+}
+
+pub type Model {
+ Model(x: Float, y: Float, animations: Animations)
+}
+
+pub fn main() {
+ lustre.application(init, update, render)
+ |> lustre.start("#root", Nil)
+}
+
+fn init(_) {
+ #(Model(0.5, 0.5, animation.new()), effect.none())
+}
+
+pub fn update(model: Model, msg: Msg) -> #(Model, Effect(Msg)) {
+ let m = case msg {
+ Left -> {
+ let new_animations =
+ animation.add(model.animations, "x", model.x, 0.0, 2.5)
+ Model(..model, animations: new_animations)
+ }
+ Right -> {
+ let new_animations =
+ animation.add(model.animations, "x", model.x, 1.0, 2.5)
+ Model(..model, animations: new_animations)
+ }
+ Top -> {
+ let new_animations =
+ animation.add(model.animations, "y", model.y, 0.0, 2.5)
+ Model(..model, animations: new_animations)
+ }
+ Bottom -> {
+ let new_animations =
+ animation.add(model.animations, "y", model.y, 1.0, 2.5)
+ Model(..model, animations: new_animations)
+ }
+ Tick(time_offset) -> {
+ let new_animations = animation.tick(model.animations, time_offset)
+ let x = animation.value(new_animations, "x", model.x)
+ let y = animation.value(new_animations, "y", model.y)
+ Model(x: x, y: y, animations: new_animations)
+ }
+ }
+ #(m, animation.effect(m.animations, Tick))
+}
+
+pub fn render(model: Model) {
+ let sp = span([], [])
+ let to_s = float.to_string
+ div(
+ [
+ style([
+ #("display", "grid"),
+ #("grid-template-rows", "1fr auto"),
+ #("width", "100%"),
+ #("height", "100%"),
+ ]),
+ ],
+ [
+ div(
+ [
+ style([
+ #("display", "grid"),
+ #(
+ "grid-template-rows",
+ to_s(model.y) <> "fr auto " <> to_s(1.0 -. model.y) <> "fr",
+ ),
+ #(
+ "grid-template-columns",
+ to_s(model.x) <> "fr auto " <> to_s(1.0 -. model.x) <> "fr",
+ ),
+ ]),
+ ],
+ [sp, sp, sp, sp, h3([], [text("Move me around")]), sp, sp, sp, sp],
+ ),
+ div(
+ [],
+ [
+ button([on_click(Left)], [text("Move to the Left")]),
+ button([on_click(Right)], [text("Move to the Right")]),
+ button([on_click(Top)], [text("Move to the Top")]),
+ button([on_click(Bottom)], [text("Move to the Bottom")]),
+ ],
+ ),
+ ],
+ )
+}
diff --git a/compat/lustre_animation/test/info.mjs b/compat/lustre_animation/test/info.mjs
new file mode 100644
index 0000000..d58e440
--- /dev/null
+++ b/compat/lustre_animation/test/info.mjs
@@ -0,0 +1,2 @@
+export const bounding_client_rect = id => document.getElementById(id).getBoundingClientRect()
+
diff --git a/compat/lustre_animation/test/lustre/animation_test.gleam b/compat/lustre_animation/test/lustre/animation_test.gleam
new file mode 100644
index 0000000..98ded63
--- /dev/null
+++ b/compat/lustre_animation/test/lustre/animation_test.gleam
@@ -0,0 +1,39 @@
+import gleeunit/should
+import lustre/animation.{add, new, tick, value}
+
+pub fn evaluate_test() {
+ new()
+ |> add("a", 7.0, 42.0, 2.0)
+ |> value("a", 0.0)
+ |> should.equal(7.0)
+}
+
+pub fn evaluate_start_test() {
+ new()
+ |> add("a", 7.0, 42.0, 2.0)
+ |> tick(1000.0)
+ |> value("a", 0.0)
+ |> should.equal(7.0)
+}
+
+pub fn evaluate_done_test() {
+ new()
+ |> add("a", 7.0, 42.0, 2.0)
+ |> tick(1000.0)
+ |> tick(3000.0)
+ |> value("a", 0.0)
+ |> should.equal(42.0)
+}
+
+pub fn evaluate_gone_test() {
+ new()
+ |> add("a", 7.0, 42.0, 2.0)
+ // start
+ |> tick(1000.0)
+ // Done
+ |> tick(3000.0001)
+ // remove
+ |> tick(3000.1)
+ |> value("a", 0.0)
+ |> should.equal(0.0)
+}
diff --git a/compat/lustre_animation/test/lustre_animation_test.gleam b/compat/lustre_animation/test/lustre_animation_test.gleam
new file mode 100644
index 0000000..ecd12ad
--- /dev/null
+++ b/compat/lustre_animation/test/lustre_animation_test.gleam
@@ -0,0 +1,5 @@
+import gleeunit
+
+pub fn main() {
+ gleeunit.main()
+}
diff --git a/compat/lustre_animation/test/start_examples.mjs b/compat/lustre_animation/test/start_examples.mjs
new file mode 100644
index 0000000..6d792c7
--- /dev/null
+++ b/compat/lustre_animation/test/start_examples.mjs
@@ -0,0 +1,5 @@
+import * as two from "../build/dev/javascript/lustre_animation/example_two_independent.mjs";
+import * as drops from "../build/dev/javascript/lustre_animation/example_drops.mjs";
+
+two.main();
+drops.main();