唯杰地图 logo唯杰地图
VJMAP
EN

右键菜单

更新于 2024-09-28约 29 分钟
.md

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

常用方法

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

菜单项类型

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

示例

地图上下文菜单

地图上下文菜单

// 选中的图标,也可以直接指定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)
                            }
                        }
                    }
                ]}
        ]
    });
})
在沙箱中运行,调用唯杰地图公共演示服务


覆盖物图层右键菜单

覆盖物图层右键菜单

// 设置点击一个覆盖物时弹出菜单,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")
在沙箱中运行,调用唯杰地图公共演示服务


标记Marker右键菜单

标记Marker右键菜单

 // 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}`);
                }
            }
        ]
    });
})
在沙箱中运行,调用唯杰地图公共演示服务


类型定义文件

/**
 * 上下文菜单.
 *
 **/
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;
}

这篇文档有帮助吗?