@thewhateverapp/tile-sdk 0.14.2 → 0.14.4
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.
|
@@ -8,6 +8,13 @@ export interface SceneFromJsonProps extends Omit<SceneRendererProps, 'spec'> {
|
|
|
8
8
|
json: unknown;
|
|
9
9
|
/** Show validation errors in UI instead of throwing */
|
|
10
10
|
showErrors?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Container sizing mode:
|
|
13
|
+
* - 'tile': Fills parent container (w-full h-full) - default
|
|
14
|
+
* - 'page': Fills viewport (w-full h-screen)
|
|
15
|
+
* - 'none': No container wrapper (you manage sizing)
|
|
16
|
+
*/
|
|
17
|
+
container?: 'tile' | 'page' | 'none';
|
|
11
18
|
}
|
|
12
19
|
/**
|
|
13
20
|
* SceneFromJson - Renders a scene from a JSON object with validation
|
|
@@ -23,5 +30,5 @@ export interface SceneFromJsonProps extends Omit<SceneRendererProps, 'spec'> {
|
|
|
23
30
|
* }
|
|
24
31
|
* ```
|
|
25
32
|
*/
|
|
26
|
-
export declare function SceneFromJson({ json, showErrors, onEvent, ...props }: SceneFromJsonProps): React.JSX.Element;
|
|
33
|
+
export declare function SceneFromJson({ json, showErrors, onEvent, container, ...props }: SceneFromJsonProps): React.JSX.Element;
|
|
27
34
|
//# sourceMappingURL=SceneFromJson.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SceneFromJson.d.ts","sourceRoot":"","sources":["../../src/scene/SceneFromJson.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAiB,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE5E;;GAEG;AACH,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC;IAC1E,4DAA4D;IAC5D,IAAI,EAAE,OAAO,CAAC;IACd,uDAAuD;IACvD,UAAU,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"SceneFromJson.d.ts","sourceRoot":"","sources":["../../src/scene/SceneFromJson.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAiB,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE5E;;GAEG;AACH,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC;IAC1E,4DAA4D;IAC5D,IAAI,EAAE,OAAO,CAAC;IACd,uDAAuD;IACvD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;CACtC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,EAC5B,IAAI,EACJ,UAAiB,EACjB,OAAO,EACP,SAAkB,EAClB,GAAG,KAAK,EACT,EAAE,kBAAkB,qBAiFpB"}
|
|
@@ -16,7 +16,14 @@ import { SceneRenderer } from './SceneRenderer.js';
|
|
|
16
16
|
* }
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
|
-
export function SceneFromJson({ json, showErrors = true, onEvent, ...props }) {
|
|
19
|
+
export function SceneFromJson({ json, showErrors = true, onEvent, container = 'tile', ...props }) {
|
|
20
|
+
// Container styles based on mode
|
|
21
|
+
const containerStyle = container === 'none'
|
|
22
|
+
? undefined
|
|
23
|
+
: {
|
|
24
|
+
width: '100%',
|
|
25
|
+
height: container === 'page' ? '100vh' : '100%',
|
|
26
|
+
};
|
|
20
27
|
// Validate the JSON
|
|
21
28
|
const validationResult = React.useMemo(() => {
|
|
22
29
|
try {
|
|
@@ -45,7 +52,7 @@ export function SceneFromJson({ json, showErrors = true, onEvent, ...props }) {
|
|
|
45
52
|
// Show errors if validation failed
|
|
46
53
|
if (!validationResult.valid) {
|
|
47
54
|
if (showErrors) {
|
|
48
|
-
|
|
55
|
+
const errorContent = (React.createElement("div", { style: {
|
|
49
56
|
width: '100%',
|
|
50
57
|
height: '100%',
|
|
51
58
|
backgroundColor: '#1a0a0a',
|
|
@@ -62,6 +69,7 @@ export function SceneFromJson({ json, showErrors = true, onEvent, ...props }) {
|
|
|
62
69
|
":"),
|
|
63
70
|
" ",
|
|
64
71
|
error.message)))));
|
|
72
|
+
return containerStyle ? React.createElement("div", { style: containerStyle }, errorContent) : errorContent;
|
|
65
73
|
}
|
|
66
74
|
// Throw if not showing errors
|
|
67
75
|
throw new Error(`Scene validation failed: ${validationResult.errors.map((e) => e.message).join(', ')}`);
|
|
@@ -70,5 +78,6 @@ export function SceneFromJson({ json, showErrors = true, onEvent, ...props }) {
|
|
|
70
78
|
if (validationResult.warnings.length > 0) {
|
|
71
79
|
console.warn('Scene validation warnings:', validationResult.warnings);
|
|
72
80
|
}
|
|
73
|
-
|
|
81
|
+
const sceneContent = (React.createElement(SceneRenderer, { spec: json, onEvent: onEvent, ...props }));
|
|
82
|
+
return containerStyle ? React.createElement("div", { style: containerStyle }, sceneContent) : sceneContent;
|
|
74
83
|
}
|
|
@@ -10,17 +10,20 @@ export interface SceneRendererProps {
|
|
|
10
10
|
onEvent?: (event: string, data?: unknown) => void;
|
|
11
11
|
/** Whether the scene is paused */
|
|
12
12
|
paused?: boolean;
|
|
13
|
-
/**
|
|
13
|
+
/** Fixed width (if not set, fills container responsively) */
|
|
14
14
|
width?: number;
|
|
15
|
-
/**
|
|
15
|
+
/** Fixed height (if not set, fills container responsively) */
|
|
16
16
|
height?: number;
|
|
17
17
|
/** Enable debug rendering */
|
|
18
18
|
debug?: boolean;
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
21
|
* SceneRenderer - Renders a SceneSpecV1 with physics, components, and timeline
|
|
22
|
+
*
|
|
23
|
+
* By default, fills its parent container responsively. Pass explicit width/height
|
|
24
|
+
* to override with fixed dimensions.
|
|
22
25
|
*/
|
|
23
|
-
export declare function SceneRenderer({ spec: inputSpec, onEvent, paused, width, height, debug, }: SceneRendererProps): React.JSX.Element;
|
|
26
|
+
export declare function SceneRenderer({ spec: inputSpec, onEvent, paused, width: fixedWidth, height: fixedHeight, debug, }: SceneRendererProps): React.JSX.Element;
|
|
24
27
|
import { useScene } from './SceneContext.js';
|
|
25
28
|
export { useScene };
|
|
26
29
|
//# sourceMappingURL=SceneRenderer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SceneRenderer.d.ts","sourceRoot":"","sources":["../../src/scene/SceneRenderer.tsx"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"SceneRenderer.d.ts","sourceRoot":"","sources":["../../src/scene/SceneRenderer.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA4D,MAAM,OAAO,CAAC;AACjF,OAAO,KAAK,EAAE,WAAW,EAAU,MAAM,2BAA2B,CAAC;AAmDrE;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,oCAAoC;IACpC,IAAI,EAAE,WAAW,CAAC;IAClB,qEAAqE;IACrE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD,kCAAkC;IAClC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6BAA6B;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAC5B,IAAI,EAAE,SAAS,EACf,OAAO,EACP,MAAc,EACd,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,WAAW,EACnB,KAAa,GACd,EAAE,kBAAkB,qBA0CpB;AAuOD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import React, { useEffect, useRef, useCallback, useMemo } from 'react';
|
|
2
|
+
import React, { useEffect, useRef, useCallback, useMemo, useState } from 'react';
|
|
3
3
|
import { compileScene } from '@thewhateverapp/scene-sdk';
|
|
4
4
|
import { PixiGame, useGameLoop, Container } from '../pixi/index.js';
|
|
5
5
|
import { SceneContext, createEntityState, createPlayerState, createCameraState, createInputState, createTimelineState, } from './SceneContext.js';
|
|
@@ -10,10 +10,42 @@ import { useComponentRunner } from './components/ComponentRunner.js';
|
|
|
10
10
|
import { useTimelineExecutor } from './timeline/TimelineExecutor.js';
|
|
11
11
|
import { useCameraController } from './camera/CameraController.js';
|
|
12
12
|
import { TILE_WIDTH, TILE_HEIGHT } from '../react/PixiGame.js';
|
|
13
|
+
/**
|
|
14
|
+
* Hook to track container size using ResizeObserver
|
|
15
|
+
*/
|
|
16
|
+
function useContainerSize(containerRef) {
|
|
17
|
+
const [size, setSize] = useState({ width: TILE_WIDTH, height: TILE_HEIGHT });
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
const container = containerRef.current;
|
|
20
|
+
if (!container)
|
|
21
|
+
return;
|
|
22
|
+
const updateSize = () => {
|
|
23
|
+
const rect = container.getBoundingClientRect();
|
|
24
|
+
if (rect.width > 0 && rect.height > 0) {
|
|
25
|
+
setSize({ width: rect.width, height: rect.height });
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
// Initial size
|
|
29
|
+
updateSize();
|
|
30
|
+
// Watch for resize
|
|
31
|
+
const observer = new ResizeObserver(updateSize);
|
|
32
|
+
observer.observe(container);
|
|
33
|
+
return () => observer.disconnect();
|
|
34
|
+
}, [containerRef]);
|
|
35
|
+
return size;
|
|
36
|
+
}
|
|
13
37
|
/**
|
|
14
38
|
* SceneRenderer - Renders a SceneSpecV1 with physics, components, and timeline
|
|
39
|
+
*
|
|
40
|
+
* By default, fills its parent container responsively. Pass explicit width/height
|
|
41
|
+
* to override with fixed dimensions.
|
|
15
42
|
*/
|
|
16
|
-
export function SceneRenderer({ spec: inputSpec, onEvent, paused = false, width
|
|
43
|
+
export function SceneRenderer({ spec: inputSpec, onEvent, paused = false, width: fixedWidth, height: fixedHeight, debug = false, }) {
|
|
44
|
+
const containerRef = useRef(null);
|
|
45
|
+
const autoSize = useContainerSize(containerRef);
|
|
46
|
+
// Use fixed dimensions if provided, otherwise auto-size to container
|
|
47
|
+
const width = fixedWidth ?? autoSize.width;
|
|
48
|
+
const height = fixedHeight ?? autoSize.height;
|
|
17
49
|
// Compile patterns once on mount
|
|
18
50
|
const compiledSpec = useMemo(() => compileScene(inputSpec), [inputSpec]);
|
|
19
51
|
// Get background color from spec
|
|
@@ -24,8 +56,9 @@ export function SceneRenderer({ spec: inputSpec, onEvent, paused = false, width
|
|
|
24
56
|
}
|
|
25
57
|
return 0x0a0a1a; // Default dark background
|
|
26
58
|
}, [compiledSpec]);
|
|
27
|
-
return (React.createElement(
|
|
28
|
-
React.createElement(
|
|
59
|
+
return (React.createElement("div", { ref: containerRef, style: { width: '100%', height: '100%' } },
|
|
60
|
+
React.createElement(PixiGame, { width: width, height: height, background: backgroundColor, paused: paused },
|
|
61
|
+
React.createElement(SceneContent, { spec: compiledSpec, onEvent: onEvent, paused: paused, width: width, height: height, debug: debug }))));
|
|
29
62
|
}
|
|
30
63
|
/**
|
|
31
64
|
* Inner component that runs inside PixiGame context
|