From dbd0684bd1eb0220641e456b3b4f8126f2d29c40 Mon Sep 17 00:00:00 2001
From: Cmen <1176967590@qq.com>
Date: Mon, 28 Feb 2022 17:39:09 +0800
Subject: [PATCH] =?UTF-8?q?=E9=80=89=E4=B8=AD=E4=BA=A4=E4=BA=92?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/editor/Catalog/index.tsx | 17 ++++++++++---
src/editor/Catalog/style.less | 7 ++++--
src/editor/Plot/Tools/index.tsx | 4 +--
src/editor/Plot/index.tsx | 2 +-
src/editor/Plot/mapHooks.ts | 4 +--
src/map/constants.ts | 4 +++
src/map/index.ts | 44 ++++++++++++++++++++++++---------
src/store/actions.ts | 23 ++++++++++-------
src/store/index.ts | 2 +-
src/store/initState.ts | 3 ++-
src/store/reducers/index.ts | 3 ++-
src/store/reducers/map/index.ts | 17 ++++++++++---
src/store/type.ts | 7 +++---
src/types/enum.ts | 13 ++++++++++
14 files changed, 110 insertions(+), 40 deletions(-)
diff --git a/src/editor/Catalog/index.tsx b/src/editor/Catalog/index.tsx
index d074312..c3f41e4 100644
--- a/src/editor/Catalog/index.tsx
+++ b/src/editor/Catalog/index.tsx
@@ -1,10 +1,10 @@
import { Collapse } from "antd";
-import { useSelector } from "react-redux";
+import { useDispatch, useSelector } from "react-redux";
-import { mapStateSelector } from "@store";
-import { IOverlay } from "@store";
+import { IOverlay, EditorAction, mapStateSelector } from "@store";
import "./style.less";
+import classNames from "classnames";
const { Panel } = Collapse;
@@ -14,12 +14,21 @@ export type OverlayListProps = {
const OverlayList = (props: OverlayListProps) => {
const { overlays } = props;
+ const dispatch = useDispatch();
+
+ const onClick = (id: string) => () =>
+ dispatch(EditorAction.selectOverlay(id));
+ const { selectedIds } = useSelector(mapStateSelector);
return (
<>
{overlays.map((overlay, index) => {
+ const selected = selectedIds && selectedIds.indexOf(overlay.id) >= 0;
+ const className = classNames("overlay-item", {
+ "overlay-item-selected": selected,
+ });
return (
-
+
{overlay.name}
);
diff --git a/src/editor/Catalog/style.less b/src/editor/Catalog/style.less
index 2031058..fbdbc2d 100644
--- a/src/editor/Catalog/style.less
+++ b/src/editor/Catalog/style.less
@@ -10,7 +10,10 @@
.overlay-item{
margin-bottom: 4px;
cursor: pointer;
- &:hover, &[data-selected]{
- background-color: #f7fafc;
+ &:hover{
+ background-color: #e5e6e7;
}
+}
+.overlay-item-selected{
+ background-color: #e5e6e7;
}
\ No newline at end of file
diff --git a/src/editor/Plot/Tools/index.tsx b/src/editor/Plot/Tools/index.tsx
index b2599f9..06ba310 100644
--- a/src/editor/Plot/Tools/index.tsx
+++ b/src/editor/Plot/Tools/index.tsx
@@ -1,7 +1,7 @@
import { Tooltip } from "antd";
import { useDispatch, useSelector } from "react-redux";
import classnames from "classnames";
-import { editorAction, OverlayNamePrefixs, mapStateSelector } from "@store";
+import { EditorAction, OverlayNamePrefixs, mapStateSelector } from "@store";
import { OverlayTypes } from "@types";
type IconWithTipProps = {
@@ -43,7 +43,7 @@ const OverlayTool = (props: OverlayToolProps) => {
const { overlayType } = useSelector(mapStateSelector);
const selected = type === overlayType;
- const onClick = () => dispatch(editorAction.createOverlay(type));
+ const onClick = () => dispatch(EditorAction.createOverlay(type));
return
;
};
diff --git a/src/editor/Plot/index.tsx b/src/editor/Plot/index.tsx
index d454032..c7a5bb0 100644
--- a/src/editor/Plot/index.tsx
+++ b/src/editor/Plot/index.tsx
@@ -2,7 +2,7 @@ import { Layout } from "antd";
import { useEffect, useRef, useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { MapEditor } from "@map";
-import { editorAction, IEditorState } from "@store";
+import { IEditorState } from "@store";
import Tools from "./Tools";
import { registerMapEventHooks } from "./mapHooks";
diff --git a/src/editor/Plot/mapHooks.ts b/src/editor/Plot/mapHooks.ts
index 1ff8113..1fed897 100644
--- a/src/editor/Plot/mapHooks.ts
+++ b/src/editor/Plot/mapHooks.ts
@@ -1,5 +1,5 @@
import { Dispatch } from "react";
-import { editorAction, IEditorState } from "@store";
+import { EditorAction, IEditorState } from "@store";
import { MapEditor } from "@map";
import { EventTypes } from "../../types/enum";
@@ -7,6 +7,6 @@ import { EventTypes } from "../../types/enum";
export function registerMapEventHooks(map: MapEditor, dispatch: Dispatch
) {
//
map.on(EventTypes.FinishCreateOverlay, (evt: any) =>
- dispatch(editorAction.finishCreateOverlay(evt))
+ dispatch(EditorAction.finishCreateOverlay(evt))
);
}
diff --git a/src/map/constants.ts b/src/map/constants.ts
index ccd4df1..81bbab1 100644
--- a/src/map/constants.ts
+++ b/src/map/constants.ts
@@ -26,3 +26,7 @@ export const PolylineOptions: OverlayOptions = {
draggable: false,
bubble: true,
};
+
+export const SelectedOptions: OverlayOptions = {
+ strokeColor: SelectedStroke,
+};
diff --git a/src/map/index.ts b/src/map/index.ts
index 5705ec6..0d429c8 100644
--- a/src/map/index.ts
+++ b/src/map/index.ts
@@ -13,9 +13,9 @@ import {
} from "./editors";
import { registerHotkey } from "../utils/hotkeys";
-import { PolygonOptions, PolylineOptions } from "./constants";
+import { PolygonOptions, PolylineOptions, SelectedOptions } from "./constants";
-import { EventTypes, OverlayTypes } from "../types/enum";
+import { Command, EventTypes, OverlayTypes } from "../types/enum";
let uuid = 0;
const getUuid = () => ++uuid;
@@ -26,11 +26,16 @@ type AMapOverlayEditor =
| AMap.PolylineEditor
| AMap.CircleEditor;
+type OverlayTemp = {
+ type: OverlayTypes;
+ target: AMap.MapOverlay;
+};
+
export class MapEditor extends Emitter {
dom: HTMLDivElement;
private _map: AMap.Map | undefined;
private overlayEditors: BaseOverlayEditor[] = [];
- private overlayMap: Record = {};
+ private overlayMap: Record = {};
private _currentOverlayEditor:
| BaseOverlayEditor
| undefined;
@@ -63,23 +68,40 @@ export class MapEditor extends Emitter {
}
update(mapState: IMapState) {
- const { status, overlayType } = mapState;
- if (status === "createOverlay") {
- this.finishCreateOverlay();
- this._currentOverlayEditor = this.overlayEditors.find(
- (editor) => editor.getType() === overlayType
- );
- this._currentOverlayEditor?.create();
+ const { command } = mapState;
+ switch (command) {
+ case Command.CreateOverlay:
+ this._createOverlay(mapState);
+ break;
+ case Command.SelectOverlay:
+ this._selectOverlays(mapState.selectedIds);
}
}
+ _createOverlay(mapState: IMapState) {
+ const { overlayType } = mapState;
+ this.finishCreateOverlay();
+ this._currentOverlayEditor = this.overlayEditors.find(
+ (editor) => editor.getType() === overlayType
+ );
+ this._currentOverlayEditor?.create();
+ }
+
+ _selectOverlays(ids?: string[]) {
+ if (!ids?.length) return;
+ ids.forEach((id) => {
+ const { target } = this.overlayMap[id];
+ target.setOptions(SelectedOptions);
+ });
+ }
+
finishCreateOverlay() {
if (this._currentOverlayEditor == null) return;
const target = this._currentOverlayEditor.finish();
if (target == null) return;
const id = getUuid();
const type = this._currentOverlayEditor.getType();
- this.overlayMap[id] = target;
+ this.overlayMap[id] = { type, target };
const evt: any = { id, type };
if (type === OverlayTypes.Circle) {
const circle = target as AMap.Circle;
diff --git a/src/store/actions.ts b/src/store/actions.ts
index f1e948e..1195b49 100644
--- a/src/store/actions.ts
+++ b/src/store/actions.ts
@@ -4,28 +4,33 @@ export enum ActionTypes {
// AddRect = "addRect",
CreateOverlay = "createOverlay",
FinishCreateOverlay = "finishCreateOverlay",
+ SelectOverlay = "selectOverlay",
}
export type CreatedOverlay = {
id: string;
type: OverlayTypes;
};
-export class EditorAction {
- // addRect() {
- // return {
- // type: ActionTypes.AddRect,
- // };
- // }
+
+type ActionCreator = (payload: any) => { type: ActionTypes; payload: any };
+
+export const EditorAction: Record = {
createOverlay(type: OverlayTypes) {
return {
type: ActionTypes.CreateOverlay,
payload: type,
};
- }
+ },
finishCreateOverlay(overlay: any) {
return {
type: ActionTypes.FinishCreateOverlay,
payload: overlay as CreatedOverlay,
};
- }
-}
+ },
+ selectOverlay(id: string) {
+ return {
+ type: ActionTypes.SelectOverlay,
+ payload: id,
+ };
+ },
+};
diff --git a/src/store/index.ts b/src/store/index.ts
index 5a16286..98f58b8 100644
--- a/src/store/index.ts
+++ b/src/store/index.ts
@@ -15,7 +15,7 @@ const store: IStore = createStore(reducer);
export { store };
-export const editorAction = new EditorAction();
+export { EditorAction };
export const StoreContext = createContext(
null
diff --git a/src/store/initState.ts b/src/store/initState.ts
index cfde017..2552d65 100644
--- a/src/store/initState.ts
+++ b/src/store/initState.ts
@@ -2,7 +2,8 @@ import { IEditorState } from "./type";
export const initState: IEditorState = {
map: {
- status: "",
+ status: null,
+ command: null,
overlayType: null,
polygons: [],
polylines: [],
diff --git a/src/store/reducers/index.ts b/src/store/reducers/index.ts
index 1d236cf..d9c3543 100644
--- a/src/store/reducers/index.ts
+++ b/src/store/reducers/index.ts
@@ -1,6 +1,6 @@
import { initState } from "../initState";
import { ActionTypes } from "../actions";
-import { createOverlay, finishCreateOverlay } from "./map";
+import { createOverlay, finishCreateOverlay, selectOverlay } from "./map";
import { IEditorState } from "@store";
export type Action = {
@@ -13,6 +13,7 @@ type ActionReducer = (state: IEditorState, payload: any) => IEditorState;
const actionReducers: Record = {
[ActionTypes.CreateOverlay]: createOverlay,
[ActionTypes.FinishCreateOverlay]: finishCreateOverlay,
+ [ActionTypes.SelectOverlay]: selectOverlay,
// addRect: undefined
};
diff --git a/src/store/reducers/map/index.ts b/src/store/reducers/map/index.ts
index c7d511c..53ef093 100644
--- a/src/store/reducers/map/index.ts
+++ b/src/store/reducers/map/index.ts
@@ -1,11 +1,12 @@
import produce from "immer";
import { initState } from "../../initState";
import { IOverlay, OverlayNamePrefixs } from "@store";
-import { OverlayTypes } from "@types";
+import { OverlayTypes, Status, Command } from "@types";
export function createOverlay(state = initState, payload: any) {
return produce(state, (draft) => {
- draft.map.status = "createOverlay";
+ draft.map.status = Status.CreateOverlay;
+ draft.map.command = Command.CreateOverlay;
draft.map.overlayType = payload as OverlayTypes;
});
}
@@ -16,7 +17,8 @@ export function finishCreateOverlay(state = initState, payload: any) {
const { type } = overlay;
// todo: uniqueName.
overlay.name = OverlayNamePrefixs[type] + overlay.id;
- draft.map.status = "";
+ draft.map.status = null;
+ draft.map.command = null;
draft.map.overlayType = null;
(type === OverlayTypes.Rectangle
? draft.map.rectangles
@@ -28,3 +30,12 @@ export function finishCreateOverlay(state = initState, payload: any) {
).push(overlay);
});
}
+
+export function selectOverlay(state = initState, payload: any) {
+ const id = payload as string;
+ return produce(state, (draft) => {
+ draft.map.command = Command.SelectOverlay;
+ draft.map.selectedIds = [id];
+ draft.map.status = null;
+ });
+}
diff --git a/src/store/type.ts b/src/store/type.ts
index d5ff051..fe4dbca 100644
--- a/src/store/type.ts
+++ b/src/store/type.ts
@@ -1,4 +1,4 @@
-import { OverlayTypes } from "@types";
+import { OverlayTypes, Status, Command } from "@types";
export interface IOverlay {
id: string;
@@ -8,14 +8,15 @@ export interface IOverlay {
paths?: number[][];
radius?: number;
}
-
export interface IMapState {
- status: string;
+ status: Status | null;
+ command: Command | null;
overlayType: OverlayTypes | null;
polygons: IOverlay[];
polylines: IOverlay[];
circles: IOverlay[];
rectangles: IOverlay[];
+ selectedIds?: string[];
}
export interface IEditorState {
diff --git a/src/types/enum.ts b/src/types/enum.ts
index 75b3e5a..3ac0f55 100644
--- a/src/types/enum.ts
+++ b/src/types/enum.ts
@@ -8,3 +8,16 @@ export enum OverlayTypes {
Polyline = "polyline",
Circle = "circle",
}
+
+// 操作指令集
+export enum Command {
+ CreateOverlay = "createOveraly",
+ SelectOverlay = "selectOverlay",
+}
+
+// 地图状态.
+export enum Status {
+ CreateOverlay = "createOverlay",
+ Searching = "searching",
+ Selecting = "selecing",
+}