improvement: 支持图层事件冒泡配置

This commit is contained in:
thinkinggis 2020-03-28 12:58:13 +08:00
parent 5e72a7d974
commit 6a0e6583dc
7 changed files with 37 additions and 20 deletions

View File

@ -56,6 +56,7 @@ const defaultLayerConfig: Partial<ILayerConfig> = {
visible: true,
autoFit: false,
pickingBuffer: 0,
enablePropagation: false,
zIndex: 0,
blend: 'normal',
pickedFeatureID: -1,

View File

@ -84,20 +84,20 @@ export default class PickingService implements IPickingService {
useFramebuffer(this.pickingFBO, () => {
const layers = this.layerService.getLayers();
layers
.filter((layer) => layer.needPick())
.filter((layer) => layer.needPick(target.type))
.reverse()
.forEach((layer) => {
.some((layer) => {
clear({
framebuffer: this.pickingFBO,
color: [0, 0, 0, 0],
stencil: 0,
depth: 1,
});
layer.hooks.beforePickingEncode.call();
layer.renderModels();
layer.hooks.afterPickingEncode.call();
this.pickFromPickingFBO(layer, target);
const isPicked = this.pickFromPickingFBO(layer, target);
return isPicked && !layer.getLayerConfig().enablePropagation;
});
});
}
@ -105,6 +105,7 @@ export default class PickingService implements IPickingService {
layer: ILayer,
{ x, y, lngLat, type }: IInteractionTarget,
) => {
let isPicked = false;
const { getViewportSize, readPixels } = this.rendererService;
const { width, height } = getViewportSize();
const { enableHighlight, enableSelect } = layer.getLayerConfig();
@ -117,7 +118,7 @@ export default class PickingService implements IPickingService {
yInDevicePixel > height - 1 * window.devicePixelRatio ||
yInDevicePixel < 0
) {
return;
return false;
}
let pickedColors: Uint8Array | undefined;
pickedColors = readPixels({
@ -136,7 +137,10 @@ export default class PickingService implements IPickingService {
) {
const pickedFeatureIdx = decodePickingColor(pickedColors);
const rawFeature = layer.getSource().getFeatureById(pickedFeatureIdx);
if (pickedFeatureIdx !== layer.getCurrentPickId()) {
if (
pickedFeatureIdx !== layer.getCurrentPickId() &&
type === 'mousemove'
) {
type = 'mouseenter';
}
@ -154,8 +158,9 @@ export default class PickingService implements IPickingService {
// );
} else {
// trigger onHover/Click callback on layer
isPicked = true;
layer.setCurrentPickId(pickedFeatureIdx);
this.triggerHoverOnLayer(layer, target);
this.triggerHoverOnLayer(layer, target); // 触发拾取事件
}
} else {
// 未选中
@ -183,8 +188,9 @@ export default class PickingService implements IPickingService {
type === 'click' &&
pickedColors?.toString() !== [0, 0, 0, 0].toString()
) {
this.selectFeature(layer, pickedColors);
this.selectFeature(layer, pickedColors); // toggle select
}
return isPicked;
};
private triggerHoverOnLayer(
layer: ILayer,

View File

@ -106,7 +106,7 @@ export interface ILayer {
options?: ISourceCFG;
};
multiPassRenderer: IMultiPassRenderer;
needPick(): boolean;
needPick(type: string): boolean;
getLayerConfig(): Partial<ILayerConfig & ISceneConfig>;
getContainer(): Container;
setContainer(container: Container): void;
@ -222,6 +222,7 @@ export interface ILayerConfig {
visible: boolean;
zIndex: number;
pickingBuffer: number;
enablePropagation: boolean;
autoFit: boolean;
name: string; //
blend: keyof typeof BlendType;

View File

@ -130,7 +130,7 @@ export default class PixelPickingPass<
* TODO
*/
private pickFromPickingFBO = ({ x, y, lngLat, type }: IInteractionTarget) => {
if (!this.layer.isVisible() || !this.layer.needPick()) {
if (!this.layer.isVisible() || !this.layer.needPick(type)) {
return;
}
const {

View File

@ -831,18 +831,21 @@ export default class BaseLayer<ChildLayerStyleOptions = {}> extends EventEmitter
return this.layerService.clock.getElapsedTime() - this.animateStartTime;
}
public needPick(): boolean {
public needPick(type: string): boolean {
const {
enableHighlight = true,
enableSelect = true,
} = this.getLayerConfig();
const eventNames = this.eventNames().filter((name) => {
return (
name !== 'inited' && name !== 'add' && name !== 'remove' && 'dataupdate' // 非拾取事件排除
);
});
const flag = eventNames.length > 0 || enableHighlight || enableSelect;
return this.isVisible() && flag;
// 判断layer是否监听事件;
let isPick = this.eventNames().indexOf(type) !== -1;
if ((type === 'click' || type === 'dblclick') && enableSelect) {
isPick = true;
}
if (type === 'mousemove' && enableHighlight) {
isPick = true;
}
return this.isVisible() && isPick;
}
public buildModels() {

View File

@ -21,7 +21,7 @@ void main() {
float shape_type = a_Shape;
float newSize = setPickingSize(a_Size)
float newSize = setPickingSize(a_Size);
// radius(16-bit)
v_radius = newSize;

View File

@ -53,6 +53,7 @@ export default class ScaleComponent extends React.Component {
scene.addLayer(layer);
const pointLayer = new PointLayer({
name: '02',
enablePropagation: true,
})
.source(pointsData, {
cluster: true,
@ -63,7 +64,7 @@ export default class ScaleComponent extends React.Component {
})
.size('point_count', [5, 10, 15, 20, 25])
.animate(false)
.active(true)
.active(false)
.color('yellow')
.style({
opacity: 0.5,
@ -71,8 +72,13 @@ export default class ScaleComponent extends React.Component {
});
scene.addLayer(pointLayer);
layer.on('click', (e) => {
console.log(1, e);
layer.setSelect(e.featureId);
});
pointLayer.on('click', (e) => {
console.log(2, e);
pointLayer.setSelect(e.featureId);
});
const scaleControl = new Scale();
const layers = {
点图层: pointLayer,