@antha/graphics-2d 0.15.1 → 0.17.0
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.
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type PartialWithUndefined, type RequireAtLeastOne } from '@augment-vir/common';
|
|
1
2
|
import { type AnthaGraphics2dModState } from './antha-graphics-2d.mod.js';
|
|
2
3
|
/**
|
|
3
4
|
* The logical dimensions and scale of a virtual viewport.
|
|
@@ -15,6 +16,15 @@ export type VirtualViewport = {
|
|
|
15
16
|
* @category Internal
|
|
16
17
|
*/
|
|
17
18
|
export type VirtualViewportSize = Pick<VirtualViewport, 'height' | 'width'>;
|
|
19
|
+
/**
|
|
20
|
+
* Options for {@link createAnthaVirtualViewportMod}.
|
|
21
|
+
*
|
|
22
|
+
* @category Pre-Built Mods
|
|
23
|
+
*/
|
|
24
|
+
export type AnthaVirtualViewportOptions = RequireAtLeastOne<{
|
|
25
|
+
virtualHeight: number;
|
|
26
|
+
virtualWidth: number;
|
|
27
|
+
}>;
|
|
18
28
|
/**
|
|
19
29
|
* State added by {@link createAnthaVirtualViewportMod}.
|
|
20
30
|
*
|
|
@@ -28,9 +38,8 @@ export type AnthaVirtualViewportModState = AnthaGraphics2dModState & {
|
|
|
28
38
|
*
|
|
29
39
|
* @category Util
|
|
30
40
|
*/
|
|
31
|
-
export declare function calculateVirtualViewport({ screenSize, virtualWidth, }: Readonly<{
|
|
41
|
+
export declare function calculateVirtualViewport({ screenSize, virtualHeight, virtualWidth, }: Readonly<PartialWithUndefined<AnthaVirtualViewportOptions> & {
|
|
32
42
|
screenSize: Readonly<VirtualViewportSize>;
|
|
33
|
-
virtualWidth: number;
|
|
34
43
|
}>): {
|
|
35
44
|
height: number;
|
|
36
45
|
scale: number;
|
|
@@ -67,14 +76,8 @@ export declare function createVirtualViewportPixiOptions(): {
|
|
|
67
76
|
resolution: number;
|
|
68
77
|
};
|
|
69
78
|
/**
|
|
70
|
-
* A pre-built mod that scales an Antha UI and Pixi canvas to a logical viewport
|
|
79
|
+
* A pre-built mod that scales an Antha UI and Pixi canvas to a logical viewport.
|
|
71
80
|
*
|
|
72
81
|
* @category Pre-Built Mods
|
|
73
82
|
*/
|
|
74
|
-
export declare function createAnthaVirtualViewportMod({ virtualWidth, }: Readonly<
|
|
75
|
-
/**
|
|
76
|
-
* The reference width for your game screen. Any browser window wider or skinnier than this will
|
|
77
|
-
* be scaled.
|
|
78
|
-
*/
|
|
79
|
-
virtualWidth: number;
|
|
80
|
-
}>): import("@antha/engine").AnthaMod<NoInfer<AnthaVirtualViewportModState>>;
|
|
83
|
+
export declare function createAnthaVirtualViewportMod({ virtualHeight, virtualWidth, }: Readonly<AnthaVirtualViewportOptions>): import("@antha/engine").AnthaMod<NoInfer<AnthaVirtualViewportModState>>;
|
|
@@ -1,19 +1,43 @@
|
|
|
1
1
|
import { defineAnthaMod } from '@antha/engine';
|
|
2
|
+
import { assertWrap } from '@augment-vir/assert';
|
|
2
3
|
/**
|
|
3
4
|
* Calculates the logical viewport for a physical screen size.
|
|
4
5
|
*
|
|
5
6
|
* @category Util
|
|
6
7
|
*/
|
|
7
|
-
export function calculateVirtualViewport({ screenSize, virtualWidth, }) {
|
|
8
|
-
if (!screenSize.
|
|
8
|
+
export function calculateVirtualViewport({ screenSize, virtualHeight, virtualWidth, }) {
|
|
9
|
+
if (!screenSize.height ||
|
|
10
|
+
!screenSize.width ||
|
|
11
|
+
virtualHeight === 0 ||
|
|
12
|
+
virtualWidth === 0 ||
|
|
13
|
+
(virtualHeight == undefined && virtualWidth == undefined)) {
|
|
9
14
|
return undefined;
|
|
10
15
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
else if (virtualHeight == undefined) {
|
|
17
|
+
const definedVirtualWidth = assertWrap.isDefined(virtualWidth);
|
|
18
|
+
const scale = screenSize.width / definedVirtualWidth;
|
|
19
|
+
return {
|
|
20
|
+
height: screenSize.height / scale,
|
|
21
|
+
scale,
|
|
22
|
+
width: definedVirtualWidth,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
else if (virtualWidth == undefined) {
|
|
26
|
+
const scale = screenSize.height / virtualHeight;
|
|
27
|
+
return {
|
|
28
|
+
height: virtualHeight,
|
|
29
|
+
scale,
|
|
30
|
+
width: screenSize.width / scale,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
const scale = Math.min(screenSize.height / virtualHeight, screenSize.width / virtualWidth);
|
|
35
|
+
return {
|
|
36
|
+
height: virtualHeight,
|
|
37
|
+
scale,
|
|
38
|
+
width: virtualWidth,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
17
41
|
}
|
|
18
42
|
/**
|
|
19
43
|
* Maps a pointer position from canvas coordinates into a virtual viewport.
|
|
@@ -46,11 +70,38 @@ function hasSameVirtualViewport({ previousVirtualViewport, virtualViewport, }) {
|
|
|
46
70
|
Math.abs(previousVirtualViewport.scale - virtualViewport.scale) < 0.0001 &&
|
|
47
71
|
previousVirtualViewport.width === virtualViewport.width);
|
|
48
72
|
}
|
|
49
|
-
function updateVirtualViewportHostElement({ hostElement, virtualViewport, }) {
|
|
50
|
-
hostElement.style.height =
|
|
51
|
-
|
|
73
|
+
function updateVirtualViewportHostElement({ hostElement, isFixedViewport, screenSize, virtualViewport, }) {
|
|
74
|
+
hostElement.style.height = isFixedViewport
|
|
75
|
+
? `${virtualViewport.height}px`
|
|
76
|
+
: `${100 / virtualViewport.scale}%`;
|
|
77
|
+
hostElement.style.transform = getVirtualViewportHostTransform({
|
|
78
|
+
isFixedViewport,
|
|
79
|
+
screenSize,
|
|
80
|
+
virtualViewport,
|
|
81
|
+
});
|
|
52
82
|
hostElement.style.transformOrigin = 'top left';
|
|
53
|
-
hostElement.style.width =
|
|
83
|
+
hostElement.style.width = isFixedViewport
|
|
84
|
+
? `${virtualViewport.width}px`
|
|
85
|
+
: `${100 / virtualViewport.scale}%`;
|
|
86
|
+
}
|
|
87
|
+
function getVirtualViewportHostTransform({ isFixedViewport, screenSize, virtualViewport, }) {
|
|
88
|
+
const horizontalOffset = isFixedViewport
|
|
89
|
+
? (screenSize.width - virtualViewport.width * virtualViewport.scale) / 2
|
|
90
|
+
: 0;
|
|
91
|
+
const verticalOffset = isFixedViewport
|
|
92
|
+
? (screenSize.height - virtualViewport.height * virtualViewport.scale) / 2
|
|
93
|
+
: 0;
|
|
94
|
+
return isFixedViewport
|
|
95
|
+
? `translate(${horizontalOffset}px, ${verticalOffset}px) scale(${virtualViewport.scale})`
|
|
96
|
+
: `scale(${virtualViewport.scale})`;
|
|
97
|
+
}
|
|
98
|
+
function getVirtualViewportScreenSize({ hostElement, isFixedViewport, }) {
|
|
99
|
+
if (!isFixedViewport) {
|
|
100
|
+
return hostElement.getBoundingClientRect();
|
|
101
|
+
}
|
|
102
|
+
const rootNode = hostElement.getRootNode();
|
|
103
|
+
const viewportContainer = rootNode instanceof ShadowRoot ? rootNode.host : hostElement.parentElement || hostElement;
|
|
104
|
+
return viewportContainer.getBoundingClientRect();
|
|
54
105
|
}
|
|
55
106
|
function resetVirtualViewportHostElement({ hostElement, }) {
|
|
56
107
|
hostElement.style.removeProperty('height');
|
|
@@ -59,11 +110,12 @@ function resetVirtualViewportHostElement({ hostElement, }) {
|
|
|
59
110
|
hostElement.style.removeProperty('width');
|
|
60
111
|
}
|
|
61
112
|
/**
|
|
62
|
-
* A pre-built mod that scales an Antha UI and Pixi canvas to a logical viewport
|
|
113
|
+
* A pre-built mod that scales an Antha UI and Pixi canvas to a logical viewport.
|
|
63
114
|
*
|
|
64
115
|
* @category Pre-Built Mods
|
|
65
116
|
*/
|
|
66
|
-
export function createAnthaVirtualViewportMod({ virtualWidth, }) {
|
|
117
|
+
export function createAnthaVirtualViewportMod({ virtualHeight, virtualWidth, }) {
|
|
118
|
+
const isFixedViewport = !!virtualHeight && !!virtualWidth;
|
|
67
119
|
return defineAnthaMod({
|
|
68
120
|
modName: 'antha-virtual-viewport',
|
|
69
121
|
cleanup({ hostElement, state }) {
|
|
@@ -73,8 +125,13 @@ export function createAnthaVirtualViewportMod({ virtualWidth, }) {
|
|
|
73
125
|
state.virtualViewport = undefined;
|
|
74
126
|
},
|
|
75
127
|
execute({ hostElement, state }) {
|
|
128
|
+
const screenSize = getVirtualViewportScreenSize({
|
|
129
|
+
hostElement,
|
|
130
|
+
isFixedViewport,
|
|
131
|
+
});
|
|
76
132
|
const virtualViewport = calculateVirtualViewport({
|
|
77
|
-
screenSize
|
|
133
|
+
screenSize,
|
|
134
|
+
virtualHeight,
|
|
78
135
|
virtualWidth,
|
|
79
136
|
});
|
|
80
137
|
if (!virtualViewport) {
|
|
@@ -83,10 +140,18 @@ export function createAnthaVirtualViewportMod({ virtualWidth, }) {
|
|
|
83
140
|
const hasViewportChanged = !hasSameVirtualViewport({
|
|
84
141
|
previousVirtualViewport: state.virtualViewport,
|
|
85
142
|
virtualViewport,
|
|
86
|
-
}) ||
|
|
143
|
+
}) ||
|
|
144
|
+
hostElement.style.transform !==
|
|
145
|
+
getVirtualViewportHostTransform({
|
|
146
|
+
isFixedViewport,
|
|
147
|
+
screenSize,
|
|
148
|
+
virtualViewport,
|
|
149
|
+
});
|
|
87
150
|
if (hasViewportChanged) {
|
|
88
151
|
updateVirtualViewportHostElement({
|
|
89
152
|
hostElement,
|
|
153
|
+
isFixedViewport,
|
|
154
|
+
screenSize,
|
|
90
155
|
virtualViewport,
|
|
91
156
|
});
|
|
92
157
|
state.virtualViewport = virtualViewport;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antha/graphics-2d",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "An Antha mod for rendering 2D graphics to a canvas.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"vir",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"scripts": {
|
|
32
32
|
"compile": "virmator compile",
|
|
33
33
|
"docs": "virmator docs",
|
|
34
|
-
"test": "virmator test web",
|
|
35
|
-
"test:coverage": "
|
|
34
|
+
"test": "NODE_OPTIONS=--import=tsx virmator test web",
|
|
35
|
+
"test:coverage": "npm test coverage",
|
|
36
36
|
"test:docs": "virmator docs check"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
"@augment-vir/common": "^32.3.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@antha/engine": "^0.
|
|
44
|
-
"@antha/web-test-runner-plugin-pixi": "^0.
|
|
43
|
+
"@antha/engine": "^0.17.0",
|
|
44
|
+
"@antha/web-test-runner-plugin-pixi": "^0.17.0",
|
|
45
45
|
"@augment-vir/test": "^32.3.0",
|
|
46
46
|
"@electrovir/color": "^2.0.0",
|
|
47
47
|
"@web/dev-server-esbuild": "^2.0.0",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"vira": "32.0.0"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
|
-
"@antha/engine": "^0.
|
|
55
|
+
"@antha/engine": "^0.17.0",
|
|
56
56
|
"@electrovir/color": "^2",
|
|
57
57
|
"element-vir": "^27",
|
|
58
58
|
"pixi.js": "^8",
|