#web-apps #browser #applications

web_macro

一个用于与网页浏览器交互的库

4个版本

0.0.3 2022年12月24日
0.0.2 2022年12月24日
0.0.1 2022年12月24日
0.0.0 2022年12月24日

#150 in #web-assembly

每月 28 次下载
3 个crate中使用(通过 web

MIT/Apache

2KB

docs.rs docs

使用Rust WebAssembly轻松编写Web应用程序

我希望有一个库,人们可以在下午学习如何使用它,并开始制作交互式浏览器体验。这个项目不支持所有浏览器功能。虽然你可以通过这个库使用的运行时JavaScript调用机制轻松添加自己的功能。请随意提交PR以添加更多功能。

  • 异步 & 协程支持
  • 元素操作
  • 鼠标、键盘和改变事件监听器
  • canvas2d
  • 本地存储
  • fetch & XMLHttpRequest
  • 样式 & 类
  • 历史 & 位置信息
  • WebGPU
  • 其他工具

请查看此处的文档

cargo add web

你好,世界!

让我们看看如何将东西放入控制台的基本示例

use web::*;

fn main() {
    console_log("Hello, world!");
}
<html>
    <head>
        <meta charset="utf-8">
        <script src="https://unpkg.com/js-wasm/js-wasm.js"></script>
        <script type="application/wasm" src="helloworld.wasm"></script>
    </head>
    <body>
        Open my console.
    </body>
</html>

请记得为WebAssembly配置你的库 Cargo.toml

# add these lines for WebAssembly to end of your Cargo.toml

[lib]
crate-type =["cdylib"]

[profile.release]
lto = true
cargo build --target wasm32-unknown-unknown --release
cp target/wasm32-unknown-unknown/release/helloworld.wasm .
python3 -m http.server

# open https://127.0.0.1:8000 in browser
# right click, inspect, look at message in console

完整的示例在这里

更高级的东西?

让我们看看我们的snake示例和一些关键功能的使用

Screen Shot 2022-12-21 at 12 35 48 PM

在这里玩演示

canvas

此示例使用canvas

//get an element and get the 2D context for canvas
let screen = query_selector("#screen");
let width: f64 = get_property_f64(&screen, "width");
let height: f64 = get_property_f64(&screen, "height");
let ctx = CanvasContext::from_element(&screen);

...

//clear screen
self.ctx.clear_rect(
    0.0,
    0.0,
    self.canvas_width as f64,
    self.canvas_height as f64,
);

// iterate through all the cells of the screen and draw a rectangle
for (_id, (pos, color)) in &mut self.world.query::<(&Position, &Color)>() {
    self.ctx.set_fill_style(&color.0);
    self.ctx.fill_rect(
        (pos.0 * (self.canvas_width / MAP_WIDTH)) as f64,
        (pos.1 * (self.canvas_height / MAP_HEIGHT)) as f64,
        (self.canvas_width / MAP_WIDTH) as f64,
        (self.canvas_height / MAP_HEIGHT) as f64,
    );
}

请求动画帧

让我们看看如何运行游戏循环

fn game_loop() {
    // run game loop assuming 15 ms has passed
    match Game::instance().run(15.0) {
        Err(e) => console_error(&e.to_string()),
        _ => (),
    };
    // request next animation frame
    request_animation_frame(game_loop);
}

... 

// start the loop
request_animation_frame(game_loop);

事件

let body = query_selector("body");
element_add_key_down_listener(&body, |e| {
    Game::instance().key_down(e.key_code as u32);
});

异步 & 协程

此库支持异步和生成协程。考虑这个程序,它启动一个循环控制台日志并在屏幕上绘制随机方块。

use web::*;

// easily make your first function async
#[web::main]
async fn main() {
    let canvas = query_selector("#canvas");
    let ctx = CanvasContext::from_element(&canvas);

    // we can spawn concurrent operations
    coroutine(async {
        loop {
            console_log("⏰ tik");
            // hand async set_timeout
            sleep(1000).await;
            console_log("⏰ tok");
            sleep(1000).await;
        }
    });

    loop {
        // draw a random color rect
        ctx.set_fill_style(&format!(
            "rgb({}, {}, {})",
            random() * 255.0,
            random() * 255.0,
            random() * 255.0
        ));
        ctx.fill_rect(
            random() * 500.0,
            random() * 500.0,
            random() * 500.0,
            random() * 500.0,
        );
        // a more async way to write graphics code
        wait_til_animation_frame().await;
    }
}

许可证

此项目受以下之一许可:

任选其一。

贡献

除非你明确声明,否则你故意提交以包含在web中的任何贡献,根据Apache-2.0许可证定义,都应按上述方式双许可,而无需任何额外的条款或条件。

依赖项

~1.5MB
~35K SLoC