@deck.gl/widgets 9.4.0-beta.1 → 9.4.0-beta.3
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/dist/index.cjs +339 -226
- package/dist/index.cjs.map +3 -3
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -15,7 +15,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
15
|
}
|
|
16
16
|
return to;
|
|
17
17
|
};
|
|
18
|
-
var __toCommonJS = (
|
|
18
|
+
var __toCommonJS = (mod2) => __copyProps(__defProp({}, "__esModule", { value: true }), mod2);
|
|
19
19
|
|
|
20
20
|
// dist/index.js
|
|
21
21
|
var index_exports = {};
|
|
@@ -126,6 +126,10 @@ var import_core = require("@math.gl/core");
|
|
|
126
126
|
function createMat4() {
|
|
127
127
|
return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
|
|
128
128
|
}
|
|
129
|
+
function mod(value, divisor) {
|
|
130
|
+
const modulus = value % divisor;
|
|
131
|
+
return modulus < 0 ? divisor + modulus : modulus;
|
|
132
|
+
}
|
|
129
133
|
function getCameraPosition(viewMatrixInverse) {
|
|
130
134
|
return [viewMatrixInverse[12], viewMatrixInverse[13], viewMatrixInverse[14]];
|
|
131
135
|
}
|
|
@@ -246,8 +250,8 @@ var _Viewport = class _Viewport {
|
|
|
246
250
|
}
|
|
247
251
|
return PROJECTION_MODE.IDENTITY;
|
|
248
252
|
}
|
|
249
|
-
// Two viewports are equal if
|
|
250
|
-
//
|
|
253
|
+
// Two viewports are equal if their dimensions, common-space scale, and
|
|
254
|
+
// view and projection matrices are (approximately) equal.
|
|
251
255
|
equals(viewport) {
|
|
252
256
|
if (!(viewport instanceof _Viewport)) {
|
|
253
257
|
return false;
|
|
@@ -255,7 +259,7 @@ var _Viewport = class _Viewport {
|
|
|
255
259
|
if (this === viewport) {
|
|
256
260
|
return true;
|
|
257
261
|
}
|
|
258
|
-
return viewport.width === this.width && viewport.height === this.height && viewport.scale === this.scale && (0, import_core2.equals)(viewport.projectionMatrix, this.projectionMatrix) && (0, import_core2.equals)(viewport.viewMatrix, this.viewMatrix);
|
|
262
|
+
return viewport.width === this.width && viewport.height === this.height && viewport.scale === this.scale && viewport.projectionMode === this.projectionMode && viewport.resolution === this.resolution && (0, import_core2.equals)(viewport.distanceScales.unitsPerMeter, this.distanceScales.unitsPerMeter) && (0, import_core2.equals)(viewport.projectionMatrix, this.projectionMatrix) && (0, import_core2.equals)(viewport.viewMatrix, this.viewMatrix);
|
|
259
263
|
}
|
|
260
264
|
/**
|
|
261
265
|
* Projects xyz (possibly latitude and longitude) to pixel coordinates in window
|
|
@@ -592,6 +596,10 @@ var _WebMercatorViewport = class _WebMercatorViewport extends Viewport {
|
|
|
592
596
|
}
|
|
593
597
|
return this._subViewports;
|
|
594
598
|
}
|
|
599
|
+
/** Returns whether two Web Mercator viewports use the same projection settings. */
|
|
600
|
+
equals(viewport) {
|
|
601
|
+
return viewport instanceof _WebMercatorViewport && viewport._pseudoMeters === this._pseudoMeters && super.equals(viewport);
|
|
602
|
+
}
|
|
595
603
|
projectPosition(xyz) {
|
|
596
604
|
if (this._pseudoMeters) {
|
|
597
605
|
return super.projectPosition(xyz);
|
|
@@ -1310,185 +1318,7 @@ var TransitionInterpolator = class {
|
|
|
1310
1318
|
};
|
|
1311
1319
|
|
|
1312
1320
|
// ../core/src/transitions/linear-interpolator.ts
|
|
1313
|
-
var import_core7 = require("@math.gl/core");
|
|
1314
|
-
|
|
1315
|
-
// ../core/src/viewports/globe-viewport.ts
|
|
1316
1321
|
var import_core5 = require("@math.gl/core");
|
|
1317
|
-
var import_web_mercator3 = require("@math.gl/web-mercator");
|
|
1318
|
-
var import_core6 = require("@math.gl/core");
|
|
1319
|
-
var import_web_mercator4 = require("@math.gl/web-mercator");
|
|
1320
|
-
var DEGREES_TO_RADIANS2 = Math.PI / 180;
|
|
1321
|
-
var RADIANS_TO_DEGREES = 180 / Math.PI;
|
|
1322
|
-
var EARTH_RADIUS = 6370972;
|
|
1323
|
-
var GLOBE_RADIUS = 256;
|
|
1324
|
-
function getDistanceScales2() {
|
|
1325
|
-
const unitsPerMeter2 = GLOBE_RADIUS / EARTH_RADIUS;
|
|
1326
|
-
const unitsPerDegree = Math.PI / 180 * GLOBE_RADIUS;
|
|
1327
|
-
return {
|
|
1328
|
-
unitsPerMeter: [unitsPerMeter2, unitsPerMeter2, unitsPerMeter2],
|
|
1329
|
-
unitsPerMeter2: [0, 0, 0],
|
|
1330
|
-
metersPerUnit: [1 / unitsPerMeter2, 1 / unitsPerMeter2, 1 / unitsPerMeter2],
|
|
1331
|
-
unitsPerDegree: [unitsPerDegree, unitsPerDegree, unitsPerMeter2],
|
|
1332
|
-
unitsPerDegree2: [0, 0, 0],
|
|
1333
|
-
degreesPerUnit: [1 / unitsPerDegree, 1 / unitsPerDegree, 1 / unitsPerMeter2]
|
|
1334
|
-
};
|
|
1335
|
-
}
|
|
1336
|
-
var GlobeViewport = class extends Viewport {
|
|
1337
|
-
constructor(opts = {}) {
|
|
1338
|
-
const {
|
|
1339
|
-
longitude = 0,
|
|
1340
|
-
bearing = 0,
|
|
1341
|
-
pitch = 0,
|
|
1342
|
-
zoom = 0,
|
|
1343
|
-
// Matches Maplibre defaults
|
|
1344
|
-
// https://github.com/maplibre/maplibre-gl-js/blob/f8ab4b48d59ab8fe7b068b102538793bbdd4c848/src/geo/projection/globe_transform.ts#L632-L633
|
|
1345
|
-
nearZMultiplier = 0.5,
|
|
1346
|
-
farZMultiplier = 1,
|
|
1347
|
-
resolution = 10
|
|
1348
|
-
} = opts;
|
|
1349
|
-
let { latitude = 0, height, altitude = 1.5, fovy } = opts;
|
|
1350
|
-
latitude = Math.max(Math.min(latitude, 90), -90);
|
|
1351
|
-
height = height || 1;
|
|
1352
|
-
if (fovy) {
|
|
1353
|
-
altitude = (0, import_web_mercator3.fovyToAltitude)(fovy);
|
|
1354
|
-
} else {
|
|
1355
|
-
fovy = (0, import_web_mercator3.altitudeToFovy)(altitude);
|
|
1356
|
-
}
|
|
1357
|
-
const scaleLatitude = Math.max(Math.min(latitude, import_web_mercator4.MAX_LATITUDE), -import_web_mercator4.MAX_LATITUDE);
|
|
1358
|
-
const scale = Math.pow(2, zoom - zoomAdjust(scaleLatitude));
|
|
1359
|
-
const pitchRadians = pitch * DEGREES_TO_RADIANS2;
|
|
1360
|
-
const nearZ = opts.nearZ ?? nearZMultiplier;
|
|
1361
|
-
const farZ = opts.farZ ?? (altitude + GLOBE_RADIUS * 2 * scale / height / Math.max(Math.cos(pitchRadians), 0.1)) * farZMultiplier;
|
|
1362
|
-
const viewMatrix2 = new import_core5.Matrix4().lookAt({ eye: [0, -altitude, 0], up: [0, 0, 1] }).rotateX(-pitchRadians).rotateY(-bearing * DEGREES_TO_RADIANS2).rotateX(latitude * DEGREES_TO_RADIANS2).rotateZ(-longitude * DEGREES_TO_RADIANS2).scale(scale / height);
|
|
1363
|
-
super({
|
|
1364
|
-
...opts,
|
|
1365
|
-
// x, y, width,
|
|
1366
|
-
height,
|
|
1367
|
-
// view matrix
|
|
1368
|
-
viewMatrix: viewMatrix2,
|
|
1369
|
-
longitude,
|
|
1370
|
-
latitude,
|
|
1371
|
-
zoom,
|
|
1372
|
-
// projection matrix parameters
|
|
1373
|
-
distanceScales: getDistanceScales2(),
|
|
1374
|
-
fovy,
|
|
1375
|
-
focalDistance: altitude,
|
|
1376
|
-
near: nearZ,
|
|
1377
|
-
far: farZ
|
|
1378
|
-
});
|
|
1379
|
-
this.scale = scale;
|
|
1380
|
-
this.latitude = latitude;
|
|
1381
|
-
this.longitude = longitude;
|
|
1382
|
-
this.bearing = bearing;
|
|
1383
|
-
this.pitch = pitch;
|
|
1384
|
-
this.fovy = fovy;
|
|
1385
|
-
this.resolution = resolution;
|
|
1386
|
-
}
|
|
1387
|
-
get projectionMode() {
|
|
1388
|
-
return PROJECTION_MODE.GLOBE;
|
|
1389
|
-
}
|
|
1390
|
-
getDistanceScales() {
|
|
1391
|
-
return this.distanceScales;
|
|
1392
|
-
}
|
|
1393
|
-
getBounds(options = {}) {
|
|
1394
|
-
const unprojectOption = { targetZ: options.z || 0 };
|
|
1395
|
-
const left = this.unproject([0, this.height / 2], unprojectOption);
|
|
1396
|
-
const top = this.unproject([this.width / 2, 0], unprojectOption);
|
|
1397
|
-
const right = this.unproject([this.width, this.height / 2], unprojectOption);
|
|
1398
|
-
const bottom = this.unproject([this.width / 2, this.height], unprojectOption);
|
|
1399
|
-
if (right[0] < this.longitude) right[0] += 360;
|
|
1400
|
-
if (left[0] > this.longitude) left[0] -= 360;
|
|
1401
|
-
return [
|
|
1402
|
-
Math.min(left[0], right[0], top[0], bottom[0]),
|
|
1403
|
-
Math.min(left[1], right[1], top[1], bottom[1]),
|
|
1404
|
-
Math.max(left[0], right[0], top[0], bottom[0]),
|
|
1405
|
-
Math.max(left[1], right[1], top[1], bottom[1])
|
|
1406
|
-
];
|
|
1407
|
-
}
|
|
1408
|
-
unproject(xyz, { topLeft = true, targetZ } = {}) {
|
|
1409
|
-
const [x, y, z] = xyz;
|
|
1410
|
-
const y2 = topLeft ? y : this.height - y;
|
|
1411
|
-
const { pixelUnprojectionMatrix } = this;
|
|
1412
|
-
let coord;
|
|
1413
|
-
if (Number.isFinite(z)) {
|
|
1414
|
-
coord = transformVector(pixelUnprojectionMatrix, [x, y2, z, 1]);
|
|
1415
|
-
} else {
|
|
1416
|
-
const coord0 = transformVector(pixelUnprojectionMatrix, [x, y2, -1, 1]);
|
|
1417
|
-
const coord1 = transformVector(pixelUnprojectionMatrix, [x, y2, 1, 1]);
|
|
1418
|
-
const lt = ((targetZ || 0) / EARTH_RADIUS + 1) * GLOBE_RADIUS;
|
|
1419
|
-
const lSqr = import_core6.vec3.sqrLen(import_core6.vec3.sub([], coord0, coord1));
|
|
1420
|
-
const l0Sqr = import_core6.vec3.sqrLen(coord0);
|
|
1421
|
-
const l1Sqr = import_core6.vec3.sqrLen(coord1);
|
|
1422
|
-
const sSqr = (4 * l0Sqr * l1Sqr - (lSqr - l0Sqr - l1Sqr) ** 2) / 16;
|
|
1423
|
-
const dSqr = 4 * sSqr / lSqr;
|
|
1424
|
-
const r0 = Math.sqrt(l0Sqr - dSqr);
|
|
1425
|
-
const dr = Math.sqrt(Math.max(0, lt * lt - dSqr));
|
|
1426
|
-
const t = (r0 - dr) / Math.sqrt(lSqr);
|
|
1427
|
-
coord = import_core6.vec3.lerp([], coord0, coord1, t);
|
|
1428
|
-
}
|
|
1429
|
-
const [X, Y, Z] = this.unprojectPosition(coord);
|
|
1430
|
-
if (Number.isFinite(z)) {
|
|
1431
|
-
return [X, Y, Z];
|
|
1432
|
-
}
|
|
1433
|
-
return Number.isFinite(targetZ) ? [X, Y, targetZ] : [X, Y];
|
|
1434
|
-
}
|
|
1435
|
-
projectPosition(xyz) {
|
|
1436
|
-
const [lng, lat, Z = 0] = xyz;
|
|
1437
|
-
const lambda = lng * DEGREES_TO_RADIANS2;
|
|
1438
|
-
const phi = lat * DEGREES_TO_RADIANS2;
|
|
1439
|
-
const cosPhi = Math.cos(phi);
|
|
1440
|
-
const D = (Z / EARTH_RADIUS + 1) * GLOBE_RADIUS;
|
|
1441
|
-
return [Math.sin(lambda) * cosPhi * D, -Math.cos(lambda) * cosPhi * D, Math.sin(phi) * D];
|
|
1442
|
-
}
|
|
1443
|
-
unprojectPosition(xyz) {
|
|
1444
|
-
const [x, y, z] = xyz;
|
|
1445
|
-
const D = import_core6.vec3.len(xyz);
|
|
1446
|
-
const phi = Math.asin(z / D);
|
|
1447
|
-
const lambda = Math.atan2(x, -y);
|
|
1448
|
-
const lng = lambda * RADIANS_TO_DEGREES;
|
|
1449
|
-
const lat = phi * RADIANS_TO_DEGREES;
|
|
1450
|
-
const Z = (D / GLOBE_RADIUS - 1) * EARTH_RADIUS;
|
|
1451
|
-
return [lng, lat, Z];
|
|
1452
|
-
}
|
|
1453
|
-
projectFlat(xyz) {
|
|
1454
|
-
return xyz;
|
|
1455
|
-
}
|
|
1456
|
-
unprojectFlat(xyz) {
|
|
1457
|
-
return xyz;
|
|
1458
|
-
}
|
|
1459
|
-
/**
|
|
1460
|
-
* Pan the globe using delta-based movement
|
|
1461
|
-
* @param coords - the geographic coordinates where the pan started
|
|
1462
|
-
* @param pixel - the current screen position
|
|
1463
|
-
* @param startPixel - the screen position where the pan started
|
|
1464
|
-
* @returns updated viewport options with new longitude/latitude
|
|
1465
|
-
*/
|
|
1466
|
-
panByPosition([startLng, startLat, startZoom], pixel, startPixel) {
|
|
1467
|
-
const scale = Math.pow(2, this.zoom - zoomAdjust(this.latitude));
|
|
1468
|
-
const rotationSpeed = 0.25 / scale;
|
|
1469
|
-
const longitude = startLng + rotationSpeed * (startPixel[0] - pixel[0]);
|
|
1470
|
-
let latitude = startLat - rotationSpeed * (startPixel[1] - pixel[1]);
|
|
1471
|
-
latitude = Math.max(Math.min(latitude, 90), -90);
|
|
1472
|
-
const out = { longitude, latitude, zoom: startZoom - zoomAdjust(startLat) };
|
|
1473
|
-
out.zoom += zoomAdjust(out.latitude);
|
|
1474
|
-
return out;
|
|
1475
|
-
}
|
|
1476
|
-
};
|
|
1477
|
-
GlobeViewport.displayName = "GlobeViewport";
|
|
1478
|
-
function zoomAdjust(latitude, clampToPoles) {
|
|
1479
|
-
if (clampToPoles) {
|
|
1480
|
-
latitude = Math.max(Math.min(latitude, import_web_mercator4.MAX_LATITUDE), -import_web_mercator4.MAX_LATITUDE);
|
|
1481
|
-
}
|
|
1482
|
-
const scaleAdjust = Math.PI * Math.cos(latitude * Math.PI / 180);
|
|
1483
|
-
return Math.log2(scaleAdjust);
|
|
1484
|
-
}
|
|
1485
|
-
function transformVector(matrix, vector) {
|
|
1486
|
-
const result = import_core6.vec4.transformMat4([], vector, matrix);
|
|
1487
|
-
import_core6.vec4.scale(result, result, 1 / result[3]);
|
|
1488
|
-
return result;
|
|
1489
|
-
}
|
|
1490
|
-
|
|
1491
|
-
// ../core/src/transitions/linear-interpolator.ts
|
|
1492
1322
|
var DEFAULT_PROPS = ["longitude", "latitude", "zoom", "bearing", "pitch"];
|
|
1493
1323
|
var DEFAULT_REQUIRED_PROPS = ["longitude", "latitude", "zoom"];
|
|
1494
1324
|
var LinearInterpolator = class extends TransitionInterpolator {
|
|
@@ -1515,28 +1345,23 @@ var LinearInterpolator = class extends TransitionInterpolator {
|
|
|
1515
1345
|
const result = super.initializeProps(startProps, endProps);
|
|
1516
1346
|
const { makeViewport, around } = this.opts;
|
|
1517
1347
|
if (makeViewport && around) {
|
|
1518
|
-
const
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
aroundPosition,
|
|
1529
|
-
width: endProps.width,
|
|
1530
|
-
height: endProps.height
|
|
1531
|
-
});
|
|
1532
|
-
}
|
|
1348
|
+
const startViewport = makeViewport(startProps);
|
|
1349
|
+
const endViewport = makeViewport(endProps);
|
|
1350
|
+
const aroundPosition = startViewport.unproject(around);
|
|
1351
|
+
result.start.around = around;
|
|
1352
|
+
Object.assign(result.end, {
|
|
1353
|
+
around: endViewport.project(aroundPosition),
|
|
1354
|
+
aroundPosition,
|
|
1355
|
+
width: endProps.width,
|
|
1356
|
+
height: endProps.height
|
|
1357
|
+
});
|
|
1533
1358
|
}
|
|
1534
1359
|
return result;
|
|
1535
1360
|
}
|
|
1536
1361
|
interpolateProps(startProps, endProps, t) {
|
|
1537
1362
|
const propsInTransition = {};
|
|
1538
1363
|
for (const key of this._propsToExtract) {
|
|
1539
|
-
propsInTransition[key] = (0,
|
|
1364
|
+
propsInTransition[key] = (0, import_core5.lerp)(startProps[key] || 0, endProps[key] || 0, t);
|
|
1540
1365
|
}
|
|
1541
1366
|
if (endProps.aroundPosition && this.opts.makeViewport) {
|
|
1542
1367
|
const viewport = this.opts.makeViewport({ ...endProps, ...propsInTransition });
|
|
@@ -1545,7 +1370,7 @@ var LinearInterpolator = class extends TransitionInterpolator {
|
|
|
1545
1370
|
viewport.panByPosition(
|
|
1546
1371
|
endProps.aroundPosition,
|
|
1547
1372
|
// anchor point in current screen coordinates
|
|
1548
|
-
(0,
|
|
1373
|
+
(0, import_core5.lerp)(startProps.around, endProps.around, t)
|
|
1549
1374
|
)
|
|
1550
1375
|
);
|
|
1551
1376
|
}
|
|
@@ -1554,6 +1379,7 @@ var LinearInterpolator = class extends TransitionInterpolator {
|
|
|
1554
1379
|
};
|
|
1555
1380
|
|
|
1556
1381
|
// ../core/src/controllers/controller.ts
|
|
1382
|
+
var import_web_mercator3 = require("@math.gl/web-mercator");
|
|
1557
1383
|
var NO_TRANSITION_PROPS = {
|
|
1558
1384
|
transitionDuration: 0
|
|
1559
1385
|
};
|
|
@@ -1602,6 +1428,7 @@ var Controller = class {
|
|
|
1602
1428
|
this.touchRotate = false;
|
|
1603
1429
|
this.multiTouchDrag = null;
|
|
1604
1430
|
this.trackpadGesture = false;
|
|
1431
|
+
this.zoomAround = "pointer";
|
|
1605
1432
|
this.keyboard = true;
|
|
1606
1433
|
this.transitionManager = new TransitionManager({
|
|
1607
1434
|
...opts,
|
|
@@ -1696,6 +1523,15 @@ var Controller = class {
|
|
|
1696
1523
|
const { offsetCenter } = event;
|
|
1697
1524
|
return [offsetCenter.x - x, offsetCenter.y - y];
|
|
1698
1525
|
}
|
|
1526
|
+
/** Resolves the zoom anchor for pointer-based controls. */
|
|
1527
|
+
getZoomPosition(position) {
|
|
1528
|
+
if (this.zoomAround === "pointer") {
|
|
1529
|
+
return position;
|
|
1530
|
+
}
|
|
1531
|
+
const viewport = this.makeViewport(this.controllerState.getViewportProps());
|
|
1532
|
+
const [centerX, centerY] = (0, import_web_mercator3.worldToPixels)(viewport.center, viewport.pixelProjectionMatrix);
|
|
1533
|
+
return [centerX, centerY];
|
|
1534
|
+
}
|
|
1699
1535
|
isPointInBounds(pos, event) {
|
|
1700
1536
|
const { width, height } = this.props;
|
|
1701
1537
|
if (event && event.handled) {
|
|
@@ -1753,6 +1589,7 @@ var Controller = class {
|
|
|
1753
1589
|
touchRotate = false,
|
|
1754
1590
|
multiTouchDrag = touchRotate ? "rotate" : null,
|
|
1755
1591
|
trackpadGesture = false,
|
|
1592
|
+
zoomAround = "pointer",
|
|
1756
1593
|
keyboard = true
|
|
1757
1594
|
} = props;
|
|
1758
1595
|
const isInteractive = Boolean(this.onViewStateChange);
|
|
@@ -1775,6 +1612,7 @@ var Controller = class {
|
|
|
1775
1612
|
this.touchRotate = multiTouchDrag === "rotate";
|
|
1776
1613
|
this.multiTouchDrag = multiTouchDrag;
|
|
1777
1614
|
this.trackpadGesture = trackpadGesture;
|
|
1615
|
+
this.zoomAround = zoomAround;
|
|
1778
1616
|
this.keyboard = keyboard;
|
|
1779
1617
|
const constraintChanged = !oldProps || oldProps.height !== props.height || oldProps.width !== props.width || oldProps.maxBounds !== props.maxBounds || oldProps.maxBoundsPadding !== props.maxBoundsPadding;
|
|
1780
1618
|
if (constraintChanged && props.maxBounds) {
|
|
@@ -2008,8 +1846,9 @@ var Controller = class {
|
|
|
2008
1846
|
if (delta < 0 && scale !== 0) {
|
|
2009
1847
|
scale = 1 / scale;
|
|
2010
1848
|
}
|
|
2011
|
-
const
|
|
2012
|
-
const
|
|
1849
|
+
const zoomPosition = this.getZoomPosition(pos);
|
|
1850
|
+
const transitionProps = smooth ? { ...this._getTransitionProps({ around: zoomPosition }), transitionDuration: 250 } : NO_TRANSITION_PROPS;
|
|
1851
|
+
const newControllerState = this.controllerState.zoom({ pos: zoomPosition, scale });
|
|
2013
1852
|
this.updateViewport(newControllerState, transitionProps, {
|
|
2014
1853
|
isZooming: true,
|
|
2015
1854
|
isPanning: true
|
|
@@ -2095,7 +1934,7 @@ var Controller = class {
|
|
|
2095
1934
|
if (!this.isPointInBounds(pos, event)) {
|
|
2096
1935
|
return false;
|
|
2097
1936
|
}
|
|
2098
|
-
const newControllerState = this.controllerState.zoomStart({ pos }, this._getConstraintContext("zoom", "start")).rotateStart({ pos }, this._getConstraintContext("rotate", "start"));
|
|
1937
|
+
const newControllerState = this.controllerState.zoomStart({ pos: this.getZoomPosition(pos) }, this._getConstraintContext("zoom", "start")).rotateStart({ pos }, this._getConstraintContext("rotate", "start"));
|
|
2099
1938
|
pinchEventWorkaround._startPinchRotation = event.rotation;
|
|
2100
1939
|
pinchEventWorkaround._lastPinchEvent = event;
|
|
2101
1940
|
this.updateViewport(newControllerState, NO_TRANSITION_PROPS, { isDragging: true });
|
|
@@ -2114,7 +1953,7 @@ var Controller = class {
|
|
|
2114
1953
|
const { scale } = event;
|
|
2115
1954
|
const pos = this.getCenter(event);
|
|
2116
1955
|
newControllerState = newControllerState.zoom(
|
|
2117
|
-
{ pos, scale },
|
|
1956
|
+
{ pos: this.getZoomPosition(pos), scale },
|
|
2118
1957
|
this._getConstraintContext("zoom", "update")
|
|
2119
1958
|
);
|
|
2120
1959
|
}
|
|
@@ -2142,15 +1981,16 @@ var Controller = class {
|
|
|
2142
1981
|
const { _lastPinchEvent } = pinchEventWorkaround;
|
|
2143
1982
|
if (this.touchZoom && inertia && _lastPinchEvent && event.scale !== _lastPinchEvent.scale) {
|
|
2144
1983
|
const pos = this.getCenter(event);
|
|
1984
|
+
const zoomPosition = this.getZoomPosition(pos);
|
|
2145
1985
|
let newControllerState = this.controllerState.rotateEnd();
|
|
2146
1986
|
const z = Math.log2(event.scale);
|
|
2147
1987
|
const velocityZ = (z - Math.log2(_lastPinchEvent.scale)) / (event.deltaTime - _lastPinchEvent.deltaTime);
|
|
2148
1988
|
const endScale = Math.pow(2, z + velocityZ * inertia / 2);
|
|
2149
|
-
newControllerState = newControllerState.zoom({ pos, scale: endScale }).zoomEnd();
|
|
1989
|
+
newControllerState = newControllerState.zoom({ pos: zoomPosition, scale: endScale }).zoomEnd();
|
|
2150
1990
|
this.updateViewport(
|
|
2151
1991
|
newControllerState,
|
|
2152
1992
|
{
|
|
2153
|
-
...this._getTransitionProps({ around:
|
|
1993
|
+
...this._getTransitionProps({ around: zoomPosition }),
|
|
2154
1994
|
transitionDuration: inertia,
|
|
2155
1995
|
transitionEasing: INERTIA_EASING
|
|
2156
1996
|
},
|
|
@@ -2195,8 +2035,12 @@ var Controller = class {
|
|
|
2195
2035
|
return false;
|
|
2196
2036
|
}
|
|
2197
2037
|
const isZoomOut = this.isFunctionKeyPressed(event);
|
|
2198
|
-
const
|
|
2199
|
-
|
|
2038
|
+
const zoomPosition = this.getZoomPosition(pos);
|
|
2039
|
+
const newControllerState = this.controllerState.zoom({
|
|
2040
|
+
pos: zoomPosition,
|
|
2041
|
+
scale: isZoomOut ? 0.5 : 2
|
|
2042
|
+
});
|
|
2043
|
+
this.updateViewport(newControllerState, this._getTransitionProps({ around: zoomPosition }), {
|
|
2200
2044
|
isZooming: true,
|
|
2201
2045
|
isPanning: true
|
|
2202
2046
|
});
|
|
@@ -2213,14 +2057,14 @@ var Controller = class {
|
|
|
2213
2057
|
this._doubleClickDragAnchor = null;
|
|
2214
2058
|
return false;
|
|
2215
2059
|
}
|
|
2216
|
-
this._doubleClickDragAnchor = pos;
|
|
2060
|
+
this._doubleClickDragAnchor = this.getZoomPosition(pos);
|
|
2217
2061
|
let newControllerState = this.controllerState.zoomStart(
|
|
2218
|
-
{ pos },
|
|
2062
|
+
{ pos: this._doubleClickDragAnchor },
|
|
2219
2063
|
this._getConstraintContext("zoom", "start")
|
|
2220
2064
|
);
|
|
2221
2065
|
if (event.scale !== 1) {
|
|
2222
2066
|
newControllerState = newControllerState.zoom(
|
|
2223
|
-
{ pos, scale: event.scale },
|
|
2067
|
+
{ pos: this._doubleClickDragAnchor, scale: event.scale },
|
|
2224
2068
|
this._getConstraintContext("zoom", "update")
|
|
2225
2069
|
);
|
|
2226
2070
|
}
|
|
@@ -2528,10 +2372,279 @@ Widget.defaultProps = {
|
|
|
2528
2372
|
className: ""
|
|
2529
2373
|
};
|
|
2530
2374
|
|
|
2375
|
+
// ../core/src/viewports/globe-viewport.ts
|
|
2376
|
+
var import_core6 = require("@math.gl/core");
|
|
2377
|
+
var import_web_mercator4 = require("@math.gl/web-mercator");
|
|
2378
|
+
var DEGREES_TO_RADIANS2 = Math.PI / 180;
|
|
2379
|
+
var RADIANS_TO_DEGREES = 180 / Math.PI;
|
|
2380
|
+
var NORTH_UP_BEARING_THRESHOLD = 1;
|
|
2381
|
+
var EARTH_RADIUS = 6370972;
|
|
2382
|
+
var GLOBE_RADIUS = 256;
|
|
2383
|
+
var GLOBE_ZOOM_ANCHOR_DAMPING_START_RATIO = 0.75;
|
|
2384
|
+
var GLOBE_ZOOM_ANCHOR_MAX_DISTANCE_RATIO = 1.15;
|
|
2385
|
+
function isGlobeNorthUp(bearing) {
|
|
2386
|
+
const normalizedBearing = mod(bearing + 180, 360) - 180;
|
|
2387
|
+
return Math.abs(normalizedBearing) < NORTH_UP_BEARING_THRESHOLD;
|
|
2388
|
+
}
|
|
2389
|
+
function getDistanceScales2() {
|
|
2390
|
+
const unitsPerMeter2 = GLOBE_RADIUS / EARTH_RADIUS;
|
|
2391
|
+
const unitsPerDegree = Math.PI / 180 * GLOBE_RADIUS;
|
|
2392
|
+
return {
|
|
2393
|
+
unitsPerMeter: [unitsPerMeter2, unitsPerMeter2, unitsPerMeter2],
|
|
2394
|
+
unitsPerMeter2: [0, 0, 0],
|
|
2395
|
+
metersPerUnit: [1 / unitsPerMeter2, 1 / unitsPerMeter2, 1 / unitsPerMeter2],
|
|
2396
|
+
unitsPerDegree: [unitsPerDegree, unitsPerDegree, unitsPerMeter2],
|
|
2397
|
+
unitsPerDegree2: [0, 0, 0],
|
|
2398
|
+
degreesPerUnit: [1 / unitsPerDegree, 1 / unitsPerDegree, 1 / unitsPerMeter2]
|
|
2399
|
+
};
|
|
2400
|
+
}
|
|
2401
|
+
var GlobeViewport = class extends Viewport {
|
|
2402
|
+
constructor(opts = {}) {
|
|
2403
|
+
const {
|
|
2404
|
+
longitude = 0,
|
|
2405
|
+
bearing = 0,
|
|
2406
|
+
pitch = 0,
|
|
2407
|
+
zoom = 0,
|
|
2408
|
+
// Matches Maplibre defaults
|
|
2409
|
+
// https://github.com/maplibre/maplibre-gl-js/blob/f8ab4b48d59ab8fe7b068b102538793bbdd4c848/src/geo/projection/globe_transform.ts#L632-L633
|
|
2410
|
+
nearZMultiplier = 0.5,
|
|
2411
|
+
farZMultiplier = 1,
|
|
2412
|
+
resolution = 10
|
|
2413
|
+
} = opts;
|
|
2414
|
+
let { latitude = 0, height, altitude = 1.5, fovy } = opts;
|
|
2415
|
+
latitude = Math.max(Math.min(latitude, 90), -90);
|
|
2416
|
+
height = height || 1;
|
|
2417
|
+
if (fovy) {
|
|
2418
|
+
altitude = (0, import_web_mercator4.fovyToAltitude)(fovy);
|
|
2419
|
+
} else {
|
|
2420
|
+
fovy = (0, import_web_mercator4.altitudeToFovy)(altitude);
|
|
2421
|
+
}
|
|
2422
|
+
const scaleLatitude = Math.max(Math.min(latitude, import_web_mercator4.MAX_LATITUDE), -import_web_mercator4.MAX_LATITUDE);
|
|
2423
|
+
const scale = Math.pow(2, zoom - zoomAdjust(scaleLatitude));
|
|
2424
|
+
const pitchRadians = pitch * DEGREES_TO_RADIANS2;
|
|
2425
|
+
const nearZ = opts.nearZ ?? nearZMultiplier;
|
|
2426
|
+
const farZ = opts.farZ ?? (altitude + GLOBE_RADIUS * 2 * scale / height / Math.max(Math.cos(pitchRadians), 0.1)) * farZMultiplier;
|
|
2427
|
+
const viewMatrix2 = new import_core6.Matrix4().lookAt({ eye: [0, -altitude, 0], up: [0, 0, 1] }).rotateX(-pitchRadians).rotateY(-bearing * DEGREES_TO_RADIANS2).rotateX(latitude * DEGREES_TO_RADIANS2).rotateZ(-longitude * DEGREES_TO_RADIANS2).scale(scale / height);
|
|
2428
|
+
super({
|
|
2429
|
+
...opts,
|
|
2430
|
+
// x, y, width,
|
|
2431
|
+
height,
|
|
2432
|
+
// view matrix
|
|
2433
|
+
viewMatrix: viewMatrix2,
|
|
2434
|
+
longitude,
|
|
2435
|
+
latitude,
|
|
2436
|
+
zoom,
|
|
2437
|
+
// projection matrix parameters
|
|
2438
|
+
distanceScales: getDistanceScales2(),
|
|
2439
|
+
fovy,
|
|
2440
|
+
focalDistance: altitude,
|
|
2441
|
+
near: nearZ,
|
|
2442
|
+
far: farZ
|
|
2443
|
+
});
|
|
2444
|
+
this.scale = scale;
|
|
2445
|
+
this.latitude = latitude;
|
|
2446
|
+
this.longitude = longitude;
|
|
2447
|
+
this.bearing = bearing;
|
|
2448
|
+
this.pitch = pitch;
|
|
2449
|
+
this.fovy = fovy;
|
|
2450
|
+
this.resolution = resolution;
|
|
2451
|
+
}
|
|
2452
|
+
get projectionMode() {
|
|
2453
|
+
return PROJECTION_MODE.GLOBE;
|
|
2454
|
+
}
|
|
2455
|
+
getDistanceScales() {
|
|
2456
|
+
return this.distanceScales;
|
|
2457
|
+
}
|
|
2458
|
+
getBounds(options = {}) {
|
|
2459
|
+
const unprojectOption = { targetZ: options.z || 0 };
|
|
2460
|
+
const left = this.unproject([0, this.height / 2], unprojectOption);
|
|
2461
|
+
const top = this.unproject([this.width / 2, 0], unprojectOption);
|
|
2462
|
+
const right = this.unproject([this.width, this.height / 2], unprojectOption);
|
|
2463
|
+
const bottom = this.unproject([this.width / 2, this.height], unprojectOption);
|
|
2464
|
+
if (right[0] < this.longitude) right[0] += 360;
|
|
2465
|
+
if (left[0] > this.longitude) left[0] -= 360;
|
|
2466
|
+
return [
|
|
2467
|
+
Math.min(left[0], right[0], top[0], bottom[0]),
|
|
2468
|
+
Math.min(left[1], right[1], top[1], bottom[1]),
|
|
2469
|
+
Math.max(left[0], right[0], top[0], bottom[0]),
|
|
2470
|
+
Math.max(left[1], right[1], top[1], bottom[1])
|
|
2471
|
+
];
|
|
2472
|
+
}
|
|
2473
|
+
/**
|
|
2474
|
+
* Builds the screen-pixel → globe-center ray and the intermediate ray/sphere
|
|
2475
|
+
* math reused by `unproject` and anchored zoom. One function so the same
|
|
2476
|
+
* pixelUnprojectionMatrix work isn't duplicated.
|
|
2477
|
+
*/
|
|
2478
|
+
_getRayToGlobe(screenPosition, { topLeft = true, targetZ } = {}) {
|
|
2479
|
+
const [screenX, screenY] = screenPosition;
|
|
2480
|
+
const adjustedScreenY = topLeft ? screenY : this.height - screenY;
|
|
2481
|
+
const { pixelUnprojectionMatrix } = this;
|
|
2482
|
+
const rayStartPosition = transformVector(pixelUnprojectionMatrix, [
|
|
2483
|
+
screenX,
|
|
2484
|
+
adjustedScreenY,
|
|
2485
|
+
-1,
|
|
2486
|
+
1
|
|
2487
|
+
]);
|
|
2488
|
+
const rayEndPosition = transformVector(pixelUnprojectionMatrix, [
|
|
2489
|
+
screenX,
|
|
2490
|
+
adjustedScreenY,
|
|
2491
|
+
1,
|
|
2492
|
+
1
|
|
2493
|
+
]);
|
|
2494
|
+
const radius = ((targetZ || 0) / EARTH_RADIUS + 1) * GLOBE_RADIUS;
|
|
2495
|
+
const rayLengthSquared = import_core6.vec3.sqrLen(import_core6.vec3.sub([], rayStartPosition, rayEndPosition));
|
|
2496
|
+
const rayStartDistanceSquared = import_core6.vec3.sqrLen(rayStartPosition);
|
|
2497
|
+
const rayEndDistanceSquared = import_core6.vec3.sqrLen(rayEndPosition);
|
|
2498
|
+
const triangleAreaSquared = (4 * rayStartDistanceSquared * rayEndDistanceSquared - (rayLengthSquared - rayStartDistanceSquared - rayEndDistanceSquared) ** 2) / 16;
|
|
2499
|
+
const distanceToCenterSquared = 4 * triangleAreaSquared / rayLengthSquared;
|
|
2500
|
+
return {
|
|
2501
|
+
rayStartPosition,
|
|
2502
|
+
rayEndPosition,
|
|
2503
|
+
radius,
|
|
2504
|
+
rayLengthSquared,
|
|
2505
|
+
rayStartDistanceSquared,
|
|
2506
|
+
distanceToCenterSquared
|
|
2507
|
+
};
|
|
2508
|
+
}
|
|
2509
|
+
_getRayDistanceToGlobeCenterRatio(screenPosition, options) {
|
|
2510
|
+
const { distanceToCenterSquared, radius } = this._getRayToGlobe(screenPosition, options);
|
|
2511
|
+
return Math.sqrt(Math.max(0, distanceToCenterSquared)) / radius;
|
|
2512
|
+
}
|
|
2513
|
+
/**
|
|
2514
|
+
* Returns how strongly a screen position should anchor zoom on the visible globe.
|
|
2515
|
+
* A value of `0` means that the controller should fall back to center zoom.
|
|
2516
|
+
* @param screenPosition - Screen position to evaluate.
|
|
2517
|
+
* @returns Anchor strength from `0` to `1`.
|
|
2518
|
+
*/
|
|
2519
|
+
getZoomAnchorStrength(screenPosition) {
|
|
2520
|
+
const distanceRatio = this._getRayDistanceToGlobeCenterRatio(screenPosition);
|
|
2521
|
+
if (distanceRatio >= GLOBE_ZOOM_ANCHOR_MAX_DISTANCE_RATIO) {
|
|
2522
|
+
return 0;
|
|
2523
|
+
}
|
|
2524
|
+
const edgeProgress = Math.max(
|
|
2525
|
+
0,
|
|
2526
|
+
Math.min(
|
|
2527
|
+
1,
|
|
2528
|
+
(distanceRatio - GLOBE_ZOOM_ANCHOR_DAMPING_START_RATIO) / (GLOBE_ZOOM_ANCHOR_MAX_DISTANCE_RATIO - GLOBE_ZOOM_ANCHOR_DAMPING_START_RATIO)
|
|
2529
|
+
)
|
|
2530
|
+
);
|
|
2531
|
+
const smoothProgress = edgeProgress * edgeProgress * (3 - 2 * edgeProgress);
|
|
2532
|
+
return 1 - smoothProgress;
|
|
2533
|
+
}
|
|
2534
|
+
unproject(xyz, { topLeft = true, targetZ } = {}) {
|
|
2535
|
+
const [x, y, z] = xyz;
|
|
2536
|
+
const y2 = topLeft ? y : this.height - y;
|
|
2537
|
+
const { pixelUnprojectionMatrix } = this;
|
|
2538
|
+
let coord;
|
|
2539
|
+
if (Number.isFinite(z)) {
|
|
2540
|
+
coord = transformVector(pixelUnprojectionMatrix, [x, y2, z, 1]);
|
|
2541
|
+
} else {
|
|
2542
|
+
const {
|
|
2543
|
+
rayStartPosition,
|
|
2544
|
+
rayEndPosition,
|
|
2545
|
+
radius,
|
|
2546
|
+
rayLengthSquared,
|
|
2547
|
+
rayStartDistanceSquared,
|
|
2548
|
+
distanceToCenterSquared
|
|
2549
|
+
} = this._getRayToGlobe(xyz, { topLeft, targetZ });
|
|
2550
|
+
const rayStartToClosestApproach = Math.sqrt(
|
|
2551
|
+
rayStartDistanceSquared - distanceToCenterSquared
|
|
2552
|
+
);
|
|
2553
|
+
const closestApproachToIntersection = Math.sqrt(
|
|
2554
|
+
Math.max(0, radius * radius - distanceToCenterSquared)
|
|
2555
|
+
);
|
|
2556
|
+
const intersectionRatio = (rayStartToClosestApproach - closestApproachToIntersection) / Math.sqrt(rayLengthSquared);
|
|
2557
|
+
coord = import_core6.vec3.lerp([], rayStartPosition, rayEndPosition, intersectionRatio);
|
|
2558
|
+
}
|
|
2559
|
+
const [X, Y, Z] = this.unprojectPosition(coord);
|
|
2560
|
+
if (Number.isFinite(z)) {
|
|
2561
|
+
return [X, Y, Z];
|
|
2562
|
+
}
|
|
2563
|
+
return Number.isFinite(targetZ) ? [X, Y, targetZ] : [X, Y];
|
|
2564
|
+
}
|
|
2565
|
+
projectPosition(xyz) {
|
|
2566
|
+
const [lng, lat, Z = 0] = xyz;
|
|
2567
|
+
const lambda = lng * DEGREES_TO_RADIANS2;
|
|
2568
|
+
const phi = lat * DEGREES_TO_RADIANS2;
|
|
2569
|
+
const cosPhi = Math.cos(phi);
|
|
2570
|
+
const D = (Z / EARTH_RADIUS + 1) * GLOBE_RADIUS;
|
|
2571
|
+
return [Math.sin(lambda) * cosPhi * D, -Math.cos(lambda) * cosPhi * D, Math.sin(phi) * D];
|
|
2572
|
+
}
|
|
2573
|
+
unprojectPosition(xyz) {
|
|
2574
|
+
const [x, y, z] = xyz;
|
|
2575
|
+
const D = import_core6.vec3.len(xyz);
|
|
2576
|
+
const phi = Math.asin(z / D);
|
|
2577
|
+
const lambda = Math.atan2(x, -y);
|
|
2578
|
+
const lng = lambda * RADIANS_TO_DEGREES;
|
|
2579
|
+
const lat = phi * RADIANS_TO_DEGREES;
|
|
2580
|
+
const Z = (D / GLOBE_RADIUS - 1) * EARTH_RADIUS;
|
|
2581
|
+
return [lng, lat, Z];
|
|
2582
|
+
}
|
|
2583
|
+
projectFlat(xyz) {
|
|
2584
|
+
return xyz;
|
|
2585
|
+
}
|
|
2586
|
+
unprojectFlat(xyz) {
|
|
2587
|
+
return xyz;
|
|
2588
|
+
}
|
|
2589
|
+
/**
|
|
2590
|
+
* Pan the globe to place geographic coordinates at a screen pixel.
|
|
2591
|
+
* When `dragStartPosition` is supplied, applies the delta-based movement used by globe dragging.
|
|
2592
|
+
* @param coordinates - Geographic anchor, or the starting longitude, latitude and zoom.
|
|
2593
|
+
* @param screenPosition - Current screen position.
|
|
2594
|
+
* @param dragStartPosition - Screen position where a drag started.
|
|
2595
|
+
* @returns Updated viewport options.
|
|
2596
|
+
*/
|
|
2597
|
+
panByPosition(coordinates, screenPosition, dragStartPosition) {
|
|
2598
|
+
if (!dragStartPosition) {
|
|
2599
|
+
let anchorStrength = this.getZoomAnchorStrength(screenPosition);
|
|
2600
|
+
if (anchorStrength === 0) {
|
|
2601
|
+
return { longitude: this.longitude, latitude: this.latitude };
|
|
2602
|
+
}
|
|
2603
|
+
const currentCoordinates = this.unproject(screenPosition);
|
|
2604
|
+
const longitudeDelta = mod(coordinates[0] - currentCoordinates[0] + 180, 360) - 180;
|
|
2605
|
+
const latitudeDelta = coordinates[1] - currentCoordinates[1];
|
|
2606
|
+
const crossesPole = Math.abs(currentCoordinates[1]) > import_web_mercator4.MAX_LATITUDE || Math.abs(longitudeDelta) > 90;
|
|
2607
|
+
if (isGlobeNorthUp(this.bearing) && crossesPole) {
|
|
2608
|
+
return { longitude: this.longitude, latitude: this.latitude };
|
|
2609
|
+
}
|
|
2610
|
+
if (isGlobeNorthUp(this.bearing) && latitudeDelta !== 0) {
|
|
2611
|
+
const latitudeLimit = latitudeDelta > 0 ? import_web_mercator4.MAX_LATITUDE : -import_web_mercator4.MAX_LATITUDE;
|
|
2612
|
+
const latitudeConstraintStrength = (latitudeLimit - this.latitude) / latitudeDelta;
|
|
2613
|
+
anchorStrength = Math.min(anchorStrength, Math.max(0, latitudeConstraintStrength));
|
|
2614
|
+
}
|
|
2615
|
+
const longitude2 = this.longitude + longitudeDelta * anchorStrength;
|
|
2616
|
+
const latitude2 = Math.max(Math.min(this.latitude + latitudeDelta * anchorStrength, 90), -90);
|
|
2617
|
+
return { longitude: longitude2, latitude: latitude2 };
|
|
2618
|
+
}
|
|
2619
|
+
const [startLongitude, startLatitude, startZoom] = coordinates;
|
|
2620
|
+
const scale = Math.pow(2, this.zoom - zoomAdjust(this.latitude));
|
|
2621
|
+
const rotationSpeed = 0.25 / scale;
|
|
2622
|
+
const longitude = startLongitude + rotationSpeed * (dragStartPosition[0] - screenPosition[0]);
|
|
2623
|
+
let latitude = startLatitude - rotationSpeed * (dragStartPosition[1] - screenPosition[1]);
|
|
2624
|
+
latitude = Math.max(Math.min(latitude, 90), -90);
|
|
2625
|
+
const nextViewState = { longitude, latitude, zoom: startZoom - zoomAdjust(startLatitude) };
|
|
2626
|
+
nextViewState.zoom += zoomAdjust(nextViewState.latitude);
|
|
2627
|
+
return nextViewState;
|
|
2628
|
+
}
|
|
2629
|
+
};
|
|
2630
|
+
GlobeViewport.displayName = "GlobeViewport";
|
|
2631
|
+
function zoomAdjust(latitude, clampToPoles) {
|
|
2632
|
+
if (clampToPoles) {
|
|
2633
|
+
latitude = Math.max(Math.min(latitude, import_web_mercator4.MAX_LATITUDE), -import_web_mercator4.MAX_LATITUDE);
|
|
2634
|
+
}
|
|
2635
|
+
const scaleAdjust = Math.PI * Math.cos(latitude * Math.PI / 180);
|
|
2636
|
+
return Math.log2(scaleAdjust);
|
|
2637
|
+
}
|
|
2638
|
+
function transformVector(matrix, vector) {
|
|
2639
|
+
const result = import_core6.vec4.transformMat4([], vector, matrix);
|
|
2640
|
+
import_core6.vec4.scale(result, result, 1 / result[3]);
|
|
2641
|
+
return result;
|
|
2642
|
+
}
|
|
2643
|
+
|
|
2531
2644
|
// ../core/src/viewports/orthographic-viewport.ts
|
|
2532
|
-
var
|
|
2645
|
+
var import_core7 = require("@math.gl/core");
|
|
2533
2646
|
var import_web_mercator5 = require("@math.gl/web-mercator");
|
|
2534
|
-
var viewMatrix = new
|
|
2647
|
+
var viewMatrix = new import_core7.Matrix4().lookAt({ eye: [0, 0, 1] });
|
|
2535
2648
|
function getProjectionMatrix({
|
|
2536
2649
|
width,
|
|
2537
2650
|
height,
|
|
@@ -2545,14 +2658,14 @@ function getProjectionMatrix({
|
|
|
2545
2658
|
let top = height / 2;
|
|
2546
2659
|
if (padding) {
|
|
2547
2660
|
const { left: l = 0, right: r = 0, top: t = 0, bottom: b = 0 } = padding;
|
|
2548
|
-
const offsetX = (0,
|
|
2549
|
-
const offsetY = (0,
|
|
2661
|
+
const offsetX = (0, import_core7.clamp)((l + width - r) / 2, 0, width) - width / 2;
|
|
2662
|
+
const offsetY = (0, import_core7.clamp)((t + height - b) / 2, 0, height) - height / 2;
|
|
2550
2663
|
left -= offsetX;
|
|
2551
2664
|
right -= offsetX;
|
|
2552
2665
|
bottom += offsetY;
|
|
2553
2666
|
top += offsetY;
|
|
2554
2667
|
}
|
|
2555
|
-
return new
|
|
2668
|
+
return new import_core7.Matrix4().ortho({
|
|
2556
2669
|
left,
|
|
2557
2670
|
right,
|
|
2558
2671
|
bottom,
|
|
@@ -2620,15 +2733,15 @@ var OrthographicViewport = class extends Viewport {
|
|
|
2620
2733
|
panByPosition(coords, pixel, startPixel) {
|
|
2621
2734
|
const fromLocation = (0, import_web_mercator5.pixelsToWorld)(pixel, this.pixelUnprojectionMatrix);
|
|
2622
2735
|
const toLocation = this.projectFlat(coords);
|
|
2623
|
-
const translate =
|
|
2624
|
-
const newCenter =
|
|
2736
|
+
const translate = import_core7.vec2.add([], toLocation, import_core7.vec2.negate([], fromLocation));
|
|
2737
|
+
const newCenter = import_core7.vec2.add([], this.center, translate);
|
|
2625
2738
|
return { target: this.unprojectFlat(newCenter) };
|
|
2626
2739
|
}
|
|
2627
2740
|
};
|
|
2628
2741
|
OrthographicViewport.displayName = "OrthographicViewport";
|
|
2629
2742
|
|
|
2630
2743
|
// ../core/src/controllers/orthographic-controller.ts
|
|
2631
|
-
var
|
|
2744
|
+
var import_core8 = require("@math.gl/core");
|
|
2632
2745
|
var ZOOM_RUBBER_BAND_RANGE = 1;
|
|
2633
2746
|
function normalizeZoom({
|
|
2634
2747
|
zoom = 0,
|
|
@@ -2647,7 +2760,7 @@ function getAxisBounds(maxBounds, index, negativeExtent, positiveExtent, target)
|
|
|
2647
2760
|
minimum,
|
|
2648
2761
|
maximum,
|
|
2649
2762
|
midpoint,
|
|
2650
|
-
settledTarget: Number.isFinite(negativeExtent) && Number.isFinite(positiveExtent) && minimum <= maximum ? (0,
|
|
2763
|
+
settledTarget: Number.isFinite(negativeExtent) && Number.isFinite(positiveExtent) && minimum <= maximum ? (0, import_core8.clamp)(target, minimum, maximum) : midpoint
|
|
2651
2764
|
};
|
|
2652
2765
|
}
|
|
2653
2766
|
var OrthographicState = class extends ViewState {
|
|
@@ -2965,7 +3078,7 @@ var OrthographicState = class extends ViewState {
|
|
|
2965
3078
|
constrainedTarget[index] = midpoint;
|
|
2966
3079
|
continue;
|
|
2967
3080
|
}
|
|
2968
|
-
const constrained = rubberBand ? settledTarget : (0,
|
|
3081
|
+
const constrained = rubberBand ? settledTarget : (0, import_core8.clamp)(target[index], minimum, maximum);
|
|
2969
3082
|
constrainedTarget[index] = (constraintContext == null ? void 0 : constraintContext.mode) === "preserve" ? target[index] : shouldRubberBand ? applyRubberBand(
|
|
2970
3083
|
target[index],
|
|
2971
3084
|
constrained,
|
|
@@ -3000,10 +3113,10 @@ var OrthographicState = class extends ViewState {
|
|
|
3000
3113
|
}
|
|
3001
3114
|
switch (zoomAxis) {
|
|
3002
3115
|
case "X":
|
|
3003
|
-
zoomX = (0,
|
|
3116
|
+
zoomX = (0, import_core8.clamp)(zoomX, minZoomX, maxZoomX);
|
|
3004
3117
|
break;
|
|
3005
3118
|
case "Y":
|
|
3006
|
-
zoomY = (0,
|
|
3119
|
+
zoomY = (0, import_core8.clamp)(zoomY, minZoomY, maxZoomY);
|
|
3007
3120
|
break;
|
|
3008
3121
|
default:
|
|
3009
3122
|
let delta = Math.min(maxZoomX - zoomX, maxZoomY - zoomY, 0);
|
|
@@ -3055,7 +3168,7 @@ var OrthographicView = class extends View {
|
|
|
3055
3168
|
OrthographicView.displayName = "OrthographicView";
|
|
3056
3169
|
|
|
3057
3170
|
// ../core/src/transitions/fly-to-interpolator.ts
|
|
3058
|
-
var
|
|
3171
|
+
var import_core9 = require("@math.gl/core");
|
|
3059
3172
|
var import_web_mercator6 = require("@math.gl/web-mercator");
|
|
3060
3173
|
var LINEARLY_INTERPOLATED_PROPS = {
|
|
3061
3174
|
bearing: 0,
|
|
@@ -3078,7 +3191,7 @@ var FlyToInterpolator = class extends TransitionInterpolator {
|
|
|
3078
3191
|
interpolateProps(startProps, endProps, t) {
|
|
3079
3192
|
const viewport = (0, import_web_mercator6.flyToViewport)(startProps, endProps, t, this.opts);
|
|
3080
3193
|
for (const key in LINEARLY_INTERPOLATED_PROPS) {
|
|
3081
|
-
viewport[key] = (0,
|
|
3194
|
+
viewport[key] = (0, import_core9.lerp)(
|
|
3082
3195
|
startProps[key] || LINEARLY_INTERPOLATED_PROPS[key],
|
|
3083
3196
|
endProps[key] || LINEARLY_INTERPOLATED_PROPS[key],
|
|
3084
3197
|
t
|
|
@@ -6188,7 +6301,7 @@ LoadingWidget.defaultProps = {
|
|
|
6188
6301
|
|
|
6189
6302
|
// dist/stats-widget.js
|
|
6190
6303
|
var import_jsx_runtime27 = require("preact/jsx-runtime");
|
|
6191
|
-
var
|
|
6304
|
+
var import_core33 = require("@luma.gl/core");
|
|
6192
6305
|
var import_preact20 = require("preact");
|
|
6193
6306
|
var import_hooks8 = require("preact/hooks");
|
|
6194
6307
|
var DEFAULT_COUNT_FORMATTER = (stat) => `${stat.name}: ${stat.count}`;
|
|
@@ -6296,7 +6409,7 @@ var StatsWidget = class extends Widget {
|
|
|
6296
6409
|
const metrics = ((_a = this.deck) == null ? void 0 : _a.metrics) ?? {};
|
|
6297
6410
|
return Object.entries(metrics);
|
|
6298
6411
|
case "luma":
|
|
6299
|
-
return Array.from(
|
|
6412
|
+
return Array.from(import_core33.luma.stats.stats.values())[0];
|
|
6300
6413
|
case "device":
|
|
6301
6414
|
const device = (_b = this.deck) == null ? void 0 : _b.device;
|
|
6302
6415
|
const stats = device == null ? void 0 : device.statsManager.stats.values();
|