Browse Source

子工具栏支持

master
Cmen 3 years ago
parent
commit
d182c32369
  1. 68
      src/editor/Plot/Tools/MinimalTools.tsx
  2. 5
      src/editor/Plot/Tools/index.tsx
  3. 23
      src/editor/Plot/index.less
  4. 3
      src/editor/Plot/index.tsx
  5. 1
      src/editor/index.less
  6. 17
      src/icon.less
  7. 2
      src/map/type.ts
  8. 6
      src/store/actions/StoreAction.ts
  9. 20
      src/store/actions/index.ts
  10. 4
      src/store/reducers/index.ts
  11. 6
      src/store/reducers/map/index.ts
  12. 4
      src/store/type.ts
  13. 3
      src/types/enum.ts

68
src/editor/Plot/Tools/MinimalTools.tsx

@ -0,0 +1,68 @@
import { useSelector } from "react-redux";
import { Button } from "antd";
import {
editorAction,
OverlayNamePrefixs,
statusSelector,
overlayTypeSelector,
} from "@store";
import { Status } from "@types";
type MinimalButtonProps = {
type: string;
text: string;
onClick: () => void;
};
const MinimalButton = (props: MinimalButtonProps) => {
return (
<Button
type="dashed"
size="small"
icon={<span className={`icon icon-${props.type}`}></span>}
onClick={props.onClick}
>
{props.text}
</Button>
);
};
export const MinimalTools = () => {
const status = useSelector(statusSelector);
console.log(status);
if (status === Status.CreateOverlay || status === Status.EditOverlay) {
return (
<>
<MinimalButton
text="完成"
type="confirm"
onClick={() => editorAction.finishCreateOverlay()}
/>
</>
);
}
if (status === Status.SelectOverlay) {
return (
<>
<MinimalButton
text="编辑"
type="edit"
onClick={() => editorAction.editSelectedOverlay()}
/>
<MinimalButton
text="复制"
type="copy"
onClick={() => editorAction.copyOverlay()}
/>
<MinimalButton
text="删除"
type="delete"
onClick={() => editorAction.deleteOverlays()}
/>
</>
);
}
return <></>;
};

5
src/editor/Plot/Tools/index.tsx

@ -12,6 +12,8 @@ import { OverlayTypes } from "@map";
import { SearchModal } from "./SearchModal";
import { useState } from "react";
import { MinimalTools } from "./MinimalTools";
type IconWithTipProps = {
type: string;
text: string;
@ -62,6 +64,9 @@ const Tools = () => {
return (
<>
<div className="minimal-tools">
<MinimalTools />
</div>
<div className="marker-tools">
<OverlayTool type={OverlayTypes.Rectangle} hotkey="Alt+1" />
<OverlayTool type={OverlayTypes.Polygon} hotkey="Alt+2" />

23
src/editor/Plot/index.less

@ -1,21 +1,32 @@
.map-stage {
position: absolute;
width: 100%;
height: 100%; //calc(100% - 40px);
// top: 40px;
height: calc(100% - 40px);
top: 40px;
left: 0;
z-index: 0;
}
.tools-properties {
.minimal-tools {
position: absolute;
padding: 8px 20px;
width: 100%;
height: 40px;
background-color: #fff;
top: 0;
left: 0;
background-color: #f5f5f5;
border-bottom: 1px solid #ccc;
color: #ccc;
.ant-btn{
margin-right: 4px;
}
.icon{
font-size: 12px;
line-height: 20px;
padding: 2px 4px 2px 0;
}
}
.tools-area {
// margin-top: 40px;
padding: 20px;
padding: 60px 20px 20px;
position: relative;
z-index: 10;
.marker-tools {

3
src/editor/Plot/index.tsx

@ -1,6 +1,6 @@
import { useEffect, useRef, useState } from "react";
import { MapEditor } from "@map";
import { IEditorState, editorAction } from "@store";
import { editorAction } from "@store";
import Tools from "./Tools";
@ -23,7 +23,6 @@ const Plot = () => {
return (
<>
<div className="map-stage" ref={mapStageRef}></div>
{/* <div className="tools-properties"></div> */}
<div className="tools-area">
<Tools />
</div>

1
src/editor/index.less

@ -6,6 +6,7 @@
line-height: 40px;
padding: 0 10px;
background-color: #dbd8d8;
border-bottom: 1px solid rgb(180, 180, 180);
font-size: 16px;
}
.editor-body-center {

17
src/icon.less

@ -1,11 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 2872894 */
src: url("//at.alicdn.com/t/font_2872894_c6wq9g1vj1v.woff2?t=1642594908994")
format("woff2"),
url("//at.alicdn.com/t/font_2872894_c6wq9g1vj1v.woff?t=1642594908994")
format("woff"),
url("//at.alicdn.com/t/font_2872894_c6wq9g1vj1v.ttf?t=1642594908994")
format("truetype");
font-family: 'iconfont'; /* Project id 2872894 */
src: url('//at.alicdn.com/t/font_2872894_d0kug781hyi.woff2?t=1650096832382') format('woff2'),
url('//at.alicdn.com/t/font_2872894_d0kug781hyi.woff?t=1650096832382') format('woff'),
url('//at.alicdn.com/t/font_2872894_d0kug781hyi.ttf?t=1650096832382') format('truetype');
}
.icon {
font-family: "iconfont";
@ -72,6 +69,12 @@
.icon-circle:after {
content: "\edf8";
}
.icon-confirm:after{
content: "\e618";
}
.icon-copy:after{
content: "\eb4e";
}
.icon-selected {
color: #14aad7;
}

2
src/map/type.ts

@ -3,6 +3,8 @@ import { EventTypes } from "@types";
export interface IMapEditor {
on(type: EventTypes, evt: any): void;
init(): Promise<void>;
finishEditOverlay(): void;
editSelectedOverlay(): void;
createOverlay(type: OverlayTypes): void;
importProject(options: IMapOptions): void;
importGeoJSON(geojson: GeoJSON.FeatureCollection): void;

6
src/store/actions/StoreAction.ts

@ -2,6 +2,7 @@ import { IOverlay, OverlayTypes } from "@map";
import { IEditorState } from "../type";
export enum ActionTypes {
CreateOverlay = "createOverlay",
EditOverlay = "editOverlay",
FinishEditOverlay = "finishEditOverlay",
SelectOverlay = "selectOverlay",
DeleteOverlays = "deleteOverlays",
@ -29,6 +30,11 @@ export const StoreAction: Record<ActionTypes, ActionCreator> = {
payload: overlay,
};
},
editOverlay() {
return {
type: ActionTypes.EditOverlay,
};
},
selectOverlay(id?: string) {
return {
type: ActionTypes.SelectOverlay,

20
src/store/actions/index.ts

@ -98,22 +98,28 @@ export class EditorAction {
title: "确定删除覆盖物吗?",
onOk: () => {
this.mapEditor?.deleteOverlays();
this.store.dispatch(StoreAction.deleteOverlays());
this.dispatch(StoreAction.deleteOverlays());
},
});
}
editSelectedOverlay() {
this.dispatch(StoreAction.editOverlay());
this.mapEditor?.editSelectedOverlay();
}
finishCreateOverlay() {
this.mapEditor?.finishEditOverlay();
}
selectOverlay(id: string, reset = true) {
const { selectedIds } = this.store.getState();
if (selectedIds.indexOf(id) >= 0) {
if (reset) {
this.mapEditor?.selectOverlays();
this.dispatch(StoreAction.selectOverlay());
}
if (selectedIds.indexOf(id) >= 0 && reset) {
this.mapEditor?.selectOverlays();
} else {
this.mapEditor?.selectOverlays([id]);
this.dispatch(StoreAction.selectOverlay(id));
}
this.dispatch(StoreAction.selectOverlay(id));
}
updateOverlay(props: Partial<IOverlay>) {

4
src/store/reducers/index.ts

@ -7,9 +7,11 @@ import {
finishEditOverlay,
deleteOverlays,
clearOverlays,
editOverlay,
} from "./map";
import { IOverlay } from "@map";
import { Status } from "../../types/enum";
export type Action = {
type: ActionTypes;
@ -27,6 +29,7 @@ const actionReducers: Record<ActionTypes, ActionReducer> = {
[ActionTypes.ClearOverlays]: clearOverlays,
[ActionTypes.UpdateOverlayProps]: updateOverlayProps,
[ActionTypes.SearchPlace]: searchPlace,
[ActionTypes.EditOverlay]: editOverlay,
};
function searchPlace(state = initState, payload: AMap.SearchResultItem[]) {
@ -53,6 +56,7 @@ export function selectOverlay(state = initState, payload: string | undefined) {
const ids = payload ? [payload] : [];
return produce(state, (draft) => {
draft.selectedIds = ids;
draft.status = ids.length ? Status.SelectOverlay : null;
});
}

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

@ -26,6 +26,12 @@ export function deleteOverlays(state = initState, payload: any) {
});
}
export function editOverlay(state = initState) {
return produce(state, (draft) => {
draft.status = Status.EditOverlay;
});
}
export function finishEditOverlay(state = initState, payload: any) {
return produce(state, (draft) => {
const overlay = payload as IOverlay;

4
src/store/type.ts

@ -1,7 +1,7 @@
import { Store } from "redux";
import { Action } from "./reducers";
import { OverlayTypes, Status } from "@types";
import { IMapOptions } from "@map";
import { Status } from "@types";
import { IMapOptions, OverlayTypes } from "@map";
export type IStore = Store<IEditorState, Action>;

3
src/types/enum.ts

@ -15,6 +15,7 @@ export enum Command {
// 地图状态.
export enum Status {
CreateOverlay = "createOverlay",
EditOverlay = "editOverlay",
Searching = "searching",
Selecting = "selecing",
SelectOverlay = "selectOverlay",
}

Loading…
Cancel
Save