@simpludify/web 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/LICENSE +21 -0
- package/README.md +21 -2
- package/dist/canvas-layout.d.ts +1 -0
- package/dist/canvas-native.d.ts +47 -0
- package/dist/canvas-node.d.ts +6 -0
- package/dist/canvas-text.d.ts +1 -0
- package/dist/canvas-ui.d.ts +1 -0
- package/dist/canvas-visual.d.ts +44 -0
- package/dist/game.d.ts +136 -0
- package/dist/geometry-tilemap-visual.d.ts +30 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +2843 -0
- package/dist/index.js.map +1 -0
- package/dist/input.d.ts +8 -0
- package/dist/pixi-ui-cleanup.d.ts +8 -0
- package/dist/pointer-routing.d.ts +1 -0
- package/dist/pointer.d.ts +24 -0
- package/dist/renderer.d.ts +61 -0
- package/dist/shared-images.d.ts +25 -0
- package/dist/style.css +193 -0
- package/dist/style.css.d.ts +1 -0
- package/dist/tilemap-visual.d.ts +39 -0
- package/dist/ui-keyboard.d.ts +6 -0
- package/dist/ui.d.ts +66 -0
- package/package.json +55 -4
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type SpriteFrame } from "@simpludify/core";
|
|
2
|
+
import { Texture } from "pixi.js";
|
|
3
|
+
/** Internal ownership boundary: the loader owns a Texture and its TextureSource. */
|
|
4
|
+
export interface ImageResource {
|
|
5
|
+
readonly texture: Texture;
|
|
6
|
+
release(): void;
|
|
7
|
+
}
|
|
8
|
+
export interface ImageLease extends ImageResource {
|
|
9
|
+
textureFor(frame?: SpriteFrame): Texture;
|
|
10
|
+
}
|
|
11
|
+
/** Renderer-local, live-reference cache. No idle retention or process-global state. */
|
|
12
|
+
export declare class SharedImages {
|
|
13
|
+
private readonly load;
|
|
14
|
+
private readonly entries;
|
|
15
|
+
private references;
|
|
16
|
+
private dead;
|
|
17
|
+
constructor(load: (url: string, signal: AbortSignal) => Promise<ImageResource>);
|
|
18
|
+
get diagnostics(): {
|
|
19
|
+
imageReferences: number;
|
|
20
|
+
imageEntries: number;
|
|
21
|
+
pendingImages: number;
|
|
22
|
+
};
|
|
23
|
+
acquire(key: string, signal: AbortSignal): Promise<ImageLease>;
|
|
24
|
+
dispose(): void;
|
|
25
|
+
}
|
package/dist/style.css
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
.simpludify {
|
|
2
|
+
position: relative;
|
|
3
|
+
isolation: isolate;
|
|
4
|
+
width: 100%;
|
|
5
|
+
height: 100%;
|
|
6
|
+
min-height: 20rem;
|
|
7
|
+
overflow: hidden;
|
|
8
|
+
background: var(--s-background);
|
|
9
|
+
color: var(--s-text);
|
|
10
|
+
font-family: var(--s-font);
|
|
11
|
+
outline-offset: -4px;
|
|
12
|
+
}
|
|
13
|
+
.simpludify,
|
|
14
|
+
.simpludify * {
|
|
15
|
+
box-sizing: border-box;
|
|
16
|
+
}
|
|
17
|
+
.simpludify > canvas {
|
|
18
|
+
position: absolute;
|
|
19
|
+
inset: 0;
|
|
20
|
+
display: block;
|
|
21
|
+
}
|
|
22
|
+
.s-ui {
|
|
23
|
+
position: absolute;
|
|
24
|
+
inset: 0;
|
|
25
|
+
z-index: 1;
|
|
26
|
+
display: flex;
|
|
27
|
+
flex-flow: column;
|
|
28
|
+
align-items: flex-start;
|
|
29
|
+
gap: 0.75rem;
|
|
30
|
+
padding: max(1rem, env(safe-area-inset-top))
|
|
31
|
+
max(1rem, env(safe-area-inset-right)) max(1rem, env(safe-area-inset-bottom))
|
|
32
|
+
max(1rem, env(safe-area-inset-left));
|
|
33
|
+
overflow: auto;
|
|
34
|
+
pointer-events: none;
|
|
35
|
+
}
|
|
36
|
+
.s-ui > * {
|
|
37
|
+
pointer-events: auto;
|
|
38
|
+
}
|
|
39
|
+
.s-panel {
|
|
40
|
+
display: flex;
|
|
41
|
+
gap: 0.75rem;
|
|
42
|
+
padding: 1rem;
|
|
43
|
+
max-width: min(100%, 30rem);
|
|
44
|
+
min-width: 0;
|
|
45
|
+
background: var(--s-surface);
|
|
46
|
+
border: 1px solid color-mix(in srgb, var(--s-muted), transparent 65%);
|
|
47
|
+
border-radius: 1rem;
|
|
48
|
+
box-shadow: 0 0.5rem 2rem #0002;
|
|
49
|
+
}
|
|
50
|
+
.s-column {
|
|
51
|
+
flex-direction: column;
|
|
52
|
+
}
|
|
53
|
+
.s-row {
|
|
54
|
+
flex-direction: row;
|
|
55
|
+
flex-wrap: wrap;
|
|
56
|
+
align-items: center;
|
|
57
|
+
}
|
|
58
|
+
.s-grid {
|
|
59
|
+
display: grid;
|
|
60
|
+
grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr));
|
|
61
|
+
width: 100%;
|
|
62
|
+
}
|
|
63
|
+
.s-ui p,
|
|
64
|
+
.s-ui h2 {
|
|
65
|
+
margin: 0;
|
|
66
|
+
overflow-wrap: anywhere;
|
|
67
|
+
line-height: 1.5;
|
|
68
|
+
}
|
|
69
|
+
.s-ui h2 {
|
|
70
|
+
font-size: 1.15rem;
|
|
71
|
+
letter-spacing: -0.02em;
|
|
72
|
+
}
|
|
73
|
+
.s-muted {
|
|
74
|
+
color: var(--s-muted);
|
|
75
|
+
font-size: 0.9rem;
|
|
76
|
+
}
|
|
77
|
+
.s-ui button {
|
|
78
|
+
font: inherit;
|
|
79
|
+
font-weight: 650;
|
|
80
|
+
color: var(--s-background);
|
|
81
|
+
background: var(--s-accent);
|
|
82
|
+
border: 0;
|
|
83
|
+
border-radius: 0.6rem;
|
|
84
|
+
padding: 0.7rem 1rem;
|
|
85
|
+
min-height: 2.75rem;
|
|
86
|
+
cursor: pointer;
|
|
87
|
+
overflow-wrap: anywhere;
|
|
88
|
+
}
|
|
89
|
+
.s-ui button:hover {
|
|
90
|
+
filter: brightness(1.08);
|
|
91
|
+
}
|
|
92
|
+
.s-ui button:disabled,
|
|
93
|
+
.s-ui button[aria-disabled="true"] {
|
|
94
|
+
opacity: 0.65;
|
|
95
|
+
cursor: progress;
|
|
96
|
+
}
|
|
97
|
+
.s-ui button:focus-visible,
|
|
98
|
+
.simpludify:focus-visible {
|
|
99
|
+
outline: 3px solid var(--s-accent);
|
|
100
|
+
outline-offset: 3px;
|
|
101
|
+
}
|
|
102
|
+
.s-error {
|
|
103
|
+
position: absolute;
|
|
104
|
+
bottom: 1rem;
|
|
105
|
+
inset-inline: 1rem;
|
|
106
|
+
z-index: 2;
|
|
107
|
+
padding: 1rem;
|
|
108
|
+
background: #6b1728;
|
|
109
|
+
color: #fff;
|
|
110
|
+
border-radius: 0.75rem;
|
|
111
|
+
}
|
|
112
|
+
@media (max-width: 32rem) {
|
|
113
|
+
.s-ui {
|
|
114
|
+
padding: 0.75rem;
|
|
115
|
+
}
|
|
116
|
+
.s-panel {
|
|
117
|
+
padding: 0.85rem;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.s-ui > .s-bottom {
|
|
122
|
+
margin-top: auto;
|
|
123
|
+
}
|
|
124
|
+
.s-ui > .s-center {
|
|
125
|
+
margin: auto;
|
|
126
|
+
}
|
|
127
|
+
.simpludify .s-hold {
|
|
128
|
+
min-width: 3rem;
|
|
129
|
+
min-height: 3rem;
|
|
130
|
+
touch-action: none;
|
|
131
|
+
user-select: none;
|
|
132
|
+
}
|
|
133
|
+
.simpludify .s-hold[aria-pressed="true"] {
|
|
134
|
+
filter: brightness(0.8);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/* Semantic keyboard/AT mirrors; all visible rendering and pointer hits use Pixi. */
|
|
138
|
+
.s-canvas-accessibility {
|
|
139
|
+
position: absolute;
|
|
140
|
+
inset: 0;
|
|
141
|
+
pointer-events: none;
|
|
142
|
+
overflow: hidden;
|
|
143
|
+
}
|
|
144
|
+
.s-canvas-accessibility button {
|
|
145
|
+
position: absolute;
|
|
146
|
+
pointer-events: none;
|
|
147
|
+
opacity: 0;
|
|
148
|
+
padding: 0;
|
|
149
|
+
border: 0;
|
|
150
|
+
margin: 0;
|
|
151
|
+
}
|
|
152
|
+
.simpludify > canvas {
|
|
153
|
+
touch-action: none;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/* Engine-owned native editing surfaces; Canvas still owns geometry/background/focus paint. */
|
|
157
|
+
.s-canvas-accessibility .s-canvas-native {
|
|
158
|
+
position: absolute;
|
|
159
|
+
pointer-events: auto;
|
|
160
|
+
box-sizing: border-box;
|
|
161
|
+
margin: 0;
|
|
162
|
+
border: 0;
|
|
163
|
+
outline: 0;
|
|
164
|
+
background: transparent;
|
|
165
|
+
border-radius: 0;
|
|
166
|
+
min-width: 0;
|
|
167
|
+
user-select: text;
|
|
168
|
+
color-scheme: dark;
|
|
169
|
+
color: var(--s-native-color);
|
|
170
|
+
}
|
|
171
|
+
.s-canvas-native option {
|
|
172
|
+
background: var(--s-native-background);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.s-canvas-accessibility input.s-canvas-native:not(:focus) {
|
|
176
|
+
color: transparent;
|
|
177
|
+
caret-color: transparent;
|
|
178
|
+
}
|
|
179
|
+
.s-canvas-accessibility input.s-canvas-native:not(:focus)::placeholder {
|
|
180
|
+
color: transparent;
|
|
181
|
+
}
|
|
182
|
+
.s-canvas-accessibility input.s-canvas-native:focus::placeholder {
|
|
183
|
+
color: currentColor;
|
|
184
|
+
opacity: 0.65;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.s-canvas-native:disabled {
|
|
188
|
+
opacity: 0.45;
|
|
189
|
+
}
|
|
190
|
+
.s-canvas-native[aria-readonly="true"] {
|
|
191
|
+
opacity: 0.7;
|
|
192
|
+
}
|
|
193
|
+
/*$vite$:1*/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type Scene, type Tilemap, type ViewTransform } from "@simpludify/core";
|
|
2
|
+
import { Container, Sprite } from "pixi.js";
|
|
3
|
+
import type { ImageLease } from "./shared-images.js";
|
|
4
|
+
/** Renderer-owned sparse visible set; sheet pixels are owned by SharedImages. */
|
|
5
|
+
export declare class TilemapVisual {
|
|
6
|
+
readonly map: Tilemap<string>;
|
|
7
|
+
private readonly changed;
|
|
8
|
+
private readonly onError;
|
|
9
|
+
private readonly released;
|
|
10
|
+
readonly display: Container<import("pixi.js").ContainerChild>;
|
|
11
|
+
readonly sprites: Map<number, Sprite>;
|
|
12
|
+
order: number;
|
|
13
|
+
depth: number;
|
|
14
|
+
controller: AbortController | undefined;
|
|
15
|
+
error: unknown;
|
|
16
|
+
disposed: boolean;
|
|
17
|
+
readonly stats: {
|
|
18
|
+
visitedCells: number;
|
|
19
|
+
updatedTiles: number;
|
|
20
|
+
createdSprites: number;
|
|
21
|
+
destroyedSprites: number;
|
|
22
|
+
validatedFrames: number;
|
|
23
|
+
};
|
|
24
|
+
private lease;
|
|
25
|
+
private readonly textures;
|
|
26
|
+
private readonly dirty;
|
|
27
|
+
private revision;
|
|
28
|
+
private range;
|
|
29
|
+
private invalid;
|
|
30
|
+
private readonly off;
|
|
31
|
+
private readonly offDispose;
|
|
32
|
+
constructor(map: Tilemap<string>, scene: Scene, acquire: (url: string, signal: AbortSignal) => Promise<ImageLease>, changed: () => void, onError: (error: unknown) => void, released: () => void);
|
|
33
|
+
private fail;
|
|
34
|
+
sync(): void;
|
|
35
|
+
private remove;
|
|
36
|
+
private cell;
|
|
37
|
+
render(view: ViewTransform): void;
|
|
38
|
+
dispose(): void;
|
|
39
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function registerGameButton(button: HTMLButtonElement, signal: AbortSignal): void;
|
|
2
|
+
export declare function uiConsumesKey(event: KeyboardEvent): boolean;
|
|
3
|
+
/** Unmanaged native buttons retain the previous isolated keyboard behavior. */
|
|
4
|
+
export declare function blocksGameKeyboard(target: EventTarget | null): boolean;
|
|
5
|
+
/** Grant surface focus from outside/editing; do not evict a compatible UI button. */
|
|
6
|
+
export declare function focusGameSurface(host: HTMLElement): void;
|
package/dist/ui.d.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export declare const Layout: {
|
|
2
|
+
readonly Column: "column";
|
|
3
|
+
readonly Row: "row";
|
|
4
|
+
readonly Grid: "grid";
|
|
5
|
+
};
|
|
6
|
+
export type Layout = (typeof Layout)[keyof typeof Layout];
|
|
7
|
+
export declare const Theme: {
|
|
8
|
+
readonly Dark: "dark";
|
|
9
|
+
readonly Light: "light";
|
|
10
|
+
};
|
|
11
|
+
export type Theme = (typeof Theme)[keyof typeof Theme];
|
|
12
|
+
export interface ThemeTokens {
|
|
13
|
+
background: string;
|
|
14
|
+
surface: string;
|
|
15
|
+
text: string;
|
|
16
|
+
muted: string;
|
|
17
|
+
accent: string;
|
|
18
|
+
font: string;
|
|
19
|
+
}
|
|
20
|
+
export declare const Themes: Readonly<Record<Theme, ThemeTokens>>;
|
|
21
|
+
export declare const Placement: {
|
|
22
|
+
readonly Top: "top";
|
|
23
|
+
readonly Center: "center";
|
|
24
|
+
readonly Bottom: "bottom";
|
|
25
|
+
};
|
|
26
|
+
export type Placement = (typeof Placement)[keyof typeof Placement];
|
|
27
|
+
export interface TextBinding {
|
|
28
|
+
readonly text: string;
|
|
29
|
+
setText(text: string): void;
|
|
30
|
+
subscribe(listener: (text: string) => void): () => void;
|
|
31
|
+
}
|
|
32
|
+
export interface LabelNode extends TextBinding {
|
|
33
|
+
readonly kind: "label";
|
|
34
|
+
readonly muted: boolean;
|
|
35
|
+
}
|
|
36
|
+
export interface ButtonNode extends TextBinding {
|
|
37
|
+
readonly kind: "button";
|
|
38
|
+
readonly onClick: (signal: AbortSignal) => void | Promise<void>;
|
|
39
|
+
}
|
|
40
|
+
export interface HoldButtonNode extends TextBinding {
|
|
41
|
+
readonly kind: "hold-button";
|
|
42
|
+
readonly onHold: (held: boolean) => void;
|
|
43
|
+
}
|
|
44
|
+
export interface PanelNode {
|
|
45
|
+
readonly kind: "panel";
|
|
46
|
+
readonly layout: Layout;
|
|
47
|
+
readonly placement: Placement;
|
|
48
|
+
readonly children: readonly UINode[];
|
|
49
|
+
readonly title?: string;
|
|
50
|
+
}
|
|
51
|
+
export type UINode = LabelNode | ButtonNode | HoldButtonNode | PanelNode;
|
|
52
|
+
export declare function Label(text: string, options?: {
|
|
53
|
+
muted?: boolean;
|
|
54
|
+
}): LabelNode;
|
|
55
|
+
export declare function Button(text: string, onClick: (signal: AbortSignal) => void | Promise<void>): ButtonNode;
|
|
56
|
+
export declare function HoldButton(text: string, onHold: (held: boolean) => void): HoldButtonNode;
|
|
57
|
+
export declare function Panel(children: readonly UINode[], options?: {
|
|
58
|
+
layout?: Layout;
|
|
59
|
+
title?: string;
|
|
60
|
+
placement?: Placement;
|
|
61
|
+
}): PanelNode;
|
|
62
|
+
export interface MountedUI {
|
|
63
|
+
readonly element: HTMLDivElement;
|
|
64
|
+
dispose(): void;
|
|
65
|
+
}
|
|
66
|
+
export declare function mountUI(nodes: readonly UINode[], onError: (error: unknown) => void): MountedUI;
|
package/package.json
CHANGED
|
@@ -1,6 +1,57 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simpludify/web",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"import": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"./style.css": {
|
|
11
|
+
"types": "./dist/style.css.d.ts",
|
|
12
|
+
"default": "./dist/style.css"
|
|
13
|
+
},
|
|
14
|
+
"./package.json": "./package.json"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@simpludify/core": "0.1.1",
|
|
18
|
+
"pixi.js": "8.22.0"
|
|
19
|
+
},
|
|
20
|
+
"description": "Browser host, PixiJS rendering and input for the experimental Simpludify 2D engine.",
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"main": "./dist/index.js",
|
|
23
|
+
"files": [
|
|
24
|
+
"dist",
|
|
25
|
+
"LICENSE",
|
|
26
|
+
"README.md"
|
|
27
|
+
],
|
|
28
|
+
"sideEffects": [
|
|
29
|
+
"./dist/index.js",
|
|
30
|
+
"./src/index.ts",
|
|
31
|
+
"**/*.css"
|
|
32
|
+
],
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/oz-coden/Simpludify.git",
|
|
37
|
+
"directory": "packages/web"
|
|
38
|
+
},
|
|
39
|
+
"homepage": "https://github.oz-coden.com/Simpludify/",
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/oz-coden/Simpludify/issues"
|
|
42
|
+
},
|
|
43
|
+
"keywords": [
|
|
44
|
+
"2d",
|
|
45
|
+
"game-engine",
|
|
46
|
+
"pixijs",
|
|
47
|
+
"typescript",
|
|
48
|
+
"experimental"
|
|
49
|
+
],
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": ">=22.12.0"
|
|
52
|
+
},
|
|
53
|
+
"publishConfig": {
|
|
54
|
+
"access": "public",
|
|
55
|
+
"registry": "https://registry.npmjs.org/"
|
|
56
|
+
}
|
|
57
|
+
}
|