mirror of https://gitee.com/antv-l7/antv-l7
feat(picking): support advanced picking API: `layer.pick({x, y})`
This commit is contained in:
parent
5fc540f8fd
commit
39fb89cc7f
|
@ -55,6 +55,7 @@ export * from './services/component/IControlService';
|
||||||
export * from './services/component/IMarkerService';
|
export * from './services/component/IMarkerService';
|
||||||
export * from './services/component/IPopUpService';
|
export * from './services/component/IPopUpService';
|
||||||
export * from './services/log/ILogService';
|
export * from './services/log/ILogService';
|
||||||
|
export * from './services/interaction/IInteractionService';
|
||||||
|
|
||||||
/** 全部渲染服务接口 */
|
/** 全部渲染服务接口 */
|
||||||
export * from './services/renderer/IAttribute';
|
export * from './services/renderer/IAttribute';
|
||||||
|
|
|
@ -10,4 +10,5 @@ export interface IInteractionService {
|
||||||
eventName: InteractionEvent,
|
eventName: InteractionEvent,
|
||||||
callback: (params: { x: number; y: number }) => void,
|
callback: (params: { x: number; y: number }) => void,
|
||||||
): void;
|
): void;
|
||||||
|
triggerHover({ x, y }: { x: number; y: number }): void;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,10 @@ export default class InteractionService extends EventEmitter
|
||||||
this.off(InteractionEvent.Hover);
|
this.off(InteractionEvent.Hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public triggerHover({ x, y }: { x: number; y: number }) {
|
||||||
|
this.emit(InteractionEvent.Hover, { x, y });
|
||||||
|
}
|
||||||
|
|
||||||
private addEventListenerOnMap() {
|
private addEventListenerOnMap() {
|
||||||
const $containter = this.mapService.getMapContainer();
|
const $containter = this.mapService.getMapContainer();
|
||||||
if ($containter) {
|
if ($containter) {
|
||||||
|
|
|
@ -73,6 +73,10 @@ export interface ILayer {
|
||||||
getEncodedData(): IEncodeFeature[];
|
getEncodedData(): IEncodeFeature[];
|
||||||
getStyleOptions(): Partial<ILayerInitializationOptions>;
|
getStyleOptions(): Partial<ILayerInitializationOptions>;
|
||||||
isDirty(): boolean;
|
isDirty(): boolean;
|
||||||
|
/**
|
||||||
|
* 直接调用拾取方法,在非鼠标交互场景中使用
|
||||||
|
*/
|
||||||
|
pick(query: { x: number; y: number }): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -126,11 +126,17 @@ export default class PixelPickingPass implements IPass {
|
||||||
const { width, height } = getViewportSize();
|
const { width, height } = getViewportSize();
|
||||||
const { enableHighlight } = this.layer.getStyleOptions();
|
const { enableHighlight } = this.layer.getStyleOptions();
|
||||||
|
|
||||||
|
const xInDevicePixel = x * window.devicePixelRatio;
|
||||||
|
const yInDevicePixel = y * window.devicePixelRatio;
|
||||||
|
if (xInDevicePixel > width || xInDevicePixel < 0 || yInDevicePixel > height || yInDevicePixel < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let pickedColors: Uint8Array | undefined;
|
let pickedColors: Uint8Array | undefined;
|
||||||
useFramebuffer(this.pickingFBO, () => {
|
useFramebuffer(this.pickingFBO, () => {
|
||||||
// avoid realloc
|
// avoid realloc
|
||||||
pickedColors = readPixels({
|
pickedColors = readPixels({
|
||||||
x: Math.round(x * window.devicePixelRatio),
|
x: Math.round(xInDevicePixel),
|
||||||
// 视口坐标系原点在左上,而 WebGL 在左下,需要翻转 Y 轴
|
// 视口坐标系原点在左上,而 WebGL 在左下,需要翻转 Y 轴
|
||||||
y: Math.round(height - (y + 1) * window.devicePixelRatio),
|
y: Math.round(height - (y + 1) * window.devicePixelRatio),
|
||||||
width: 1,
|
width: 1,
|
||||||
|
@ -171,7 +177,6 @@ export default class PixelPickingPass implements IPass {
|
||||||
y: number;
|
y: number;
|
||||||
feature: unknown;
|
feature: unknown;
|
||||||
}) {
|
}) {
|
||||||
// TODO: onClick
|
|
||||||
const { onHover, onClick } = this.layer.getStyleOptions();
|
const { onHover, onClick } = this.layer.getStyleOptions();
|
||||||
if (onHover) {
|
if (onHover) {
|
||||||
onHover({
|
onHover({
|
||||||
|
@ -180,6 +185,13 @@ export default class PixelPickingPass implements IPass {
|
||||||
feature,
|
feature,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (onClick) {
|
||||||
|
onClick({
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
feature,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3,12 +3,14 @@ import {
|
||||||
IFontService,
|
IFontService,
|
||||||
IGlobalConfigService,
|
IGlobalConfigService,
|
||||||
IIconService,
|
IIconService,
|
||||||
|
IInteractionService,
|
||||||
ILayer,
|
ILayer,
|
||||||
ILayerInitializationOptions,
|
ILayerInitializationOptions,
|
||||||
ILayerPlugin,
|
ILayerPlugin,
|
||||||
IMapService,
|
IMapService,
|
||||||
IModel,
|
IModel,
|
||||||
IMultiPassRenderer,
|
IMultiPassRenderer,
|
||||||
|
InteractionEvent,
|
||||||
IRendererService,
|
IRendererService,
|
||||||
IShaderModuleService,
|
IShaderModuleService,
|
||||||
ISourceCFG,
|
ISourceCFG,
|
||||||
|
@ -149,6 +151,9 @@ export default class BaseLayer<ChildLayerStyleOptions = {}> implements ILayer {
|
||||||
@lazyInject(TYPES.IMapService)
|
@lazyInject(TYPES.IMapService)
|
||||||
private readonly map: IMapService;
|
private readonly map: IMapService;
|
||||||
|
|
||||||
|
@lazyInject(TYPES.IInteractionService)
|
||||||
|
private readonly interactionService: IInteractionService;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
styleOptions: Partial<ILayerInitializationOptions & ChildLayerStyleOptions>,
|
styleOptions: Partial<ILayerInitializationOptions & ChildLayerStyleOptions>,
|
||||||
) {
|
) {
|
||||||
|
@ -278,6 +283,10 @@ export default class BaseLayer<ChildLayerStyleOptions = {}> implements ILayer {
|
||||||
return this.encodedData;
|
return this.encodedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public pick({ x, y }: { x: number; y: number }) {
|
||||||
|
this.interactionService.triggerHover({ x, y });
|
||||||
|
}
|
||||||
|
|
||||||
protected buildLayerModel(options: ILayerModelInitializationOptions): IModel {
|
protected buildLayerModel(options: ILayerModelInitializationOptions): IModel {
|
||||||
const { moduleName, vertexShader, fragmentShader, triangulation } = options;
|
const { moduleName, vertexShader, fragmentShader, triangulation } = options;
|
||||||
this.shaderModuleService.registerModule(moduleName, {
|
this.shaderModuleService.registerModule(moduleName, {
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
xxxss
|
|
|
@ -69,17 +69,10 @@ export default class AdvancedAPI extends React.Component {
|
||||||
enablePicking: true,
|
enablePicking: true,
|
||||||
enableHighlight: true,
|
enableHighlight: true,
|
||||||
highlightColor: [0, 0, 255],
|
highlightColor: [0, 0, 255],
|
||||||
|
pickingX: window.innerWidth / 2,
|
||||||
|
pickingY: window.innerHeight / 2,
|
||||||
};
|
};
|
||||||
const pointFolder = gui.addFolder('拾取 & 高亮');
|
const pointFolder = gui.addFolder('非鼠标 hover 交互');
|
||||||
// pointFolder
|
|
||||||
// .add(styleOptions, 'enablePicking')
|
|
||||||
// .onChange((enablePicking: boolean) => {
|
|
||||||
// // FIXME: 该配置项会影响到初始化阶段 PixelPickingPass 的添加,暂不支持在运行时更改
|
|
||||||
// layer.style({
|
|
||||||
// enablePicking,
|
|
||||||
// });
|
|
||||||
// scene.render();
|
|
||||||
// });
|
|
||||||
pointFolder
|
pointFolder
|
||||||
.add(styleOptions, 'enableHighlight')
|
.add(styleOptions, 'enableHighlight')
|
||||||
.onChange((enableHighlight: boolean) => {
|
.onChange((enableHighlight: boolean) => {
|
||||||
|
@ -88,6 +81,18 @@ export default class AdvancedAPI extends React.Component {
|
||||||
});
|
});
|
||||||
scene.render();
|
scene.render();
|
||||||
});
|
});
|
||||||
|
pointFolder
|
||||||
|
.add(styleOptions, 'pickingX', 0, window.innerWidth)
|
||||||
|
.onChange((pickingX: number) => {
|
||||||
|
layer.pick({ x: pickingX, y: styleOptions.pickingY });
|
||||||
|
// scene.render();
|
||||||
|
});
|
||||||
|
pointFolder
|
||||||
|
.add(styleOptions, 'pickingY', 0, window.innerHeight)
|
||||||
|
.onChange((pickingY: number) => {
|
||||||
|
layer.pick({ x: styleOptions.pickingX, y: pickingY });
|
||||||
|
// scene.render();
|
||||||
|
});
|
||||||
pointFolder
|
pointFolder
|
||||||
.addColor(styleOptions, 'highlightColor')
|
.addColor(styleOptions, 'highlightColor')
|
||||||
.onChange((highlightColor: number[]) => {
|
.onChange((highlightColor: number[]) => {
|
||||||
|
|
Loading…
Reference in New Issue