diff --git a/src/pages/editor/Container.tsx b/src/pages/editor/Container.tsx index ccf55a4..05c5a85 100644 --- a/src/pages/editor/Container.tsx +++ b/src/pages/editor/Container.tsx @@ -10,8 +10,8 @@ import { import { connect } from 'dva'; import HeaderComponent from './components/Header'; import CanvasControl from './components/CanvasControl'; -import SourceBox from './SourceBox'; -import TargetBox from './TargetBox'; +import SourceBox from './TargetBox'; +import TargetBox from './SourceBox'; import Calibration from 'components/Calibration'; import DynamicEngine, { componentsType } from '@/core/DynamicEngine'; import { FormRender } from '@/core'; diff --git a/src/pages/editor/SourceBox.tsx b/src/pages/editor/SourceBox.tsx index b91079d..cc8c5f6 100644 --- a/src/pages/editor/SourceBox.tsx +++ b/src/pages/editor/SourceBox.tsx @@ -1,216 +1,70 @@ -import React, { memo, useCallback, useEffect, useMemo, useState } from 'react'; -import { useDrop } from 'react-dnd'; -import Draggable, { DraggableData, DraggableEvent } from 'react-draggable'; -import { ItemCallback } from 'react-grid-layout'; -import { connect } from 'dva'; -import { ViewRender } from '@/core'; +import React, { useMemo, memo, ReactNode, useContext, CSSProperties } from 'react'; +import { useDrag } from 'react-dnd'; +import schema from '@/materials/schema'; import styles from './index.less'; -import { uuid } from '@/utils/tool'; -import { Dispatch } from 'umi'; -import { StateWithHistory } from 'redux-undo'; -import { Menu, Item, MenuProvider } from 'react-contexify'; -import 'react-contexify/dist/ReactContexify.min.css'; -interface SourceBoxProps { - pstate: { pointData: { id: string; item: any; point: any; isMenu?: any }[]; curPoint: any }; - cstate: { pointData: { id: string; item: any; point: any }[]; curPoint: any }; - scaleNum: number; + +interface TargetBoxProps { + item: any; + children: ReactNode; canvasId: string; - allType: string[]; - dispatch: Dispatch; - dragState: { x: number; y: number }; - setDragState: React.Dispatch< - React.SetStateAction<{ - x: number; - y: number; - }> - >; } -const SourceBox = memo((props: SourceBoxProps) => { - const { pstate, scaleNum, canvasId, allType, dispatch, dragState, setDragState, cstate } = props; +const SourceBox = memo((props: TargetBoxProps) => { + const { item } = props; - let pointData = pstate ? pstate.pointData : []; - const cpointData = cstate ? cstate.pointData : []; - - const [canvasRect, setCanvasRect] = useState([]); - const [isShowTip, setIsShowTip] = useState(true); - const [{ isOver }, drop] = useDrop({ - accept: allType, - drop: (item: { h: number; type: string; x: number }, monitor) => { - let parentDiv = document.getElementById(canvasId), - pointRect = parentDiv!.getBoundingClientRect(), - top = pointRect.top, - pointEnd = monitor.getSourceClientOffset(), - y = pointEnd!.y < top ? 0 : pointEnd!.y - top, - col = 24, // 网格列数 - cellHeight = 2, - w = item.type === 'Icon' ? 3 : col; - // 转换成网格规则的坐标和大小 - let gridY = Math.ceil(y / cellHeight); - dispatch({ - type: 'editorModal/addPointData', - payload: { - id: uuid(6, 10), - item, - point: { i: `x-${pointData.length}`, x: 0, y: gridY, w, h: item.h, isBounded: true }, - status: 'inToCanvas', - }, - }); + const [{ isDragging }, drag] = useDrag({ + item: { + type: item.type, + config: schema[item.type as keyof typeof schema].config, + h: item.h, + editableEl: schema[item.type as keyof typeof schema].editData, + category: item.category, + x: item.x || 0, }, collect: monitor => ({ - isOver: monitor.isOver(), - canDrop: monitor.canDrop(), - item: monitor.getItem(), + isDragging: monitor.isDragging(), }), }); - const dragStop: ItemCallback = useMemo(() => { - return (layout, oldItem, newItem, placeholder, e, element) => { - const curPointData = pointData.filter(item => item.id === newItem.i)[0]; - dispatch({ - type: 'editorModal/modPointData', - payload: { ...curPointData, point: newItem, status: 'inToCanvas' }, - }); - }; - }, [cpointData, dispatch, pointData]); - - const onDragStart: ItemCallback = useMemo(() => { - return (layout, oldItem, newItem, placeholder, e, element) => { - const curPointData = pointData.filter(item => item.id === newItem.i)[0]; - dispatch({ - type: 'editorModal/modPointData', - payload: { ...curPointData, status: 'inToCanvas' }, - }); - }; - }, [dispatch, pointData]); - - const onResizeStop: ItemCallback = useMemo(() => { - return (layout, oldItem, newItem, placeholder, e, element) => { - const curPointData = pointData.filter(item => item.id === newItem.i)[0]; - dispatch({ - type: 'editorModal/modPointData', - payload: { ...curPointData, point: newItem, status: 'inToCanvas' }, - }); - }; - }, [dispatch, pointData]); - - const handleContextMenuDel = () => { - if (pstate.curPoint) { - dispatch({ - type: 'editorModal/delPointData', - payload: { id: pstate.curPoint.id }, - }); - } - }; - - const handleContextMenuCopy = () => { - if (pstate.curPoint) { - dispatch({ - type: 'editorModal/copyPointData', - payload: { id: pstate.curPoint.id }, - }); - } - }; - - const onConTextClick = (type: string) => { - if (type === 'del') { - handleContextMenuDel(); - } else if (type === 'copy') { - handleContextMenuCopy(); - } - }; - - const MyAwesomeMenu = useCallback( - () => ( - - onConTextClick('copy')}>复制 - onConTextClick('del')}>删除 - - ), - [onConTextClick], + const containerStyle: CSSProperties = useMemo( + () => ({ + opacity: isDragging ? 0.4 : 1, + cursor: 'move', + height: '140px', + }), + [isDragging], ); - - useEffect(() => { - let { width, height } = document.getElementById(canvasId)!.getBoundingClientRect(); - setCanvasRect([width, height]); - }, [canvasId]); - - useEffect(() => { - let timer = window.setTimeout(() => { - setIsShowTip(false); - }, 3000); - return () => { - window.clearTimeout(timer); - }; - }, []); - const opacity = isOver ? 0.7 : 1; - - const render = useMemo(() => { - return ( - { - setDragState({ x: data.x, y: data.y }); - }} - > -
- -
-
- {pointData.length > 0 ? ( - - ) : null} -
-
-
-
-
- ); - }, [ - canvasId, - canvasRect, - dragState, - dragStop, - drop, - isShowTip, - onDragStart, - onResizeStop, - opacity, - pointData, - scaleNum, - setDragState, - ]); - return ( <> - {render} - +
+
+
+ {props.children} +
+
+ {props.item.displayName} +
+
+
); }); -export default connect((state: StateWithHistory) => ({ - pstate: state.present.editorModal, - cstate: state.present.editorPcModal, -}))(SourceBox); +export default SourceBox; diff --git a/src/pages/editor/TargetBox.tsx b/src/pages/editor/TargetBox.tsx index c2b18eb..47c0962 100644 --- a/src/pages/editor/TargetBox.tsx +++ b/src/pages/editor/TargetBox.tsx @@ -1,70 +1,216 @@ -import React, { useMemo, memo, ReactNode, useContext, CSSProperties } from 'react'; -import { useDrag } from 'react-dnd'; -import schema from '@/materials/schema'; +import React, { memo, useCallback, useEffect, useMemo, useState } from 'react'; +import { useDrop } from 'react-dnd'; +import Draggable, { DraggableData, DraggableEvent } from 'react-draggable'; +import { ItemCallback } from 'react-grid-layout'; +import { connect } from 'dva'; +import { ViewRender } from '@/core'; import styles from './index.less'; - -interface TargetBoxProps { - item: any; - children: ReactNode; +import { uuid } from '@/utils/tool'; +import { Dispatch } from 'umi'; +import { StateWithHistory } from 'redux-undo'; +import { Menu, Item, MenuProvider } from 'react-contexify'; +import 'react-contexify/dist/ReactContexify.min.css'; +interface SourceBoxProps { + pstate: { pointData: { id: string; item: any; point: any; isMenu?: any }[]; curPoint: any }; + cstate: { pointData: { id: string; item: any; point: any }[]; curPoint: any }; + scaleNum: number; canvasId: string; + allType: string[]; + dispatch: Dispatch; + dragState: { x: number; y: number }; + setDragState: React.Dispatch< + React.SetStateAction<{ + x: number; + y: number; + }> + >; } -const TargetBox = memo((props: TargetBoxProps) => { - const { item } = props; +const TargetBox = memo((props: SourceBoxProps) => { + const { pstate, scaleNum, canvasId, allType, dispatch, dragState, setDragState, cstate } = props; - const [{ isDragging }, drag] = useDrag({ - item: { - type: item.type, - config: schema[item.type as keyof typeof schema].config, - h: item.h, - editableEl: schema[item.type as keyof typeof schema].editData, - category: item.category, - x: item.x || 0, + let pointData = pstate ? pstate.pointData : []; + const cpointData = cstate ? cstate.pointData : []; + + const [canvasRect, setCanvasRect] = useState([]); + const [isShowTip, setIsShowTip] = useState(true); + const [{ isOver }, drop] = useDrop({ + accept: allType, + drop: (item: { h: number; type: string; x: number }, monitor) => { + let parentDiv = document.getElementById(canvasId), + pointRect = parentDiv!.getBoundingClientRect(), + top = pointRect.top, + pointEnd = monitor.getSourceClientOffset(), + y = pointEnd!.y < top ? 0 : pointEnd!.y - top, + col = 24, // 网格列数 + cellHeight = 2, + w = item.type === 'Icon' ? 3 : col; + // 转换成网格规则的坐标和大小 + let gridY = Math.ceil(y / cellHeight); + dispatch({ + type: 'editorModal/addPointData', + payload: { + id: uuid(6, 10), + item, + point: { i: `x-${pointData.length}`, x: 0, y: gridY, w, h: item.h, isBounded: true }, + status: 'inToCanvas', + }, + }); }, collect: monitor => ({ - isDragging: monitor.isDragging(), + isOver: monitor.isOver(), + canDrop: monitor.canDrop(), + item: monitor.getItem(), }), }); - const containerStyle: CSSProperties = useMemo( - () => ({ - opacity: isDragging ? 0.4 : 1, - cursor: 'move', - height: '140px', - }), - [isDragging], + const dragStop: ItemCallback = useMemo(() => { + return (layout, oldItem, newItem, placeholder, e, element) => { + const curPointData = pointData.filter(item => item.id === newItem.i)[0]; + dispatch({ + type: 'editorModal/modPointData', + payload: { ...curPointData, point: newItem, status: 'inToCanvas' }, + }); + }; + }, [cpointData, dispatch, pointData]); + + const onDragStart: ItemCallback = useMemo(() => { + return (layout, oldItem, newItem, placeholder, e, element) => { + const curPointData = pointData.filter(item => item.id === newItem.i)[0]; + dispatch({ + type: 'editorModal/modPointData', + payload: { ...curPointData, status: 'inToCanvas' }, + }); + }; + }, [dispatch, pointData]); + + const onResizeStop: ItemCallback = useMemo(() => { + return (layout, oldItem, newItem, placeholder, e, element) => { + const curPointData = pointData.filter(item => item.id === newItem.i)[0]; + dispatch({ + type: 'editorModal/modPointData', + payload: { ...curPointData, point: newItem, status: 'inToCanvas' }, + }); + }; + }, [dispatch, pointData]); + + const handleContextMenuDel = () => { + if (pstate.curPoint) { + dispatch({ + type: 'editorModal/delPointData', + payload: { id: pstate.curPoint.id }, + }); + } + }; + + const handleContextMenuCopy = () => { + if (pstate.curPoint) { + dispatch({ + type: 'editorModal/copyPointData', + payload: { id: pstate.curPoint.id }, + }); + } + }; + + const onConTextClick = (type: string) => { + if (type === 'del') { + handleContextMenuDel(); + } else if (type === 'copy') { + handleContextMenuCopy(); + } + }; + + const MyAwesomeMenu = useCallback( + () => ( + + onConTextClick('copy')}>复制 + onConTextClick('del')}>删除 + + ), + [onConTextClick], ); + + useEffect(() => { + let { width, height } = document.getElementById(canvasId)!.getBoundingClientRect(); + setCanvasRect([width, height]); + }, [canvasId]); + + useEffect(() => { + let timer = window.setTimeout(() => { + setIsShowTip(false); + }, 3000); + return () => { + window.clearTimeout(timer); + }; + }, []); + const opacity = isOver ? 0.7 : 1; + + const render = useMemo(() => { + return ( + { + setDragState({ x: data.x, y: data.y }); + }} + > +
+ +
+
+ {pointData.length > 0 ? ( + + ) : null} +
+
+
+
+
+ ); + }, [ + canvasId, + canvasRect, + dragState, + dragStop, + drop, + isShowTip, + onDragStart, + onResizeStop, + opacity, + pointData, + scaleNum, + setDragState, + ]); + return ( <> -
-
-
- {props.children} -
-
- {props.item.displayName} -
-
-
+ {render} + ); }); -export default TargetBox; +export default connect((state: StateWithHistory) => ({ + pstate: state.present.editorModal, + cstate: state.present.editorPcModal, +}))(TargetBox);