@rpgjs/client 5.0.0-alpha.9 → 5.0.0-beta.10
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/CHANGELOG.md +37 -0
- package/LICENSE +19 -0
- package/dist/Game/AnimationManager.d.ts +8 -0
- package/dist/Game/AnimationManager.js +35 -0
- package/dist/Game/AnimationManager.js.map +1 -0
- package/dist/Game/AnimationManager.spec.d.ts +1 -0
- package/dist/Game/Event.d.ts +1 -1
- package/dist/Game/Event.js +12 -0
- package/dist/Game/Event.js.map +1 -0
- package/dist/Game/Map.d.ts +31 -2
- package/dist/Game/Map.js +138 -0
- package/dist/Game/Map.js.map +1 -0
- package/dist/Game/Object.d.ts +189 -0
- package/dist/Game/Object.js +255 -0
- package/dist/Game/Object.js.map +1 -0
- package/dist/Game/Player.d.ts +1 -1
- package/dist/Game/Player.js +12 -0
- package/dist/Game/Player.js.map +1 -0
- package/dist/Gui/Gui.d.ts +192 -7
- package/dist/Gui/Gui.js +475 -0
- package/dist/Gui/Gui.js.map +1 -0
- package/dist/Gui/Gui.spec.d.ts +1 -0
- package/dist/Gui/NotificationManager.d.ts +23 -0
- package/dist/Gui/NotificationManager.js +49 -0
- package/dist/Gui/NotificationManager.js.map +1 -0
- package/dist/Resource.d.ts +97 -0
- package/dist/Resource.js +133 -0
- package/dist/Resource.js.map +1 -0
- package/dist/RpgClient.d.ts +295 -13
- package/dist/RpgClientEngine.d.ts +671 -15
- package/dist/RpgClientEngine.js +1442 -0
- package/dist/RpgClientEngine.js.map +1 -0
- package/dist/Sound.d.ts +199 -0
- package/dist/Sound.js +167 -0
- package/dist/Sound.js.map +1 -0
- package/dist/_virtual/_@oxc-project_runtime@0.130.0/helpers/decorate.js +9 -0
- package/dist/_virtual/_@oxc-project_runtime@0.130.0/helpers/decorateMetadata.js +6 -0
- package/dist/components/animations/animation.ce.js +23 -0
- package/dist/components/animations/animation.ce.js.map +1 -0
- package/dist/components/animations/hit.ce.js +64 -0
- package/dist/components/animations/hit.ce.js.map +1 -0
- package/dist/components/animations/index.d.ts +4 -0
- package/dist/components/animations/index.js +11 -0
- package/dist/components/animations/index.js.map +1 -0
- package/dist/components/character.ce.js +572 -0
- package/dist/components/character.ce.js.map +1 -0
- package/dist/components/dynamics/bar.ce.js +96 -0
- package/dist/components/dynamics/bar.ce.js.map +1 -0
- package/dist/components/dynamics/image.ce.js +23 -0
- package/dist/components/dynamics/image.ce.js.map +1 -0
- package/dist/components/dynamics/parse-value.d.ts +4 -0
- package/dist/components/dynamics/parse-value.js +63 -0
- package/dist/components/dynamics/parse-value.js.map +1 -0
- package/dist/components/dynamics/parse-value.spec.d.ts +1 -0
- package/dist/components/dynamics/shape-utils.d.ts +16 -0
- package/dist/components/dynamics/shape-utils.js +73 -0
- package/dist/components/dynamics/shape-utils.js.map +1 -0
- package/dist/components/dynamics/shape-utils.spec.d.ts +1 -0
- package/dist/components/dynamics/shape.ce.js +83 -0
- package/dist/components/dynamics/shape.ce.js.map +1 -0
- package/dist/components/dynamics/text.ce.js +50 -0
- package/dist/components/dynamics/text.ce.js.map +1 -0
- package/dist/components/gui/box.ce.js +26 -0
- package/dist/components/gui/box.ce.js.map +1 -0
- package/dist/components/gui/dialogbox/index.ce.js +198 -0
- package/dist/components/gui/dialogbox/index.ce.js.map +1 -0
- package/dist/components/gui/gameover.ce.js +169 -0
- package/dist/components/gui/gameover.ce.js.map +1 -0
- package/dist/components/gui/hud/hud.ce.js +83 -0
- package/dist/components/gui/hud/hud.ce.js.map +1 -0
- package/dist/components/gui/index.d.ts +15 -3
- package/dist/components/gui/index.js +14 -0
- package/dist/components/gui/menu/equip-menu.ce.js +427 -0
- package/dist/components/gui/menu/equip-menu.ce.js.map +1 -0
- package/dist/components/gui/menu/exit-menu.ce.js +55 -0
- package/dist/components/gui/menu/exit-menu.ce.js.map +1 -0
- package/dist/components/gui/menu/items-menu.ce.js +326 -0
- package/dist/components/gui/menu/items-menu.ce.js.map +1 -0
- package/dist/components/gui/menu/main-menu.ce.js +399 -0
- package/dist/components/gui/menu/main-menu.ce.js.map +1 -0
- package/dist/components/gui/menu/options-menu.ce.js +49 -0
- package/dist/components/gui/menu/options-menu.ce.js.map +1 -0
- package/dist/components/gui/menu/skills-menu.ce.js +102 -0
- package/dist/components/gui/menu/skills-menu.ce.js.map +1 -0
- package/dist/components/gui/mobile/index.d.ts +8 -0
- package/dist/components/gui/mobile/index.js +21 -0
- package/dist/components/gui/mobile/index.js.map +1 -0
- package/dist/components/gui/mobile/mobile.ce.js +79 -0
- package/dist/components/gui/mobile/mobile.ce.js.map +1 -0
- package/dist/components/gui/notification/notification.ce.js +62 -0
- package/dist/components/gui/notification/notification.ce.js.map +1 -0
- package/dist/components/gui/save-load.ce.js +211 -0
- package/dist/components/gui/save-load.ce.js.map +1 -0
- package/dist/components/gui/shop/shop.ce.js +614 -0
- package/dist/components/gui/shop/shop.ce.js.map +1 -0
- package/dist/components/gui/title-screen.ce.js +164 -0
- package/dist/components/gui/title-screen.ce.js.map +1 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +4 -0
- package/dist/components/player-components-utils.d.ts +67 -0
- package/dist/components/player-components-utils.js +162 -0
- package/dist/components/player-components-utils.js.map +1 -0
- package/dist/components/player-components-utils.spec.d.ts +1 -0
- package/dist/components/player-components.ce.js +188 -0
- package/dist/components/player-components.ce.js.map +1 -0
- package/dist/components/prebuilt/hp-bar.ce.js +113 -0
- package/dist/components/prebuilt/hp-bar.ce.js.map +1 -0
- package/dist/components/prebuilt/index.d.ts +19 -0
- package/dist/components/prebuilt/index.js +2 -0
- package/dist/components/prebuilt/light-halo.ce.js +70 -0
- package/dist/components/prebuilt/light-halo.ce.js.map +1 -0
- package/dist/components/scenes/canvas.ce.js +196 -0
- package/dist/components/scenes/canvas.ce.js.map +1 -0
- package/dist/components/scenes/draw-map.ce.js +79 -0
- package/dist/components/scenes/draw-map.ce.js.map +1 -0
- package/dist/components/scenes/event-layer.ce.js +29 -0
- package/dist/components/scenes/event-layer.ce.js.map +1 -0
- package/dist/core/inject.js +18 -0
- package/dist/core/inject.js.map +1 -0
- package/dist/core/setup.js +16 -0
- package/dist/core/setup.js.map +1 -0
- package/dist/decorators/spritesheet.d.ts +1 -0
- package/dist/decorators/spritesheet.js +11 -0
- package/dist/decorators/spritesheet.js.map +1 -0
- package/dist/index.d.ts +16 -1
- package/dist/index.js +45 -14
- package/dist/module.d.ts +43 -4
- package/dist/module.js +179 -0
- package/dist/module.js.map +1 -0
- package/dist/node_modules/.pnpm/@signe_di@3.0.1/node_modules/@signe/di/dist/index.js +167 -0
- package/dist/node_modules/.pnpm/@signe_di@3.0.1/node_modules/@signe/di/dist/index.js.map +1 -0
- package/dist/node_modules/.pnpm/@signe_reactive@3.0.1/node_modules/@signe/reactive/dist/index.js +239 -0
- package/dist/node_modules/.pnpm/@signe_reactive@3.0.1/node_modules/@signe/reactive/dist/index.js.map +1 -0
- package/dist/node_modules/.pnpm/@signe_room@3.0.1/node_modules/@signe/room/dist/chunk-EUXUH3YW.js +13 -0
- package/dist/node_modules/.pnpm/@signe_room@3.0.1/node_modules/@signe/room/dist/chunk-EUXUH3YW.js.map +1 -0
- package/dist/node_modules/.pnpm/@signe_room@3.0.1/node_modules/@signe/room/dist/index.js +696 -0
- package/dist/node_modules/.pnpm/@signe_room@3.0.1/node_modules/@signe/room/dist/index.js.map +1 -0
- package/dist/node_modules/.pnpm/@signe_sync@3.0.1/node_modules/@signe/sync/dist/client/index.js +44 -0
- package/dist/node_modules/.pnpm/@signe_sync@3.0.1/node_modules/@signe/sync/dist/client/index.js.map +1 -0
- package/dist/node_modules/.pnpm/@signe_sync@3.0.1/node_modules/@signe/sync/dist/index.js +241 -0
- package/dist/node_modules/.pnpm/@signe_sync@3.0.1/node_modules/@signe/sync/dist/index.js.map +1 -0
- package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/chunk-HAC622V3.js +115 -0
- package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/chunk-HAC622V3.js.map +1 -0
- package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/chunk-S74YV6PU.js +401 -0
- package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/chunk-S74YV6PU.js.map +1 -0
- package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/index.js +2 -0
- package/dist/node_modules/.pnpm/zod@3.24.2/node_modules/zod/lib/index.js +3756 -0
- package/dist/node_modules/.pnpm/zod@3.24.2/node_modules/zod/lib/index.js.map +1 -0
- package/dist/presets/animation.d.ts +31 -0
- package/dist/presets/animation.js +39 -0
- package/dist/presets/animation.js.map +1 -0
- package/dist/presets/faceset.d.ts +30 -0
- package/dist/presets/faceset.js +51 -0
- package/dist/presets/faceset.js.map +1 -0
- package/dist/presets/icon.d.ts +20 -0
- package/dist/presets/icon.js +15 -0
- package/dist/presets/icon.js.map +1 -0
- package/dist/presets/index.d.ts +123 -0
- package/dist/presets/index.js +17 -0
- package/dist/presets/index.js.map +1 -0
- package/dist/presets/lpc.d.ts +89 -0
- package/dist/presets/lpc.js +98 -0
- package/dist/presets/lpc.js.map +1 -0
- package/dist/presets/rmspritesheet.js +42 -0
- package/dist/presets/rmspritesheet.js.map +1 -0
- package/dist/services/AbstractSocket.d.ts +9 -5
- package/dist/services/AbstractSocket.js +11 -0
- package/dist/services/AbstractSocket.js.map +1 -0
- package/dist/services/keyboardControls.d.ts +15 -0
- package/dist/services/keyboardControls.js +23 -0
- package/dist/services/keyboardControls.js.map +1 -0
- package/dist/services/loadMap.d.ts +6 -0
- package/dist/services/loadMap.js +123 -0
- package/dist/services/loadMap.js.map +1 -0
- package/dist/services/mmorpg.d.ts +21 -9
- package/dist/services/mmorpg.js +136 -0
- package/dist/services/mmorpg.js.map +1 -0
- package/dist/services/save.d.ts +19 -0
- package/dist/services/save.js +77 -0
- package/dist/services/save.js.map +1 -0
- package/dist/services/save.spec.d.ts +1 -0
- package/dist/services/standalone.d.ts +67 -7
- package/dist/services/standalone.js +168 -0
- package/dist/services/standalone.js.map +1 -0
- package/dist/utils/getEntityProp.d.ts +39 -0
- package/dist/utils/getEntityProp.js +53 -0
- package/dist/utils/getEntityProp.js.map +1 -0
- package/dist/utils/getEntityProp.spec.d.ts +1 -0
- package/dist/utils/readPropValue.d.ts +2 -0
- package/dist/utils/readPropValue.js +13 -0
- package/dist/utils/readPropValue.js.map +1 -0
- package/package.json +14 -11
- package/src/Game/AnimationManager.spec.ts +30 -0
- package/src/Game/AnimationManager.ts +33 -0
- package/src/Game/Event.ts +1 -1
- package/src/Game/Map.ts +184 -3
- package/src/Game/Object.ts +409 -14
- package/src/Game/Player.ts +1 -1
- package/src/Gui/Gui.spec.ts +273 -0
- package/src/Gui/Gui.ts +566 -23
- package/src/Gui/NotificationManager.ts +69 -0
- package/src/Resource.ts +149 -0
- package/src/RpgClient.ts +309 -14
- package/src/RpgClientEngine.ts +1790 -63
- package/src/Sound.ts +253 -0
- package/src/components/{effects → animations}/animation.ce +3 -6
- package/src/components/{effects → animations}/index.ts +1 -1
- package/src/components/character.ce +801 -59
- package/src/components/dynamics/bar.ce +87 -0
- package/src/components/dynamics/image.ce +20 -0
- package/src/components/dynamics/parse-value.spec.ts +83 -0
- package/src/components/dynamics/parse-value.ts +154 -0
- package/src/components/dynamics/shape-utils.spec.ts +46 -0
- package/src/components/dynamics/shape-utils.ts +61 -0
- package/src/components/dynamics/shape.ce +89 -0
- package/src/components/dynamics/text.ce +68 -0
- package/src/components/gui/box.ce +17 -0
- package/src/components/gui/dialogbox/index.ce +213 -187
- package/src/components/gui/gameover.ce +158 -0
- package/src/components/gui/hud/hud.ce +61 -0
- package/src/components/gui/index.ts +30 -4
- package/src/components/gui/menu/equip-menu.ce +410 -0
- package/src/components/gui/menu/exit-menu.ce +41 -0
- package/src/components/gui/menu/items-menu.ce +317 -0
- package/src/components/gui/menu/main-menu.ce +294 -0
- package/src/components/gui/menu/options-menu.ce +35 -0
- package/src/components/gui/menu/skills-menu.ce +83 -0
- package/src/components/gui/mobile/index.ts +24 -0
- package/src/components/gui/mobile/mobile.ce +80 -0
- package/src/components/gui/notification/notification.ce +51 -0
- package/src/components/gui/save-load.ce +208 -0
- package/src/components/gui/shop/shop.ce +493 -0
- package/src/components/gui/title-screen.ce +163 -0
- package/src/components/index.ts +3 -0
- package/src/components/player-components-utils.spec.ts +109 -0
- package/src/components/player-components-utils.ts +205 -0
- package/src/components/player-components.ce +221 -0
- package/src/components/prebuilt/hp-bar.ce +255 -0
- package/src/components/prebuilt/index.ts +24 -0
- package/src/components/prebuilt/light-halo.ce +148 -0
- package/src/components/scenes/canvas.ce +185 -21
- package/src/components/scenes/draw-map.ce +55 -21
- package/src/components/scenes/event-layer.ce +8 -2
- package/src/components/scenes/transition.ce +60 -0
- package/src/core/setup.ts +2 -2
- package/src/decorators/spritesheet.ts +8 -0
- package/src/index.ts +17 -2
- package/src/module.ts +132 -10
- package/src/presets/animation.ts +46 -0
- package/src/presets/faceset.ts +60 -0
- package/src/presets/icon.ts +17 -0
- package/src/presets/index.ts +9 -1
- package/src/presets/lpc.ts +108 -0
- package/src/services/AbstractSocket.ts +10 -2
- package/src/services/keyboardControls.ts +20 -0
- package/src/services/loadMap.ts +3 -1
- package/src/services/mmorpg.ts +106 -12
- package/src/services/save.spec.ts +127 -0
- package/src/services/save.ts +103 -0
- package/src/services/standalone.ts +110 -18
- package/src/utils/getEntityProp.spec.ts +96 -0
- package/src/utils/getEntityProp.ts +88 -0
- package/src/utils/readPropValue.ts +16 -0
- package/vite.config.ts +4 -2
- package/dist/Game/EffectManager.d.ts +0 -5
- package/dist/components/effects/index.d.ts +0 -4
- package/dist/index.js.map +0 -1
- package/dist/index10.js +0 -8
- package/dist/index10.js.map +0 -1
- package/dist/index11.js +0 -10
- package/dist/index11.js.map +0 -1
- package/dist/index12.js +0 -8
- package/dist/index12.js.map +0 -1
- package/dist/index13.js +0 -17
- package/dist/index13.js.map +0 -1
- package/dist/index14.js +0 -107
- package/dist/index14.js.map +0 -1
- package/dist/index15.js +0 -50
- package/dist/index15.js.map +0 -1
- package/dist/index16.js +0 -191
- package/dist/index16.js.map +0 -1
- package/dist/index17.js +0 -9
- package/dist/index17.js.map +0 -1
- package/dist/index18.js +0 -387
- package/dist/index18.js.map +0 -1
- package/dist/index19.js +0 -31
- package/dist/index19.js.map +0 -1
- package/dist/index2.js +0 -181
- package/dist/index2.js.map +0 -1
- package/dist/index20.js +0 -24
- package/dist/index20.js.map +0 -1
- package/dist/index21.js +0 -2421
- package/dist/index21.js.map +0 -1
- package/dist/index22.js +0 -114
- package/dist/index22.js.map +0 -1
- package/dist/index23.js +0 -109
- package/dist/index23.js.map +0 -1
- package/dist/index24.js +0 -71
- package/dist/index24.js.map +0 -1
- package/dist/index25.js +0 -21
- package/dist/index25.js.map +0 -1
- package/dist/index26.js +0 -41
- package/dist/index26.js.map +0 -1
- package/dist/index27.js +0 -5
- package/dist/index27.js.map +0 -1
- package/dist/index28.js +0 -322
- package/dist/index28.js.map +0 -1
- package/dist/index29.js +0 -27
- package/dist/index29.js.map +0 -1
- package/dist/index3.js +0 -87
- package/dist/index3.js.map +0 -1
- package/dist/index30.js +0 -11
- package/dist/index30.js.map +0 -1
- package/dist/index31.js +0 -11
- package/dist/index31.js.map +0 -1
- package/dist/index32.js +0 -174
- package/dist/index32.js.map +0 -1
- package/dist/index33.js +0 -501
- package/dist/index33.js.map +0 -1
- package/dist/index34.js +0 -12
- package/dist/index34.js.map +0 -1
- package/dist/index35.js +0 -4403
- package/dist/index35.js.map +0 -1
- package/dist/index36.js +0 -316
- package/dist/index36.js.map +0 -1
- package/dist/index37.js +0 -61
- package/dist/index37.js.map +0 -1
- package/dist/index38.js +0 -20
- package/dist/index38.js.map +0 -1
- package/dist/index39.js +0 -20
- package/dist/index39.js.map +0 -1
- package/dist/index4.js +0 -67
- package/dist/index4.js.map +0 -1
- package/dist/index5.js +0 -16
- package/dist/index5.js.map +0 -1
- package/dist/index6.js +0 -17
- package/dist/index6.js.map +0 -1
- package/dist/index7.js +0 -39
- package/dist/index7.js.map +0 -1
- package/dist/index8.js +0 -108
- package/dist/index8.js.map +0 -1
- package/dist/index9.js +0 -76
- package/dist/index9.js.map +0 -1
- package/src/Game/EffectManager.ts +0 -20
- package/src/components/gui/dialogbox/itemMenu.ce +0 -23
- package/src/components/gui/dialogbox/selection.ce +0 -67
- /package/src/components/{effects → animations}/hit.ce +0 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
<Container width={width} height={containerHeight} minWidth={width} minHeight={containerHeight}>
|
|
2
|
+
<Graphics width={width} height={containerHeight} draw={drawBar} />
|
|
3
|
+
@if (hasLabel) {
|
|
4
|
+
<Text text={labelText} x={labelPosition.x} y={labelPosition.y} size={labelSize} color={labelColor} />
|
|
5
|
+
}
|
|
6
|
+
</Container>
|
|
7
|
+
|
|
8
|
+
<script>
|
|
9
|
+
import { computed } from "canvasengine";
|
|
10
|
+
import { resolveDynamicValue } from "./parse-value";
|
|
11
|
+
|
|
12
|
+
const { object, current, max, style, text } = defineProps();
|
|
13
|
+
|
|
14
|
+
const read = (prop, fallback) => prop ? prop() : fallback;
|
|
15
|
+
|
|
16
|
+
const toNumber = (value, fallback = 0) => {
|
|
17
|
+
const resolved = resolveDynamicValue(value, object);
|
|
18
|
+
const num = typeof resolved === 'number' ? resolved : parseFloat(resolved);
|
|
19
|
+
return Number.isFinite(num) ? num : fallback;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const toColor = (value, fallback) => {
|
|
23
|
+
const resolved = resolveDynamicValue(value, object);
|
|
24
|
+
if (typeof resolved === 'number') return resolved;
|
|
25
|
+
if (typeof resolved === 'string' && resolved.startsWith('#')) {
|
|
26
|
+
return parseInt(resolved.slice(1), 16);
|
|
27
|
+
}
|
|
28
|
+
return resolved ?? fallback;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const config = computed(() => read(style, {}) ?? {});
|
|
32
|
+
const width = computed(() => toNumber(config().width, 50));
|
|
33
|
+
const height = computed(() => toNumber(config().height, 8));
|
|
34
|
+
const borderRadius = computed(() => toNumber(config().borderRadius, 3));
|
|
35
|
+
const borderWidth = computed(() => toNumber(config().borderWidth, 1));
|
|
36
|
+
const backgroundColor = computed(() => toColor(config().bgColor, 0x16213e));
|
|
37
|
+
const fillColor = computed(() => toColor(config().fillColor, 0x4ade80));
|
|
38
|
+
const borderColor = computed(() => toColor(config().borderColor, 0x4a5568));
|
|
39
|
+
const opacity = computed(() => Math.max(0, Math.min(1, toNumber(config().opacity, 1))));
|
|
40
|
+
|
|
41
|
+
const currentValue = computed(() => toNumber(read(current, 0), 0));
|
|
42
|
+
const maxValue = computed(() => Math.max(0, toNumber(read(max, 0), 0)));
|
|
43
|
+
const percent = computed(() => {
|
|
44
|
+
const max = maxValue();
|
|
45
|
+
if (max <= 0) return 0;
|
|
46
|
+
return Math.max(0, Math.min(1, currentValue() / max));
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const fillWidth = computed(() => Math.max(0, width() * percent()));
|
|
50
|
+
const labelTemplate = computed(() => read(text, null));
|
|
51
|
+
const labelText = computed(() => {
|
|
52
|
+
const template = labelTemplate();
|
|
53
|
+
if (template == null || template === '') return '';
|
|
54
|
+
|
|
55
|
+
const value = String(template)
|
|
56
|
+
.replace(/\{\$current\}/g, String(currentValue()))
|
|
57
|
+
.replace(/\{\$max\}/g, String(maxValue()))
|
|
58
|
+
.replace(/\{\$percent\}/g, String(Math.round(percent() * 100)));
|
|
59
|
+
|
|
60
|
+
return String(resolveDynamicValue(value, object) ?? '');
|
|
61
|
+
});
|
|
62
|
+
const labelSize = computed(() => toNumber(config().fontSize, 10));
|
|
63
|
+
const hasLabel = computed(() => labelText().length > 0);
|
|
64
|
+
const labelOffset = computed(() => hasLabel() ? labelSize() + 2 : 0);
|
|
65
|
+
const containerHeight = computed(() => labelOffset() + height());
|
|
66
|
+
const labelColor = computed(() => toColor(config().textColor, 0xffffff));
|
|
67
|
+
const labelPosition = computed(() => ({
|
|
68
|
+
x: 0,
|
|
69
|
+
y: 0
|
|
70
|
+
}));
|
|
71
|
+
|
|
72
|
+
const drawBar = (g) => {
|
|
73
|
+
g.roundRect(0, labelOffset(), width(), height(), borderRadius());
|
|
74
|
+
g.fill({ color: backgroundColor(), alpha: opacity() });
|
|
75
|
+
|
|
76
|
+
const currentWidth = fillWidth();
|
|
77
|
+
if (currentWidth > 0) {
|
|
78
|
+
g.roundRect(0, labelOffset(), currentWidth, height(), borderRadius());
|
|
79
|
+
g.fill({ color: fillColor(), alpha: opacity() });
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const strokeWidth = borderWidth();
|
|
83
|
+
if (strokeWidth <= 0) return;
|
|
84
|
+
g.roundRect(0, labelOffset(), width(), height(), borderRadius());
|
|
85
|
+
g.stroke({ color: borderColor(), width: strokeWidth, alpha: opacity() });
|
|
86
|
+
};
|
|
87
|
+
</script>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<Sprite sheet={sheet} />
|
|
2
|
+
|
|
3
|
+
<script>
|
|
4
|
+
import { computed } from "canvasengine";
|
|
5
|
+
import { RpgClientEngine } from "../../RpgClientEngine";
|
|
6
|
+
import { inject } from "../../core/inject";
|
|
7
|
+
import { resolveDynamicValue } from "./parse-value";
|
|
8
|
+
|
|
9
|
+
const { object, value } = defineProps();
|
|
10
|
+
const client = inject(RpgClientEngine);
|
|
11
|
+
|
|
12
|
+
const sheet = computed(() => {
|
|
13
|
+
const id = resolveDynamicValue(value?.(), object);
|
|
14
|
+
if (!id) return null;
|
|
15
|
+
return {
|
|
16
|
+
definition: client.getSpriteSheet(id),
|
|
17
|
+
playing: 'default'
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
</script>
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { describe, expect, test } from "vitest";
|
|
2
|
+
import { signal } from "canvasengine";
|
|
3
|
+
import { resolveDynamicProps, resolveDynamicValue } from "./parse-value";
|
|
4
|
+
|
|
5
|
+
describe("dynamic component values", () => {
|
|
6
|
+
test("resolves player properties and keeps bar placeholders for the bar renderer", () => {
|
|
7
|
+
const object = {
|
|
8
|
+
_name: signal("Alex"),
|
|
9
|
+
_speed: signal(4),
|
|
10
|
+
_canMove: signal(true),
|
|
11
|
+
hpSignal: signal(100),
|
|
12
|
+
_param: signal({ maxHp: 120 }),
|
|
13
|
+
get name() {
|
|
14
|
+
return this._name();
|
|
15
|
+
},
|
|
16
|
+
set name(value: string) {
|
|
17
|
+
this._name.set(value);
|
|
18
|
+
},
|
|
19
|
+
get speed() {
|
|
20
|
+
return this._speed();
|
|
21
|
+
},
|
|
22
|
+
set speed(value: number) {
|
|
23
|
+
this._speed.set(value);
|
|
24
|
+
},
|
|
25
|
+
get canMove() {
|
|
26
|
+
return this._canMove();
|
|
27
|
+
},
|
|
28
|
+
set canMove(value: boolean) {
|
|
29
|
+
this._canMove.set(value);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
expect(resolveDynamicValue("HP: {hp}/{param.maxHp} {name} {speed} {canMove} {$current}", object)).toBe("HP: 100/120 Alex 4 true {$current}");
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test("keeps resolved props reactive", () => {
|
|
37
|
+
const object = {
|
|
38
|
+
_name: signal("Alex"),
|
|
39
|
+
_speed: signal(4),
|
|
40
|
+
_canMove: signal(true),
|
|
41
|
+
hpSignal: signal(100),
|
|
42
|
+
_param: signal({ maxHp: 120 }),
|
|
43
|
+
get name() {
|
|
44
|
+
return this._name();
|
|
45
|
+
},
|
|
46
|
+
set name(value: string) {
|
|
47
|
+
this._name.set(value);
|
|
48
|
+
},
|
|
49
|
+
get speed() {
|
|
50
|
+
return this._speed();
|
|
51
|
+
},
|
|
52
|
+
set speed(value: number) {
|
|
53
|
+
this._speed.set(value);
|
|
54
|
+
},
|
|
55
|
+
get canMove() {
|
|
56
|
+
return this._canMove();
|
|
57
|
+
},
|
|
58
|
+
set canMove(value: boolean) {
|
|
59
|
+
this._canMove.set(value);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
const props: any = resolveDynamicProps({
|
|
63
|
+
value: "HP: {hp} {name} {speed} {canMove}",
|
|
64
|
+
text: "{$current}/{$max} {name}",
|
|
65
|
+
style: {
|
|
66
|
+
width: "{hp}"
|
|
67
|
+
}
|
|
68
|
+
}, object);
|
|
69
|
+
|
|
70
|
+
expect(props.value()).toBe("HP: 100 Alex 4 true");
|
|
71
|
+
expect(props.text()).toBe("{$current}/{$max} Alex");
|
|
72
|
+
expect(props.style()).toEqual({ width: "100" });
|
|
73
|
+
|
|
74
|
+
object.hpSignal.set(10);
|
|
75
|
+
object.name = "Sam";
|
|
76
|
+
object.speed = 6;
|
|
77
|
+
object.canMove = false;
|
|
78
|
+
|
|
79
|
+
expect(props.value()).toBe("HP: 10 Sam 6 false");
|
|
80
|
+
expect(props.text()).toBe("{$current}/{$max} Sam");
|
|
81
|
+
expect(props.style()).toEqual({ width: "10" });
|
|
82
|
+
});
|
|
83
|
+
});
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { computed } from "canvasengine";
|
|
2
|
+
|
|
3
|
+
interface MatchResult {
|
|
4
|
+
property: string;
|
|
5
|
+
fullMatch: string;
|
|
6
|
+
index: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const readSignal = (value: any) => typeof value === 'function' ? value() : value;
|
|
10
|
+
const DYNAMIC_VALUE_PATTERN = /\{([^}]+)\}/g;
|
|
11
|
+
|
|
12
|
+
const hasDynamicValue = (value: any) => {
|
|
13
|
+
value = readSignal(value);
|
|
14
|
+
if (typeof value !== 'string') return false;
|
|
15
|
+
DYNAMIC_VALUE_PATTERN.lastIndex = 0;
|
|
16
|
+
return DYNAMIC_VALUE_PATTERN.test(value);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const resolveDynamicSnapshot = (value: any, object?: any): any => {
|
|
20
|
+
value = readSignal(value);
|
|
21
|
+
|
|
22
|
+
if (Array.isArray(value)) {
|
|
23
|
+
return value.map((entry) => resolveDynamicSnapshot(entry, object));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (value && typeof value === 'object') {
|
|
27
|
+
return Object.fromEntries(
|
|
28
|
+
Object.entries(value).map(([key, entry]) => [key, resolveDynamicSnapshot(entry, object)])
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return resolveDynamicValue(value, object);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const getDynamicValue = (property: string, object?: any) => {
|
|
36
|
+
try {
|
|
37
|
+
const propertyPath = property.split('.');
|
|
38
|
+
let currentValue = object;
|
|
39
|
+
|
|
40
|
+
for (let j = 0; j < propertyPath.length; j++) {
|
|
41
|
+
let prop = propertyPath[j];
|
|
42
|
+
|
|
43
|
+
currentValue = readSignal(currentValue);
|
|
44
|
+
|
|
45
|
+
if (j === 0) {
|
|
46
|
+
if (prop === 'hp') prop = 'hpSignal';
|
|
47
|
+
if (prop === 'sp') prop = 'spSignal';
|
|
48
|
+
if (prop === 'param') prop = '_param';
|
|
49
|
+
if (prop === 'name' && currentValue && typeof currentValue === 'object' && '_name' in currentValue) {
|
|
50
|
+
prop = '_name';
|
|
51
|
+
}
|
|
52
|
+
if (prop === 'speed' && currentValue && typeof currentValue === 'object' && '_speed' in currentValue) {
|
|
53
|
+
prop = '_speed';
|
|
54
|
+
}
|
|
55
|
+
if (prop === 'canMove' && currentValue && typeof currentValue === 'object' && '_canMove' in currentValue) {
|
|
56
|
+
prop = '_canMove';
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (currentValue && typeof currentValue === 'object' && prop in currentValue) {
|
|
61
|
+
currentValue = currentValue[prop];
|
|
62
|
+
} else {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return readSignal(currentValue);
|
|
68
|
+
} catch (error) {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const resolveDynamicValue = (value: any, object?: any): any => {
|
|
74
|
+
value = readSignal(value);
|
|
75
|
+
|
|
76
|
+
if (typeof value !== 'string') {
|
|
77
|
+
return value;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return value.replace(DYNAMIC_VALUE_PATTERN, (fullMatch, property) => {
|
|
81
|
+
const propertyValue = getDynamicValue(property, object);
|
|
82
|
+
if (propertyValue == null && property.startsWith('$')) return fullMatch;
|
|
83
|
+
return propertyValue != null ? String(propertyValue) : '';
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const resolveDynamicProp = (value: any, object?: any): any => {
|
|
88
|
+
if (Array.isArray(value) || (value && typeof value === 'object' && typeof value !== 'function')) {
|
|
89
|
+
return computed(() => resolveDynamicSnapshot(value, object));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (typeof value === 'function' || hasDynamicValue(value)) {
|
|
93
|
+
return computed(() => resolveDynamicValue(value, object));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return value;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export const resolveDynamicProps = (props: any, object?: any): any => {
|
|
100
|
+
props = readSignal(props);
|
|
101
|
+
|
|
102
|
+
if (Array.isArray(props)) {
|
|
103
|
+
return computed(() => resolveDynamicSnapshot(props, object));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (props && typeof props === 'object') {
|
|
107
|
+
return Object.fromEntries(
|
|
108
|
+
Object.entries(props).map(([key, value]) => [key, resolveDynamicProp(value, object)])
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return resolveDynamicProp(props, object);
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
export const parseDynamicValue = (value: any, object?: any) => {
|
|
116
|
+
if (typeof value !== 'string') {
|
|
117
|
+
return computed(() => String(value ?? ''));
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Find all dynamic references like {propertyName}
|
|
121
|
+
const matches: MatchResult[] = [];
|
|
122
|
+
let match;
|
|
123
|
+
|
|
124
|
+
DYNAMIC_VALUE_PATTERN.lastIndex = 0;
|
|
125
|
+
while ((match = DYNAMIC_VALUE_PATTERN.exec(value)) !== null) {
|
|
126
|
+
matches.push({
|
|
127
|
+
property: match[1],
|
|
128
|
+
fullMatch: match[0],
|
|
129
|
+
index: match.index!
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// If no dynamic references found, return simple computed
|
|
134
|
+
if (matches.length === 0) {
|
|
135
|
+
return computed(() => value);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Create computed that tracks all referenced signals
|
|
139
|
+
return computed(() => {
|
|
140
|
+
let result = value;
|
|
141
|
+
|
|
142
|
+
// Replace from end to start to preserve indices
|
|
143
|
+
for (let i = matches.length - 1; i >= 0; i--) {
|
|
144
|
+
const { property, fullMatch } = matches[i];
|
|
145
|
+
|
|
146
|
+
const currentValue = getDynamicValue(property, object);
|
|
147
|
+
const propertyValue = currentValue != null ? String(currentValue) : property.startsWith('$') ? fullMatch : '';
|
|
148
|
+
|
|
149
|
+
result = result.replace(fullMatch, propertyValue);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return result;
|
|
153
|
+
});
|
|
154
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { describe, expect, test } from "vitest";
|
|
2
|
+
import { getShapeBox, getShapePointBounds, translatePolygonPoints } from "./shape-utils";
|
|
3
|
+
|
|
4
|
+
describe("shape utilities", () => {
|
|
5
|
+
test("normalizes rectangles and circles around their rendered bounds", () => {
|
|
6
|
+
expect(getShapeBox({ type: "rect", width: 32, height: 32 })).toEqual({
|
|
7
|
+
width: 32,
|
|
8
|
+
height: 32,
|
|
9
|
+
offsetX: 0,
|
|
10
|
+
offsetY: 0
|
|
11
|
+
});
|
|
12
|
+
expect(getShapeBox({ type: "circle", radius: 8 })).toEqual({
|
|
13
|
+
width: 16,
|
|
14
|
+
height: 16,
|
|
15
|
+
offsetX: 0,
|
|
16
|
+
offsetY: 0
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test("normalizes line bounds with negative coordinates", () => {
|
|
21
|
+
expect(getShapeBox({ type: "line", x1: -4, y1: 6, x2: 12, y2: -2 })).toEqual({
|
|
22
|
+
width: 16,
|
|
23
|
+
height: 8,
|
|
24
|
+
offsetX: 4,
|
|
25
|
+
offsetY: 2
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test("normalizes polygon bounds and translated points", () => {
|
|
30
|
+
const box = getShapeBox({ type: "polygon", points: [-5, 2, 15, 2, 5, 12] });
|
|
31
|
+
|
|
32
|
+
expect(getShapePointBounds([-5, 2, 15, 2, 5, 12])).toEqual({
|
|
33
|
+
minX: -5,
|
|
34
|
+
minY: 2,
|
|
35
|
+
maxX: 15,
|
|
36
|
+
maxY: 12
|
|
37
|
+
});
|
|
38
|
+
expect(box).toEqual({
|
|
39
|
+
width: 20,
|
|
40
|
+
height: 10,
|
|
41
|
+
offsetX: 5,
|
|
42
|
+
offsetY: -2
|
|
43
|
+
});
|
|
44
|
+
expect(translatePolygonPoints([-5, 2, 15, 2, 5, 12], box)).toEqual([0, 0, 20, 0, 10, 10]);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const defaultToNumber = (value: any, fallback = 0) => {
|
|
2
|
+
const num = typeof value === 'number' ? value : parseFloat(value);
|
|
3
|
+
return Number.isFinite(num) ? num : fallback;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
export function getShapePointBounds(points: any[] = [], toNumber = defaultToNumber) {
|
|
7
|
+
if (!Array.isArray(points) || points.length < 2) {
|
|
8
|
+
return { minX: 0, minY: 0, maxX: 1, maxY: 1 };
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
let minX = Infinity;
|
|
12
|
+
let minY = Infinity;
|
|
13
|
+
let maxX = -Infinity;
|
|
14
|
+
let maxY = -Infinity;
|
|
15
|
+
|
|
16
|
+
for (let i = 0; i < points.length; i += 2) {
|
|
17
|
+
const x = toNumber(points[i], 0);
|
|
18
|
+
const y = toNumber(points[i + 1], 0);
|
|
19
|
+
minX = Math.min(minX, x);
|
|
20
|
+
minY = Math.min(minY, y);
|
|
21
|
+
maxX = Math.max(maxX, x);
|
|
22
|
+
maxY = Math.max(maxY, y);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return { minX, minY, maxX, maxY };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function getShapeBox(cfg: any, toNumber = defaultToNumber) {
|
|
29
|
+
if (cfg.type === 'circle') {
|
|
30
|
+
return { width: cfg.radius * 2, height: cfg.radius * 2, offsetX: 0, offsetY: 0 };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (cfg.type === 'line') {
|
|
34
|
+
const minX = Math.min(cfg.x1, cfg.x2);
|
|
35
|
+
const minY = Math.min(cfg.y1, cfg.y2);
|
|
36
|
+
const maxX = Math.max(cfg.x1, cfg.x2);
|
|
37
|
+
const maxY = Math.max(cfg.y1, cfg.y2);
|
|
38
|
+
return {
|
|
39
|
+
width: Math.max(1, maxX - minX),
|
|
40
|
+
height: Math.max(1, maxY - minY),
|
|
41
|
+
offsetX: -minX,
|
|
42
|
+
offsetY: -minY
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (cfg.type === 'polygon') {
|
|
47
|
+
const bounds = getShapePointBounds(cfg.points, toNumber);
|
|
48
|
+
return {
|
|
49
|
+
width: Math.max(1, bounds.maxX - bounds.minX),
|
|
50
|
+
height: Math.max(1, bounds.maxY - bounds.minY),
|
|
51
|
+
offsetX: -bounds.minX,
|
|
52
|
+
offsetY: -bounds.minY
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return { width: cfg.width, height: cfg.height, offsetX: 0, offsetY: 0 };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function translatePolygonPoints(points: any[] = [], box: { offsetX: number; offsetY: number }, toNumber = defaultToNumber) {
|
|
60
|
+
return points.map((point, index) => toNumber(point, 0) + (index % 2 === 0 ? box.offsetX : box.offsetY));
|
|
61
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
<Container width={shapeWidth} height={shapeHeight} minWidth={shapeWidth} minHeight={shapeHeight}>
|
|
2
|
+
<Graphics width={shapeWidth} height={shapeHeight} draw={drawShape} />
|
|
3
|
+
</Container>
|
|
4
|
+
|
|
5
|
+
<script>
|
|
6
|
+
import { computed } from "canvasengine";
|
|
7
|
+
import { resolveDynamicValue } from "./parse-value";
|
|
8
|
+
import { getShapeBox, translatePolygonPoints } from "./shape-utils";
|
|
9
|
+
|
|
10
|
+
const props = defineProps();
|
|
11
|
+
const { object } = props;
|
|
12
|
+
|
|
13
|
+
const read = (prop, fallback) => prop ? prop() : fallback;
|
|
14
|
+
|
|
15
|
+
const toNumber = (value, fallback = 0) => {
|
|
16
|
+
const resolved = resolveDynamicValue(value, object);
|
|
17
|
+
const num = typeof resolved === 'number' ? resolved : parseFloat(resolved);
|
|
18
|
+
return Number.isFinite(num) ? num : fallback;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const toColor = (value, fallback) => {
|
|
22
|
+
const resolved = resolveDynamicValue(value, object);
|
|
23
|
+
if (typeof resolved === 'number') return resolved;
|
|
24
|
+
if (typeof resolved === 'string' && resolved.startsWith('#')) {
|
|
25
|
+
return parseInt(resolved.slice(1), 16);
|
|
26
|
+
}
|
|
27
|
+
return resolved ?? fallback;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const config = computed(() => ({
|
|
31
|
+
type: read(props.type, 'rectangle'),
|
|
32
|
+
fill: toColor(read(props.fill, '#ffffff'), 0xffffff),
|
|
33
|
+
radius: toNumber(read(props.radius, 8), 8),
|
|
34
|
+
width: toNumber(read(props.width, 16), 16),
|
|
35
|
+
height: toNumber(read(props.height, 16), 16),
|
|
36
|
+
x1: toNumber(read(props.x1, 0), 0),
|
|
37
|
+
y1: toNumber(read(props.y1, 0), 0),
|
|
38
|
+
x2: toNumber(read(props.x2, 16), 16),
|
|
39
|
+
y2: toNumber(read(props.y2, 0), 0),
|
|
40
|
+
opacity: Math.max(0, Math.min(1, toNumber(read(props.opacity, 1), 1))),
|
|
41
|
+
points: read(props.points, []),
|
|
42
|
+
line: read(props.line, null)
|
|
43
|
+
}));
|
|
44
|
+
|
|
45
|
+
const shapeBox = computed(() => getShapeBox(config(), toNumber));
|
|
46
|
+
|
|
47
|
+
const shapeWidth = computed(() => shapeBox().width);
|
|
48
|
+
const shapeHeight = computed(() => shapeBox().height);
|
|
49
|
+
|
|
50
|
+
const drawShape = (g) => {
|
|
51
|
+
const cfg = config();
|
|
52
|
+
const box = shapeBox();
|
|
53
|
+
|
|
54
|
+
if (cfg.type === 'circle') {
|
|
55
|
+
g.circle(cfg.radius, cfg.radius, cfg.radius);
|
|
56
|
+
} else if (cfg.type === 'ellipse') {
|
|
57
|
+
g.ellipse(box.width / 2, box.height / 2, box.width / 2, box.height / 2);
|
|
58
|
+
} else if (cfg.type === 'line') {
|
|
59
|
+
g.moveTo(cfg.x1 + box.offsetX, cfg.y1 + box.offsetY);
|
|
60
|
+
g.lineTo(cfg.x2 + box.offsetX, cfg.y2 + box.offsetY);
|
|
61
|
+
} else if (cfg.type === 'polygon' && Array.isArray(cfg.points)) {
|
|
62
|
+
g.poly(translatePolygonPoints(cfg.points, box, toNumber));
|
|
63
|
+
} else if (cfg.type === 'rounded-rectangle') {
|
|
64
|
+
g.roundRect(0, 0, box.width, box.height, toNumber(read(props.radius, 4), 4));
|
|
65
|
+
} else {
|
|
66
|
+
g.rect(0, 0, box.width, box.height);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (cfg.type === 'line') {
|
|
70
|
+
const line = cfg.line ?? {};
|
|
71
|
+
g.stroke({
|
|
72
|
+
color: toColor(line.color, cfg.fill),
|
|
73
|
+
width: toNumber(line.width, 1),
|
|
74
|
+
alpha: toNumber(line.alpha, cfg.opacity)
|
|
75
|
+
});
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
g.fill({ color: cfg.fill, alpha: cfg.opacity });
|
|
80
|
+
|
|
81
|
+
if (cfg.line) {
|
|
82
|
+
g.stroke({
|
|
83
|
+
color: toColor(cfg.line.color, cfg.fill),
|
|
84
|
+
width: toNumber(cfg.line.width, 1),
|
|
85
|
+
alpha: toNumber(cfg.line.alpha, cfg.opacity)
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
</script>
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<Text text={textValue} color={textColor} size={textSize} fontFamily={textFontFamily} style={textStyle} />
|
|
2
|
+
|
|
3
|
+
<script>
|
|
4
|
+
import { computed } from "canvasengine";
|
|
5
|
+
import { resolveDynamicValue } from "./parse-value";
|
|
6
|
+
|
|
7
|
+
const { object, value, style } = defineProps();
|
|
8
|
+
|
|
9
|
+
const read = (prop, fallback) => prop ? prop() : fallback;
|
|
10
|
+
|
|
11
|
+
const parseNumericStyleValue = (value, object) => {
|
|
12
|
+
value = resolveDynamicValue(value, object);
|
|
13
|
+
if (value === undefined || value === null) return undefined;
|
|
14
|
+
if (typeof value === 'number') return value;
|
|
15
|
+
|
|
16
|
+
const num = parseFloat(value);
|
|
17
|
+
return isNaN(num) ? undefined : num;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const getTextStyle = (style) => {
|
|
21
|
+
if (!style) return {};
|
|
22
|
+
const textStyle = {};
|
|
23
|
+
|
|
24
|
+
if (style.fontStyle !== undefined) {
|
|
25
|
+
textStyle.fontStyle = resolveDynamicValue(style.fontStyle, object);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (style.fontWeight !== undefined) {
|
|
29
|
+
textStyle.fontWeight = resolveDynamicValue(style.fontWeight, object);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (style.stroke !== undefined) {
|
|
33
|
+
textStyle.stroke = resolveDynamicValue(style.stroke, object);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (style.opacity !== undefined) {
|
|
37
|
+
const opacityValue = parseNumericStyleValue(style.opacity, object);
|
|
38
|
+
if (opacityValue !== undefined) {
|
|
39
|
+
textStyle.opacity = opacityValue;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (style.wordWrap !== undefined) {
|
|
44
|
+
textStyle.wordWrap = style.wordWrap;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (style.align !== undefined) {
|
|
48
|
+
textStyle.align = resolveDynamicValue(style.align, object);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return textStyle;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const textValue = computed(() => String(resolveDynamicValue(read(value, ''), object) ?? ''));
|
|
55
|
+
const textColor = computed(() => {
|
|
56
|
+
const currentStyle = read(style, {});
|
|
57
|
+
return currentStyle.fill !== undefined ? resolveDynamicValue(currentStyle.fill, object) : undefined;
|
|
58
|
+
});
|
|
59
|
+
const textSize = computed(() => {
|
|
60
|
+
const currentStyle = read(style, {});
|
|
61
|
+
return currentStyle.fontSize !== undefined ? parseNumericStyleValue(currentStyle.fontSize, object) : undefined;
|
|
62
|
+
});
|
|
63
|
+
const textFontFamily = computed(() => {
|
|
64
|
+
const currentStyle = read(style, {});
|
|
65
|
+
return currentStyle.fontFamily !== undefined ? resolveDynamicValue(currentStyle.fontFamily, object) : undefined;
|
|
66
|
+
});
|
|
67
|
+
const textStyle = computed(() => getTextStyle(read(style, {})));
|
|
68
|
+
</script>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<Container positionType="absolute" top={top} left={left}>
|
|
2
|
+
<Container
|
|
3
|
+
anchor={[0.5, 0.5]}
|
|
4
|
+
>
|
|
5
|
+
<Rect width height color={_color} />
|
|
6
|
+
<Container attach={child}></Container>
|
|
7
|
+
</Container>
|
|
8
|
+
</Container>
|
|
9
|
+
|
|
10
|
+
<script>
|
|
11
|
+
import { RpgClientEngine, inject } from "../../index";
|
|
12
|
+
|
|
13
|
+
const { width, height, children, color, top, left } = defineProps();
|
|
14
|
+
const engine = inject(RpgClientEngine)
|
|
15
|
+
const child = children[0]
|
|
16
|
+
const _color = computed(() => engine.globalConfig.gui?.windowColor || color?.() || "#1a1a2e")
|
|
17
|
+
</script>
|