Browse Source

feat: 走通地图&redux更新逻辑

master
Cmen 3 years ago
parent
commit
987cbdb56c
  1. 1
      package.json
  2. 20
      src/editor/Plot/Tools/index.tsx
  3. 27
      src/editor/Plot/index.tsx
  4. 5
      src/index.tsx
  5. 15
      src/map/editors/BaseLayerEditor.ts
  6. 7
      src/map/editors/RectangleEditor.ts
  7. 2
      src/map/editors/index.ts
  8. 21
      src/map/index.ts
  9. 18
      src/store/actions.ts
  10. 13
      src/store/index.ts
  11. 2
      src/store/initState.ts
  12. 22
      src/store/reducers.ts
  13. 2
      src/store/type.ts
  14. 6
      src/types/index.d.ts
  15. 22
      src/types/index.ts
  16. 8
      tsconfig.json
  17. 9
      vite.config.js
  18. 48
      yarn.lock

1
package.json

@ -14,6 +14,7 @@
"lodash": "^4.17.21", "lodash": "^4.17.21",
"react": "^17.0.2", "react": "^17.0.2",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-redux": "^7.2.6",
"redux": "^4.1.2" "redux": "^4.1.2"
}, },
"devDependencies": { "devDependencies": {

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

@ -1,24 +1,38 @@
import { Tooltip } from "antd"; import { Tooltip } from "antd";
import { useDispatch } from "react-redux";
import { editorAction } from "@store";
type IconWithTipProps = { type IconWithTipProps = {
type: string; type: string;
text: string; text: string;
onClick?: () => void;
placement?: "top" | "right"; placement?: "top" | "right";
}; };
const IconWithTip = ({ type, text, placement = "top" }: IconWithTipProps) => { const IconWithTip = ({
type,
text,
onClick = () => {},
placement = "top",
}: IconWithTipProps) => {
return ( return (
<Tooltip title={text} placement={placement}> <Tooltip title={text} placement={placement}>
<span className={`icon icon-${type}`}></span> <span className={`icon icon-${type}`} onClick={onClick}></span>
</Tooltip> </Tooltip>
); );
}; };
const Tools = () => { const Tools = () => {
const dispatch = useDispatch();
const createOverlay = (type: string) => () =>
dispatch(editorAction.createOverlay(type));
const createRectangle = createOverlay("rect");
return ( return (
<> <>
<div className="marker-tools"> <div className="marker-tools">
<IconWithTip type="rect" text="矩形工具" /> <IconWithTip type="rect" text="矩形工具" onClick={createRectangle} />
<IconWithTip type="circle" text="圆形工具" /> <IconWithTip type="circle" text="圆形工具" />
</div> </div>
<div className="common-tools"> <div className="common-tools">

27
src/editor/Plot/index.tsx

@ -1,19 +1,34 @@
import { Layout } from "antd"; import { Layout } from "antd";
import { useEffect, useRef } from "react"; import { useEffect, useRef, useState } from "react";
import { MapStage } from "../../mapStage"; import { useSelector, useDispatch } from "react-redux";
import { MapEditor } from "@map";
import { editorAction, IEditorState } from "@store";
import Tools from "./Tools"; import Tools from "./Tools";
import "./index.less"; import "./index.less";
const mapStateSelector = (state: IEditorState) => state.map;
const { Header, Footer, Sider, Content } = Layout; const { Header, Footer, Sider, Content } = Layout;
const Plot = () => { const Plot = () => {
const mapStageRef = useRef<HTMLDivElement>(null); const mapStageRef = useRef<HTMLDivElement>(null);
const mapState = useSelector(mapStateSelector);
const dispatch = useDispatch();
const [mapEditor, setMapEditor] = useState<MapEditor | null>(null);
// !mapEditor &&
useEffect(() => { useEffect(() => {
const map = new MapStage(mapStageRef.current!); if (mapEditor == null) {
map.init(); const editor = new MapEditor(mapStageRef.current!);
setMapEditor(editor);
editor.init().then(() => {
editor.update(mapState);
}); });
}
}, [mapEditor, mapState]);
mapEditor?.update(mapState);
return ( return (
<> <>
@ -26,4 +41,8 @@ const Plot = () => {
); );
}; };
// const mapStateToProps = (state: IEditorState) => {
// return state.map;
// };
export default Plot; export default Plot;

5
src/index.tsx

@ -1,5 +1,6 @@
import React from "react"; import React from "react";
import ReactDOM from "react-dom"; import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import "antd/dist/antd.css"; import "antd/dist/antd.css";
@ -8,8 +9,8 @@ import { Editor } from "./editor";
import "./index.less"; import "./index.less";
ReactDOM.render( ReactDOM.render(
<StoreContext.Provider value={store}> <Provider store={store}>
<Editor /> <Editor />
</StoreContext.Provider>, </Provider>,
document.getElementById("app") document.getElementById("app")
); );

15
src/map/editors/BaseLayerEditor.ts

@ -0,0 +1,15 @@
export abstract class BaseLayerEditor<T extends AMap.BaseEditor> {
map: AMap.Map;
editor: T;
constructor(map: AMap.Map) {
this.map = map;
this.editor = this.initEditor(map);
}
abstract initEditor(map: AMap.Map): T;
create() {
this.editor.setTarget(null);
this.editor.open();
}
}

7
src/map/editors/RectangleEditor.ts

@ -0,0 +1,7 @@
import { BaseLayerEditor } from "./BaseLayerEditor";
export class RectangleEditor extends BaseLayerEditor<AMap.PolygonEditor> {
initEditor(map: AMap.Map) {
return new AMap.RectangleEditor(this.map);
}
}

2
src/map/editors/index.ts

@ -0,0 +1,2 @@
export * from "./BaseLayerEditor";
export * from "./RectangleEditor";

21
src/mapStage/index.ts → src/map/index.ts

@ -1,15 +1,18 @@
import "@amap/amap-jsapi-types"; import "@amap/amap-jsapi-types";
import "../types/index.d"; import "../types";
import { IMapState } from "@store";
import { RectangleEditor } from "./editors";
export class MapStage { export class MapEditor {
dom: HTMLDivElement; dom: HTMLDivElement;
private _map: AMap.Map | undefined; private _map: AMap.Map | undefined;
private rectangleEditor: RectangleEditor | undefined;
constructor(dom: HTMLDivElement) { constructor(dom: HTMLDivElement) {
this.dom = dom; this.dom = dom;
} }
get map() { get map() {
return this._map; return this._map!;
} }
async init() { async init() {
@ -25,5 +28,17 @@ export class MapStage {
], ],
}); });
this._map = new AMap.Map(this.dom); this._map = new AMap.Map(this.dom);
this.initEditors();
}
update(state: IMapState) {
if (state.status === "createOverlay") {
this.rectangleEditor?.create();
}
}
initEditors() {
const { map } = this;
this.rectangleEditor = new RectangleEditor(map);
} }
} }

18
src/store/actions.ts

@ -0,0 +1,18 @@
export enum ActionTypes {
AddRect = "addRect",
CreateOverlay = "createOverlay",
}
export class EditorAction {
addRect() {
return {
type: ActionTypes.AddRect,
};
}
createOverlay(type: string) {
return {
type: ActionTypes.CreateOverlay,
payload: type,
};
}
}

13
src/store/index.ts

@ -2,6 +2,9 @@ import { createStore, Store } from "redux";
import { createContext, Context, useContext } from "react"; import { createContext, Context, useContext } from "react";
import { reducer, Action } from "./reducers"; import { reducer, Action } from "./reducers";
import { IEditorState } from "./type"; import { IEditorState } from "./type";
import { EditorAction } from "./actions";
export * from "./type";
type IStore = Store<IEditorState, Action>; type IStore = Store<IEditorState, Action>;
const store: IStore = createStore(reducer); const store: IStore = createStore(reducer);
@ -24,11 +27,13 @@ export { store };
// } // }
// } // }
export const editorAction = new EditorAction();
export const StoreContext = createContext<IStore | null>( export const StoreContext = createContext<IStore | null>(
null null
) as Context<IStore>; ) as Context<IStore>;
export const useStore = () => { // export const useStore = () => {
const store = useContext(StoreContext); // const store = useReduxContext(StoreContext);
return store; // return store;
}; // };

2
src/store/initState.ts

@ -2,6 +2,8 @@ import { IEditorState } from "./type";
export const initState: IEditorState = { export const initState: IEditorState = {
map: { map: {
status: "",
overlayType: "",
polygons: [], polygons: [],
}, },
}; };

22
src/store/reducers.ts

@ -1,11 +1,27 @@
import { createStore } from "redux"; import { createStore } from "redux";
import { initState } from "./initState"; import { initState } from "./initState";
import { ActionTypes } from "./actions";
import { IEditorState } from "./type";
export type Action = { export type Action = {
type: string; type: ActionTypes;
payload: any; payload?: any;
}; };
export function reducer(state = initState, action: Action) { export function reducer(state = initState, action: Action): IEditorState {
const { type, payload } = action;
switch (type) {
case ActionTypes.CreateOverlay:
return {
...state,
map: {
...state.map,
status: "createOverlay",
overlayType: payload as string,
},
//
};
default:
return state; return state;
}
} }

2
src/store/type.ts

@ -4,6 +4,8 @@ export interface IPolygon {
} }
export interface IMapState { export interface IMapState {
status: string;
overlayType: string;
polygons: IPolygon[]; polygons: IPolygon[];
} }

6
src/types/index.d.ts vendored

@ -1,6 +0,0 @@
declare global {
namespace AMapLoader {
const load: (config: any) => Promise<AMap.Map>;
}
}
export {};

22
src/types/index.ts

@ -0,0 +1,22 @@
declare global {
namespace AMapLoader {
const load: (config: any) => Promise<AMap.Map>;
}
namespace AMap {
interface IBaseEditor {
// new (map: AMap.Map): any;
}
class BaseEditor implements IBaseEditor {
constructor(map: AMap.Map);
setTarget(target: any): void;
open(): void;
}
class PolygonEditor extends BaseEditor {
//
}
class RectangleEditor extends BaseEditor {
//
}
}
}
export {};

8
tsconfig.json

@ -14,7 +14,13 @@
"resolveJsonModule": true, "resolveJsonModule": true,
"isolatedModules": true, "isolatedModules": true,
"noEmit": true, "noEmit": true,
"jsx": "react-jsx" "jsx": "react-jsx",
"paths": {
"@store": ["./src/store"],
"@editor": ["./src/editor"],
"@map": ["./src/map"],
"@types": ["./src/types"],
}
}, },
"include": ["./src"] "include": ["./src"]
} }

9
vite.config.js

@ -1,5 +1,5 @@
import { defineConfig } from 'vite' import { defineConfig } from "vite";
import react from '@vitejs/plugin-react' import react from "@vitejs/plugin-react";
import path from "path"; import path from "path";
// https://vitejs.dev/config/ // https://vitejs.dev/config/
@ -9,11 +9,12 @@ export default defineConfig({
alias: { alias: {
"@store": path.resolve(__dirname, "src/store"), "@store": path.resolve(__dirname, "src/store"),
"@editor": path.resolve(__dirname, "src/editor"), "@editor": path.resolve(__dirname, "src/editor"),
"@map": path.resolve(__dirname, "src/map"),
"@app": path.resolve(__dirname, "src/app"), "@app": path.resolve(__dirname, "src/app"),
"@types": path.resolve(__dirname, "src/types"), "@types": path.resolve(__dirname, "src/types"),
}, },
}, },
server: { server: {
port: 8080 port: 8080,
}, },
}) });

48
yarn.lock

@ -1201,7 +1201,7 @@
core-js-pure "^3.20.2" core-js-pure "^3.20.2"
regenerator-runtime "^0.13.4" regenerator-runtime "^0.13.4"
"@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
version "7.16.7" version "7.16.7"
resolved "https://registry.npmmirror.com/@babel/runtime/download/@babel/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa" resolved "https://registry.npmmirror.com/@babel/runtime/download/@babel/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa"
integrity sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ== integrity sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ==
@ -1356,6 +1356,14 @@
resolved "https://registry.npmmirror.com/@rushstack/eslint-patch/download/@rushstack/eslint-patch-1.1.0.tgz#7f698254aadf921e48dda8c0a6b304026b8a9323" resolved "https://registry.npmmirror.com/@rushstack/eslint-patch/download/@rushstack/eslint-patch-1.1.0.tgz#7f698254aadf921e48dda8c0a6b304026b8a9323"
integrity sha1-f2mCVKrfkh5I3ajAprMEAmuKkyM= integrity sha1-f2mCVKrfkh5I3ajAprMEAmuKkyM=
"@types/hoist-non-react-statics@^3.3.0":
version "3.3.1"
resolved "https://registry.npmmirror.com/@types/hoist-non-react-statics/download/@types/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
integrity sha1-ESSq/lEYy1kZd66xzqrtEHDrA58=
dependencies:
"@types/react" "*"
hoist-non-react-statics "^3.3.0"
"@types/json-schema@^7.0.9": "@types/json-schema@^7.0.9":
version "7.0.9" version "7.0.9"
resolved "https://registry.npmmirror.com/@types/json-schema/download/@types/json-schema-7.0.9.tgz?cache=0&sync_timestamp=1637265456183&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40types%2Fjson-schema%2Fdownload%2F%40types%2Fjson-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" resolved "https://registry.npmmirror.com/@types/json-schema/download/@types/json-schema-7.0.9.tgz?cache=0&sync_timestamp=1637265456183&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40types%2Fjson-schema%2Fdownload%2F%40types%2Fjson-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d"
@ -1383,6 +1391,16 @@
dependencies: dependencies:
"@types/react" "*" "@types/react" "*"
"@types/react-redux@^7.1.20":
version "7.1.22"
resolved "https://registry.npmmirror.com/@types/react-redux/download/@types/react-redux-7.1.22.tgz#0eab76a37ef477cc4b53665aeaf29cb60631b72a"
integrity sha512-GxIA1kM7ClU73I6wg9IRTVwSO9GS+SAKZKe0Enj+82HMU6aoESFU2HNAdNi3+J53IaOHPiUfT3kSG4L828joDQ==
dependencies:
"@types/hoist-non-react-statics" "^3.3.0"
"@types/react" "*"
hoist-non-react-statics "^3.3.0"
redux "^4.0.0"
"@types/react@*", "@types/react@^17.0.33": "@types/react@*", "@types/react@^17.0.33":
version "17.0.38" version "17.0.38"
resolved "https://registry.npmmirror.com/@types/react/download/@types/react-17.0.38.tgz#f24249fefd89357d5fa71f739a686b8d7c7202bd" resolved "https://registry.npmmirror.com/@types/react/download/@types/react-17.0.38.tgz#f24249fefd89357d5fa71f739a686b8d7c7202bd"
@ -2820,6 +2838,13 @@ has@^1.0.3:
dependencies: dependencies:
function-bind "^1.1.1" function-bind "^1.1.1"
hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
version "3.3.2"
resolved "https://registry.nlark.com/hoist-non-react-statics/download/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
integrity sha1-7OCsr3HWLClpwuxZ/v9CpLGoW0U=
dependencies:
react-is "^16.7.0"
human-signals@^2.1.0: human-signals@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.nlark.com/human-signals/download/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" resolved "https://registry.nlark.com/human-signals/download/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
@ -3941,11 +3966,28 @@ react-dom@^17.0.2:
object-assign "^4.1.1" object-assign "^4.1.1"
scheduler "^0.20.2" scheduler "^0.20.2"
react-is@^16.12.0, react-is@^16.13.1: react-is@^16.12.0, react-is@^16.13.1, react-is@^16.7.0:
version "16.13.1" version "16.13.1"
resolved "https://registry.npmmirror.com/react-is/download/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" resolved "https://registry.npmmirror.com/react-is/download/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha1-eJcppNw23imZ3BVt1sHZwYzqVqQ= integrity sha1-eJcppNw23imZ3BVt1sHZwYzqVqQ=
react-is@^17.0.2:
version "17.0.2"
resolved "https://registry.npmmirror.com/react-is/download/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha1-5pHUqOnHiTZWVVOas3J2Kw77VPA=
react-redux@^7.2.6:
version "7.2.6"
resolved "https://registry.npmmirror.com/react-redux/download/react-redux-7.2.6.tgz#49633a24fe552b5f9caf58feb8a138936ddfe9aa"
integrity sha512-10RPdsz0UUrRL1NZE0ejTkucnclYSgXp5q+tB5SWx2qeG2ZJQJyymgAhwKy73yiL/13btfB6fPr+rgbMAaZIAQ==
dependencies:
"@babel/runtime" "^7.15.4"
"@types/react-redux" "^7.1.20"
hoist-non-react-statics "^3.3.2"
loose-envify "^1.4.0"
prop-types "^15.7.2"
react-is "^17.0.2"
react-refresh@^0.11.0: react-refresh@^0.11.0:
version "0.11.0" version "0.11.0"
resolved "https://registry.npmmirror.com/react-refresh/download/react-refresh-0.11.0.tgz#77198b944733f0f1f1a90e791de4541f9f074046" resolved "https://registry.npmmirror.com/react-refresh/download/react-refresh-0.11.0.tgz#77198b944733f0f1f1a90e791de4541f9f074046"
@ -3959,7 +4001,7 @@ react@^17.0.2:
loose-envify "^1.1.0" loose-envify "^1.1.0"
object-assign "^4.1.1" object-assign "^4.1.1"
redux@^4.1.2: redux@^4.0.0, redux@^4.1.2:
version "4.1.2" version "4.1.2"
resolved "https://registry.npmmirror.com/redux/download/redux-4.1.2.tgz#140f35426d99bb4729af760afcf79eaaac407104" resolved "https://registry.npmmirror.com/redux/download/redux-4.1.2.tgz#140f35426d99bb4729af760afcf79eaaac407104"
integrity sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw== integrity sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==

Loading…
Cancel
Save