proteus-sdk 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +69 -2
- package/dist/convert.d.ts +24 -0
- package/dist/convert.js +76 -0
- package/dist/index.d.ts +586 -0
- package/dist/index.js +750 -0
- package/dist/mount.d.ts +57 -0
- package/dist/mount.js +32 -0
- package/dist/types.d.ts +586 -0
- package/dist/types.js +9 -0
- package/package.json +53 -4
- package/pkg/README.md +11 -0
- package/pkg/package.json +34 -0
- package/pkg/proteus_sdk_web.d.ts +309 -0
- package/pkg/proteus_sdk_web.js +9 -0
- package/pkg/proteus_sdk_web_bg.js +1671 -0
- package/pkg/proteus_sdk_web_bg.wasm +0 -0
- package/pkg/proteus_sdk_web_bg.wasm.d.ts +76 -0
- package/pkg-host/README.md +11 -0
- package/pkg-host/package.json +34 -0
- package/pkg-host/proteus_host_web.d.ts +323 -0
- package/pkg-host/proteus_host_web.js +9 -0
- package/pkg-host/proteus_host_web_bg.js +3436 -0
- package/pkg-host/proteus_host_web_bg.wasm +0 -0
- package/pkg-host/proteus_host_web_bg.wasm.d.ts +84 -0
package/README.md
CHANGED
|
@@ -1,3 +1,70 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/ichellin1/proteus/main/brand/logo/assets/lockup-color-dark.png">
|
|
4
|
+
<img alt="Proteus" src="https://raw.githubusercontent.com/ichellin1/proteus/main/brand/logo/assets/lockup-color-light.png" width="210">
|
|
5
|
+
</picture>
|
|
6
|
+
</p>
|
|
2
7
|
|
|
3
|
-
|
|
8
|
+
# proteus-sdk
|
|
9
|
+
|
|
10
|
+
The TypeScript SDK for [Proteus](https://github.com/ichellin1/proteus), a UI framework whose components transform into one
|
|
11
|
+
another instead of loading new screens: a button can become the panel it opens. It draws on a
|
|
12
|
+
`<canvas>` with WebGPU, or WebGL2 where WebGPU isn't available. Its core is written in Rust and
|
|
13
|
+
compiled to WebAssembly.
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install proteus-sdk
|
|
17
|
+
npm install --save-dev vite-plugin-wasm vite-plugin-top-level-await@1.5.0 @swc/core@1.10.16
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
With Vite, add both plugins to `vite.config.ts`: `plugins: [wasm(), topLevelAwait()]`. Then, with
|
|
21
|
+
a `<canvas id="app">` on the page, a button that turns into a panel when it's clicked, and back
|
|
22
|
+
when the panel is clicked:
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
import { colorFrom, mount, type Geometry } from "proteus-sdk";
|
|
26
|
+
|
|
27
|
+
function centered(width: number, height: number, cornerRadius: number): Geometry {
|
|
28
|
+
return {
|
|
29
|
+
position: { x: 0, y: 0, z: 0 },
|
|
30
|
+
size: { width, height },
|
|
31
|
+
rotation: 0,
|
|
32
|
+
scale: 1,
|
|
33
|
+
anchor: { x: 0.5, y: 0.5 },
|
|
34
|
+
color: colorFrom("#7359cc"),
|
|
35
|
+
cornerRadius,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
await mount("app", {
|
|
40
|
+
setup(app) {
|
|
41
|
+
const button = app.component({
|
|
42
|
+
geometry: centered(200, 60, 30),
|
|
43
|
+
text: { content: "Open", sizePx: 24 },
|
|
44
|
+
});
|
|
45
|
+
const panel = app.component({
|
|
46
|
+
geometry: centered(480, 320, 16),
|
|
47
|
+
text: { content: "Close", sizePx: 24 },
|
|
48
|
+
visible: false,
|
|
49
|
+
});
|
|
50
|
+
const channel = app.transitionChannel();
|
|
51
|
+
button.onClick(() => channel.set(panel, button, { duration: 0.4 }));
|
|
52
|
+
panel.onClick(() => channel.set(button, panel, { duration: 0.4 }));
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Learn more
|
|
58
|
+
|
|
59
|
+
- [Getting started in TypeScript](https://github.com/ichellin1/proteus/blob/main/docs/getting-started/typescript.md),
|
|
60
|
+
step by step.
|
|
61
|
+
- [Guides](https://github.com/ichellin1/proteus/tree/main/docs): the concepts, and how-tos.
|
|
62
|
+
- [API reference](https://ichellin1.github.io/proteus/api/ts/).
|
|
63
|
+
- [Examples](https://github.com/ichellin1/proteus/tree/main/examples), and
|
|
64
|
+
[the reference demo](https://ichellin1.github.io/proteus/), running in your browser.
|
|
65
|
+
- Proteus is written in Rust, and its [Rust crates](https://crates.io/crates/proteus-sdk) can be
|
|
66
|
+
used directly.
|
|
67
|
+
|
|
68
|
+
## License
|
|
69
|
+
|
|
70
|
+
MIT or Apache-2.0, at your option.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Color, Vec2 } from "./types.js";
|
|
2
|
+
/** Converts degrees to radians, the unit {@link Geometry.rotation} uses. */
|
|
3
|
+
export declare function degreesToRadians(degrees: number): number;
|
|
4
|
+
/** Converts radians to degrees. */
|
|
5
|
+
export declare function radiansToDegrees(radians: number): number;
|
|
6
|
+
/**
|
|
7
|
+
* Converts a hex color or a color name to a {@link Color}.
|
|
8
|
+
*
|
|
9
|
+
* Accepts `#rgb`, `#rrggbb` and `#rrggbbaa`, with or without the `#`, and the
|
|
10
|
+
* names black, white, red, green, blue, yellow, orange, purple, gray (or grey)
|
|
11
|
+
* and transparent.
|
|
12
|
+
*
|
|
13
|
+
* @throws if `input` isn't one of those.
|
|
14
|
+
*/
|
|
15
|
+
export declare function colorFrom(input: string): Color;
|
|
16
|
+
/**
|
|
17
|
+
* Converts a position measured from the canvas's top-left corner, with y
|
|
18
|
+
* pointing down (the usual page and canvas convention), to world units, with
|
|
19
|
+
* the origin at the center and y pointing up. `viewportWidth` and
|
|
20
|
+
* `viewportHeight` are the canvas's size in the same units as `x` and `y`.
|
|
21
|
+
*/
|
|
22
|
+
export declare function topLeftToWorld(x: number, y: number, viewportWidth: number, viewportHeight: number): Vec2;
|
|
23
|
+
/** Converts world units back to a position from the top-left; the inverse of {@link topLeftToWorld}. */
|
|
24
|
+
export declare function worldToTopLeft(x: number, y: number, viewportWidth: number, viewportHeight: number): Vec2;
|
package/dist/convert.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// Conversions from familiar web conventions (degrees, hex and named colors,
|
|
2
|
+
// page coordinates) to the values the SDK takes (radians, RGBA from 0 to 1,
|
|
3
|
+
// world units with the origin at the viewport center and y up).
|
|
4
|
+
/** Converts degrees to radians, the unit {@link Geometry.rotation} uses. */
|
|
5
|
+
export function degreesToRadians(degrees) {
|
|
6
|
+
return (degrees * Math.PI) / 180;
|
|
7
|
+
}
|
|
8
|
+
/** Converts radians to degrees. */
|
|
9
|
+
export function radiansToDegrees(radians) {
|
|
10
|
+
return (radians * 180) / Math.PI;
|
|
11
|
+
}
|
|
12
|
+
// A small set of CSS color names for quick prototyping. Deliberately not the
|
|
13
|
+
// full CSS list.
|
|
14
|
+
const NAMED_COLORS = {
|
|
15
|
+
black: "#000000",
|
|
16
|
+
white: "#ffffff",
|
|
17
|
+
red: "#ff0000",
|
|
18
|
+
green: "#008000",
|
|
19
|
+
blue: "#0000ff",
|
|
20
|
+
yellow: "#ffff00",
|
|
21
|
+
orange: "#ffa500",
|
|
22
|
+
purple: "#800080",
|
|
23
|
+
gray: "#808080",
|
|
24
|
+
grey: "#808080",
|
|
25
|
+
transparent: "#00000000",
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Converts a hex color or a color name to a {@link Color}.
|
|
29
|
+
*
|
|
30
|
+
* Accepts `#rgb`, `#rrggbb` and `#rrggbbaa`, with or without the `#`, and the
|
|
31
|
+
* names black, white, red, green, blue, yellow, orange, purple, gray (or grey)
|
|
32
|
+
* and transparent.
|
|
33
|
+
*
|
|
34
|
+
* @throws if `input` isn't one of those.
|
|
35
|
+
*/
|
|
36
|
+
export function colorFrom(input) {
|
|
37
|
+
const named = NAMED_COLORS[input.toLowerCase()];
|
|
38
|
+
const hex = (named ?? input).replace(/^#/, "");
|
|
39
|
+
let r;
|
|
40
|
+
let g;
|
|
41
|
+
let b;
|
|
42
|
+
let a = 1;
|
|
43
|
+
if (hex.length === 3) {
|
|
44
|
+
r = parseInt(hex[0] + hex[0], 16);
|
|
45
|
+
g = parseInt(hex[1] + hex[1], 16);
|
|
46
|
+
b = parseInt(hex[2] + hex[2], 16);
|
|
47
|
+
}
|
|
48
|
+
else if (hex.length === 6 || hex.length === 8) {
|
|
49
|
+
r = parseInt(hex.slice(0, 2), 16);
|
|
50
|
+
g = parseInt(hex.slice(2, 4), 16);
|
|
51
|
+
b = parseInt(hex.slice(4, 6), 16);
|
|
52
|
+
if (hex.length === 8) {
|
|
53
|
+
a = parseInt(hex.slice(6, 8), 16) / 255;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
throw new Error(`colorFrom: unrecognized color "${input}"`);
|
|
58
|
+
}
|
|
59
|
+
if ([r, g, b].some((c) => Number.isNaN(c))) {
|
|
60
|
+
throw new Error(`colorFrom: unrecognized color "${input}"`);
|
|
61
|
+
}
|
|
62
|
+
return { r: r / 255, g: g / 255, b: b / 255, a };
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Converts a position measured from the canvas's top-left corner, with y
|
|
66
|
+
* pointing down (the usual page and canvas convention), to world units, with
|
|
67
|
+
* the origin at the center and y pointing up. `viewportWidth` and
|
|
68
|
+
* `viewportHeight` are the canvas's size in the same units as `x` and `y`.
|
|
69
|
+
*/
|
|
70
|
+
export function topLeftToWorld(x, y, viewportWidth, viewportHeight) {
|
|
71
|
+
return { x: x - viewportWidth / 2, y: viewportHeight / 2 - y };
|
|
72
|
+
}
|
|
73
|
+
/** Converts world units back to a position from the top-left; the inverse of {@link topLeftToWorld}. */
|
|
74
|
+
export function worldToTopLeft(x, y, viewportWidth, viewportHeight) {
|
|
75
|
+
return { x: x + viewportWidth / 2, y: viewportHeight / 2 - y };
|
|
76
|
+
}
|