Browse Source

选择编辑

master
Cmen 3 years ago
parent
commit
e459b73a23
  1. 6
      src/editor/Plot/mapHooks.ts
  2. 5
      src/map/editors/BaseOverlayEditor.ts
  3. 65
      src/map/index.ts
  4. 6
      src/store/actions.ts
  5. 4
      src/store/reducers/index.ts
  6. 26
      src/store/reducers/map/index.ts
  7. 2
      src/types/enum.ts

6
src/editor/Plot/mapHooks.ts

@ -1,12 +1,12 @@
import { Dispatch } from "react";
import { EditorAction, IEditorState } from "@store";
import { EditorAction } from "@store";
import { MapEditor } from "@map";
import { EventTypes } from "../../types/enum";
// 注册地图的事件钩子
export function registerMapEventHooks(map: MapEditor, dispatch: Dispatch<any>) {
//
map.on(EventTypes.FinishCreateOverlay, (evt: any) =>
dispatch(EditorAction.finishCreateOverlay(evt))
map.on(EventTypes.FinishEditOverlay, (evt: any) =>
dispatch(EditorAction.finishEditOverlay(evt))
);
}

5
src/map/editors/BaseOverlayEditor.ts

@ -23,5 +23,10 @@ export abstract class BaseOverlayEditor<T extends AMap.BaseEditor> {
return target;
}
edit(target: AMap.MapOverlay) {
this.editor.setTarget(target);
this.editor.open();
}
abstract getType(): OverlayTypes;
}

65
src/map/index.ts

@ -18,7 +18,7 @@ import { PolygonOptions, PolylineOptions, SelectedOptions } from "./constants";
import { Command, EventTypes, OverlayTypes } from "../types/enum";
let uuid = 0;
const getUuid = () => ++uuid;
const getUuid = () => ++uuid + "";
type AMapOverlayEditor =
| AMap.RectangleEditor
@ -39,6 +39,8 @@ export class MapEditor extends Emitter {
private _currentOverlayEditor:
| BaseOverlayEditor<AMapOverlayEditor>
| undefined;
private _selectedIds: string[] = [];
private _editorStatus: "editing" | "creating" | null = null;
constructor(dom: HTMLDivElement) {
super();
this.dom = dom;
@ -64,10 +66,17 @@ export class MapEditor extends Emitter {
this._map = new AMap.Map(this.dom);
this.initEditors();
// Space的key是空字符串, 这就离谱.
registerHotkey(" ", { callback: this.finishCreateOverlay.bind(this) });
registerHotkey(" ", { callback: this._finishEditOverlay.bind(this) });
registerHotkey("e", {
callback: this._editSelectedOverlay.bind(this),
alt: true,
});
}
update(mapState: IMapState) {
if (this._editorStatus != null) {
this._finishEditOverlay();
}
const { command } = mapState;
switch (command) {
case Command.CreateOverlay:
@ -78,30 +87,50 @@ export class MapEditor extends Emitter {
}
}
_createOverlay(mapState: IMapState) {
const { overlayType } = mapState;
this.finishCreateOverlay();
this._currentOverlayEditor = this.overlayEditors.find(
initEditors() {
const { map } = this;
this.overlayEditors = [
new RectangleEditor(map),
new PolygonEditor(map),
new PolylineEditor(map),
new CircleEditor(map),
];
}
getEditorByType(overlayType: OverlayTypes) {
return this.overlayEditors.find(
(editor) => editor.getType() === overlayType
);
}
_createOverlay(mapState: IMapState) {
const { overlayType } = mapState;
this._currentOverlayEditor = this.getEditorByType(overlayType!);
this._currentOverlayEditor?.create();
this._editorStatus = "creating";
}
_selectOverlays(ids?: string[]) {
if (!ids?.length) return;
this._selectedIds = ids;
ids.forEach((id) => {
const { target } = this.overlayMap[id];
target.setOptions(SelectedOptions);
});
}
finishCreateOverlay() {
_finishEditOverlay() {
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] = { type, target };
const isCreatingOverlay = this._editorStatus === "creating";
let id = getUuid();
if (isCreatingOverlay) {
this.overlayMap[id] = { type, target };
} else {
id = this._selectedIds[0];
}
const evt: any = { id, type };
if (type === OverlayTypes.Circle) {
const circle = target as AMap.Circle;
@ -113,16 +142,16 @@ export class MapEditor extends Emitter {
target.setOptions(
type === OverlayTypes.Polyline ? PolylineOptions : PolygonOptions
);
this.emit(EventTypes.FinishCreateOverlay, evt);
this.emit(EventTypes.FinishEditOverlay, evt);
this._editorStatus = null;
}
initEditors() {
const { map } = this;
this.overlayEditors = [
new RectangleEditor(map),
new PolygonEditor(map),
new PolylineEditor(map),
new CircleEditor(map),
];
_editSelectedOverlay() {
if (this._selectedIds.length !== 1) return;
const [id] = this._selectedIds;
const { target, type } = this.overlayMap[id];
this._currentOverlayEditor = this.getEditorByType(type);
this._currentOverlayEditor?.edit(target);
this._editorStatus = "editing";
}
}

6
src/store/actions.ts

@ -3,7 +3,7 @@ import { OverlayTypes } from "@types";
export enum ActionTypes {
// AddRect = "addRect",
CreateOverlay = "createOverlay",
FinishCreateOverlay = "finishCreateOverlay",
FinishEditOverlay = "finishEditOverlay",
SelectOverlay = "selectOverlay",
}
@ -21,9 +21,9 @@ export const EditorAction: Record<ActionTypes, ActionCreator> = {
payload: type,
};
},
finishCreateOverlay(overlay: any) {
finishEditOverlay(overlay: any) {
return {
type: ActionTypes.FinishCreateOverlay,
type: ActionTypes.FinishEditOverlay,
payload: overlay as CreatedOverlay,
};
},

4
src/store/reducers/index.ts

@ -1,6 +1,6 @@
import { initState } from "../initState";
import { ActionTypes } from "../actions";
import { createOverlay, finishCreateOverlay, selectOverlay } from "./map";
import { createOverlay, finishEditOverlay, selectOverlay } from "./map";
import { IEditorState } from "@store";
export type Action = {
@ -12,7 +12,7 @@ type ActionReducer = (state: IEditorState, payload: any) => IEditorState;
const actionReducers: Record<ActionTypes, ActionReducer> = {
[ActionTypes.CreateOverlay]: createOverlay,
[ActionTypes.FinishCreateOverlay]: finishCreateOverlay,
[ActionTypes.FinishEditOverlay]: finishEditOverlay,
[ActionTypes.SelectOverlay]: selectOverlay,
// addRect: undefined
};

26
src/store/reducers/map/index.ts

@ -11,23 +11,29 @@ export function createOverlay(state = initState, payload: any) {
});
}
export function finishCreateOverlay(state = initState, payload: any) {
export function finishEditOverlay(state = initState, payload: any) {
return produce(state, (draft) => {
const overlay = payload as IOverlay;
const { type } = overlay;
const { type, id } = overlay;
// todo: uniqueName.
overlay.name = OverlayNamePrefixs[type] + overlay.id;
draft.map.status = null;
draft.map.command = null;
draft.map.overlayType = null;
(type === OverlayTypes.Rectangle
? draft.map.rectangles
: type === OverlayTypes.Circle
? draft.map.circles
: type === OverlayTypes.Polygon
? draft.map.polygons
: draft.map.polylines
).push(overlay);
const overlays =
type === OverlayTypes.Rectangle
? draft.map.rectangles
: type === OverlayTypes.Circle
? draft.map.circles
: type === OverlayTypes.Polygon
? draft.map.polygons
: draft.map.polylines;
const existed = overlays.find((overlay) => overlay.id === id);
if (existed) {
overlays[overlays.indexOf(existed)] = overlay;
} else {
overlays.push(overlay);
}
});
}

2
src/types/enum.ts

@ -1,5 +1,5 @@
export enum EventTypes {
FinishCreateOverlay = "finishCreateOverlay",
FinishEditOverlay = "finishEditOverlay",
}
export enum OverlayTypes {

Loading…
Cancel
Save