mirror of
https://github.com/MrXujiang/h5-Dooring.git
synced 2025-12-15 04:12:49 +00:00
commit
b9219c9ebc
@ -1,5 +1,6 @@
|
||||
const template = {
|
||||
type: 'Footer',
|
||||
h: 24,
|
||||
x: 12,
|
||||
};
|
||||
export default template;
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
const template = {
|
||||
type: 'Header',
|
||||
h: 28,
|
||||
x: 12,
|
||||
};
|
||||
export default template;
|
||||
|
||||
@ -1,23 +1,32 @@
|
||||
import { dynamic } from 'umi';
|
||||
import Loading from '../LoadingCp';
|
||||
import { useMemo, memo, FC } from 'react';
|
||||
import { useMemo, memo, FC, useContext } from 'react';
|
||||
import React from 'react';
|
||||
import { dooringContext, dooringContextType } from '@/layouts';
|
||||
// import { AllTemplateType } from './schema';
|
||||
|
||||
export type componentsType = 'media' | 'base' | 'visible';
|
||||
|
||||
const DynamicFunc = (type: string, componentsType: string) =>
|
||||
dynamic({
|
||||
const DynamicFunc = (type: string, componentsType: string, context: dooringContextType) => {
|
||||
const prefix = context === 'pc' ? 'Pc' : '';
|
||||
return dynamic({
|
||||
loader: async function() {
|
||||
let Component: FC<{ isTpl: boolean }>;
|
||||
|
||||
if (componentsType === 'base') {
|
||||
const { default: Graph } = await import(`@/components/BasicShop/BasicComponents/${type}`);
|
||||
const { default: Graph } = await import(
|
||||
`@/components/Basic${prefix}Shop/BasicComponents/${type}`
|
||||
);
|
||||
Component = Graph;
|
||||
} else if (componentsType === 'media') {
|
||||
const { default: Graph } = await import(`@/components/BasicShop/MediaComponents/${type}`);
|
||||
const { default: Graph } = await import(
|
||||
`@/components/Basic${prefix}Shop/MediaComponents/${type}`
|
||||
);
|
||||
Component = Graph;
|
||||
} else {
|
||||
const { default: Graph } = await import(`@/components/BasicShop/VisualComponents/${type}`);
|
||||
const { default: Graph } = await import(
|
||||
`@/components/Basic${prefix}Shop/VisualComponents/${type}`
|
||||
);
|
||||
Component = Graph;
|
||||
}
|
||||
return (props: DynamicType) => {
|
||||
@ -31,6 +40,7 @@ const DynamicFunc = (type: string, componentsType: string) =>
|
||||
</div>
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
type DynamicType = {
|
||||
isTpl: boolean;
|
||||
@ -41,10 +51,11 @@ type DynamicType = {
|
||||
};
|
||||
const DynamicEngine = memo((props: DynamicType) => {
|
||||
const { type, config, category } = props;
|
||||
const context = useContext(dooringContext);
|
||||
const Dynamic = useMemo(() => {
|
||||
return (DynamicFunc(type, category) as unknown) as FC<DynamicType>;
|
||||
return (DynamicFunc(type, category, context.theme) as unknown) as FC<DynamicType>;
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [config]);
|
||||
}, [config, context.theme]);
|
||||
|
||||
return <Dynamic {...props} />;
|
||||
});
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import React, { createContext, useCallback, useState } from 'react';
|
||||
import { library, generateRespones, RenderList, useRegister } from 'chatbot-antd';
|
||||
import { IRouteComponentProps } from 'umi';
|
||||
import { Button } from 'antd';
|
||||
import { CustomerServiceOutlined } from '@ant-design/icons';
|
||||
import { stat } from 'fs/promises';
|
||||
|
||||
library.push(
|
||||
//语料库,push进去,也可以不用
|
||||
@ -21,6 +22,17 @@ library.push(
|
||||
},
|
||||
);
|
||||
|
||||
export type dooringContextType = 'h5' | 'pc';
|
||||
|
||||
export interface IdooringContextType {
|
||||
theme: dooringContextType;
|
||||
setTheme: Function;
|
||||
}
|
||||
export const dooringContext = createContext<IdooringContextType>({
|
||||
theme: 'h5',
|
||||
setTheme: () => {},
|
||||
});
|
||||
|
||||
export default function Layout({ children }: IRouteComponentProps) {
|
||||
const [modalOpen, setModalOpen] = useState(false);
|
||||
const callb = useCallback((v: RenderList) => {
|
||||
@ -46,23 +58,33 @@ export default function Layout({ children }: IRouteComponentProps) {
|
||||
{},
|
||||
<div>welcome!欢迎使用h5-Dooring,你有任何问题,都可以咨询我哦~</div>,
|
||||
);
|
||||
|
||||
const [state, setState] = useState<dooringContextType>('h5');
|
||||
|
||||
return (
|
||||
<div style={{ height: '100%', width: '100%' }}>
|
||||
<div
|
||||
style={{
|
||||
position: 'fixed',
|
||||
right: `${modalOpen ? '-100%' : '10px'}`,
|
||||
bottom: '80px',
|
||||
transition: 'all 0.5s ease-in-out',
|
||||
zIndex: 2,
|
||||
}}
|
||||
>
|
||||
<Button type="primary" onClick={() => setModalOpen(!modalOpen)}>
|
||||
<CustomerServiceOutlined></CustomerServiceOutlined>
|
||||
</Button>
|
||||
<dooringContext.Provider
|
||||
value={{
|
||||
theme: state,
|
||||
setTheme: setState,
|
||||
}}
|
||||
>
|
||||
<div style={{ height: '100%', width: '100%' }}>
|
||||
<div
|
||||
style={{
|
||||
position: 'fixed',
|
||||
right: `${modalOpen ? '-100%' : '10px'}`,
|
||||
bottom: '80px',
|
||||
transition: 'all 0.5s ease-in-out',
|
||||
zIndex: 2,
|
||||
}}
|
||||
>
|
||||
<Button type="primary" onClick={() => setModalOpen(!modalOpen)}>
|
||||
<CustomerServiceOutlined></CustomerServiceOutlined>
|
||||
</Button>
|
||||
</div>
|
||||
{render}
|
||||
{children}
|
||||
</div>
|
||||
{render}
|
||||
{children}
|
||||
</div>
|
||||
</dooringContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect, useMemo } from 'react';
|
||||
import React, { useState, useEffect, useMemo, useContext } from 'react';
|
||||
import { Slider, Result, Tabs, Alert } from 'antd';
|
||||
import {
|
||||
PieChartOutlined,
|
||||
@ -15,24 +15,82 @@ import TargetBox from './TargetBox';
|
||||
import Calibration from 'components/Calibration';
|
||||
import DynamicEngine, { componentsType } from 'components/DynamicEngine';
|
||||
import FormEditor from 'components/PanelComponents/FormEditor';
|
||||
import template from 'components/BasicShop/BasicComponents/template';
|
||||
import mediaTpl from 'components/BasicShop/MediaComponents/template';
|
||||
import graphTpl from 'components/BasicShop/VisualComponents/template';
|
||||
import schema from 'components/BasicShop/schema';
|
||||
|
||||
import template1 from 'components/BasicShop/BasicComponents/template';
|
||||
import template2 from 'components/BasicPcShop/BasicComponents/template';
|
||||
import mediaTpl1 from 'components/BasicShop/MediaComponents/template';
|
||||
import mediaTpl2 from 'components/BasicPcShop/MediaComponents/template';
|
||||
import graphTpl1 from 'components/BasicShop/VisualComponents/template';
|
||||
import graphTpl2 from 'components/BasicPcShop/VisualComponents/template';
|
||||
|
||||
import schema1 from 'components/BasicShop/schema';
|
||||
import schema2 from 'components/BasicPcShop/schema';
|
||||
|
||||
import { ActionCreators } from 'redux-undo';
|
||||
import { StateWithHistory } from 'redux-undo';
|
||||
import styles from './index.less';
|
||||
import { useGetBall } from 'react-draggable-ball';
|
||||
import { useAnimation } from '@/utils/tool';
|
||||
import { dooringContext } from '@/layouts';
|
||||
|
||||
const { TabPane } = Tabs;
|
||||
|
||||
const Container = (props: { history?: any; location?: any; pstate?: any; dispatch?: any }) => {
|
||||
const Container = (props: {
|
||||
history?: any;
|
||||
location?: any;
|
||||
pstate?: any;
|
||||
cstate?: any;
|
||||
dispatch?: any;
|
||||
}) => {
|
||||
const [scaleNum, setScale] = useState(1);
|
||||
const [collapsed, setCollapsed] = useState(false);
|
||||
const [collapsed, setCollapsed] = useState(true);
|
||||
|
||||
const { pstate, cstate, dispatch } = props;
|
||||
const pointData = pstate ? pstate.pointData : [];
|
||||
const cpointData = cstate ? cstate.pointData : [];
|
||||
|
||||
const context = useContext(dooringContext);
|
||||
const curPoint = useMemo(() => {
|
||||
if (context.theme === 'h5') {
|
||||
return pstate ? pstate.curPoint : {};
|
||||
} else {
|
||||
return cstate ? cstate.curPoint : {};
|
||||
}
|
||||
}, [context.theme, cstate, pstate]);
|
||||
|
||||
const schema = useMemo(() => {
|
||||
if (context.theme === 'h5') {
|
||||
return schema1;
|
||||
} else {
|
||||
console.log(schema2);
|
||||
return schema2;
|
||||
}
|
||||
}, [context.theme]);
|
||||
|
||||
const template = useMemo(() => {
|
||||
if (context.theme === 'h5') {
|
||||
return template1;
|
||||
} else {
|
||||
return template2;
|
||||
}
|
||||
}, [context.theme]);
|
||||
|
||||
const mediaTpl = useMemo(() => {
|
||||
if (context.theme === 'h5') {
|
||||
return mediaTpl1;
|
||||
} else {
|
||||
return mediaTpl2;
|
||||
}
|
||||
}, [context.theme]);
|
||||
|
||||
const graphTpl = useMemo(() => {
|
||||
if (context.theme === 'h5') {
|
||||
return graphTpl1;
|
||||
} else {
|
||||
return graphTpl2;
|
||||
}
|
||||
}, [context.theme]);
|
||||
|
||||
const { pstate, dispatch } = props;
|
||||
const pointData = pstate ? pstate.pointData : {};
|
||||
const curPoint = pstate ? pstate.curPoint : {};
|
||||
// 指定画布的id
|
||||
let canvasId = 'js_canvas';
|
||||
|
||||
@ -41,6 +99,7 @@ const Container = (props: { history?: any; location?: any; pstate?: any; dispatc
|
||||
};
|
||||
|
||||
const toggleCollapsed = (checked: boolean) => {
|
||||
console.log(checked);
|
||||
setCollapsed(checked);
|
||||
};
|
||||
|
||||
@ -69,23 +128,51 @@ const Container = (props: { history?: any; location?: any; pstate?: any; dispatc
|
||||
setScale(prev => (prev <= 0.5 ? 0.5 : prev - 0.1));
|
||||
}
|
||||
};
|
||||
const handleFormSave = (data: any) => {
|
||||
dispatch({
|
||||
type: 'editorModal/modPointData',
|
||||
payload: { ...curPoint, item: { ...curPoint.item, config: data } },
|
||||
});
|
||||
};
|
||||
|
||||
const clearData = () => {
|
||||
dispatch({ type: 'editorModal/clearAll' });
|
||||
};
|
||||
const handleFormSave = useMemo(() => {
|
||||
if (context.theme === 'h5') {
|
||||
return (data: any) => {
|
||||
dispatch({
|
||||
type: 'editorModal/modPointData',
|
||||
payload: { ...curPoint, item: { ...curPoint.item, config: data } },
|
||||
});
|
||||
};
|
||||
} else {
|
||||
return (data: any) => {
|
||||
dispatch({
|
||||
type: 'editorPcModal/modPointData',
|
||||
payload: { ...curPoint, item: { ...curPoint.item, config: data } },
|
||||
});
|
||||
};
|
||||
}
|
||||
}, [context.theme, curPoint, dispatch]);
|
||||
|
||||
const clearData = useMemo(() => {
|
||||
if (context.theme === 'h5') {
|
||||
dispatch({ type: 'editorModal/clearAll' });
|
||||
} else {
|
||||
dispatch({ type: 'editorPcModal/clearAll' });
|
||||
}
|
||||
}, [context.theme, dispatch]);
|
||||
|
||||
const handleDel = useMemo(() => {
|
||||
if (context.theme === 'h5') {
|
||||
return (id: any) => {
|
||||
dispatch({
|
||||
type: 'editorModal/delPointData',
|
||||
payload: { id },
|
||||
});
|
||||
};
|
||||
} else {
|
||||
return (id: any) => {
|
||||
dispatch({
|
||||
type: 'editorPcModal/delPointData',
|
||||
payload: { id },
|
||||
});
|
||||
};
|
||||
}
|
||||
}, [context.theme, dispatch]);
|
||||
|
||||
const handleDel = (id: any) => {
|
||||
dispatch({
|
||||
type: 'editorModal/delPointData',
|
||||
payload: { id },
|
||||
});
|
||||
};
|
||||
const redohandler = () => {
|
||||
dispatch(ActionCreators.redo());
|
||||
};
|
||||
@ -120,18 +207,81 @@ const Container = (props: { history?: any; location?: any; pstate?: any; dispatc
|
||||
intervalDelay: 5,
|
||||
});
|
||||
|
||||
const [display] = useAnimation(collapsed, 500);
|
||||
|
||||
const renderRight = useMemo(() => {
|
||||
if (context.theme === 'h5') {
|
||||
return (
|
||||
<div className={styles.attrSetting}>
|
||||
{pointData.length && curPoint ? (
|
||||
<>
|
||||
<div className={styles.tit}>属性设置</div>
|
||||
<FormEditor
|
||||
config={curPoint.item.editableEl}
|
||||
uid={curPoint.id}
|
||||
defaultValue={curPoint.item.config}
|
||||
onSave={handleFormSave}
|
||||
onDel={handleDel}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<div style={{ paddingTop: '100px' }}>
|
||||
<Result
|
||||
status="404"
|
||||
title="还没有数据哦"
|
||||
subTitle="赶快拖拽组件来生成你的H5页面吧~"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div className={styles.attrSetting}>
|
||||
{cpointData.length && curPoint ? (
|
||||
<>
|
||||
<div className={styles.tit}>属性设置</div>
|
||||
<FormEditor
|
||||
config={curPoint.item.editableEl}
|
||||
uid={curPoint.id}
|
||||
defaultValue={curPoint.item.config}
|
||||
onSave={handleFormSave}
|
||||
onDel={handleDel}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<div style={{ paddingTop: '100px' }}>
|
||||
<Result
|
||||
status="404"
|
||||
title="还没有数据哦"
|
||||
subTitle="赶快拖拽组件来生成你的H5页面吧~"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}, [context.theme, cpointData.length, curPoint, handleDel, handleFormSave, pointData.length]);
|
||||
|
||||
return (
|
||||
<div className={styles.editorWrap}>
|
||||
<HeaderComponent
|
||||
redohandler={redohandler}
|
||||
undohandler={undohandler}
|
||||
pointData={pointData}
|
||||
pointData={context.theme === 'h5' ? pointData : cpointData}
|
||||
clearData={clearData}
|
||||
location={props.location}
|
||||
toggleCollapsed={toggleCollapsed}
|
||||
/>
|
||||
<div className={styles.container}>
|
||||
<div className={!collapsed ? styles.list : styles.collapsed}>
|
||||
<div
|
||||
className={styles.list}
|
||||
style={{
|
||||
transform: collapsed ? 'translate(0,0)' : 'translate(-100%,0)',
|
||||
transition: 'all ease-in-out 0.5s',
|
||||
display: display ? 'none' : 'block',
|
||||
}}
|
||||
>
|
||||
<div className={styles.searchBar}>
|
||||
<Alert
|
||||
banner
|
||||
@ -228,33 +378,12 @@ const Container = (props: { history?: any; location?: any; pstate?: any; dispatc
|
||||
<ExpandOutlined onClick={backSize} />
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.attrSetting}>
|
||||
{pointData.length && curPoint ? (
|
||||
<>
|
||||
<div className={styles.tit}>属性设置</div>
|
||||
<FormEditor
|
||||
config={curPoint.item.editableEl}
|
||||
uid={curPoint.id}
|
||||
defaultValue={curPoint.item.config}
|
||||
onSave={handleFormSave}
|
||||
onDel={handleDel}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<div style={{ paddingTop: '100px' }}>
|
||||
<Result
|
||||
status="404"
|
||||
title="还没有数据哦"
|
||||
subTitle="赶快拖拽组件来生成你的H5页面吧~"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{renderRight}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default connect((state: StateWithHistory<any>) => {
|
||||
return { pstate: state.present.editorModal };
|
||||
return { pstate: state.present.editorModal, cstate: state.present.editorPcModal };
|
||||
})(Container);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import React, { memo, useEffect, useState } from 'react';
|
||||
import React, { memo, useContext, useEffect, useMemo, useState } from 'react';
|
||||
import { useDrop } from 'react-dnd';
|
||||
import Draggable, { DraggableData, DraggableEvent } from 'react-draggable';
|
||||
import GridLayout, { ItemCallback } from 'react-grid-layout';
|
||||
@ -9,8 +9,10 @@ import styles from './index.less';
|
||||
import { uuid } from '@/utils/tool';
|
||||
import { Dispatch } from 'umi';
|
||||
import { StateWithHistory } from 'redux-undo';
|
||||
import { dooringContext } from '@/layouts';
|
||||
interface SourceBoxProps {
|
||||
pstate: { pointData: { id: string; item: any; point: any }[] };
|
||||
pstate: { pointData: { id: string; item: any; point: any }[]; curPoint: any };
|
||||
cstate: { pointData: { id: string; item: any; point: any }[]; curPoint: any };
|
||||
scaleNum: number;
|
||||
canvasId: string;
|
||||
allType: string[];
|
||||
@ -25,14 +27,17 @@ interface SourceBoxProps {
|
||||
}
|
||||
|
||||
const SourceBox = memo((props: SourceBoxProps) => {
|
||||
const { pstate, scaleNum, canvasId, allType, dispatch, dragState, setDragState } = props;
|
||||
const { pstate, scaleNum, canvasId, allType, dispatch, dragState, setDragState, cstate } = props;
|
||||
const context = useContext(dooringContext);
|
||||
|
||||
const pointData = pstate ? pstate.pointData : [];
|
||||
const cpointData = cstate ? cstate.pointData : [];
|
||||
|
||||
const [canvasRect, setCanvasRect] = useState<number[]>([]);
|
||||
const [isShowTip, setIsShowTip] = useState(true);
|
||||
const [{ isOver }, drop] = useDrop({
|
||||
accept: allType,
|
||||
drop: (item: { h: number; type: string }, monitor) => {
|
||||
drop: (item: { h: number; type: string; x: number }, monitor) => {
|
||||
let parentDiv = document.getElementById(canvasId),
|
||||
pointRect = parentDiv!.getBoundingClientRect(),
|
||||
top = pointRect.top,
|
||||
@ -43,14 +48,33 @@ const SourceBox = memo((props: SourceBoxProps) => {
|
||||
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 },
|
||||
},
|
||||
});
|
||||
if (context.theme === 'h5') {
|
||||
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 },
|
||||
},
|
||||
});
|
||||
} else {
|
||||
console.log(item.x);
|
||||
dispatch({
|
||||
type: 'editorPcModal/addPointData',
|
||||
payload: {
|
||||
id: uuid(6, 10),
|
||||
item,
|
||||
point: {
|
||||
i: `x-${cpointData.length}`,
|
||||
x: item.x || 0,
|
||||
y: gridY,
|
||||
w,
|
||||
h: item.h,
|
||||
isBounded: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
collect: monitor => ({
|
||||
isOver: monitor.isOver(),
|
||||
@ -59,34 +83,65 @@ const SourceBox = memo((props: SourceBoxProps) => {
|
||||
}),
|
||||
});
|
||||
|
||||
const dragStop: ItemCallback = (layout, oldItem, newItem, placeholder, e, element) => {
|
||||
const curPointData = pointData.filter(item => item.id === newItem.i)[0];
|
||||
dispatch({
|
||||
type: 'editorModal/modPointData',
|
||||
payload: { ...curPointData, point: newItem },
|
||||
});
|
||||
};
|
||||
const dragStop: ItemCallback = useMemo(() => {
|
||||
return (layout, oldItem, newItem, placeholder, e, element) => {
|
||||
if (context.theme === 'h5') {
|
||||
const curPointData = pointData.filter(item => item.id === newItem.i)[0];
|
||||
dispatch({
|
||||
type: 'editorModal/modPointData',
|
||||
payload: { ...curPointData, point: newItem },
|
||||
});
|
||||
} else {
|
||||
const curPointData = cpointData.filter(item => item.id === newItem.i)[0];
|
||||
dispatch({
|
||||
type: 'editorPcModal/modPointData',
|
||||
payload: { ...curPointData, point: newItem },
|
||||
});
|
||||
}
|
||||
};
|
||||
}, [context.theme, cpointData, dispatch, pointData]);
|
||||
|
||||
const onDragStart: ItemCallback = (layout, oldItem, newItem, placeholder, e, element) => {
|
||||
const curPointData = pointData.filter(item => item.id === newItem.i)[0];
|
||||
dispatch({
|
||||
type: 'editorModal/modPointData',
|
||||
payload: { ...curPointData },
|
||||
});
|
||||
};
|
||||
const onDragStart: ItemCallback = useMemo(() => {
|
||||
return (layout, oldItem, newItem, placeholder, e, element) => {
|
||||
if (context.theme === 'h5') {
|
||||
const curPointData = pointData.filter(item => item.id === newItem.i)[0];
|
||||
dispatch({
|
||||
type: 'editorModal/modPointData',
|
||||
payload: { ...curPointData },
|
||||
});
|
||||
} else {
|
||||
const curPointData = cpointData.filter(item => item.id === newItem.i)[0];
|
||||
dispatch({
|
||||
type: 'editorPcModal/modPointData',
|
||||
payload: { ...curPointData },
|
||||
});
|
||||
}
|
||||
};
|
||||
}, [context.theme, cpointData, dispatch, pointData]);
|
||||
|
||||
const onResizeStop: ItemCallback = (layout, oldItem, newItem, placeholder, e, element) => {
|
||||
const curPointData = pointData.filter(item => item.id === newItem.i)[0];
|
||||
dispatch({
|
||||
type: 'editorModal/modPointData',
|
||||
payload: { ...curPointData, point: newItem },
|
||||
});
|
||||
};
|
||||
const onResizeStop: ItemCallback = useMemo(() => {
|
||||
return (layout, oldItem, newItem, placeholder, e, element) => {
|
||||
if (context.theme === 'h5') {
|
||||
const curPointData = pointData.filter(item => item.id === newItem.i)[0];
|
||||
dispatch({
|
||||
type: 'editorModal/modPointData',
|
||||
payload: { ...curPointData, point: newItem },
|
||||
});
|
||||
} else {
|
||||
const curPointData = cpointData.filter(item => item.id === newItem.i)[0];
|
||||
dispatch({
|
||||
type: 'editorPcModal/modPointData',
|
||||
payload: { ...curPointData, point: newItem },
|
||||
});
|
||||
}
|
||||
};
|
||||
}, [context.theme, cpointData, dispatch, pointData]);
|
||||
|
||||
useEffect(() => {
|
||||
let { width, height } = document.getElementById(canvasId)!.getBoundingClientRect();
|
||||
console.log(width, height);
|
||||
setCanvasRect([width, height]);
|
||||
}, [canvasId]);
|
||||
}, [canvasId, context.theme]);
|
||||
|
||||
useEffect(() => {
|
||||
let timer = window.setTimeout(() => {
|
||||
@ -99,73 +154,162 @@ const SourceBox = memo((props: SourceBoxProps) => {
|
||||
const opacity = isOver ? 0.7 : 1;
|
||||
// const backgroundColor = isOver ? 1 : 0.7;
|
||||
|
||||
return (
|
||||
<Draggable
|
||||
position={dragState}
|
||||
handle=".js_box"
|
||||
onStop={(e: DraggableEvent, data: DraggableData) => {
|
||||
setDragState({ x: data.x, y: data.y });
|
||||
}}
|
||||
>
|
||||
<div className={styles.canvasBox}>
|
||||
<div
|
||||
style={{
|
||||
transform: `scale(${scaleNum})`,
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
const render = useMemo(() => {
|
||||
if (context.theme === 'h5') {
|
||||
return (
|
||||
<Draggable
|
||||
position={dragState}
|
||||
handle=".js_box"
|
||||
onStop={(e: DraggableEvent, data: DraggableData) => {
|
||||
setDragState({ x: data.x, y: data.y });
|
||||
}}
|
||||
>
|
||||
<div
|
||||
id={canvasId}
|
||||
className={styles.canvas}
|
||||
style={{
|
||||
opacity,
|
||||
}}
|
||||
ref={drop}
|
||||
>
|
||||
<Tooltip placement="right" title="鼠标按住此处拖拽画布" visible={isShowTip}>
|
||||
<div className={styles.canvasBox}>
|
||||
<div
|
||||
style={{
|
||||
transform: `scale(${scaleNum})`,
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="js_box"
|
||||
id={canvasId}
|
||||
className={styles.canvas}
|
||||
style={{
|
||||
width: '10px',
|
||||
height: '100%',
|
||||
position: 'absolute',
|
||||
borderRadius: '0 6px 6px 0',
|
||||
backgroundColor: '#2f54eb',
|
||||
right: '-10px',
|
||||
top: '0',
|
||||
color: '#fff',
|
||||
cursor: 'move',
|
||||
opacity,
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
|
||||
{pointData.length > 0 ? (
|
||||
<GridLayout
|
||||
className={styles.layout}
|
||||
cols={24}
|
||||
rowHeight={2}
|
||||
width={canvasRect[0] || 0}
|
||||
margin={[0, 0]}
|
||||
onDragStop={dragStop}
|
||||
onDragStart={onDragStart}
|
||||
onResizeStop={onResizeStop}
|
||||
ref={drop}
|
||||
>
|
||||
{pointData.map(value => (
|
||||
<div className={styles.dragItem} key={value.id} data-grid={value.point}>
|
||||
<DynamicEngine {...value.item} isTpl={false} />
|
||||
</div>
|
||||
))}
|
||||
</GridLayout>
|
||||
) : null}
|
||||
<Tooltip placement="right" title="鼠标按住此处拖拽画布" visible={isShowTip}>
|
||||
<div
|
||||
className="js_box"
|
||||
style={{
|
||||
width: '10px',
|
||||
height: '100%',
|
||||
position: 'absolute',
|
||||
borderRadius: '0 6px 6px 0',
|
||||
backgroundColor: '#2f54eb',
|
||||
right: '-10px',
|
||||
top: '0',
|
||||
color: '#fff',
|
||||
cursor: 'move',
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
|
||||
{pointData.length > 0 ? (
|
||||
<GridLayout
|
||||
className={styles.layout}
|
||||
cols={24}
|
||||
rowHeight={2}
|
||||
width={canvasRect[0] || 0}
|
||||
margin={[0, 0]}
|
||||
onDragStop={dragStop}
|
||||
onDragStart={onDragStart}
|
||||
onResizeStop={onResizeStop}
|
||||
>
|
||||
{pointData.map(value => (
|
||||
<div className={styles.dragItem} key={value.id} data-grid={value.point}>
|
||||
<DynamicEngine {...value.item} isTpl={false} />
|
||||
</div>
|
||||
))}
|
||||
</GridLayout>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Draggable>
|
||||
);
|
||||
</Draggable>
|
||||
);
|
||||
} else {
|
||||
//pc可能要传递宽度
|
||||
return (
|
||||
<Draggable
|
||||
position={dragState}
|
||||
handle=".js_box"
|
||||
onStop={(e: DraggableEvent, data: DraggableData) => {
|
||||
setDragState({ x: data.x, y: data.y });
|
||||
}}
|
||||
>
|
||||
<div className={styles.canvasBox2}>
|
||||
<div
|
||||
style={{
|
||||
transform: `scale(${scaleNum - 0.2})`,
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
id={canvasId}
|
||||
className={styles.canvas2}
|
||||
style={{
|
||||
opacity,
|
||||
}}
|
||||
ref={drop}
|
||||
>
|
||||
<Tooltip placement="right" title="鼠标按住此处拖拽画布" visible={isShowTip}>
|
||||
<div
|
||||
className="js_box"
|
||||
style={{
|
||||
width: '10px',
|
||||
height: '100%',
|
||||
position: 'absolute',
|
||||
borderRadius: '0 6px 6px 0',
|
||||
backgroundColor: '#2f54eb',
|
||||
right: '-10px',
|
||||
top: '0',
|
||||
color: '#fff',
|
||||
cursor: 'move',
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
|
||||
{cpointData.length > 0 ? (
|
||||
<GridLayout
|
||||
className={styles.layout}
|
||||
cols={24}
|
||||
rowHeight={2}
|
||||
width={canvasRect[0] || 0}
|
||||
margin={[0, 0]}
|
||||
onDragStop={dragStop}
|
||||
onDragStart={onDragStart}
|
||||
onResizeStop={onResizeStop}
|
||||
>
|
||||
{cpointData.map(value => (
|
||||
<div className={styles.dragItem} key={value.id} data-grid={value.point}>
|
||||
<DynamicEngine {...value.item} isTpl={false} />
|
||||
</div>
|
||||
))}
|
||||
</GridLayout>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Draggable>
|
||||
);
|
||||
}
|
||||
}, [
|
||||
canvasId,
|
||||
canvasRect,
|
||||
context.theme,
|
||||
cpointData,
|
||||
dragState,
|
||||
dragStop,
|
||||
drop,
|
||||
isShowTip,
|
||||
onDragStart,
|
||||
onResizeStop,
|
||||
opacity,
|
||||
pointData,
|
||||
scaleNum,
|
||||
setDragState,
|
||||
]);
|
||||
|
||||
return <>{render}</>;
|
||||
});
|
||||
|
||||
export default connect((state: StateWithHistory<any>) => ({ pstate: state.present.editorModal }))(
|
||||
SourceBox,
|
||||
);
|
||||
export default connect((state: StateWithHistory<any>) => ({
|
||||
pstate: state.present.editorModal,
|
||||
cstate: state.present.editorPcModal,
|
||||
}))(SourceBox);
|
||||
|
||||
@ -18,6 +18,7 @@ const TargetBox = memo((props: TargetBoxProps) => {
|
||||
h: item.h,
|
||||
editableEl: schema[item.type as keyof typeof schema].editData,
|
||||
category: item.category,
|
||||
x: item.x || 0,
|
||||
},
|
||||
collect: monitor => ({
|
||||
isDragging: monitor.isDragging(),
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import React, { useRef, memo } from 'react';
|
||||
import { Button, Input, Popover, Modal, Switch } from 'antd';
|
||||
import React, { useRef, memo, useContext } from 'react';
|
||||
import { Button, Input, Popover, Modal, Switch, Select } from 'antd';
|
||||
import {
|
||||
ArrowLeftOutlined,
|
||||
MobileOutlined,
|
||||
@ -17,6 +17,7 @@ import Zan from 'components/Zan';
|
||||
import req from '@/utils/req';
|
||||
import Code from '@/assets/code.png';
|
||||
import styles from './index.less';
|
||||
import { dooringContext } from '@/layouts';
|
||||
|
||||
const { confirm } = Modal;
|
||||
|
||||
@ -128,7 +129,7 @@ const HeaderComponent = memo((props: HeaderComponentProps) => {
|
||||
req.post('/visible/preview', { tid, tpl: pointData });
|
||||
};
|
||||
const handleSaveCode = () => {};
|
||||
|
||||
const { setTheme } = useContext(dooringContext);
|
||||
return (
|
||||
<div className={styles.header}>
|
||||
<div className={styles.logoArea}>
|
||||
@ -136,7 +137,7 @@ const HeaderComponent = memo((props: HeaderComponentProps) => {
|
||||
<ArrowLeftOutlined />
|
||||
</div>
|
||||
<div className={styles.logo}>Dooring</div>
|
||||
{/* <Switch onChange={toggleCollapsed} style={{ marginLeft: '100px' }} />暂时隐藏 TODO */}
|
||||
<Switch defaultChecked onChange={toggleCollapsed} style={{ marginLeft: '100px' }} />
|
||||
</div>
|
||||
<div className={styles.controlArea}>
|
||||
<Button type="primary" style={{ marginRight: '9px' }} onClick={useTemplate}>
|
||||
@ -211,6 +212,16 @@ const HeaderComponent = memo((props: HeaderComponentProps) => {
|
||||
预览
|
||||
</Button>
|
||||
</div>
|
||||
<Select
|
||||
defaultValue="h5"
|
||||
style={{ width: 120 }}
|
||||
onChange={e => {
|
||||
setTheme(e);
|
||||
}}
|
||||
>
|
||||
<Select.Option value="h5">h5模式</Select.Option>
|
||||
<Select.Option value="pc">pc模式</Select.Option>
|
||||
</Select>
|
||||
<div className={styles.btnArea}>
|
||||
<Zan />
|
||||
</div>
|
||||
|
||||
@ -18,10 +18,10 @@
|
||||
width: 100%;
|
||||
}
|
||||
.container {
|
||||
width: 100%; //写vw产生滚动条会出现横向滚动条
|
||||
// height: 100vh;
|
||||
height: calc(100% - 56px);
|
||||
display: flex;
|
||||
|
||||
.list {
|
||||
width: 350px;
|
||||
height: 100%;
|
||||
@ -56,10 +56,10 @@
|
||||
}
|
||||
}
|
||||
.tickMark {
|
||||
width: calc(100% - 750px);
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
flex: 1;
|
||||
.tickMarkTop {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
@ -108,6 +108,40 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.canvasBox2 {
|
||||
width: 1200px;
|
||||
min-height: 800px;
|
||||
height: 800px;
|
||||
left: 15%;
|
||||
position: relative;
|
||||
margin-left: -200px;
|
||||
top: 20px;
|
||||
.canvas2 {
|
||||
position: relative;
|
||||
width: 1200px;
|
||||
min-height: 800px;
|
||||
background-color: #fff;
|
||||
box-shadow: 2px 0px 10px rgba(0, 0, 0, 0.2);
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
transition: transform 300ms ease-out;
|
||||
.dragItem {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
border: 2px solid transparent;
|
||||
cursor: move;
|
||||
&:hover {
|
||||
border: 2px solid #06c;
|
||||
}
|
||||
:global(a) {
|
||||
display: block;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.resetBall {
|
||||
position: absolute;
|
||||
right: 24px;
|
||||
@ -152,6 +186,7 @@
|
||||
height: 100%;
|
||||
box-shadow: -2px 0px 4px 0px rgba(0, 0, 0, 0.1);
|
||||
overflow: auto;
|
||||
|
||||
.tit {
|
||||
margin-bottom: 16px;
|
||||
font-size: 18px;
|
||||
@ -205,10 +240,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.collapsed {
|
||||
.list;
|
||||
height: calc(56px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
58
src/pages/editor/models/editorPcModel.ts
Normal file
58
src/pages/editor/models/editorPcModel.ts
Normal file
@ -0,0 +1,58 @@
|
||||
const pointData = localStorage.getItem('userPcData') || '[]';
|
||||
|
||||
function overSave(name: string, data: any) {
|
||||
localStorage.setItem(name, JSON.stringify(data));
|
||||
}
|
||||
|
||||
export default {
|
||||
namespace: 'editorPcModal',
|
||||
state: {
|
||||
pointData: JSON.parse(pointData),
|
||||
curPoint: null,
|
||||
},
|
||||
reducers: {
|
||||
addPointData(state: any, { payload }: any) {
|
||||
let pointData = [...state.pointData, payload];
|
||||
overSave('userPcData', pointData);
|
||||
return {
|
||||
...state,
|
||||
pointData,
|
||||
curPoint: payload,
|
||||
};
|
||||
},
|
||||
modPointData(state: any, { payload }: any) {
|
||||
const { id } = payload;
|
||||
const pointData = state.pointData.map((item: any) => {
|
||||
if (item.id === id) {
|
||||
return payload;
|
||||
}
|
||||
return { ...item };
|
||||
});
|
||||
overSave('userPcData', pointData);
|
||||
return {
|
||||
...state,
|
||||
pointData,
|
||||
curPoint: payload,
|
||||
};
|
||||
},
|
||||
delPointData(state: any, { payload }: any) {
|
||||
const { id } = payload;
|
||||
const pointData = state.pointData.filter((item: any) => item.id !== id);
|
||||
overSave('userPcData', pointData);
|
||||
return {
|
||||
...state,
|
||||
pointData,
|
||||
curPoint: null,
|
||||
};
|
||||
},
|
||||
clearAll(state: any) {
|
||||
overSave('userPcData', []);
|
||||
return {
|
||||
...state,
|
||||
pointData: [],
|
||||
curPoint: null,
|
||||
};
|
||||
},
|
||||
},
|
||||
effects: {},
|
||||
};
|
||||
@ -63,3 +63,21 @@ export function useGetScrollBarWidth(ref: RefObject<HTMLElement>) {
|
||||
}, [ref]);
|
||||
return width;
|
||||
}
|
||||
|
||||
export function useAnimation(state: boolean, delay: number) {
|
||||
const [display, setDisplay] = useState(false);
|
||||
useEffect(() => {
|
||||
let timer: number;
|
||||
if (state && display === true) {
|
||||
setDisplay(false);
|
||||
} else if (!state && display === false) {
|
||||
timer = window.setTimeout(() => {
|
||||
setDisplay(true);
|
||||
}, delay);
|
||||
}
|
||||
return () => {
|
||||
window.clearTimeout(timer);
|
||||
};
|
||||
}, [delay, display, state]);
|
||||
return [display, setDisplay];
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user