@octane-xplat/canvas 0.0.0 → 0.7.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/LICENSE +21 -0
- package/dist/native/Canvas.tsrx.js +35 -0
- package/dist/native/gpu.js +10 -0
- package/dist/native/index.js +3 -0
- package/dist/native/octane-client-build.json +8 -0
- package/dist/web/Canvas.web.tsrx.js +50 -0
- package/dist/web/gpu.web.js +10 -0
- package/dist/web/index.js +3 -0
- package/dist/web/octane-client-build.json +8 -0
- package/package.json +68 -5
- package/src/Canvas.tsrx +39 -0
- package/src/Canvas.web.tsrx +23 -0
- package/src/gpu.ts +8 -0
- package/src/gpu.web.ts +7 -0
- package/src/index.ts +5 -0
- package/src/index.web.ts +5 -0
- package/src/props.ts +33 -0
- package/types/index.d.ts +13 -0
- package/types/props.d.ts +26 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alec Larson
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { defineUniversalComponent, registerElement, universalPlan, universalValue } from "@nativescript-community/octane";
|
|
2
|
+
import { Canvas } from "@nativescript/canvas";
|
|
3
|
+
//#region src/Canvas.tsrx
|
|
4
|
+
var __octaneUniversalPlan0 = universalPlan("nativescript", {
|
|
5
|
+
"kind": "host",
|
|
6
|
+
"type": "nscanvas",
|
|
7
|
+
"bindings": [
|
|
8
|
+
["id", 0],
|
|
9
|
+
["className", 1],
|
|
10
|
+
["style", 2],
|
|
11
|
+
["width", 3],
|
|
12
|
+
["height", 4],
|
|
13
|
+
["onReady", 5]
|
|
14
|
+
]
|
|
15
|
+
});
|
|
16
|
+
registerElement("nscanvas", Canvas);
|
|
17
|
+
var Canvas$1 = defineUniversalComponent("nativescript", function Canvas(props) {
|
|
18
|
+
const ready = (event) => {
|
|
19
|
+
const canvas = event.object;
|
|
20
|
+
props.onReady?.({
|
|
21
|
+
canvas,
|
|
22
|
+
context: props.context ? canvas.getContext(props.context) : null
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
return universalValue(__octaneUniversalPlan0, [
|
|
26
|
+
props.id,
|
|
27
|
+
props.className,
|
|
28
|
+
props.style,
|
|
29
|
+
props.width,
|
|
30
|
+
props.height,
|
|
31
|
+
ready
|
|
32
|
+
]);
|
|
33
|
+
}, { "module": "@nativescript-community/octane" });
|
|
34
|
+
//#endregion
|
|
35
|
+
export { Canvas$1 as Canvas };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { GPU } from "@nativescript/canvas";
|
|
2
|
+
//#region src/gpu.ts
|
|
3
|
+
/** getGPU — returns the plugin's GPU shim (wgpu over Metal/Vulkan). Same
|
|
4
|
+
* spec-shaped surface as web's `navigator.gpu`: `requestAdapter()` +
|
|
5
|
+
* `getPreferredCanvasFormat()`. */
|
|
6
|
+
function getGPU() {
|
|
7
|
+
return new GPU();
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
export { getGPU };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { __s, bag7, clone, queueRefAttach, queueRefDetach, setStyle, template } from "octane";
|
|
2
|
+
import { bindSignalAttribute, enableSignalBindings, replaceRef, setPlainAttribute } from "octane/internal/client";
|
|
3
|
+
//#region src/Canvas.web.tsrx
|
|
4
|
+
enableSignalBindings(1, true);
|
|
5
|
+
var _t$0 = /* @__PURE__ */ template("<canvas></canvas>");
|
|
6
|
+
var _rm$0 = [
|
|
7
|
+
"r",
|
|
8
|
+
"g",
|
|
9
|
+
"b"
|
|
10
|
+
];
|
|
11
|
+
var Canvas = /* @__PURE__ */ __s(function Canvas(props, __s, __extra) {
|
|
12
|
+
let _b = __s.slots[0];
|
|
13
|
+
if (_b === void 0) {
|
|
14
|
+
let _m1, _m6;
|
|
15
|
+
const _root = clone(_t$0);
|
|
16
|
+
_m1 = _root;
|
|
17
|
+
queueRefAttach(__s, _m6 = (el) => {
|
|
18
|
+
if (!el) return;
|
|
19
|
+
props.onReady?.({
|
|
20
|
+
canvas: el,
|
|
21
|
+
context: props.context ? el.getContext(props.context) : null
|
|
22
|
+
});
|
|
23
|
+
}, _m1);
|
|
24
|
+
(__s.cleanups ??= []).push(() => _b && queueRefDetach(_b.g, _b.b));
|
|
25
|
+
_b = bag7(__s, _root, void 0, _m1, void 0, void 0, void 0, void 0, _m6);
|
|
26
|
+
__s.refFields = _rm$0;
|
|
27
|
+
} else {
|
|
28
|
+
const _r = (el) => {
|
|
29
|
+
if (!el) return;
|
|
30
|
+
props.onReady?.({
|
|
31
|
+
canvas: el,
|
|
32
|
+
context: props.context ? el.getContext(props.context) : null
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
if (_r !== _b.g) _b.g = replaceRef(__s, _b.g, _r, _b.b);
|
|
36
|
+
}
|
|
37
|
+
_b.a = bindSignalAttribute(__s, _b.a, _b.b, "id", props.id, "b:f0c24829", setPlainAttribute);
|
|
38
|
+
_b.c = bindSignalAttribute(__s, _b.c, _b.b, "class", props.className, "b:ea9117bd", "class");
|
|
39
|
+
{
|
|
40
|
+
const _v = props.style;
|
|
41
|
+
if (_b.d !== _v) {
|
|
42
|
+
setStyle(_b.b, _v, _b.d);
|
|
43
|
+
_b.d = _v;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
_b.e = bindSignalAttribute(__s, _b.e, _b.b, "width", typeof props.width === "number" ? props.width : void 0, "b:b4becda6", setPlainAttribute);
|
|
47
|
+
_b.f = bindSignalAttribute(__s, _b.f, _b.b, "height", typeof props.height === "number" ? props.height : void 0, "b:7ec30b3a", setPlainAttribute);
|
|
48
|
+
});
|
|
49
|
+
//#endregion
|
|
50
|
+
export { Canvas };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region src/gpu.web.ts
|
|
2
|
+
/** getGPU — returns the WebGPU entry point (`navigator.gpu`) or null when
|
|
3
|
+
* WebGPU is unavailable (insecure context, unsupported browser). The
|
|
4
|
+
* returned object is spec-shaped: `requestAdapter()` +
|
|
5
|
+
* `getPreferredCanvasFormat()`. */
|
|
6
|
+
function getGPU() {
|
|
7
|
+
return globalThis.navigator?.gpu ?? null;
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
export { getGPU };
|
package/package.json
CHANGED
|
@@ -1,6 +1,69 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
"name": "@octane-xplat/canvas",
|
|
3
|
+
"version": "0.7.1",
|
|
4
|
+
"description": "Canvas/GPU surface for Octane xplat — web <canvas> + @nativescript/canvas (2D, WebGL/WebGL2, WebGPU/WGSL)",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"octane",
|
|
7
|
+
"xplat",
|
|
8
|
+
"cross-platform",
|
|
9
|
+
"canvas",
|
|
10
|
+
"webgl",
|
|
11
|
+
"webgl2",
|
|
12
|
+
"webgpu",
|
|
13
|
+
"wgsl",
|
|
14
|
+
"gpu",
|
|
15
|
+
"graphics",
|
|
16
|
+
"nativescript"
|
|
17
|
+
],
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"homepage": "https://github.com/octane-xplat/octane-xplat/tree/main/packages/canvas",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/octane-xplat/octane-xplat.git",
|
|
23
|
+
"directory": "packages/canvas"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"types",
|
|
28
|
+
"src"
|
|
29
|
+
],
|
|
30
|
+
"type": "module",
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"types": "./types/index.d.ts",
|
|
34
|
+
"web": "./dist/web/index.js",
|
|
35
|
+
"native": "./dist/native/index.js",
|
|
36
|
+
"default": "./dist/native/index.js"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@nativescript/canvas": "3.0.0-alpha.15"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@nativescript-community/octane": "0.2.1",
|
|
47
|
+
"@nativescript/core": "9.1.2",
|
|
48
|
+
"@octanejs/vite-plugin": "0.1.61",
|
|
49
|
+
"octane": "0.6.3",
|
|
50
|
+
"typescript": "5.9.3",
|
|
51
|
+
"vite": "8.3.0"
|
|
52
|
+
},
|
|
53
|
+
"peerDependencies": {
|
|
54
|
+
"@nativescript-community/octane": ">=0.2.1 <1",
|
|
55
|
+
"@nativescript/core": ">=9.1.0 <10",
|
|
56
|
+
"octane": ">=0.6.3 <1"
|
|
57
|
+
},
|
|
58
|
+
"peerDependenciesMeta": {
|
|
59
|
+
"@nativescript-community/octane": {
|
|
60
|
+
"optional": true
|
|
61
|
+
},
|
|
62
|
+
"@nativescript/core": {
|
|
63
|
+
"optional": true
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"scripts": {
|
|
67
|
+
"build": "vite build && vite build --mode native && tsc -p tsconfig.types.json && node ../../scripts/check-native-dist.mjs"
|
|
68
|
+
}
|
|
69
|
+
}
|
package/src/Canvas.tsrx
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** @jsxImportSource @nativescript-community/octane */
|
|
2
|
+
import { registerElement } from '@nativescript-community/octane';
|
|
3
|
+
import type { Attributes } from '@nativescript-community/octane/intrinsics';
|
|
4
|
+
import { Canvas as NSCanvas } from '@nativescript/canvas';
|
|
5
|
+
import type { CanvasProps } from './props';
|
|
6
|
+
|
|
7
|
+
declare module '@nativescript-community/octane/intrinsics' {
|
|
8
|
+
interface NativeScriptElements {
|
|
9
|
+
nscanvas: Attributes<typeof NSCanvas>;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// @nativescript/canvas — Skia + wgpu core exposing the DOM Canvas API
|
|
14
|
+
// (2d, webgl, webgl2, webgpu) on iOS + Android. Element name is `nscanvas`
|
|
15
|
+
// rather than `canvas` because `canvas` is DOM vocabulary in the
|
|
16
|
+
// element-vocabulary lint.
|
|
17
|
+
registerElement('nscanvas', NSCanvas);
|
|
18
|
+
|
|
19
|
+
/** Canvas — DOM Canvas API surface on native. `onReady` wraps the plugin's
|
|
20
|
+
* `ready` event: it fires once the GPU surface exists, which is the
|
|
21
|
+
* earliest `getContext` may be called. */
|
|
22
|
+
export function Canvas(props: CanvasProps) @{
|
|
23
|
+
const ready = (event: any) => {
|
|
24
|
+
const canvas = event.object;
|
|
25
|
+
props.onReady?.({
|
|
26
|
+
canvas,
|
|
27
|
+
context: props.context ? canvas.getContext(props.context) : null,
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
<nscanvas
|
|
32
|
+
id={props.id}
|
|
33
|
+
className={props.className}
|
|
34
|
+
style={props.style}
|
|
35
|
+
width={props.width as any}
|
|
36
|
+
height={props.height as any}
|
|
37
|
+
onReady={ready}
|
|
38
|
+
/>;
|
|
39
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { CanvasProps } from './props';
|
|
2
|
+
|
|
3
|
+
/** Canvas — a plain <canvas>. `onReady` fires at mount with the element
|
|
4
|
+
* and the resolved context. */
|
|
5
|
+
export function Canvas(props: CanvasProps) @{
|
|
6
|
+
<canvas
|
|
7
|
+
id={props.id}
|
|
8
|
+
className={props.className}
|
|
9
|
+
style={props.style}
|
|
10
|
+
width={typeof props.width === 'number' ? props.width : undefined}
|
|
11
|
+
height={typeof props.height === 'number' ? props.height : undefined}
|
|
12
|
+
ref={(el: HTMLCanvasElement | null) => {
|
|
13
|
+
if (!el) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
props.onReady?.({
|
|
18
|
+
canvas: el,
|
|
19
|
+
context: props.context ? el.getContext(props.context) : null,
|
|
20
|
+
});
|
|
21
|
+
}}
|
|
22
|
+
/>
|
|
23
|
+
}
|
package/src/gpu.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { GPU } from '@nativescript/canvas';
|
|
2
|
+
|
|
3
|
+
/** getGPU — returns the plugin's GPU shim (wgpu over Metal/Vulkan). Same
|
|
4
|
+
* spec-shaped surface as web's `navigator.gpu`: `requestAdapter()` +
|
|
5
|
+
* `getPreferredCanvasFormat()`. */
|
|
6
|
+
export function getGPU(): any {
|
|
7
|
+
return new GPU();
|
|
8
|
+
}
|
package/src/gpu.web.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** getGPU — returns the WebGPU entry point (`navigator.gpu`) or null when
|
|
2
|
+
* WebGPU is unavailable (insecure context, unsupported browser). The
|
|
3
|
+
* returned object is spec-shaped: `requestAdapter()` +
|
|
4
|
+
* `getPreferredCanvasFormat()`. */
|
|
5
|
+
export function getGPU(): any {
|
|
6
|
+
return (globalThis.navigator as any)?.gpu ?? null;
|
|
7
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// Platform barrels — explicit .tsrx leaf imports (moduleSuffixes don't
|
|
2
|
+
// reach .tsrx; same convention as @octane-xplat/ui index.*.ts).
|
|
3
|
+
export { Canvas } from './Canvas.tsrx';
|
|
4
|
+
export { getGPU } from './gpu';
|
|
5
|
+
export type { CanvasProps, CanvasContextKind, CanvasReady } from './props';
|
package/src/index.web.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// Platform barrels — explicit .tsrx leaf imports (moduleSuffixes don't
|
|
2
|
+
// reach .tsrx; same convention as @octane-xplat/ui index.*.ts).
|
|
3
|
+
export { Canvas } from './Canvas.web.tsrx';
|
|
4
|
+
export { getGPU } from './gpu.web';
|
|
5
|
+
export type { CanvasProps, CanvasContextKind, CanvasReady } from './props';
|
package/src/props.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export type CanvasContextKind =
|
|
2
|
+
| '2d'
|
|
3
|
+
| 'webgl'
|
|
4
|
+
| 'webgl2'
|
|
5
|
+
| 'webgpu'
|
|
6
|
+
| 'bitmaprenderer';
|
|
7
|
+
|
|
8
|
+
export interface CanvasReady {
|
|
9
|
+
/** HTMLCanvasElement on web, the plugin's Canvas view on native —
|
|
10
|
+
* both expose `getContext()`. */
|
|
11
|
+
canvas: any;
|
|
12
|
+
/** The resolved context for the `context` prop, or null when that
|
|
13
|
+
* kind is unsupported/unavailable. WebGPU still needs a device —
|
|
14
|
+
* `getGPU()` normalizes adapter/device acquisition. */
|
|
15
|
+
context: any;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface CanvasProps {
|
|
19
|
+
className?: any;
|
|
20
|
+
style?: any;
|
|
21
|
+
id?: string;
|
|
22
|
+
/** Context kind resolved before `onReady` fires. Omit to defer
|
|
23
|
+
* `getContext` to user code (only one kind per canvas — call once). */
|
|
24
|
+
context?: CanvasContextKind;
|
|
25
|
+
/** Web: after mount. Native: the plugin's `ready` event (fires when the
|
|
26
|
+
* GPU surface exists — earlier `getContext` calls can return null). */
|
|
27
|
+
onReady?: (ready: CanvasReady) => void;
|
|
28
|
+
/** Numeric values map to the element's width/height — on web that is
|
|
29
|
+
* the canvas *drawing buffer* size (pair with style for display
|
|
30
|
+
* size), on native dip size. */
|
|
31
|
+
width?: string | number;
|
|
32
|
+
height?: string | number;
|
|
33
|
+
}
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Boundary types for @octane-xplat/canvas — the mechanical wrapper over
|
|
2
|
+
// props.ts (tsrx-tsc can't emit .tsrx declarations; see ui/types/index.d.ts
|
|
3
|
+
// for the same pattern).
|
|
4
|
+
import type { UniversalComponent } from 'octane/universal'
|
|
5
|
+
import type { CanvasProps } from './props'
|
|
6
|
+
|
|
7
|
+
export declare const Canvas: UniversalComponent<CanvasProps>
|
|
8
|
+
|
|
9
|
+
/** Returns the WebGPU entry point — `navigator.gpu` on web, the plugin's
|
|
10
|
+
* GPU shim on native — or null where WebGPU is unavailable. */
|
|
11
|
+
export declare function getGPU(): any
|
|
12
|
+
|
|
13
|
+
export type { CanvasProps, CanvasContextKind, CanvasReady } from './props'
|
package/types/props.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type CanvasContextKind = '2d' | 'webgl' | 'webgl2' | 'webgpu' | 'bitmaprenderer';
|
|
2
|
+
export interface CanvasReady {
|
|
3
|
+
/** HTMLCanvasElement on web, the plugin's Canvas view on native —
|
|
4
|
+
* both expose `getContext()`. */
|
|
5
|
+
canvas: any;
|
|
6
|
+
/** The resolved context for the `context` prop, or null when that
|
|
7
|
+
* kind is unsupported/unavailable. WebGPU still needs a device —
|
|
8
|
+
* `getGPU()` normalizes adapter/device acquisition. */
|
|
9
|
+
context: any;
|
|
10
|
+
}
|
|
11
|
+
export interface CanvasProps {
|
|
12
|
+
className?: any;
|
|
13
|
+
style?: any;
|
|
14
|
+
id?: string;
|
|
15
|
+
/** Context kind resolved before `onReady` fires. Omit to defer
|
|
16
|
+
* `getContext` to user code (only one kind per canvas — call once). */
|
|
17
|
+
context?: CanvasContextKind;
|
|
18
|
+
/** Web: after mount. Native: the plugin's `ready` event (fires when the
|
|
19
|
+
* GPU surface exists — earlier `getContext` calls can return null). */
|
|
20
|
+
onReady?: (ready: CanvasReady) => void;
|
|
21
|
+
/** Numeric values map to the element's width/height — on web that is
|
|
22
|
+
* the canvas *drawing buffer* size (pair with style for display
|
|
23
|
+
* size), on native dip size. */
|
|
24
|
+
width?: string | number;
|
|
25
|
+
height?: string | number;
|
|
26
|
+
}
|