From e68af0eef6653491cb843e316642449cbbb22c4c Mon Sep 17 00:00:00 2001 From: seanybaggins Date: Wed, 2 Dec 2020 10:36:23 -0800 Subject: [PATCH] Have a working example with trunk --- .gitignore | 1 + Cargo.toml | 1 + .../Cargo.toml | 9 + .../Makefile.toml | 31 +++ .../animation-no-wasm-bindgen-start/README.md | 13 ++ .../index.html | 14 ++ .../src/main.rs | 176 ++++++++++++++++++ 7 files changed, 245 insertions(+) create mode 100644 examples/animation-no-wasm-bindgen-start/Cargo.toml create mode 100644 examples/animation-no-wasm-bindgen-start/Makefile.toml create mode 100644 examples/animation-no-wasm-bindgen-start/README.md create mode 100644 examples/animation-no-wasm-bindgen-start/index.html create mode 100644 examples/animation-no-wasm-bindgen-start/src/main.rs diff --git a/.gitignore b/.gitignore index 6090055f5..ba2a6ffc3 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ **.wasm **/*.rs.bk **/*.log +dist # --- Dependencies and Build artifacts --- **/node_modules diff --git a/Cargo.toml b/Cargo.toml index 203c7cbd3..8cbf40e59 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -117,6 +117,7 @@ features = [ [workspace] members = [ "examples/animation", + "examples/animation-no-wasm-bindgen-start", "examples/auth", "examples/bunnies", "examples/component_builder", diff --git a/examples/animation-no-wasm-bindgen-start/Cargo.toml b/examples/animation-no-wasm-bindgen-start/Cargo.toml new file mode 100644 index 000000000..7f33c88b8 --- /dev/null +++ b/examples/animation-no-wasm-bindgen-start/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "animation-no-wasm-bindgen-start" +version = "0.1.0" +authors = ["David O'Connor "] +edition = "2018" + +[dependencies] +seed = {path = "../../"} +rand = { version = "0.7.3", features = ["wasm-bindgen"] } diff --git a/examples/animation-no-wasm-bindgen-start/Makefile.toml b/examples/animation-no-wasm-bindgen-start/Makefile.toml new file mode 100644 index 000000000..ec324ff9b --- /dev/null +++ b/examples/animation-no-wasm-bindgen-start/Makefile.toml @@ -0,0 +1,31 @@ +extend = "../../Makefile.toml" + +# ---- BUILD ---- + +[tasks.build] +command = "trunk" +args = ["build"] + +[tasks.build_release] +command = "trunk" +args = ["build", "--release"] + +# ---- START ---- + +[tasks.start] +command = "trunk" +args = ["serve"] + +[tasks.start_release] +command = "trunk" +args = ["serve", "--release"] + +# ---- TEST ---- + +[tasks.test_firefox] +alias = "default_test_firefox" + +# ---- LINT ---- + +[tasks.clippy] +alias = "default_clippy" diff --git a/examples/animation-no-wasm-bindgen-start/README.md b/examples/animation-no-wasm-bindgen-start/README.md new file mode 100644 index 000000000..144cf9af9 --- /dev/null +++ b/examples/animation-no-wasm-bindgen-start/README.md @@ -0,0 +1,13 @@ +## Animation example + +How to make a basic animation with random generators. + +## TODO: Should this section be automated with cargo make? +Follow the installation instructions for trunk here: + +Build and run the example by running +``` +trunk serve +``` + +Open [127.0.0.1:8080](http://127.0.0.1:8080) in your browser. \ No newline at end of file diff --git a/examples/animation-no-wasm-bindgen-start/index.html b/examples/animation-no-wasm-bindgen-start/index.html new file mode 100644 index 000000000..89d0c1ef2 --- /dev/null +++ b/examples/animation-no-wasm-bindgen-start/index.html @@ -0,0 +1,14 @@ + + + + + + + Animation example + + + +
+ + + diff --git a/examples/animation-no-wasm-bindgen-start/src/main.rs b/examples/animation-no-wasm-bindgen-start/src/main.rs new file mode 100644 index 000000000..ad227ef0f --- /dev/null +++ b/examples/animation-no-wasm-bindgen-start/src/main.rs @@ -0,0 +1,176 @@ +use rand::prelude::*; +use seed::{prelude::*, *}; + +type CarColor = String; + +// ------ ------ +// Init +// ------ ------ + +fn init(_: Url, orders: &mut impl Orders) -> Model { + orders + .send_msg(Msg::SetViewportWidth) + .stream(streams::window_event(Ev::Resize, |_| Msg::SetViewportWidth)) + .after_next_render(Msg::Rendered); + + Model::default() +} + +// ------ ------ +// Model +// ------ ------ + +#[derive(Default)] +struct Model { + viewport_width: f64, + car: Car, +} + +// ------ Car ------ + +#[derive(Debug)] +struct Car { + x: f64, + y: f64, + speed: f64, + color: CarColor, + width: f64, + height: f64, +} + +impl Car { + /// Pixels per second. + /// _Note_: + /// Optional feature "wasm-bindgen" has to be enabled for crate `rand` (otherwise it panics). + fn generate_speed() -> f64 { + thread_rng().gen_range(400., 800.) + } + + fn generate_color() -> CarColor { + let hue = thread_rng().gen_range(0, 360); + format!("hsl({}, 80%, 50%)", hue) + } +} + +impl Default for Car { + fn default() -> Self { + let car_width = 120.; + Self { + x: -car_width, + y: 100., + speed: Self::generate_speed(), + color: Self::generate_color(), + width: car_width, + height: 60., + } + } +} + +// ------ ------ +// Update +// ------ ------ + +#[derive(Copy, Clone)] +enum Msg { + Rendered(RenderInfo), + SetViewportWidth, +} + +fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders) { + match msg { + Msg::Rendered(render_info) => { + let delta = render_info.timestamp_delta.unwrap_or_default(); + if delta > 0. { + // Move car at least 1px to the right. + model.car.x += f64::max(1., delta / 1000. * model.car.speed); + + // We don't see car anymore => back to start + generate new color and speed. + if model.car.x > model.viewport_width { + model.car = Car::default(); + } + } + orders.after_next_render(Msg::Rendered); + } + Msg::SetViewportWidth => { + model.viewport_width = f64::from(body().client_width()); + orders.skip(); + } + } +} + +// ------ ------ +// View +// ------ ------ + +fn view(model: &Model) -> Node { + // Scene container, also represents sky. + div![ + id!("animation"), + style! { + St::Overflow => "hidden"; + St::Width => unit!(100, %); + St::Position => "relative"; + St::Height => unit!(170, px); + St::BackgroundColor => "deepskyblue"; + }, + // Road. + div![style! { + St::Width => unit!(100, %); + St::Height => unit!(20, px); + St::Bottom => 0; + St::BackgroundColor => "darkgray"; + St::Position => "absolute"; + }], + view_car(&model.car) + ] +} + +fn view_car(car: &Car) -> Node { + div![ + // Car container. + style! { + St::Width => unit!(car.width, px); + St::Height => unit!(car.height, px); + St::Top => unit!(car.y, px); + St::Left => unit!(car.x, px); + St::Position => "absolute"; + }, + // Windows. + div![style! { + St::BackgroundColor => "rgb(255, 255, 255, 0.5)"; + St::Left => unit!(car.width * 0.25, px); + St::Width => unit!(car.width * 0.5, px); + St::Height => unit!(car.height * 0.6, px); + St::BorderRadius => unit!(9999, px); + St::Position => "absolute"; + }], + // Body. + div![style! { + St::Top => unit!(car.height * 0.35, px); + St::BackgroundColor => car.color; + St::Width => unit!(car.width, px); + St::Height => unit!(car.height * 0.5, px); + St::BorderRadius => unit!(9999, px); + St::Position => "absolute"; + }], + view_wheel(car.width * 0.15, car), + view_wheel(car.width * 0.6, car) + ] +} + +fn view_wheel(wheel_x: f64, car: &Car) -> Node { + let wheel_radius = car.height * 0.4; + div![style! { + St::Top => unit!(car.height * 0.55, px); + St::Left => unit!(wheel_x, px); + St::BackgroundColor => "black"; + St::Width => unit!(wheel_radius, px); + St::Height => unit!(wheel_radius, px); + St::BorderRadius => unit!(9999, px); + St::Position => "absolute"; + }] +} + +fn main() { + App::start("app", init, update, view); +}