@guardian/interactive-component-library 0.1.0-alpha.43 → 0.1.0-alpha.44

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.
@@ -145,10 +145,10 @@ const LegendItem = ({
145
145
  })]
146
146
  });
147
147
  };
148
- const bar$2 = "_bar_1jxh9_1";
149
- const label$1 = "_label_1jxh9_5";
150
- const labelStroke = "_labelStroke_1jxh9_11";
151
- const backgroundRect = "_backgroundRect_1jxh9_17";
148
+ const bar$2 = "_bar_1b3uz_1";
149
+ const label$1 = "_label_1b3uz_5";
150
+ const labelStroke = "_labelStroke_1b3uz_12";
151
+ const backgroundRect = "_backgroundRect_1b3uz_18";
152
152
  const defaultStyles$v = {
153
153
  bar: bar$2,
154
154
  label: label$1,
@@ -5921,32 +5921,6 @@ let Map$2 = class Map2 {
5921
5921
  this._renderer = new MapRenderer(this);
5922
5922
  this._resizeObserver = new ResizeObserver(() => this._updateSize());
5923
5923
  this._resizeObserver.observe(this.target);
5924
- this.view.transform = zoomIdentity;
5925
- this._zoomBypassKey = navigator.userAgent.indexOf("Mac") !== -1 ? "metaKey" : "ctrlKey";
5926
- this._zoomBehaviour = zoom().scaleExtent(this.view.scaleExtent).filter((event) => {
5927
- const filterEvent = (filter) => {
5928
- this._filterEventCallback(filter);
5929
- return !filter;
5930
- };
5931
- if (event.type === "wheel" && !event[this._zoomBypassKey]) {
5932
- return filterEvent(true);
5933
- }
5934
- if ("targetTouches" in event && this.collaborativeGesturesEnabled) {
5935
- if (event.targetTouches.length < 2) {
5936
- return false;
5937
- }
5938
- event.preventDefault();
5939
- return filterEvent(false);
5940
- }
5941
- return (!event.ctrlKey || event.type === "wheel") && !event.button;
5942
- }).on("zoom", (event) => {
5943
- this.view.transform = event.transform;
5944
- this._requestRender();
5945
- this.dispatcher.dispatch(MapEvent.ZOOM, {
5946
- currentZoomLevel: event.transform.k
5947
- });
5948
- });
5949
- select(this._viewport).call(this._zoomBehaviour);
5950
5924
  this._viewport.addEventListener("touchmove", (event) => {
5951
5925
  if (event.targetTouches.length < 2) {
5952
5926
  this._filterEventCallback(true);
@@ -6031,7 +6005,7 @@ let Map$2 = class Map2 {
6031
6005
  const paddedViewPortWidth = viewPortWidth - padding.left - padding.right;
6032
6006
  const paddedViewPortHeight = viewPortHeight - padding.top - padding.bottom;
6033
6007
  const featureScale = Math.min(paddedViewPortWidth / featureWidth, paddedViewPortHeight / featureHeight);
6034
- const zoomScale = Math.min(this.view.maxZoom, featureScale);
6008
+ const zoomScale = Math.min(this.view.scaleExtent[1], featureScale);
6035
6009
  const scaledPadding = {
6036
6010
  top: padding.top / zoomScale,
6037
6011
  right: padding.right / zoomScale,
@@ -6110,11 +6084,40 @@ let Map$2 = class Map2 {
6110
6084
  const view = this.view;
6111
6085
  if (view) {
6112
6086
  view.viewPortSize = size;
6087
+ this._createZoomBehaviour(size);
6113
6088
  }
6114
- this._zoomBehaviour.extent([[0, 0], size]);
6115
- this._zoomBehaviour.translateExtent([[0, 0], size]);
6116
6089
  this._requestRender();
6117
6090
  }
6091
+ _createZoomBehaviour(viewPortSize) {
6092
+ if (this._zoomBehaviour) {
6093
+ this._zoomBehaviour.on("zoom", null);
6094
+ }
6095
+ this._zoomBypassKey = navigator.userAgent.indexOf("Mac") !== -1 ? "metaKey" : "ctrlKey";
6096
+ this._zoomBehaviour = zoom().extent([[0, 0], viewPortSize]).translateExtent([[0, 0], viewPortSize]).scaleExtent(this.view.scaleExtent).filter((event) => {
6097
+ const filterEvent = (filter) => {
6098
+ this._filterEventCallback(filter);
6099
+ return !filter;
6100
+ };
6101
+ if (event.type === "wheel" && !event[this._zoomBypassKey]) {
6102
+ return filterEvent(true);
6103
+ }
6104
+ if ("targetTouches" in event) {
6105
+ if (event.targetTouches.length < 2) {
6106
+ return false;
6107
+ }
6108
+ event.preventDefault();
6109
+ return filterEvent(false);
6110
+ }
6111
+ return (!event.ctrlKey || event.type === "wheel") && !event.button;
6112
+ }).on("zoom", (event) => {
6113
+ this.view.transform = event.transform;
6114
+ this._requestRender();
6115
+ this.dispatcher.dispatch(MapEvent.ZOOM, {
6116
+ zoomScale: event.transform.k
6117
+ });
6118
+ });
6119
+ select(this._viewport).call(this._zoomBehaviour);
6120
+ }
6118
6121
  _requestRender() {
6119
6122
  if (!this._renderer || !!this._animationFrameRequestID || this._isTransitioning)
6120
6123
  return;
@@ -6144,6 +6147,32 @@ function bboxFeature(bounds) {
6144
6147
  };
6145
6148
  return feature;
6146
6149
  }
6150
+ const BASE_RESOLUTION = 156543.03392;
6151
+ function zoomLevelToZoomScale(zoomLevel, initialResolution) {
6152
+ const resolution = BASE_RESOLUTION / Math.pow(2, zoomLevel);
6153
+ const zoomScale = initialResolution / resolution;
6154
+ return zoomScale;
6155
+ }
6156
+ function zoomLevelForResolution(currentResolution) {
6157
+ const zoomLevel = Math.log2(BASE_RESOLUTION / currentResolution);
6158
+ return zoomLevel;
6159
+ }
6160
+ function haversineDistance(lat1, lon1, lat2, lon2) {
6161
+ const R2 = 6371e3;
6162
+ const toRadians = (degrees2) => degrees2 * Math.PI / 180;
6163
+ const dLat = toRadians(lat2 - lat1);
6164
+ const dLon = toRadians(lon2 - lon1);
6165
+ const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(toRadians(lat1)) * Math.cos(toRadians(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
6166
+ const c2 = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
6167
+ return R2 * c2;
6168
+ }
6169
+ function resolutionForExtent(extent, viewportSize) {
6170
+ const [lonMin, latMin, lonMax, latMax] = extent;
6171
+ const latMid = (latMin + latMax) / 2;
6172
+ const distance = haversineDistance(latMid, lonMin, latMid, lonMax);
6173
+ const resolution = distance / viewportSize[0];
6174
+ return resolution;
6175
+ }
6147
6176
  class View {
6148
6177
  constructor({
6149
6178
  projection,
@@ -6157,6 +6186,7 @@ class View {
6157
6186
  this.extent = extent;
6158
6187
  this.minZoom = minZoom;
6159
6188
  this.maxZoom = maxZoom;
6189
+ this._transform = zoomIdentity;
6160
6190
  this._padding = padding;
6161
6191
  this._viewPortSize = [0, 0];
6162
6192
  this.pixelRatio = window.devicePixelRatio;
@@ -6166,6 +6196,8 @@ class View {
6166
6196
  this._viewPortSize = size;
6167
6197
  if (previousSize !== size) {
6168
6198
  this.fitObject(bboxFeature(this.extent));
6199
+ const initialExtent = this.getVisibleExtent(zoomIdentity, this.projection);
6200
+ this.initialResolution = resolutionForExtent(initialExtent, size);
6169
6201
  }
6170
6202
  }
6171
6203
  get viewPortSize() {
@@ -6191,9 +6223,10 @@ class View {
6191
6223
  };
6192
6224
  return scalePadding(scaledPadding, this.pixelRatio);
6193
6225
  }
6194
- // defines the upper and lower limits for zoom behaviour
6226
+ // calculates the upper and lower zoom scales
6195
6227
  get scaleExtent() {
6196
- return [this.minZoom, this.maxZoom];
6228
+ const maxScale = zoomLevelToZoomScale(this.maxZoom, this.initialResolution);
6229
+ return [1, maxScale];
6197
6230
  }
6198
6231
  setProjection(projection) {
6199
6232
  this.projection = projection;
@@ -6239,6 +6272,14 @@ class View {
6239
6272
  const points = [topLeft, topRight, bottomRight, bottomLeft, topLeft];
6240
6273
  return points.map((d2) => this.invert(d2));
6241
6274
  }
6275
+ // map resolution (meters per pixel)
6276
+ getResolution() {
6277
+ return resolutionForExtent(this.getVisibleExtent(this.transform, this.projection), this.viewPortSize);
6278
+ }
6279
+ // map zoom level (0 = the entire world)
6280
+ getZoomLevel() {
6281
+ return zoomLevelForResolution(this.getResolution());
6282
+ }
6242
6283
  // get extent for drawn map
6243
6284
  getMapExtent() {
6244
6285
  const mapSizeInPixels = this.mapSize;
@@ -6265,6 +6306,7 @@ class View {
6265
6306
  zoomLevel: transform.k,
6266
6307
  pixelRatio: this.pixelRatio,
6267
6308
  padding: this.padding,
6309
+ viewPortSize: this.viewPortSize,
6268
6310
  sizeInPixels: scaleSize(this.viewPortSize, this.pixelRatio),
6269
6311
  visibleExtent: this.getVisibleExtent(transform, projection)
6270
6312
  };
@@ -6513,12 +6555,15 @@ class TextLayerRenderer {
6513
6555
  style2.pointerEvents = "none";
6514
6556
  style2.overflow = "hidden";
6515
6557
  }
6516
- renderFrame(frameState) {
6558
+ renderFrame(frameState, targetElement) {
6559
+ if (this.layer.opacity === 0)
6560
+ return targetElement;
6517
6561
  const {
6518
6562
  declutterTree
6519
6563
  } = frameState;
6520
6564
  const {
6521
6565
  projection,
6566
+ viewPortSize,
6522
6567
  sizeInPixels,
6523
6568
  visibleExtent,
6524
6569
  transform
@@ -6537,15 +6582,15 @@ class TextLayerRenderer {
6537
6582
  const featureStyle = styleFunction2(feature);
6538
6583
  const textElement = this.getTextElementWithID(feature.uid);
6539
6584
  textElement.innerText = featureStyle.text.content;
6540
- const [x, y] = transform.apply(point.coordinates);
6585
+ const [relativeX, relativeY] = transform.apply(point.coordinates).map((d2, i) => d2 / sizeInPixels[i]);
6541
6586
  const position = {
6542
- left: `${x / sizeInPixels[0] * 100}%`,
6543
- top: `${y / sizeInPixels[1] * 100}%`
6587
+ left: `${relativeX * 100}%`,
6588
+ top: `${relativeY * 100}%`
6544
6589
  };
6545
6590
  this.styleTextElement(textElement, featureStyle.text, position);
6546
6591
  const bbox = this.getElementBBox(textElement, {
6547
- x,
6548
- y
6592
+ x: relativeX * viewPortSize[0],
6593
+ y: relativeY * viewPortSize[1]
6549
6594
  });
6550
6595
  if (declutterTree.collides(bbox)) {
6551
6596
  continue;
@@ -6611,7 +6656,7 @@ class TextLayerRenderer {
6611
6656
  style2.top = `${bbox.minY}px`;
6612
6657
  style2.width = `${bbox.maxX - bbox.minX}px`;
6613
6658
  style2.height = `${bbox.maxY - bbox.minY}px`;
6614
- style2.border = "1px solid black";
6659
+ style2.border = "2px solid black";
6615
6660
  return element;
6616
6661
  }
6617
6662
  }