Commit 1593d4af authored by Jeremy Soller's avatar Jeremy Soller

Merge branch 'wasm' into 'master'

Wasm

See merge request !67
parents 904157c3 bd21395d
Pipeline #9150 passed with stage
in 1 minute and 12 seconds
......@@ -9,4 +9,5 @@
# Generated by Cargo
Cargo.lock
/target/
target/
node_modules/
\ No newline at end of file
......@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 0.3.31
* Web support
## 0.3.28
* Add sdl2 bundled and static feature
......
[package]
name = "orbclient"
version = "0.3.30"
version = "0.3.31"
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
description = "The Orbital Client Library"
documentation = "https://docs.rs/orbclient"
......@@ -17,7 +17,7 @@ keywords = [
name = "orbclient"
path = "src/lib.rs"
[target.'cfg(not(target_os = "redox"))'.dependencies]
[target.'cfg(all(not(target_os = "redox"), not(target_arch = "wasm32")))'.dependencies]
sdl2 = { version = "0.34", features = ["raw-window-handle"] }
sdl2-sys = "0.34"
libc = "0.2"
......@@ -26,6 +26,35 @@ raw-window-handle = "0.3"
[target.'cfg(target_os="redox")'.dependencies]
redox_syscall = { version = "0.2.1" }
[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = "0.2.69"
# js-sys = "0.3"
[target.'cfg(target_arch = "wasm32")'.dependencies.web-sys]
version = "0.3"
features = [
"Node",
"Element",
"console",
"CanvasRenderingContext2d",
"Document",
"Element",
"ImageData",
"HtmlCanvasElement",
"HtmlElement",
"Window",
"CssStyleDeclaration",
"MouseEvent",
"KeyboardEvent",
"WheelEvent",
"FocusEvent",
"DragEvent",
"DataTransfer",
"Navigator",
"Clipboard",
"DomRect"
]
[features]
default = ["bundled"]
bundled = ["sdl2/bundled", "sdl2/static-link", "sdl2-sys/bundled", "sdl2-sys/static-link"]
......
......@@ -6,6 +6,18 @@ The Orbital Client Library. Compatible with Redox and SDL2.
[![crates.io](http://meritbadge.herokuapp.com/orbclient)](https://crates.io/crates/orbclient)
[![docs.rs](https://docs.rs/orbclient/badge.svg)](https://docs.rs/orbclient)
## Platform notes
### Web
* Rust standard toolchain `rustup`, `rustc`, `cargo` ([install](https://www.rust-lang.org/tools/install))
* Rust web assembly toolchain `wasm-pack` ([install](https://rustwasm.github.io/wasm-pack/installer/))
* JavaScript package manager npm ([install](https://www.npmjs.com/get-npm))
* Run simple example
* Navigate to `examples/simple` director
* Run `npm install`
* Run `npm run serve`
### Troubleshooting
* Make sure that you work with the current ```nightly``` version of Rust
......
[package]
name = "simple"
version = "0.1.0"
authors = ["Florian Blasius <flovanpt@posteo.de>"]
[lib]
crate-type = ["cdylib", "rlib"]
[dependencies]
wasm-bindgen = "0.2"
orbclient = { path = "../.." }
# The `console_error_panic_hook` crate provides better debugging of panics by
# logging them with `console.error`. This is great for development, but requires
# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
# code size when deploying.
console_error_panic_hook = { version = "0.1.6" }
# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size
# compared to the default allocator's ~10K. It is slower than the default
# allocator, however.
#
# Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now.
wee_alloc = { version = "0.4.5", optional = true }
[dev-dependencies]
wasm-bindgen-test = "0.3.8"
[profile.release]
# Tell `rustc` to optimize for small code size.
opt-level = "s"
\ No newline at end of file
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type"/>
</head>
<body>
</body>
</html>
\ No newline at end of file
import('./pkg')
.catch(console.error);
\ No newline at end of file
This diff is collapsed.
{
"scripts": {
"build": "webpack",
"serve": "webpack-dev-server"
},
"devDependencies": {
"@wasm-tool/wasm-pack-plugin": "1.3.1",
"text-encoding": "^0.7.0",
"html-webpack-plugin": "^3.2.0",
"webpack": "4.43.0",
"webpack-cli": "3.3.11",
"webpack-dev-server": "3.11.0"
}
}
extern crate console_error_panic_hook;
extern crate orbclient;
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use orbclient::{animation_loop, log, Color, EventOption, GraphicsPath, Mode, Renderer, Window};
use std::panic;
#[wasm_bindgen(start)]
pub fn start() {
console_error_panic_hook::set_once();
let (width, height) = orbclient::get_display_size().unwrap();
let mut window = Window::new(
(width as i32) / 4,
(height as i32) / 4,
width / 2,
height / 2,
"TITLE",
)
.unwrap();
let (win_w, win_h) = (width / 2, height / 2);
// top left -> bottom rigth
window.linear_gradient(
0,
0,
win_w / 3,
win_h,
0,
0,
(win_w / 3) as i32,
(win_h / 2) as i32,
Color::rgb(128, 128, 128),
Color::rgb(255, 255, 255),
);
// horizontal gradient
window.linear_gradient(
(win_w / 3) as i32,
0,
win_w / 3,
win_h,
(win_w / 3) as i32,
0,
(2 * win_w / 3) as i32,
0,
Color::rgb(128, 255, 255),
Color::rgb(255, 255, 255),
);
// vertical gradient
window.linear_gradient(
(2 * win_w / 3) as i32,
0,
win_w / 3,
win_h,
(2 * win_w / 3) as i32,
0,
(2 * win_w / 3) as i32,
win_h as i32,
Color::rgb(0, 128, 0),
Color::rgb(255, 255, 255),
);
window.arc(100, 100, -25, 1 << 0 | 1 << 2, Color::rgb(0, 0, 255));
window.arc(100, 100, -25, 1 << 1 | 1 << 3, Color::rgb(0, 255, 255));
window.arc(100, 100, -25, 1 << 4 | 1 << 6, Color::rgb(255, 0, 255));
window.arc(100, 100, -25, 1 << 5 | 1 << 7, Color::rgb(255, 255, 0));
window.circle(100, 100, 25, Color::rgb(0, 0, 0));
window.circle(100, 101, -25, Color::rgb(0, 255, 0));
window.circle(220, 220, -100, Color::rgba(128, 128, 128, 80));
window.wu_circle(150, 220, 100, Color::rgba(255, 0, 0, 255));
window.line(0, 0, 200, 200, Color::rgb(255, 0, 0));
window.line(0, 200, 200, 0, Color::rgb(128, 255, 0));
// vertical and horizontal line test
window.line(100, 0, 100, 200, Color::rgb(0, 0, 255));
window.line(0, 100, 200, 100, Color::rgb(255, 255, 0));
window.wu_line(100, 220, 400, 250, Color::rgba(255, 0, 0, 255));
window.line(100, 230, 400, 260, Color::rgba(255, 0, 0, 255));
// path and bezier curve example draw a cloud
let mut cloud_path = GraphicsPath::new();
cloud_path.move_to(170, 80);
cloud_path.bezier_curve_to(130, 100, 130, 150, 230, 150);
cloud_path.bezier_curve_to(250, 180, 320, 180, 340, 150);
cloud_path.bezier_curve_to(420, 150, 420, 120, 390, 100);
cloud_path.bezier_curve_to(430, 40, 370, 30, 340, 50);
cloud_path.bezier_curve_to(320, 5, 250, 20, 250, 50);
cloud_path.bezier_curve_to(200, 5, 150, 20, 170, 80);
window.draw_path_stroke(cloud_path, Color::rgb(0, 0, 255));
// path and quadratic curve example draw a balloon
let mut balloon_path = GraphicsPath::new();
balloon_path.move_to(75, 25);
balloon_path.quadratic_curve_to(25, 25, 25, 62);
balloon_path.quadratic_curve_to(25, 100, 50, 100);
balloon_path.quadratic_curve_to(50, 120, 30, 125);
balloon_path.quadratic_curve_to(60, 120, 65, 100);
balloon_path.quadratic_curve_to(125, 100, 125, 62);
balloon_path.quadratic_curve_to(125, 25, 75, 25);
window.draw_path_stroke(balloon_path, Color::rgb(0, 0, 255));
window.char(200, 200, '═', Color::rgb(0, 0, 0));
window.char(208, 200, '═', Color::rgb(0, 0, 0));
// testing for non existent x,y position : does not panic but returns Color(0,0,0,0)
let _non_existent_pixel = window.getpixel(width as i32 + 10, height as i32 + 10);
// testing PartialEq for Color
if Color::rgb(11, 2, 3) == Color::rgba(1, 2, 3, 100) {
log("Testing colors: they are the same!")
} else {
log("Testing colors: they are NOT the same!")
}
//Draw a transparent rectangle over window content
// default mode is Blend
window.rect(250, 200, 80, 80, Color::rgba(100, 100, 100, 100));
//Draw an opaque rectangle replacing window content
window.mode().set(Mode::Overwrite); // set window drawing mode to Overwrite from now on
window.rect(300, 220, 80, 80, Color::rgb(100, 100, 100));
//Draw a hole in the window replacing alpha channel (Only in Orbital, not in SDL2)
window.rect(300, 100, 80, 80, Color::rgba(10, 10, 10, 1));
//Draw a transparent rectangle over window content
window.mode().set(Mode::Blend); //set mode to Blend fron now on
window.rect(200, 230, 80, 80, Color::rgba(100, 100, 100, 100));
//Draw a blured box over window content
window.box_blur(170, 100, 150, 150, 10);
//Draw a shadow around a box
window.box_shadow(170, 100, 150, 150, 0, 0, 20, Color::rgba(0, 0, 0, 255));
window.sync();
animation_loop(move || {
for event in window.events() {
match event.to_option() {
EventOption::Quit(_quit_event) => return false,
EventOption::Mouse(evt) => log(format!(
"At position {:?} pixel color is : {:?}",
(evt.x, evt.y),
window.getpixel(evt.x, evt.y)
)
.as_str()),
event_option => log(format!("{:?}", event_option)),
}
}
true
});
}
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const WasmPackPlugin = require("@wasm-tool/wasm-pack-plugin");
module.exports = {
entry: './index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
},
plugins: [
new HtmlWebpackPlugin({
template: 'index.html'
}),
new WasmPackPlugin({
crateDirectory: path.resolve(__dirname, ".")
}),
// Have this example work in Edge which doesn't ship `TextEncoder` or
// `TextDecoder` at this time.
new webpack.ProvidePlugin({
TextDecoder: ['text-encoding', 'TextDecoder'],
TextEncoder: ['text-encoding', 'TextEncoder']
})
],
mode: 'development'
};
\ No newline at end of file
......@@ -12,32 +12,51 @@ impl Color {
/// Create a new color from RGB
pub const fn rgb(r: u8, g: u8, b: u8) -> Self {
Color {
#[cfg(not(target_arch = "wasm32"))]
data: 0xFF000000 | ((r as u32) << 16) | ((g as u32) << 8) | (b as u32),
#[cfg(target_arch = "wasm32")]
data: 0xFF000000 | ((b as u32) << 16) | ((g as u32) << 8) | (r as u32),
}
}
/// Set the alpha
pub const fn rgba(r: u8, g: u8, b: u8, a: u8) -> Self {
Color {
#[cfg(not(target_arch = "wasm32"))]
data: ((a as u32) << 24) | ((r as u32) << 16) | ((g as u32) << 8) | (b as u32),
#[cfg(target_arch = "wasm32")]
data: ((a as u32) << 24) | ((b as u32) << 16) | ((g as u32) << 8) | (r as u32),
}
}
/// Get the r value
#[cfg(not(target_arch = "wasm32"))]
pub fn r(&self) -> u8 {
((self.data & 0x00FF0000) >> 16) as u8
}
/// Get the r value
#[cfg(target_arch = "wasm32")]
pub fn r(&self) -> u8 {
(self.data & 0x000000FF) as u8
}
/// Get the g value
pub fn g(&self) -> u8 {
((self.data & 0x0000FF00) >> 8) as u8
}
/// Get the b value
#[cfg(not(target_arch = "wasm32"))]
pub fn b(&self) -> u8 {
(self.data & 0x000000FF) as u8
}
#[cfg(target_arch = "wasm32")]
pub fn b(&self) -> u8 {
((self.data & 0x00FF0000) >> 16) as u8
}
/// Get the alpha value
pub fn a(&self) -> u8 {
((self.data & 0xFF000000) >> 24) as u8
......@@ -80,5 +99,4 @@ mod tests {
assert_eq!(false, Color::rgb(1, 2, 3) == Color::rgba(11, 2, 3, 200));
assert_eq!(true, Color::rgba(1, 2, 3, 200) == Color::rgba(1, 2, 3, 200));
}
}
......@@ -17,6 +17,9 @@ pub use renderer::Renderer;
#[cfg(not(feature = "no_std"))]
pub use sys::{get_display_size, EventIter, Window};
#[cfg(target_arch = "wasm32")]
pub use sys::{animation_loop, log};
#[cfg(not(feature = "no_std"))]
mod blur;
pub mod color;
......@@ -41,10 +44,22 @@ pub enum Mode {
Overwrite, //Replace
}
#[cfg(all(not(feature = "no_std"), target_os = "redox"))]
#[cfg(all(
not(feature = "no_std"),
not(target_arch = "wasm32"),
target_os = "redox"
))]
#[path = "sys/orbital.rs"]
mod sys;
#[cfg(all(not(feature = "no_std"), not(target_os = "redox")))]
#[cfg(all(
not(feature = "no_std"),
not(target_arch = "wasm32"),
not(target_os = "redox")
))]
#[path = "sys/sdl2.rs"]
mod sys;
#[cfg(target_arch = "wasm32")]
#[path = "sys/web.rs"]
mod sys;
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment