mirror of https://gitee.com/antv-l7/antv-l7
fix: 还原旧版图层选择控件 Layers
This commit is contained in:
parent
2980c38d77
commit
f706753866
|
@ -1,11 +1,4 @@
|
|||
import {
|
||||
GaodeMap,
|
||||
IControlOption,
|
||||
Logo,
|
||||
Scale,
|
||||
Scene,
|
||||
Zoom,
|
||||
} from '@antv/l7';
|
||||
import { GaodeMap, IControlOption, Logo, Scale, Scene, Zoom } from '@antv/l7';
|
||||
import React, { FunctionComponent, useEffect, useRef } from 'react';
|
||||
|
||||
const Demo: FunctionComponent = () => {
|
||||
|
|
|
@ -0,0 +1,325 @@
|
|||
import { PositionType } from '@antv/l7-core';
|
||||
import { bindAll, DOM } from '@antv/l7-utils';
|
||||
import Control, { IControlOption } from './baseControl/control';
|
||||
|
||||
interface IInputItem extends HTMLInputElement {
|
||||
layerId: string;
|
||||
}
|
||||
|
||||
export interface ILayerControlOption extends IControlOption {
|
||||
collapsed: boolean;
|
||||
autoZIndex: boolean;
|
||||
hideSingleBase: boolean;
|
||||
sortLayers: boolean;
|
||||
|
||||
sortFunction: (...args: any[]) => any;
|
||||
}
|
||||
|
||||
export default class Layers extends Control {
|
||||
private layerControlInputs: any[];
|
||||
private layers: any[];
|
||||
private lastZIndex: number;
|
||||
private handlingClick: boolean;
|
||||
private layersLink: HTMLElement;
|
||||
private baseLayersList: HTMLElement;
|
||||
private separator: HTMLElement;
|
||||
private overlaysList: HTMLElement;
|
||||
private form: HTMLElement;
|
||||
|
||||
constructor(cfg: Partial<ILayerControlOption>) {
|
||||
super(cfg);
|
||||
this.layerControlInputs = [];
|
||||
this.layers = [];
|
||||
this.lastZIndex = 0;
|
||||
this.handlingClick = false;
|
||||
this.initLayers();
|
||||
|
||||
bindAll(
|
||||
[
|
||||
'checkDisabledLayers',
|
||||
'onLayerChange',
|
||||
'collapse',
|
||||
'extend',
|
||||
'expand',
|
||||
'onInputClick',
|
||||
],
|
||||
this,
|
||||
);
|
||||
}
|
||||
|
||||
public getDefault() {
|
||||
return {
|
||||
collapsed: true,
|
||||
position: PositionType.TOPRIGHT,
|
||||
autoZIndex: true,
|
||||
hideSingleBase: false,
|
||||
sortLayers: false,
|
||||
name: 'layers',
|
||||
};
|
||||
}
|
||||
public onAdd() {
|
||||
this.initLayout();
|
||||
this.update();
|
||||
this.mapsService.on('zoomend', this.checkDisabledLayers);
|
||||
this.layers.forEach((layerItem) => {
|
||||
layerItem.layer.on('remove', this.onLayerChange);
|
||||
layerItem.layer.on('add', this.onLayerChange);
|
||||
});
|
||||
return this.container;
|
||||
}
|
||||
|
||||
public addVisualLayer(layer: any, name: string | number) {
|
||||
this.addLayer(layer, name, true);
|
||||
return this.mapsService ? this.update() : this;
|
||||
}
|
||||
public expand() {
|
||||
const { height } = this.renderService.getViewportSize();
|
||||
DOM.addClass(this.container, 'l7-control-layers-expanded');
|
||||
this.form.style.height = 'null';
|
||||
const acceptableHeight = height - (this.container.offsetTop + 50);
|
||||
if (acceptableHeight < this.form.clientHeight) {
|
||||
DOM.addClass(this.form, 'l7-control-layers-scrollbar');
|
||||
this.form.style.height = acceptableHeight + 'px';
|
||||
} else {
|
||||
DOM.removeClass(this.form, 'l7-control-layers-scrollbar');
|
||||
}
|
||||
this.checkDisabledLayers();
|
||||
return this;
|
||||
}
|
||||
|
||||
public collapse() {
|
||||
DOM.removeClass(this.container, 'l7-control-layers-expanded');
|
||||
return this;
|
||||
}
|
||||
|
||||
public onRemove() {
|
||||
if (!this.mapsService) {
|
||||
return;
|
||||
}
|
||||
this.mapsService.off('click', this.collapse);
|
||||
this.layers.forEach((layerItem) => {
|
||||
layerItem.layer.off('remove', this.onLayerChange);
|
||||
layerItem.layer.off('add', this.onLayerChange);
|
||||
});
|
||||
}
|
||||
private initLayout() {
|
||||
const className = 'l7-control-layers';
|
||||
const container = (this.container = DOM.create('div', className));
|
||||
const { collapsed } = this.controlOption;
|
||||
// makes this work on IE touch devices by stopping it from firing a mouseout event when the touch is released
|
||||
container.setAttribute('aria-haspopup', 'true');
|
||||
const form = (this.form = DOM.create(
|
||||
'form',
|
||||
className + '-list',
|
||||
) as HTMLElement);
|
||||
|
||||
if (collapsed) {
|
||||
this.mapsService.on('click', this.collapse);
|
||||
container.addEventListener('mouseenter', this.expand);
|
||||
container.addEventListener('mouseleave', this.collapse);
|
||||
}
|
||||
|
||||
this.layersLink = DOM.create('a', className + '-toggle', container);
|
||||
const link = this.layersLink;
|
||||
// link.href = '#';
|
||||
link.title = 'Layers';
|
||||
if (!collapsed) {
|
||||
this.expand();
|
||||
}
|
||||
this.baseLayersList = DOM.create('div', className + '-base', form);
|
||||
this.separator = DOM.create('div', className + '-separator', form);
|
||||
this.overlaysList = DOM.create('div', className + '-overlays', form);
|
||||
container.appendChild(form);
|
||||
}
|
||||
private initLayers() {
|
||||
const { baseLayers = {}, overlayers = {} } = this.controlOption;
|
||||
Object.keys(baseLayers).forEach((name: string) => {
|
||||
// baseLayers[name].once('inited', this.update);
|
||||
this.addLayer(baseLayers[name], name, false);
|
||||
});
|
||||
Object.keys(overlayers).forEach((name: any) => {
|
||||
// overlayers[name].once('inited', this.update);
|
||||
this.addLayer(overlayers[name], name, true);
|
||||
});
|
||||
}
|
||||
|
||||
private update() {
|
||||
if (!this.container) {
|
||||
return this;
|
||||
}
|
||||
|
||||
DOM.empty(this.baseLayersList);
|
||||
DOM.empty(this.overlaysList);
|
||||
|
||||
this.layerControlInputs = [];
|
||||
let baseLayersPresent;
|
||||
let overlaysPresent;
|
||||
let i;
|
||||
let obj;
|
||||
let baseLayersCount = 0;
|
||||
|
||||
for (i = 0; i < this.layers.length; i++) {
|
||||
obj = this.layers[i];
|
||||
this.addItem(obj);
|
||||
overlaysPresent = overlaysPresent || obj.overlay;
|
||||
baseLayersPresent = baseLayersPresent || !obj.overlay;
|
||||
baseLayersCount += !obj.overlay ? 1 : 0;
|
||||
}
|
||||
|
||||
// Hide base layers section if there's only one layer.
|
||||
if (this.controlOption.hideSingleBase) {
|
||||
baseLayersPresent = baseLayersPresent && baseLayersCount > 1;
|
||||
this.baseLayersList.style.display = baseLayersPresent ? '' : 'none';
|
||||
}
|
||||
|
||||
this.separator.style.display =
|
||||
overlaysPresent && baseLayersPresent ? '' : 'none';
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private checkDisabledLayers() {
|
||||
const inputs = this.layerControlInputs;
|
||||
let input: IInputItem;
|
||||
let layer;
|
||||
const zoom = this.mapsService.getZoom();
|
||||
|
||||
for (let i = inputs.length - 1; i >= 0; i--) {
|
||||
input = inputs[i];
|
||||
layer = this.layerService.getLayer(input.layerId);
|
||||
|
||||
if (layer && layer.inited) {
|
||||
const minZoom = layer.getMinZoom();
|
||||
const maxZoom = layer.getMaxZoom();
|
||||
|
||||
input.disabled = zoom < minZoom || zoom > maxZoom;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private addLayer(layer: any, name: string | number, overlay: boolean) {
|
||||
if (this.mapsService) {
|
||||
layer.on('add', this.onLayerChange);
|
||||
layer.on('remove', this.onLayerChange);
|
||||
}
|
||||
this.layers.push({
|
||||
layer,
|
||||
name,
|
||||
overlay,
|
||||
});
|
||||
const { sortLayers, sortFunction, autoZIndex } = this.controlOption;
|
||||
if (sortLayers) {
|
||||
this.layers.sort((a, b) => {
|
||||
return sortFunction(a.layer, b.layer, a.name, b.name);
|
||||
});
|
||||
}
|
||||
|
||||
if (autoZIndex && layer.setZIndex) {
|
||||
this.lastZIndex++;
|
||||
layer.setZIndex(this.lastZIndex);
|
||||
}
|
||||
|
||||
this.expandIfNotCollapsed();
|
||||
}
|
||||
|
||||
private expandIfNotCollapsed() {
|
||||
if (this.mapsService && !this.controlOption.collapsed) {
|
||||
this.expand();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private onLayerChange(e: any) {
|
||||
if (!this.handlingClick) {
|
||||
this.update();
|
||||
}
|
||||
|
||||
const obj = this.layerService.getLayer(e.target.layerId);
|
||||
|
||||
// @ts-ignore
|
||||
const type = obj?.overlay
|
||||
? e.type === 'add'
|
||||
? 'overlayadd'
|
||||
: 'overlayremove'
|
||||
: e.type === 'add'
|
||||
? 'baselayerchange'
|
||||
: null;
|
||||
|
||||
if (type) {
|
||||
this.emit(type, obj);
|
||||
}
|
||||
}
|
||||
|
||||
private createRadioElement(name: string, checked: boolean): ChildNode {
|
||||
const radioHtml =
|
||||
'<input type="radio" class="l7-control-layers-selector" name="' +
|
||||
name +
|
||||
'"' +
|
||||
(checked ? ' checked="checked"' : '') +
|
||||
'/>';
|
||||
|
||||
const radioFragment = document.createElement('div');
|
||||
radioFragment.innerHTML = radioHtml;
|
||||
|
||||
return radioFragment.firstChild as ChildNode;
|
||||
}
|
||||
|
||||
private addItem(obj: any) {
|
||||
const label = document.createElement('label');
|
||||
const layer = this.layerService.getLayer(obj.layer.id);
|
||||
const checked = layer && layer.inited && obj.layer.isVisible();
|
||||
let input: IInputItem;
|
||||
if (obj.overlay) {
|
||||
input = document.createElement('input') as IInputItem;
|
||||
input.type = 'checkbox';
|
||||
input.className = 'l7-control-layers-selector';
|
||||
input.defaultChecked = checked;
|
||||
} else {
|
||||
input = this.createRadioElement('l7-base-layers', checked) as IInputItem;
|
||||
}
|
||||
this.layerControlInputs.push(input);
|
||||
input.layerId = obj.layer.id;
|
||||
input.addEventListener('click', this.onInputClick);
|
||||
|
||||
const name = document.createElement('span');
|
||||
name.innerHTML = ' ' + obj.name;
|
||||
|
||||
const holder = document.createElement('div');
|
||||
|
||||
label.appendChild(holder);
|
||||
holder.appendChild(input);
|
||||
holder.appendChild(name);
|
||||
|
||||
const container = obj.overlay ? this.overlaysList : this.baseLayersList;
|
||||
container.appendChild(label);
|
||||
|
||||
this.checkDisabledLayers();
|
||||
return label;
|
||||
}
|
||||
|
||||
private onInputClick() {
|
||||
const inputs = this.layerControlInputs;
|
||||
let input;
|
||||
let layer;
|
||||
const addedLayers = [];
|
||||
const removedLayers = [];
|
||||
this.handlingClick = true;
|
||||
for (let i = inputs.length - 1; i >= 0; i--) {
|
||||
input = inputs[i];
|
||||
layer = this.layerService.getLayer(input.layerId);
|
||||
if (input.checked) {
|
||||
addedLayers.push(layer);
|
||||
} else if (!input.checked) {
|
||||
removedLayers.push(layer);
|
||||
}
|
||||
}
|
||||
removedLayers.forEach((l: any) => {
|
||||
l.hide();
|
||||
});
|
||||
addedLayers.forEach((l: any) => {
|
||||
l.show();
|
||||
});
|
||||
|
||||
this.handlingClick = false;
|
||||
}
|
||||
}
|
|
@ -18,6 +18,9 @@ export * from './control/scale';
|
|||
export * from './popup/popup';
|
||||
export * from './popup/layerPopup';
|
||||
|
||||
// 为了兼容老版 LayerSwitch
|
||||
export * from './control/layer';
|
||||
|
||||
export { Marker, MarkerLayer };
|
||||
|
||||
export * from './interface';
|
||||
|
|
Loading…
Reference in New Issue