Skip to content

Commit 0c01a20

Browse files
fix(core): reproduce-able viewports (#9923)
1 parent a15c8ce commit 0c01a20

File tree

6 files changed

+140
-5
lines changed

6 files changed

+140
-5
lines changed

modules/core/src/viewports/first-person-viewport.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,13 @@ export type FirstPersonViewportOptions = {
4444
};
4545

4646
export default class FirstPersonViewport extends Viewport {
47+
static displayName = 'FirstPersonViewport';
48+
4749
longitude?: number;
4850
latitude?: number;
51+
pitch: number;
52+
bearing: number;
53+
up: [number, number, number];
4954

5055
constructor(props: FirstPersonViewportOptions) {
5156
// TODO - push direction handling into Matrix4.lookAt
@@ -75,5 +80,8 @@ export default class FirstPersonViewport extends Viewport {
7580

7681
this.latitude = latitude;
7782
this.longitude = longitude;
83+
this.pitch = pitch;
84+
this.bearing = bearing;
85+
this.up = up;
7886
}
7987
}

modules/core/src/viewports/globe-viewport.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,12 @@ export type GlobeViewportOptions = {
6767
};
6868

6969
export default class GlobeViewport extends Viewport {
70-
longitude!: number;
71-
latitude!: number;
72-
resolution!: number;
70+
static displayName = 'GlobeViewport';
71+
72+
longitude: number;
73+
latitude: number;
74+
fovy: number;
75+
resolution: number;
7376

7477
constructor(opts: GlobeViewportOptions = {}) {
7578
const {
@@ -129,6 +132,7 @@ export default class GlobeViewport extends Viewport {
129132
this.scale = scale;
130133
this.latitude = latitude;
131134
this.longitude = longitude;
135+
this.fovy = fovy;
132136
this.resolution = resolution;
133137
}
134138

modules/core/src/viewports/orbit-viewport.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,14 @@ export type OrbitViewportOptions = {
8686
};
8787

8888
export default class OrbitViewport extends Viewport {
89+
static displayName = 'OrbitViewport';
90+
8991
projectedCenter: number[];
92+
orbitAxis: 'Y' | 'Z';
93+
rotationOrbit: number;
94+
rotationX: number;
95+
target: [number, number, number];
96+
fovy: number;
9097

9198
constructor(props: OrbitViewportOptions) {
9299
const {
@@ -125,6 +132,11 @@ export default class OrbitViewport extends Viewport {
125132
zoom
126133
});
127134

135+
this.target = target;
136+
this.orbitAxis = orbitAxis;
137+
this.rotationX = rotationX;
138+
this.rotationOrbit = rotationOrbit;
139+
this.fovy = fovy;
128140
this.projectedCenter = this.project(this.center);
129141
}
130142

modules/core/src/viewports/orthographic-viewport.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ export type OrthographicViewportOptions = {
6464
/** The zoom level of the viewport. `zoom: 0` maps one unit distance to one pixel on screen, and increasing `zoom` by `1` scales the same object to twice as large.
6565
* To apply independent zoom levels to the X and Y axes, supply an array `[zoomX, zoomY]`. Default `0`. */
6666
zoom?: number | [number, number];
67+
/** Independent zoom along the X axis. Overrides `zoom`. */
68+
zoomX?: number;
69+
/** Independent zoom along the Y axis. Overrides `zoom`. */
70+
zoomY?: number;
6771
/** Padding around the viewport, in pixels. */
6872
padding?: Padding | null;
6973
/** Distance of near clipping plane. Default `0.1`. */
@@ -75,6 +79,13 @@ export type OrthographicViewportOptions = {
7579
};
7680

7781
export default class OrthographicViewport extends Viewport {
82+
static displayName = 'OrthographicViewport';
83+
84+
target: [number, number, number] | [number, number];
85+
zoomX: number;
86+
zoomY: number;
87+
flipY: boolean;
88+
7889
constructor(props: OrthographicViewportOptions) {
7990
const {
8091
width,
@@ -86,8 +97,8 @@ export default class OrthographicViewport extends Viewport {
8697
padding = null,
8798
flipY = true
8899
} = props;
89-
const zoomX = Array.isArray(zoom) ? zoom[0] : zoom;
90-
const zoomY = Array.isArray(zoom) ? zoom[1] : zoom;
100+
const zoomX = props.zoomX ?? (Array.isArray(zoom) ? zoom[0] : zoom);
101+
const zoomY = props.zoomY ?? (Array.isArray(zoom) ? zoom[1] : zoom);
91102
const zoom_ = Math.min(zoomX, zoomY);
92103
const scale = Math.pow(2, zoom_);
93104

@@ -119,6 +130,11 @@ export default class OrthographicViewport extends Viewport {
119130
zoom: zoom_,
120131
distanceScales
121132
});
133+
134+
this.target = target;
135+
this.zoomX = zoomX;
136+
this.zoomY = zoomY;
137+
this.flipY = flipY;
122138
}
123139

124140
projectFlat([X, Y]: number[]): [number, number] {
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import test from 'tape-promise/tape';
2+
import {
3+
type Viewport,
4+
WebMercatorViewport,
5+
OrthographicViewport,
6+
OrbitViewport,
7+
_GlobeViewport as GlobeViewport,
8+
FirstPersonViewport
9+
} from '@deck.gl/core';
10+
11+
test('Viewport#recreate', t => {
12+
const TEST_CASES = [
13+
new WebMercatorViewport({
14+
width: 100,
15+
height: 100
16+
}),
17+
new WebMercatorViewport({
18+
width: 400,
19+
height: 300,
20+
longitude: -122.4,
21+
latitude: 37.8,
22+
fovy: 50,
23+
zoom: 12,
24+
pitch: 24,
25+
bearing: -160,
26+
position: [0, 0, 2]
27+
}),
28+
new WebMercatorViewport({
29+
width: 400,
30+
height: 300,
31+
longitude: -122.4,
32+
latitude: 37.8,
33+
zoom: 12,
34+
nearZ: 0.01,
35+
farZMultiplier: 10
36+
}),
37+
new OrbitViewport({
38+
width: 100,
39+
height: 100
40+
}),
41+
new OrbitViewport({
42+
width: 400,
43+
height: 300,
44+
target: [-10.24, 2833, 47.2],
45+
orbitAxis: 'Y',
46+
rotationX: 45,
47+
rotationOrbit: -111,
48+
zoom: -3,
49+
fovy: 60
50+
}),
51+
new OrthographicViewport({
52+
width: 100,
53+
height: 100
54+
}),
55+
new OrthographicViewport({
56+
width: 400,
57+
height: 300,
58+
target: [100, 500],
59+
zoom: [1, -4],
60+
flipY: false
61+
}),
62+
new GlobeViewport({
63+
width: 100,
64+
height: 100
65+
}),
66+
new GlobeViewport({
67+
width: 400,
68+
height: 300,
69+
longitude: -122.4,
70+
latitude: 37.8,
71+
fovy: 50,
72+
zoom: 12
73+
}),
74+
new FirstPersonViewport({
75+
width: 100,
76+
height: 100
77+
}),
78+
new FirstPersonViewport({
79+
width: 400,
80+
height: 300,
81+
longitude: -122.4,
82+
latitude: 37.8,
83+
pitch: 35,
84+
bearing: -140,
85+
focalDistance: 2
86+
})
87+
];
88+
for (const viewport of TEST_CASES) {
89+
const ViewportType = viewport.constructor as {new (props: unknown): Viewport};
90+
const clone = new ViewportType({...viewport});
91+
t.ok(viewport.equals(clone), String(viewport.id));
92+
}
93+
t.end();
94+
});

test/modules/core/viewports/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ import './viewport.spec';
66
import './globe-viewport.spec';
77
import './web-mercator-project-unproject.spec';
88
import './web-mercator-viewport.spec';
9+
import './conformance.spec';

0 commit comments

Comments
 (0)