@mapka/maplibre-gl-sdk 0.12.0 → 0.13.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.
package/src/map.ts CHANGED
@@ -27,6 +27,8 @@ import type {
27
27
  StyleSpecification,
28
28
  } from "maplibre-gl";
29
29
  import type { MapkaMarkerOptions, MapkaPopupOptions } from "./types/marker.js";
30
+ import type { MapkaExportOptions } from "./types/export.js";
31
+ import { exportMap } from "./modules/export.js";
30
32
 
31
33
  export interface MapkaMapOptions extends MapOptions {
32
34
  maxPopups?: number;
@@ -72,9 +74,16 @@ export type MapMapkaMarker = {
72
74
  marker: Marker;
73
75
  };
74
76
 
77
+ interface Logger {
78
+ log: (...args: unknown[]) => void;
79
+ warn: (...args: unknown[]) => void;
80
+ error: (...args: unknown[]) => void;
81
+ }
82
+
75
83
  export class MapkaMap extends maplibregl.Map {
76
84
  static env: string = "prod";
77
85
 
86
+ public logger: Logger = console;
78
87
  public markers: MapMapkaMarker[] = [];
79
88
 
80
89
  public maxPopups: number = 1;
@@ -129,19 +138,23 @@ export class MapkaMap extends maplibregl.Map {
129
138
  removeMarkers(this);
130
139
  }
131
140
 
132
- public openPopup(popup: MapkaPopupOptions, id: string = getPopupId(popup)) {
133
- return openPopup(this, popup, id);
141
+ public openPopup(popup: MapkaPopupOptions) {
142
+ return openPopup(this, popup);
134
143
  }
135
144
 
136
145
  public closePopup(id: string) {
137
146
  closePopupsById(this, id);
138
147
  }
139
148
 
140
- public updatePopup(popup: MapkaPopupOptions, id: string = getPopupId(popup)) {
141
- return updatePopup(this, popup, id);
149
+ public updatePopup(popup: MapkaPopupOptions) {
150
+ return updatePopup(this, popup);
142
151
  }
143
152
 
144
153
  public removePopups() {
145
154
  removePopups(this);
146
155
  }
156
+
157
+ public async export(options?: MapkaExportOptions) {
158
+ return exportMap(this, options);
159
+ }
147
160
  }
@@ -0,0 +1,55 @@
1
+ import { toPng } from "html-to-image";
2
+ import type { MapkaMap } from "../map.js";
3
+ import type { MapkaExportOptions } from "../types/export.js";
4
+
5
+ export async function exportMap(
6
+ map: MapkaMap,
7
+ options: MapkaExportOptions = {},
8
+ ): Promise<HTMLImageElement> {
9
+ const { hideControls = false, hideMarkers = false, hidePopups = false, bbox } = options;
10
+
11
+ const container = map.getContainer();
12
+ const originalBounds = map.getBounds();
13
+
14
+ if (bbox) {
15
+ map.fitBounds(bbox, { padding: 20, animate: false });
16
+ }
17
+
18
+ return new Promise<HTMLImageElement>((resolve, reject) => {
19
+ map.once("render", () => {
20
+ toPng(container, {
21
+ skipFonts: navigator.userAgent.includes("Firefox"),
22
+ filter: (node) => {
23
+ if (node.classList) {
24
+ const isControlsVisibleOrNotControl =
25
+ !hideControls || !node.classList.contains("maplibregl-control-container");
26
+ const isMarkersVisibleOrNotMarker =
27
+ !hideMarkers || !node.classList.contains("maplibregl-marker");
28
+ const isPopupsVisibleOrNotPopup =
29
+ !hidePopups || !node.classList.contains("maplibregl-popup");
30
+
31
+ return (
32
+ isControlsVisibleOrNotControl &&
33
+ isMarkersVisibleOrNotMarker &&
34
+ isPopupsVisibleOrNotPopup
35
+ );
36
+ }
37
+ return true;
38
+ },
39
+ })
40
+ .then((dataUrl) => {
41
+ const img = new Image();
42
+ img.src = dataUrl;
43
+ img.onload = () => resolve(img);
44
+ img.onerror = reject;
45
+ })
46
+ .catch(reject)
47
+ .finally(() => {
48
+ if (bbox) {
49
+ map.fitBounds(originalBounds, { animate: false });
50
+ }
51
+ });
52
+ });
53
+ map.triggerRepaint();
54
+ });
55
+ }
@@ -24,8 +24,8 @@ export function enforceMaxPopups(map: MapkaMap) {
24
24
  }
25
25
  }
26
26
 
27
- export function openPopup(map: MapkaMap, options: MapkaPopupOptions, id: string) {
28
- const { lngLat, content, closeButton, ...popupOptions } = options;
27
+ export function openPopup(map: MapkaMap, options: MapkaPopupOptions) {
28
+ const { lngLat, content, closeButton, id = getPopupId(options), ...popupOptions } = options;
29
29
  if (content instanceof HTMLElement) {
30
30
  const popup = new Popup({
31
31
  ...popupOptions,
@@ -70,14 +70,10 @@ export function openPopup(map: MapkaMap, options: MapkaPopupOptions, id: string)
70
70
  return id;
71
71
  } else if (typeof content === "function") {
72
72
  const newContent = content(id);
73
- return openPopup(
74
- map,
75
- {
76
- ...options,
77
- content: newContent,
78
- },
79
- id,
80
- );
73
+ return openPopup(map, {
74
+ ...options,
75
+ content: newContent,
76
+ });
81
77
  }
82
78
 
83
79
  throw new Error("Invalid popup content");
@@ -102,11 +98,9 @@ export function updatePopupBaseOptions(
102
98
  return popup;
103
99
  }
104
100
 
105
- export function updatePopup(
106
- map: MapkaMap,
107
- { content, ...newOptions }: MapkaPopupOptions,
108
- id: string,
109
- ) {
101
+ export function updatePopup(map: MapkaMap, { content, ...newOptions }: MapkaPopupOptions) {
102
+ const id = getPopupId(newOptions);
103
+
110
104
  if (content instanceof HTMLElement) {
111
105
  const mapkaPopups = map.popups.filter((popup) => popup.id === id);
112
106
  for (const { popup, options } of mapkaPopups) {
@@ -125,14 +119,10 @@ export function updatePopup(
125
119
  }
126
120
  } else if (typeof content === "function") {
127
121
  const newContent = content(id);
128
- return updatePopup(
129
- map,
130
- {
131
- ...newOptions,
132
- content: newContent,
133
- },
134
- id,
135
- );
122
+ return updatePopup(map, {
123
+ ...newOptions,
124
+ content: newContent,
125
+ });
136
126
  }
137
127
  }
138
128
 
@@ -0,0 +1,6 @@
1
+ export type MapkaExportOptions = {
2
+ hideControls?: boolean;
3
+ hideMarkers?: boolean;
4
+ hidePopups?: boolean;
5
+ bbox?: [number, number, number, number];
6
+ };