@maptiler/sdk 3.7.0 → 3.8.0-rc.9
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/README.md +189 -0
- package/dist/maptiler-sdk.css +5 -0
- package/dist/maptiler-sdk.mjs +3446 -2515
- package/dist/maptiler-sdk.mjs.map +1 -1
- package/dist/src/ImageViewer/ImageViewer.d.ts +354 -0
- package/dist/src/ImageViewer/events.d.ts +44 -0
- package/dist/src/ImageViewer/index.d.ts +4 -0
- package/dist/src/ImageViewer/monkeyPatchML.d.ts +4 -0
- package/dist/src/Map.d.ts +31 -1
- package/dist/src/Telemetry.d.ts +2 -0
- package/dist/src/controls/ImageViewerFitImageToBoundsControl.d.ts +13 -0
- package/dist/src/controls/MaptilerCustomControl.d.ts +17 -0
- package/dist/src/controls/MaptilerExternalControl.d.ts +25 -0
- package/dist/src/controls/MaptilerProjectionControl.d.ts +1 -0
- package/dist/src/controls/MaptilerTerrainControl.d.ts +1 -0
- package/dist/src/controls/index.d.ts +2 -0
- package/dist/src/custom-layers/CubemapLayer/CubemapLayer.d.ts +4 -2
- package/dist/src/custom-layers/RadialGradientLayer/RadialGradientLayer.d.ts +8 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/utils/errors.d.ts +5 -0
- package/package.json +5 -2
- package/vitest-setup-tests.ts +0 -1
package/README.md
CHANGED
|
@@ -451,7 +451,145 @@ const map = new Map({
|
|
|
451
451
|
})
|
|
452
452
|
```
|
|
453
453
|
|
|
454
|
+
# 🧩 Custom Controls
|
|
454
455
|
|
|
456
|
+
MapTiler SDK JS supports two flexible ways to add custom controls to your map interface. Whether you're building a dynamic application or integrating with static HTML, there's a matching approach for both.
|
|
457
|
+
|
|
458
|
+
## Programmatic Controls
|
|
459
|
+
|
|
460
|
+
Use `map.addControl()` with `MaptilerExternalControl` to register custom UI elements manually. This approach is ideal for dynamic logic, event-driven behavior, or integration with frameworks like React. The control element can be provided either as a reference to the **element itself**, or as its **CSS selector**. Optionally, two callback functions can be provided:
|
|
461
|
+
|
|
462
|
+
* `onClick` function that is called when the element is clicked, and
|
|
463
|
+
* `onRender` function that is called every time the map renders a new state.
|
|
464
|
+
|
|
465
|
+
Both callbacks receive the active `Map` instance, the associated control element itself, and an event object associated with the original event (`PointerEvent` and `MapLibreEvent` respectively).
|
|
466
|
+
|
|
467
|
+
### Example
|
|
468
|
+
|
|
469
|
+
```ts
|
|
470
|
+
const panControl = new maptilersdk.MaptilerExternalControl(
|
|
471
|
+
".pan-control",
|
|
472
|
+
(map) => map.panBy([10, 10]), // Move southeast on click
|
|
473
|
+
(map, el) => el.classList.toggle( // Style based on hemisphere
|
|
474
|
+
"northern-hemisphere", map.getCenter().lat > 0
|
|
475
|
+
)
|
|
476
|
+
);
|
|
477
|
+
map.addControl(panControl);
|
|
478
|
+
|
|
479
|
+
const element = document.createElement("button");
|
|
480
|
+
element.textContent = "Pan NW";
|
|
481
|
+
map.addControl(
|
|
482
|
+
new maptilersdk.MaptilerExternalControl(
|
|
483
|
+
element,
|
|
484
|
+
(map) => map.panBy([-10, -10]) // Move northwest
|
|
485
|
+
),
|
|
486
|
+
"top-left"
|
|
487
|
+
);
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
### Behavior Overview
|
|
491
|
+
|
|
492
|
+
- On add, control element is moved into the map UI
|
|
493
|
+
- `onClick` binds user interaction
|
|
494
|
+
- `onRender` enables state-based styling or logic
|
|
495
|
+
- Control maintains its own DOM context
|
|
496
|
+
- On removal, element is returned to its original DOM position (if any) to not interfere with DOM handling of frameworks like React
|
|
497
|
+
|
|
498
|
+
## Declarative Controls
|
|
499
|
+
|
|
500
|
+
Add controls using HTML attributes – no JavaScript required. This is perfect for simple UI setups.
|
|
501
|
+
|
|
502
|
+
### Enabling Detection
|
|
503
|
+
|
|
504
|
+
```ts
|
|
505
|
+
const map = new maptilersdk.Map({
|
|
506
|
+
container: "map",
|
|
507
|
+
customControls: true, // or ".custom-ui"
|
|
508
|
+
});
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
You can pass `true` to enable detection globally, or a CSS selector to scope it.
|
|
512
|
+
|
|
513
|
+
### Declaring Controls
|
|
514
|
+
|
|
515
|
+
Use `data-maptiler-control` attribute:
|
|
516
|
+
|
|
517
|
+
```html
|
|
518
|
+
<button data-maptiler-control="zoom-in">+</button>
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
Supported values:
|
|
522
|
+
|
|
523
|
+
| Value | Description |
|
|
524
|
+
|---------------------|--------------------------------------------------|
|
|
525
|
+
| `zoom-in` | Zooms in |
|
|
526
|
+
| `zoom-out` | Zooms out |
|
|
527
|
+
| `toggle-projection` | Switches Mercator ↔ Globe |
|
|
528
|
+
| `toggle-terrain` | Toggles terrain layer |
|
|
529
|
+
| `reset-view` | Resets bearing, pitch, and roll |
|
|
530
|
+
| `reset-bearing` | Resets bearing only |
|
|
531
|
+
| `reset-pitch` | Resets pitch only |
|
|
532
|
+
| `reset-roll` | Resets roll only |
|
|
533
|
+
| *(empty)* | Registers control without built-in functionality |
|
|
534
|
+
|
|
535
|
+
> ⚠️ An error is thrown if an unrecognized value is used.
|
|
536
|
+
|
|
537
|
+
### Grouping Controls
|
|
538
|
+
|
|
539
|
+
Use `data-maptiler-control-group` to group buttons:
|
|
540
|
+
|
|
541
|
+
```html
|
|
542
|
+
<div data-maptiler-control-group>
|
|
543
|
+
<button data-maptiler-control="zoom-in">+</button>
|
|
544
|
+
<button data-maptiler-control="zoom-out">−</button>
|
|
545
|
+
</div>
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
Groups are styled and positioned together but don't add functionality themselves. Functional behavior is attached to valid descendant elements.
|
|
549
|
+
|
|
550
|
+
### Positioning Controls
|
|
551
|
+
|
|
552
|
+
Use `data-maptiler-position` to set placement:
|
|
553
|
+
|
|
554
|
+
```html
|
|
555
|
+
<button data-maptiler-control="reset-view" data-maptiler-position="top-left">↻</button>
|
|
556
|
+
<div data-maptiler-control-group data-maptiler-position="bottom-right">
|
|
557
|
+
<button data-maptiler-control="zoom-in">+</button>
|
|
558
|
+
<button data-maptiler-control="zoom-out">−</button>
|
|
559
|
+
</div>
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
Valid positions: `'top-left'`, `'top-right'`, `'bottom-left'`, `'bottom-right'`
|
|
563
|
+
|
|
564
|
+
## Styling with CSS Variables
|
|
565
|
+
|
|
566
|
+
When declarative controls are enabled, the map container exposes dynamic CSS variables:
|
|
567
|
+
|
|
568
|
+
| Variable | Description | Type |
|
|
569
|
+
|----------------------------------|--------------------------------------------------|-----------------|
|
|
570
|
+
| `--maptiler-center-lng` | Longitude of center | unitless number |
|
|
571
|
+
| `--maptiler-center-lat` | Latitude of center | unitless number |
|
|
572
|
+
| `--maptiler-zoom` | Zoom level | unitless number |
|
|
573
|
+
| `--maptiler-bearing` | Map rotation | unitless number |
|
|
574
|
+
| `--maptiler-pitch` | Pitch angle | unitless number |
|
|
575
|
+
| `--maptiler-roll` | Roll angle | unitless number |
|
|
576
|
+
| `--maptiler-is-globe-projection` | `true` if globe is active<br>`false` otherwise | string |
|
|
577
|
+
| `--maptiler-has-terrain` | `true` if terrain is active<br>`false` otherwise | string |
|
|
578
|
+
|
|
579
|
+
### Example
|
|
580
|
+
|
|
581
|
+
```css
|
|
582
|
+
.compass-icon {
|
|
583
|
+
transform: rotateX(calc(var(--maptiler-pitch) * 1deg))
|
|
584
|
+
rotateZ(calc(var(--maptiler-bearing) * -1deg));
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
@container style(--maptiler-is-globe-projection: true) {
|
|
588
|
+
.projection-icon {
|
|
589
|
+
content: "globe";
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
```
|
|
455
593
|
|
|
456
594
|
# 3D terrain in one call
|
|
457
595
|
<p align="center">
|
|
@@ -592,6 +730,13 @@ map.on("load", () => {
|
|
|
592
730
|
});
|
|
593
731
|
});
|
|
594
732
|
```
|
|
733
|
+
|
|
734
|
+
To disable state transitions for halo or space:
|
|
735
|
+
```ts
|
|
736
|
+
map.disableHaloAnimations();
|
|
737
|
+
map.disableSpaceAnimations();
|
|
738
|
+
```
|
|
739
|
+
|
|
595
740
|
## `space` (Background Environment)
|
|
596
741
|
|
|
597
742
|
The space option allows customizing the background environment of the globe, simulating deep space or skybox effects.
|
|
@@ -675,6 +820,50 @@ Note: if `space.color` or `space.<faces | path | preset>` are not explicitly set
|
|
|
675
820
|
|
|
676
821
|
Further code examples can be found in `~/demos/`
|
|
677
822
|
|
|
823
|
+
# `ImageViewer`
|
|
824
|
+
|
|
825
|
+
MapTiler's `ImageViewer` component allows you to display tiled, non-georeferenced images but interact with them in almost the same way you would if you were displaying map. These can be handy for zoomable non-georeferenced, geographically "inaccurate" maps such as hotel maps, golf courses, theme parks etc. Think pixels instead of lattitudes and longtidues.
|
|
826
|
+
|
|
827
|
+
```ts
|
|
828
|
+
export type ImageViewerConstructorOptions = {
|
|
829
|
+
imageUUID: string; // the unique UUID of the image object you are displaying
|
|
830
|
+
center?: [number, number]; // the center you want the viewer to init on, defaults to the center of the image.
|
|
831
|
+
container: string | HTMLElement // the container element you want to mount the viewer on
|
|
832
|
+
apiKey: string; // your MapTiler API Key
|
|
833
|
+
zoom?: number;
|
|
834
|
+
maxZoom?: number;
|
|
835
|
+
minZoom?: number;
|
|
836
|
+
bearing?: number;
|
|
837
|
+
debug?: boolean; // whether you want to debug the tiles
|
|
838
|
+
};
|
|
839
|
+
|
|
840
|
+
const imageViewer = new ImageViewer({
|
|
841
|
+
container: document.getElementById("map")!, // the container element you want to use
|
|
842
|
+
apiKey: "YOUR_MAPTILER_API_KEY", // your api key
|
|
843
|
+
imageUUID: "11111111-2222-3333-4444-555555555555", // unique UUID of the image object
|
|
844
|
+
// ...other options, see below
|
|
845
|
+
}: ImageViewerConstructorOptions);
|
|
846
|
+
|
|
847
|
+
await imageViewer.onReadyAsync()
|
|
848
|
+
|
|
849
|
+
// OR
|
|
850
|
+
|
|
851
|
+
imageViewer.on("imageviewerready", () => { console.log('Ready!') })
|
|
852
|
+
```
|
|
853
|
+
|
|
854
|
+
## Methods
|
|
855
|
+
`ImageViewer` provides a subset of methods for interaction with the map. A major caveat is that the `ImageViewer` component works in pixels and not in LngLat. Thus, when using methods such as `setCenter` or `flyTo` the pixel values provided refer to the _absolute pixel position_ on the image, not screen pixel position.
|
|
856
|
+
|
|
857
|
+
Imagine your image is 10,000px x 10,000px, if regardless if your zoom is 2 or 4, calling `.setCenter(500,500)` will always position the viewer over the same part of the image.
|
|
858
|
+
|
|
859
|
+
For full details on supported methods see the type declaration for `ImageViewer`.
|
|
860
|
+
|
|
861
|
+
## Events
|
|
862
|
+
In a similar manner, a subset of map events are fired by the image viewer. All UI interaction events that would normally include a `LngLat` in the event data instead receive an `imageX` and `imageY` field, representing an absolute pixel position of the image. This is same for `flyTo`, `jumpTo`, `panTo` etc.
|
|
863
|
+
|
|
864
|
+
A full list of supported events can be found in the exported type declaration `ImageViewerEventTypes`
|
|
865
|
+
|
|
866
|
+
|
|
678
867
|
# Easy language switching
|
|
679
868
|
The language generally depends on the style but we made it possible to easily set and update from a built-in list of languages.
|
|
680
869
|
|
package/dist/maptiler-sdk.css
CHANGED
|
@@ -143,6 +143,11 @@
|
|
|
143
143
|
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20width%3D%2233%22%20height%3D%2233%22%20viewBox%3D%220%200%2033%2033%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M26.5%209.85H6.5C6.41716%209.85%206.35%209.91716%206.35%2010V23C6.35%2023.0828%206.41716%2023.15%206.5%2023.15H26.5C26.5828%2023.15%2026.65%2023.0828%2026.65%2023V10C26.65%209.91716%2026.5828%209.85%2026.5%209.85ZM6.5%208C5.39543%208%204.5%208.89543%204.5%2010V23C4.5%2024.1046%205.39543%2025%206.5%2025H26.5C27.6046%2025%2028.5%2024.1046%2028.5%2023V10C28.5%208.89543%2027.6046%208%2026.5%208H6.5Z%22%20fill%3D%22%23444952%22%2F%3E%0A%3Cpath%20d%3D%22M5.5%2012.8H28.5V14.65H5.5V12.8Z%22%20fill%3D%22%23444952%22%2F%3E%0A%3Cpath%20d%3D%22M10.0375%2025L10.0375%208L11.8875%208L11.8875%2025H10.0375Z%22%20fill%3D%22%23444952%22%2F%3E%0A%3Cpath%20d%3D%22M15.5751%2025L15.5751%208L17.4251%208L17.4251%2025H15.5751Z%22%20fill%3D%22%23444952%22%2F%3E%0A%3Cpath%20d%3D%22M21.1127%2025V8L22.9627%208L22.9627%2025H21.1127Z%22%20fill%3D%22%23444952%22%2F%3E%0A%3Cpath%20d%3D%22M5.5%2018.35H28.5V20.2H5.5V18.35Z%22%20fill%3D%22%23444952%22%2F%3E%0A%3C%2Fsvg%3E%0A");
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
+
/* Center image control icon - globe */
|
|
147
|
+
.maplibregl-ctrl button.maplibregl-ctrl-fit-image-to-bounds .maplibregl-ctrl-icon {
|
|
148
|
+
background-image: url("data:image/svg+xml;charset=utf-8,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%0A%3Csvg%0A%20%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%0A%20%20width%3D%2224%22%0A%20%20height%3D%2224%22%0A%20%20viewBox%3D%220%200%2032%2032%22%0A%3E%0A%20%20%3Cpath%0A%20%20%20%20fill%3D%22%23444952%22%0A%20%20%20%20d%3D%22M8%202H2v6h2V4h4zm16%200h6v6h-2V4h-4zM8%2030H2v-6h2v4h4zm16%200h6v-6h-2v4h-4zm0-6H8a2%202%200%200%201-2-2V10a2%202%200%200%201%202-2h16a2%202%200%200%201%202%202v12a2%202%200%200%201-2%202M8%2010v12h16V10z%22%0A%20%20%3E%3C%2Fpath%3E%0A%3C%2Fsvg%3E");
|
|
149
|
+
}
|
|
150
|
+
|
|
146
151
|
.maplibregl-ctrl-scale {
|
|
147
152
|
background-color: hsla(0,0%,100%,.75);
|
|
148
153
|
border: 1px solid #444952;
|