Newer
Older
DH_Apicture / public / static / libs / mapbox / extend / mapbox-gl-contextmenu.js
@wudi wudi 19 days ago 4 KB 1
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ?
        module.exports = factory() :
        typeof define === 'function' && define.amd ? define(factory) :
            (global = typeof globalThis !== 'undefined' ? globalThis :
                global || self, global.mapboxgl1.ContextMenu = factory(global.mapboxgl1));
}(window, (function (mapboxgl) {

    const css = `
/* 样式设置 */
.mapbox-gl-contextmenu {
  background-color: white;
  border: 1px solid #ccc;
  box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
  padding: 5px;
  font-size: 14px;
  z-index: 9999;
  display: none;
  color:black;
}

.mapbox-gl-contextmenu ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.mapbox-gl-contextmenu li {
  padding: 8px;
  cursor: pointer;
}

.mapbox-gl-contextmenu li:hover {
  background-color: #f0f0f0;
}
`;
    document.write(`<style type='text/css'>${css}</style>`);

     class ContextMenu {

        constructor(options) {
            this._options = options || {};
            this._contextmenu = this._options.contextmenu || function () {};
            this._items = this._options.items || []; // 用户定义的菜单项
            this._contextMenuData = null; // 存储右键点击的坐标
        }

        // 添加到地图
        onAdd(map) {
            this._map = map;

            // 创建菜单容器
            this._container = document.createElement('div');
            this._container.className = 'mapbox-gl-contextmenu';
            this._container.style.position = 'absolute';
            this._container.style.display = 'none';
            this._container.style.zIndex = '9999'; // 确保菜单在顶部

            // 监听右键点击事件
            map.on('contextmenu', (e) => {
                this._showMenu(e); // 显示菜单
                this._contextmenu(e.lngLat, this._contextMenuFeature,this._contextMenuLayerId);
            });

            // 监听地图的平移或缩放事件,更新菜单位置
            map.on('move', () => {
                if (this._contextMenuData) {
                    this._updateMenuPosition(this._contextMenuData);
                }
            });

            // 点击地图的其他地方时关闭菜单
            map.on('click', () => {
                this._closeMenu();
            });

            // 点击页面其他地方时关闭菜单
            document.addEventListener('click', (event) => {
                if (!this._container.contains(event.target)) {
                    this._closeMenu();
                }
            });

            return this._container;
        };

        // 显示菜单
        _showMenu(e) {
            // 阻止默认右键菜单
            e.preventDefault();

            // 获取右键点击的经纬度
            this._contextMenuData = e.lngLat;

            // 使用 map.project() 方法将经纬度转换为屏幕坐标
            this._updateMenuPosition(this._contextMenuData);

            // 清空当前菜单内容
            this._container.innerHTML = '';
            const feature = (this._map.queryRenderedFeatures([[e.point.x - 10 / 2, e.point.y - 10 / 2], [e.point.x + 10 / 2, e.point.y + 10 / 2],]) || [])[0];

            this._contextMenuFeature = feature;
            this._contextMenuLayerId = ((feature || {}).layer || {}).id;
                // 创建菜单项列表
                const ul = document.createElement('ul');
                this._items.forEach((item) => {
                    if(item.isShow?item.isShow(this._contextMenuData,this._contextMenuFeature,this._contextMenuLayerId):true){
                        const li = document.createElement('li');
                        li.innerHTML = item.text;
                        li.addEventListener('click', () => {
                            this._contextMenuCheck = item.text;
                            if (item.callback) {
                                item.callback(this._contextMenuData,this._contextMenuFeature,this._contextMenuLayerId);
                            }
                            this._closeMenu();
                        });
                        ul.appendChild(li);
                    }
                });

                this._container.appendChild(ul);

                // 显示菜单
                this._container.style.display = 'block';
        };

        // 更新菜单的位置
        _updateMenuPosition(lngLat) {
            // 使用 map.project() 方法将经纬度转换为屏幕坐标
            const point = this._map.project(lngLat);

            // 设置菜单的位置
            this._container.style.left = `${point.x}px`;
            this._container.style.top = `${point.y}px`;
        };

        // 关闭菜单
        _closeMenu() {
            if (this._container) {
                this._container.style.display = 'none';
            }
        };

        // 将右键菜单控件添加到地图上
        addTo(map) {
            this._map = map;
            map.getContainer().appendChild(this.onAdd(map));
        };
    }

    return ContextMenu;
})));