From 17674cef1eeb500ca5db1a4c3f358817254de71f Mon Sep 17 00:00:00 2001 From: heiyexing <496845051@qq.com> Date: Fri, 28 Oct 2022 10:08:19 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=8E=A7=E4=BB=B6=E7=9A=84=20position?= =?UTF-8?q?=20=E6=94=AF=E6=8C=81=E8=87=AA=E5=AE=9A=E4=B9=89=20DOM=20?= =?UTF-8?q?=E5=AE=B9=E5=99=A8=20(#1440)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: yanxiong --- dev-demos/layer/control/position.tsx | 40 ++++++++++++++----- packages/component/__tests__/control.spec.ts | 11 +++++ .../src/control/baseControl/control.ts | 19 +++++---- .../src/control/baseControl/popperControl.ts | 3 +- .../docs/api/component/control/control.zh.md | 2 +- packages/site/docs/common/control/api.md | 3 +- 6 files changed, 58 insertions(+), 20 deletions(-) diff --git a/dev-demos/layer/control/position.tsx b/dev-demos/layer/control/position.tsx index cfc30af3c6..d481248955 100644 --- a/dev-demos/layer/control/position.tsx +++ b/dev-demos/layer/control/position.tsx @@ -1,7 +1,16 @@ -import { GaodeMap, Logo, PositionName, Scale, Scene, Zoom } from '@antv/l7'; -import { FunctionComponent, useEffect } from 'react'; +import { + GaodeMap, + IControlOption, + Logo, + Scale, + Scene, + Zoom, +} from '@antv/l7'; +import React, { FunctionComponent, useEffect, useRef } from 'react'; const Demo: FunctionComponent = () => { + const containerRef = useRef(null); + useEffect(() => { const scene = new Scene({ id: 'map', @@ -15,7 +24,7 @@ const Demo: FunctionComponent = () => { }); scene.on('loaded', () => { - function createTestControl(position: PositionName) { + function createTestControl(position: IControlOption['position']) { scene.addControl( new Zoom({ position, @@ -48,16 +57,27 @@ const Demo: FunctionComponent = () => { createTestControl('leftcenter'); createTestControl('rightcenter'); createTestControl('bottomcenter'); + + if (containerRef.current) { + scene.addControl( + new Logo({ + position: containerRef.current, + }), + ); + } }); }, []); return ( -
+ <> +
+
+ ); }; diff --git a/packages/component/__tests__/control.spec.ts b/packages/component/__tests__/control.spec.ts index 32f0670dbe..21b0a821c5 100644 --- a/packages/component/__tests__/control.spec.ts +++ b/packages/component/__tests__/control.spec.ts @@ -1,6 +1,7 @@ import { TestScene } from '@antv/l7-test-utils'; import { DOM } from '@antv/l7-utils'; import { Control } from '../src/control/baseControl'; +import { Zoom } from '../src/control/zoom'; class TestControl extends Control { public onAdd(): HTMLElement { @@ -65,4 +66,14 @@ describe('control', () => { expect(container.classList).toContain(className); expect(container.style.color).toEqual(color); }); + + // 测试自定义位置 + it('position', () => { + const dom = document.createElement('div'); + const zoom = new Zoom({ + position: dom, + }); + scene.addControl(zoom); + expect(dom.firstChild).toEqual(zoom.getContainer()); + }); }); diff --git a/packages/component/src/control/baseControl/control.ts b/packages/component/src/control/baseControl/control.ts index ac20c94587..778aabd7af 100644 --- a/packages/component/src/control/baseControl/control.ts +++ b/packages/component/src/control/baseControl/control.ts @@ -21,7 +21,7 @@ export { Control }; export interface IControlOption { name: string; - position: PositionName; + position: PositionName | Element; className?: string; style?: string; [key: string]: any; @@ -226,7 +226,7 @@ export default class Control * @param position */ public setPosition( - position: PositionType | PositionName = PositionType.TOPLEFT, + position: PositionType | IControlOption['position'] = PositionType.TOPLEFT, ) { // 考虑组件的自动布局,需要销毁重建 const controlService = this.controlService; @@ -273,13 +273,18 @@ export default class Control * @protected */ protected insertContainer() { - const container = this.container; const position = this.controlOption.position; - const corner = this.controlService.controlCorners[position]; - if (position.indexOf('bottom') !== -1) { - corner.insertBefore(container, corner.firstChild); + const container = this.container; + + if (position instanceof Element) { + position.appendChild(container); } else { - corner.appendChild(container); + const corner = this.controlService.controlCorners[position]; + if (position.indexOf('bottom') !== -1) { + corner.insertBefore(container, corner.firstChild); + } else { + corner.appendChild(container); + } } } diff --git a/packages/component/src/control/baseControl/popperControl.ts b/packages/component/src/control/baseControl/popperControl.ts index e492377c50..45c82e86b9 100644 --- a/packages/component/src/control/baseControl/popperControl.ts +++ b/packages/component/src/control/baseControl/popperControl.ts @@ -52,7 +52,8 @@ export default class PopperControl< const position = option?.position ?? defaultOption.position!; return { ...super.getDefault(option), - popperPlacement: PopperPlacementMap[position], + popperPlacement: + position instanceof Element ? 'bottom' : PopperPlacementMap[position], popperTrigger: 'click', }; } diff --git a/packages/site/docs/api/component/control/control.zh.md b/packages/site/docs/api/component/control/control.zh.md index 0a615446c4..b73628fbce 100644 --- a/packages/site/docs/api/component/control/control.zh.md +++ b/packages/site/docs/api/component/control/control.zh.md @@ -47,7 +47,7 @@ const onPositionChange = () => { ## 插槽 -当前 L7 中的控件支持插入到地图的**左上、左下、右上、右下、上、左、下、右**八个位置的控件插槽中,并且在同一插槽中的多个控件支持**横向**和**纵向**排列。 +当前 L7 中的控件支持插入到地图的**左上、左下、右上、右下、上、左、下、右**八个位置插槽或者用户自定义的 `DOM` 中,并且在同一地图插槽中,多个控件之间支持**横向**和**纵向**排列。 在初始化所有的控件类时,可以传入 `position` 参数来设置控件对应的插槽以及排列方式。 diff --git a/packages/site/docs/common/control/api.md b/packages/site/docs/common/control/api.md index 1f3e179e6f..994f1408a1 100644 --- a/packages/site/docs/common/control/api.md +++ b/packages/site/docs/common/control/api.md @@ -19,5 +19,6 @@ export type Position = | 'topcenter' // ↑ 上方中央,横向排列 | 'bottomcenter' // ↓ 下方中间,横向排列 | 'leftcenter' // ← 左边中间,纵向排列 - | 'rightcenter'; // → 右边中间,纵向排列 + | 'rightcenter' // → 右边中间,纵向排列 + | Element; // 传入 DOM 作为当前控件的容器 ```