---
title: Map Controls
source: https://vjmap.com/en/guide/control.html
---

# Map Controls

### Currently Supported Controls

The currently supported controls are:

- Navigation control `NavigationControl`
- Scale control `ScaleControl`
- Fullscreen control `FullscreenControl`
- Mouse position control `MousePositionControl`
- Mini map control (overview/inset) `MiniMapControl`
- Button group control `ButtonGroupControl`
### Example

<mapFrameEx>
<pre>
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// Open map
let res = await svc.openMap({
    mapid: env.exampleMapId, // map ID
    // @ts-ignore
    mapopenway: vjmap.MapOpenWay.GeomRender, // geometry render
    style: vjmap.openMapLightStyle() // use dark style when container has dark background
})
if (res.error) {
    // open failed
    showError(res.error)
    return;
}
// Map bounds
let mapBounds = vjmap.GeoBounds.fromString(res.bounds);
// Create projection from bounds
let prj = new vjmap.GeoProjection(mapBounds);
//
// Map instance
let map = new vjmap.Map({
    container: 'map', // container ID
    style: svc.rasterStyle(), // raster style
    center: prj.toLngLat(mapBounds.center()), // center
    zoom: 2, // zoom level
    pitch: 45,
    antialias: true, // antialias
    renderWorldCopies: false // no world copies
});
//
// Attach service and projection
map.attach(svc, prj);
await map.onLoad();
// Scale control
let scaleControl =  new vjmap.ScaleControl();
map.addControl(scaleControl, "bottom-left");
// Navigation control
let navigationControl = new vjmap.NavigationControl();
map.addControl(navigationControl, "top-right");
// Fullscreen control
let fullScreenControl = new vjmap.FullscreenControl();
map.addControl(fullScreenControl, "bottom-right");
// Mouse position control
let mousePositionControl =  new vjmap.MousePositionControl();
map.addControl(mousePositionControl, "top-left");
map.addControl(new vjmap.MiniMapControl({
    containerStyle: {
    background: "#31346a85",
    transform: "scale(0.6)",
    transformOrigin: "0% 100%"
    // Adjust transformOrigin for different positions
    //'top-right'
    //transformOrigin: "100% 0%"
    //'top-left'
    //transformOrigin: "0% 0%"
    //'bottom-right'
    //transformOrigin: "100% 100%"
    //'bottom-left'
    //transformOrigin: "0% 100%"
    }
}), 'bottom-left');
</pre>
</mapFrameEx>
<br/>
<br/>

#### 
```js
// Scale control
let scaleControl =  new vjmap.ScaleControl();
map.addControl(scaleControl, "bottom-left");

// Navigation control
let navigationControl = new vjmap.NavigationControl();
map.addControl(navigationControl, "top-right");

// Fullscreen control
let fullScreenControl = new vjmap.FullscreenControl();
map.addControl(fullScreenControl, "bottom-right");

// Mouse position control
let mousePositionControl =  new vjmap.MousePositionControl();
map.addControl(mousePositionControl, "top-left");
```

### Mini Map Control (Overview/Inset)
```js
map.addControl(new vjmap.MiniMapControl({
containerStyle: {
background: "#31346a85",
transform: "scale(0.6)",
transformOrigin: "100% 0%"
// Adjust transformOrigin based on placement position
//'top-right'
//transformOrigin: "100% 0%"
//'top-left'
//transformOrigin: "0% 0%"
//'bottom-right'
//transformOrigin: "100% 100%"
//'bottom-left'
//transformOrigin: "0% 100%"
}
}), 'top-right');
```

### Button Group Control
<mapFrameEx>
<pre>
// Button group control
// Map service
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// Open map
let res = await svc.openMap({
    mapid: env.exampleMapId, // map ID
    mapopenway: vjmap.MapOpenWay.GeomRender, // geometry render
    style: vjmap.openMapDarkStyle() // dark style for dark container
})
if (res.error) {
    message.error(res.error)
}
// Map bounds
let mapExtent = vjmap.GeoBounds.fromString(res.bounds);
// Create projection
let prj = new vjmap.GeoProjection(mapExtent);
// Map instance
let map = new vjmap.Map({
    container: 'map', // container ID
    style: svc.rasterStyle(), // raster style
    center: prj.toLngLat(mapExtent.center()), // center
    zoom: 2, // zoom level
    pitch: 0, // pitch
    renderWorldCopies: false // no world copies
});
// Attach service and projection
map.attach(svc, prj);
// Fit map to full extent
//map.fitMapBounds();
await map.onLoad();
const mapBounds = map.getGeoBounds(0.6);
let options = {};
options.buttons = [
    {
        id: "zoomFit",
        title: "Fit to map",
        style: {
            "background-image": `url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAALNJREFUWEftltENgCAMRGEwJtBRdAZ1Bh1FJ2AwTIwkBqw56EcxKd+lHK9Ne9YIHyv8vlEBGQE/HBNVFrd1C1Kykhy5gHEPpIC1h0rmC3LQAoKdUyEsAjZc+VzyCVJAGoig/4qJVH4g4G5CFDdKJjZmmhdqKvSRmjgVoASUgBJQAu0RoJZGzZx/3oGXEbW32QJul/QDPxD9nLQle0OO2jSeKZW25dxmK73f3hwo/QE3XpzACTqIZiEG/iYrAAAAAElFTkSuQmCC')`,
            "background-size": "80% 80%"
        },
        onActivate: (ctx) => {
            map.fitMapBounds();
        }
    },
    {
        id: "zoomFit",
        title: "Enable right-drag rotate",
        style: {
            "background-image": `url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAllJREFUWEfFl1FOwzAMhu1wAcR4ZwwOwk4CuwWqkMYkVLgF4ySUe8Ao7xRxgDVB7prKCW6Sdkj0sW3qL/bv3ynCP1/4z/FhNMDx+c0Fh99ut+V3+VAO3dAggMlZdgUGlgAwFQMZUxjEQmv9lAqTBBANLG97XWu9ioEEAQ6n19MDpd6F768NQIkIH/TMGDhBYy4AkTLDs1OiUovP17uirzQOAAW0xELwEhBW1Vu+DtVZzBbCom9dB0CiMnW9rI1ZUABv5+tqkzf3U6/JLHsEgCv7fq31qVQOJwOTWUbpdgRmAG6/NvkqNTB/72iWLRHgtr1X1lrPfQgfwKEGY4rq/X4+JrhdwyGkzbgAuzYjCH4lqTmoC5ZZvxQOQKMDrZ99AFTqKaTkWIZCWfjVhq0OCkB4iSk+Fpg/7/TllTXJiKRA1KZKqUsEmKYYDu8KXoZRAJJHxAznTwH8Hm/cMNKurUE1Akel5lZTozLg9betUNCs+Jq9AaQZwT8qaWYQALVjrO1aiCUNpZTxy8tWbfIu804JWkryb1K26N1DWs9rQ2Mtudrkp/aZBLDz7sAEGwrBBeiL9dc4PlCKnJAGkjg8hgan9yezzO4eePp3+/Su2PAYCsBrHx1G9uN8LMf6OwTkj2Nee1ED9mY7lMg0mrMBQaQo3ROdM9r72rTXiHhHWPXSkayudRE6aEpHspBHBJ3Qz0S3w/b47RxKd9nqjmAWOjYjkqy4FRL9iMj/A7IQks6RSQD0fTZ+G6PqFR/CIlYmvjYZwA/If83G/paJPjC0z/d9f3QG9g1s1/8ATi1yMPW6z1YAAAAASUVORK5CYII=')`,
            "background-size": "80% 80%"
        },
        isCheckbox: true,
        checked: true,
        onActivate: (ctx, e) => {
            e.target.checked ? map.dragRotate.enable() : map.dragRotate.disable();
        }
    },
    {
        id: "pos",
        title: "Fly to a position",
        text: "Locate",
        onActivate: (ctx, e) => {
            map.flyTo({
                center: [10, 20],
                pitch: 30,
                zoom: 6,
                speed: 0.2,
                easing(t) {
                    return t;
                }
            });;
        }
    }
];
let btnGroupCtrl = new vjmap.ButtonGroupControl(options);
map.addControl(btnGroupCtrl, 'top-right');
</pre>
</mapFrameEx>
<br/>
<br/>

### Custom Controls

#### Example
```js
// Custom control to display zoom level
class CustomShowZoomControl {
    constructor(options = {}) {
        this.style = options.style || {};// Style
    }
    _insertControl() {
        this.container = document.createElement("div");
        this.container.classList.add("vjmap-ctrl");

        this.container.style.border = this.style.border || "1px";
        this.container.style.backgroundColor = this.style.backgroundColor || "#A0CFFF";

        this.panel = document.createElement("div");
        this._zoomend();
        this.container.appendChild(this.panel);
    }
    _zoomend() {
        let strZoom = `Current level: ${this.map.getZoom().toFixed(2)}`
        this.panel.innerHTML = strZoom;
    }
    onAdd(map) {
        this.map = map;
        this._insertControl();
        this.map.on("zoomend", this._zoomend.bind(this));
        return this.container;
    }

    onRemove() {
        this.map.off("zoomend", this._zoomend.bind(this));
        this.container.parentNode.removeChild(this.container);
    }

    getDefaultPosition() {
        return "bottom-left";
    }
}

let control = new CustomShowZoomControl({style: {border : "1px"}})
map.addControl(control);
```
