# 右键菜单

ContextMenu 上下文菜单用于右键弹出菜单界面显示。

# 常用方法

方法 描述
add 增加菜单项
show 显示菜单
hide 隐藏菜单
toggle 切换菜单状态

# 菜单项类型

类型 描述
seperator 分隔线
custom 自定义菜单项
multi 多个按钮
submenu 子菜单项
hovermenu 悬浮菜单项
normal 缺省正常菜单项

# 示例

# 地图上下文菜单

地图上下文菜单 (opens new window)

// 选中的图标,也可以直接指定src路径
const checkIcon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAANpJREFUOE9jZKAQMFKon2FgDKjZHVHf4rqiEeR6kl1QuzOyn+E/4/lmj2WLSDagekdkASMjg1aL+/I0WNgR7YLaHRG2/xgZYlrdV6QjBzzRBtTsijzzl4nVvd1l0VucBtTsjlz5/z/jt1a3ZYnIimp2RZ7//+9fQ6vHyo3o0Q53Qc32CAcGpv88DIxMxQyMDB9aXJcHghTX7IxcyMjAeLTZfdksbGkGqxdqdkUuZ2BgkPjPyDCFgeG/W6srqr+JCoPqXZG9jAwM9iyszy0aHA/8wZViiQ7EYWwAAPShQBF/1IlVAAAAAElFTkSuQmCC";
map.setMenu(event => {
    return new vjmap.ContextMenu({
        event: event.originalEvent,
        theme: "dark", //light
        width: "250px",
        items: [
            {type: 'custom', markup: `<span style="color: #ffff00; padding-left: 30px">菜单右键功能演示</span>`},
            {type: 'multi', items: [
                    {label: '全图', onClick: () => { map.fitMapBounds(); }},
                    {label: '不旋转', onClick: () => { map.setBearing(0); }},
                    {label: '不倾斜', onClick: () => { map.setPitch(0); }},
                ]},
            {label: '获取此位置的坐标', onClick: () => {
                    let point = map.fromLngLat(event.lngLat);
                    map.logInfo(`当前坐标为 x: ${point.x}, y: ${point.y}`);
                }},
            {type: 'seperator'},
            {type: 'submenu', label: '地图缩放', items: [
                    {label: '放大一级', onClick: () => { map.setZoom(map.getZoom() + 1)}},
                    {label: '缩小一级', onClick: () => { map.setZoom(map.getZoom() - 1)}, enabled: map.getZoom() - 1 > 0},
                    {label: '缩小至最小级', onClick: () => { map.setZoom(0)}},
                    {label: '飞行至此位置', onClick: () => {
                            map.flyTo({
                                center: event.lngLat,
                                pitch: 60,
                                zoom: 5
                            })
                        }}
                ]},
            {type: 'hovermenu', label: '地图设置', items: [
                    {
                        label: '双击鼠标进行缩放',
                        icon: map.doubleClickZoom.isEnabled() ? checkIcon : "",
                        onClick: () => {
                            if (map.doubleClickZoom.isEnabled()) {
                                map.doubleClickZoom.disable()
                            } else {
                                map.doubleClickZoom.enable()
                            }
                        }
                    },
                    {
                        label: '允许地图旋转',
                        icon: map.dragRotate.isEnabled() ? checkIcon : "",
                        onClick: () => {
                            if (map.dragRotate.isEnabled()) {
                                map.dragRotate.disable();
                            } else {
                                map.dragRotate.enable();
                            }
                        }
                    },
                    {
                        label: '允许地图倾斜',
                        icon: map.getMaxPitch() != 0 ? checkIcon : "",
                        onClick: () => {
                            if (map.getMaxPitch() == 0) {
                                map.setMaxPitch(85)
                            } else {
                                map.setMaxPitch(0)
                            }
                        }
                    }
                ]}
        ]
    });
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
显示代码
全屏显示


# 覆盖物图层右键菜单

覆盖物图层右键菜单 (opens new window)

// 设置点击一个覆盖物时弹出菜单,key值可以自定义设置。如果函数返回空时,将触发上面的地图右键菜单。如果函数不返回空,则会弹出此函数的菜单
map.setMenu(event => {
    let features = map.queryRenderedFeatures(event.point, {
        layers: [polygon.layerId]
    });
    if (features.length == 0) {
        // 如果点击位置没有上面多边形图层的实体,则将回空,这样将会弹出上面的默认地图菜单
        return null;
    }
    // 如果点击位置有上面多边形图层的实体,则弹出此图层的自定义右键菜单
    return new vjmap.ContextMenu({
        event: event.originalEvent,
        theme: "dark", //light
        width: "250px",
        items: [
            {type: 'custom', markup: `<span style="color: #ffff00; padding-left: 30px">我是多边形图层的右键菜单</span>`},
            {
                label: '查看选择的多边形信息',
                onClick: () => {
                    map.logInfo(`当前多边形ID: ${features[0].properties.id}, 当前多边形颜色: ${features[0].properties.color}`);
                }
            },
            {
                label: '删除',
                onClick: () => {
                    let data = polygon.getData();
                    data.features = data.features.filter(f => f.id != features[0].properties.id);
                    polygon.setData(data);
                }
            }
        ]
    });
}, "overlay")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
显示代码
全屏显示


# 标记Marker右键菜单

标记Marker右键菜单 (opens new window)

 // marker与多边形等覆盖物图层不同的时,marker是div,而覆盖物图层是canvas渲染与map属于同一个div
// 所以marker的右键,得由自己的div的上下文菜单来触发
marker.getElement().addEventListener("mousedown", event => {
    if (event.button != 2) return;//不是右键
    // 阻止地图默认右键菜单触发
    event.preventDefault();
    event.stopPropagation();
    return new vjmap.ContextMenu({
        event: event,
        theme: "dark", //light
        width: "250px",
        items: [
            {type: 'custom', markup: `<span style="color: #ffff00; padding-left: 30px">我是标注Marker的右键菜单</span>`},
            {
                label: '获取此Marker的信息',
                onClick: () => {
                    map.logInfo(`当前MarkerId为 ${marker.id}`);
                }
            }
        ]
    });
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
显示代码
全屏显示


# 类型定义文件

/**
 * 上下文菜单.
 *
 **/
export  class ContextMenu {
    private options;
    private menuControl;
    private position;
    /**
     * Creates a new ContextMenu menu
     * @param {object} opts options which build the menu e.g. position and items
     * @param {number} opts.width sets the width of the menu including children
     * @param {object} opts.event 事件对象
     * @param {theme} opts.theme 自定义的样式主题,支持dark和light,默认dark
     * @param {boolean} opts.isSticky sets how the menu apears, follow the mouse or sticky
     * @param {Array<ContextMenuItem>} opts.items sets the default items in the menu
     */
    constructor(opts: ContextMenuOptions);
    /**
     * Adds item to this ContextMenu menu instance
     * @param {ContextMenuItem} item item to add to the ContextMenu menu
     */
    add(item: any): void;
    /**
     * Makes this ContextMenu menu visible
     */
    show(): void;
    /**
     * Hides this ContextMenu menu
     */
    hide(): void;
    /**
     * Toggle visibility of menu
     */
    toggle(): void;
}

/**
 * 上下文菜单选项.
 *
 **/
export  interface ContextMenuOptions {
    /** 事件对象. */
    event: Event;
    /** 菜单宽度(包括子菜单),像素,默认150px. */
    width?: string;
    /** 菜单主题色.(dark和light,默认dark)*/
    theme?: string;
    /** 菜单外面容器的内部宽,用于菜单超时范围时自动调位置,默认是window大小宽 可通过 map.getContainer().getBoundingClientRect().width来设置 */
    innerWidth?: number;
    /** 菜单外面容器的内部宽,用于菜单超时范围时自动调位置,默认是window大小高 可通过 map.getContainer().getBoundingClientRect().height来设置 */
    innerHeight?: number;
    /** 子项 */
    items: ContextMenuSubItemOptions[];
}

/**
 * 上下文菜单子项选项.
 *
 **/
export  interface ContextMenuSubItemOptions {
    /** 子菜单类型. */
    type?: "custom" | "multi" | "Button" | "seperator" | "submenu" | "hovermenu" | "normal";
    /** 类型为'custom'时的自定义html内容 */
    markup?: string;
    /** 类型为'multi'时子菜单项*/
    items?: ContextMenuSubItemOptions[];
    /** 点击事件*/
    onClick?: Function;
    /** 菜单名称*/
    label?: string;
    /** 快捷菜单*/
    shortcut?: string;
    /** 是否能用*/
    enabled?: boolean;
    /** css图标*/
    cssIcon?: string;
    /** 图标*/
    icon?: string;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81