diff --git a/.gitignore b/.gitignore index bf2d02e..2ee863e 100644 --- a/.gitignore +++ b/.gitignore @@ -103,4 +103,8 @@ dist # TernJS port file .tern-port +<<<<<<< HEAD +/**/*.umi +======= .umi/ +>>>>>>> upstream/master diff --git a/src/components/Carousel/index.js b/src/components/Carousel/index.js index 64247c5..878d01d 100644 --- a/src/components/Carousel/index.js +++ b/src/components/Carousel/index.js @@ -3,44 +3,39 @@ import { Carousel } from 'zarm'; import styles from './index.less'; const XCarousel = memo(props => { - const { - direction, - swipeable, - autoPlay, - isTpl, - imgList, - tplImg - } = props - + const { direction, swipeable, autoPlay, isTpl, imgList, tplImg } = props; + const contentRender = () => { return imgList.map((item, i) => { return (
- ) - }) - } + ); + }); + }; - return
- { - isTpl ?
- -
- : - { - // console.log(`onChange: ${index}`); - }} - direction={direction} - swipeable={swipeable} - autoPlay={autoPlay} - loop - > - {contentRender()} - - } + return ( +
+ {isTpl ? ( +
+
-}) + ) : ( + { + // console.log(`onChange: ${index}`); + }} + direction={direction} + swipeable={swipeable} + autoPlay={autoPlay} + loop + > + {contentRender()} + + )} +
+ ); +}); -export default XCarousel; \ No newline at end of file +export default XCarousel; diff --git a/src/components/DynamicEngine/index.js b/src/components/DynamicEngine/index.js index d98a10d..ea032b4 100644 --- a/src/components/DynamicEngine/index.js +++ b/src/components/DynamicEngine/index.js @@ -2,35 +2,38 @@ import { dynamic } from 'umi'; import Loading from '../LoadingCp'; import { useMemo, memo } from 'react'; -const needList = ['Tab', 'Carousel', 'Upload', 'Video'] +const needList = ['Tab', 'Carousel', 'Upload', 'Video']; -const DynamicFunc = (type) => dynamic({ - loader: async function() { - let Component; - if(needList.includes(type)) { - const { default: Graph } = await import(`@/components/${type}`) - Component = Graph - }else { - const Components = await import(`@/components/DynamicEngine/components`) - Component = Components[type] - } +const DynamicFunc = type => + dynamic({ + loader: async function() { + let Component; + if (needList.includes(type)) { + const { default: Graph } = await import(`@/components/${type}`); + Component = Graph; + } else { + const Components = await import(`@/components/DynamicEngine/components`); + Component = Components[type]; + } - return (props) => { - const { config } = props - return - } - }, - loading: () =>
- -
-}) + return props => { + const { config } = props; + return ; + }; + }, + loading: () => ( +
+ +
+ ), + }); -const DynamicEngine = memo((props) => { - const { type, config } = props +const DynamicEngine = memo(props => { + const { type, config } = props; const Dynamic = useMemo(() => { - return DynamicFunc(type) - }, [type]) - return -}) + return DynamicFunc(type); + }, [type, config]); + return ; +}); -export default DynamicEngine \ No newline at end of file +export default DynamicEngine; diff --git a/src/components/DynamicEngine/schema.js b/src/components/DynamicEngine/schema.js index b8083be..65d059b 100644 --- a/src/components/DynamicEngine/schema.js +++ b/src/components/DynamicEngine/schema.js @@ -1,218 +1,218 @@ export default { - "Carousel": { - "editData": [ + Carousel: { + editData: [ { - "key": "direction", - "name": "方向", - "type": "Radio", - "range": [ + key: 'direction', + name: '方向', + type: 'Radio', + range: [ { - key: "top", - text: "从上到下" + key: 'top', + text: '从上到下', }, { - key: "left", - text: "从左到右" - } - ] + key: 'left', + text: '从左到右', + }, + ], }, { - "key": "swipeable", - "name": "是否可拖拽", - "type": "Switch", + key: 'swipeable', + name: '是否可拖拽', + type: 'Switch', }, { - "key": "autoPlay", - "name": "是否自动播放", - "type": "Switch", + key: 'autoPlay', + name: '是否自动播放', + type: 'Switch', }, { - "key": "imgList", - "name": "图片列表", - "type": "DataList", - } + key: 'imgList', + name: '图片列表', + type: 'DataList', + }, ], - "config": { - "direction": "left", - "swipeable": false, - "autoPlay": false, - "imgList": [ + config: { + direction: 'left', + swipeable: false, + autoPlay: false, + imgList: [ { - "id": 1, - "title": "趣谈小课1", - "desc": "致力于打造优质小课程", - "link": "xxxxx", - "imgUrl": [ + id: 1, + title: '趣谈小课1', + desc: '致力于打造优质小课程', + link: 'xxxxx', + imgUrl: [ { - "uid": "001", - "name": "image.png", - "status": "done", - "url": "http://io.nainor.com/uploads/1_1740bd7c3dc.png", - } - ] + uid: '001', + name: 'image.png', + status: 'done', + url: 'http://io.nainor.com/uploads/1_1740bd7c3dc.png', + }, + ], }, { - "id": 2, - "title": "趣谈小课1", - "desc": "致力于打造优质小课程", - "link": "xxxxx", - "imgUrl": [ + id: 2, + title: '趣谈小课1', + desc: '致力于打造优质小课程', + link: 'xxxxx', + imgUrl: [ { - "uid": "001", - "name": "image.png", - "status": "done", - "url": "http://io.nainor.com/uploads/2_1740bd8d525.png", - } - ] - } + uid: '001', + name: 'image.png', + status: 'done', + url: 'http://io.nainor.com/uploads/2_1740bd8d525.png', + }, + ], + }, ], - "tplImg": "http://io.nainor.com/uploads/carousal_17442e1420f.png" - } + tplImg: 'http://io.nainor.com/uploads/carousal_17442e1420f.png', + }, }, - "Text": { - "editData": [ + Text: { + editData: [ { - "key": "text", - "name": "文字", - "type": "Text" + key: 'text', + name: '文字', + type: 'Text', }, { - "key": "color", - "name": "标题颜色", - "type": "Color" + key: 'color', + name: '标题颜色', + type: 'Color', }, { - "key": "fontSize", - "name": "字体大小", - "type": "Number" + key: 'fontSize', + name: '字体大小', + type: 'Number', }, { - "key": "align", - "name": "对齐方式", - "type": "Select", - "range": [ + key: 'align', + name: '对齐方式', + type: 'Select', + range: [ { - "key": "left", - "text": "左对齐" + key: 'left', + text: '左对齐', }, { - "key": "center", - "text": "居中对齐" + key: 'center', + text: '居中对齐', }, { - "key": "right", - "text": "右对齐" - } - ] + key: 'right', + text: '右对齐', + }, + ], }, { - "key": "lineHeight", - "name": "行高", - "type": "Number" - } + key: 'lineHeight', + name: '行高', + type: 'Number', + }, ], - "config": { - "text": "我是文本", - "color": "rgba(60,60,60,1)", - "fontSize": 18, - "align": "center", - "lineHeight": 2 - } + config: { + text: '我是文本', + color: 'rgba(60,60,60,1)', + fontSize: 18, + align: 'center', + lineHeight: 2, + }, }, - "Tab": { - "editData": [ + Tab: { + editData: [ { - "key": "tabs", - "name": "项目类别", - "type": "MutiText" + key: 'tabs', + name: '项目类别', + type: 'MutiText', }, { - "key": "activeColor", - "name": "激活颜色", - "type": "Color" + key: 'activeColor', + name: '激活颜色', + type: 'Color', }, { - "key": "color", - "name": "文字颜色", - "type": "Color" + key: 'color', + name: '文字颜色', + type: 'Color', }, { - "key": "fontSize", - "name": "文字大小", - "type": "Number" + key: 'fontSize', + name: '文字大小', + type: 'Number', }, { - "key": "imgSize", - "name": "图片大小", - "type": "Number" + key: 'imgSize', + name: '图片大小', + type: 'Number', }, { - "key": "sourceData", - "name": "数据源", - "type": "DataList" - } + key: 'sourceData', + name: '数据源', + type: 'DataList', + }, ], - "config": { - "tabs": ["类别一", "类别二"], - "color": "rgba(153,153,153,1)", - "activeColor": "rgba(0,102,204,1)", - "fontSize": 16, - "imgSize": 100, - "sourceData": [ + config: { + tabs: ['类别一', '类别二'], + color: 'rgba(153,153,153,1)', + activeColor: 'rgba(0,102,204,1)', + fontSize: 16, + imgSize: 100, + sourceData: [ { - "id": 1, - "title": "趣谈小课1", - "desc": "致力于打造优质小课程", - "link": "xxxxx", - "type": 0, - "imgUrl": [ + id: 1, + title: '趣谈小课1', + desc: '致力于打造优质小课程', + link: 'xxxxx', + type: 0, + imgUrl: [ { - "uid": "001", - "name": "image.png", - "status": "done", - "url": "http://io.nainor.com/uploads/1_1740c6fbcd9.png", - } - ] + uid: '001', + name: 'image.png', + status: 'done', + url: 'http://io.nainor.com/uploads/1_1740c6fbcd9.png', + }, + ], }, { - "id": 2, - "title": "趣谈小课2", - "desc": "致力于打造优质小课程", - "link": "xxxxx", - "type": 0, - "imgUrl": [ + id: 2, + title: '趣谈小课2', + desc: '致力于打造优质小课程', + link: 'xxxxx', + type: 0, + imgUrl: [ { - "uid": "001", - "name": "image.png", - "status": "done", - "url": "http://io.nainor.com/uploads/2_1740c7033a9.png", - } - ] + uid: '001', + name: 'image.png', + status: 'done', + url: 'http://io.nainor.com/uploads/2_1740c7033a9.png', + }, + ], }, { - "id": 3, - "title": "趣谈小课3", - "desc": "致力于打造优质小课程", - "link": "xxxxx", - "type": 1, - "imgUrl": [ + id: 3, + title: '趣谈小课3', + desc: '致力于打造优质小课程', + link: 'xxxxx', + type: 1, + imgUrl: [ { - "uid": "001", - "name": "image.png", - "status": "done", - "url": "http://io.nainor.com/uploads/1_1740c6fbcd9.png", - } - ] - } - ] - } + uid: '001', + name: 'image.png', + status: 'done', + url: 'http://io.nainor.com/uploads/1_1740c6fbcd9.png', + }, + ], + }, + ], + }, }, - "Notice": { - "editData": [ + Notice: { + editData: [ { - "key": "text", - "name": "文本", - "type": "Text" + key: 'text', + name: '文本', + type: 'Text', }, // { // "key": "link", @@ -220,393 +220,393 @@ export default { // "type": "Text" // }, { - "key": "speed", - "name": "滚动速度", - "type": "Number" + key: 'speed', + name: '滚动速度', + type: 'Number', }, { - "key": "theme", - "name": "主题", - "type": "Select", - "range": [ + key: 'theme', + name: '主题', + type: 'Select', + range: [ { - "key": "default", - "text": "默认" + key: 'default', + text: '默认', }, { - "key": "warning", - "text": "警告" + key: 'warning', + text: '警告', }, { - "key": "primary", - "text": "主要" + key: 'primary', + text: '主要', }, { - "key": "success", - "text": "成功" + key: 'success', + text: '成功', }, { - "key": "danger", - "text": "危险" - } - ] + key: 'danger', + text: '危险', + }, + ], }, { - "key": "isClose", - "name": "是否可关闭", - "type": "Switch" - } + key: 'isClose', + name: '是否可关闭', + type: 'Switch', + }, ], - "config": { - "text": "通知栏: 趣谈前端上线啦", - "link": "", - "speed": 50, - "theme": "warning", - "isClose": false - } + config: { + text: '通知栏: 趣谈前端上线啦', + link: '', + speed: 50, + theme: 'warning', + isClose: false, + }, }, - "Qrcode": { - "editData": [ + Qrcode: { + editData: [ { - "key": "qrcode", - "name": "二维码", - "type": "Upload" + key: 'qrcode', + name: '二维码', + type: 'Upload', }, { - "key": "text", - "name": "文字", - "type": "Text" + key: 'text', + name: '文字', + type: 'Text', }, { - "key": "color", - "name": "文字颜色", - "type": "Color" + key: 'color', + name: '文字颜色', + type: 'Color', }, { - "key": "fontSize", - "name": "文字大小", - "type": "Number" - } + key: 'fontSize', + name: '文字大小', + type: 'Number', + }, ], - "config": { - "qrcode": [ + config: { + qrcode: [ { - uid: "001", - name: "image.png", - status: "done", - url: "http://io.nainor.com/uploads/code_173e1705e0c.png", - } + uid: '001', + name: 'image.png', + status: 'done', + url: 'http://io.nainor.com/uploads/code_173e1705e0c.png', + }, ], - "text": "二维码", - "color": "rgba(153,153,153,1)", - "fontSize": 14 - } + text: '二维码', + color: 'rgba(153,153,153,1)', + fontSize: 14, + }, }, - "Footer": { - "editData": [ + Footer: { + editData: [ { - "key": "bgColor", - "name": "背景色", - "type": "Color" + key: 'bgColor', + name: '背景色', + type: 'Color', }, { - "key": "height", - "name": "高度", - "type": "Number" + key: 'height', + name: '高度', + type: 'Number', }, { - "key": "text", - "name": "文字", - "type": "Text" + key: 'text', + name: '文字', + type: 'Text', }, { - "key": "fontSize", - "name": "字体大小", - "type": "Number" + key: 'fontSize', + name: '字体大小', + type: 'Number', }, { - "key": "color", - "name": "文字颜色", - "type": "Color" + key: 'color', + name: '文字颜色', + type: 'Color', }, { - "key": "align", - "name": "对齐方式", - "type": "Select", - "range": [ + key: 'align', + name: '对齐方式', + type: 'Select', + range: [ { - "key": "left", - "text": "左对齐" + key: 'left', + text: '左对齐', }, { - "key": "center", - "text": "居中对齐" + key: 'center', + text: '居中对齐', }, { - "key": "right", - "text": "右对齐" - } - ] - } + key: 'right', + text: '右对齐', + }, + ], + }, ], - "config": { - "bgColor": "rgba(0,0,0,1)", - "text": "页脚Footer", - "color": "rgba(255,255,255,1)", - "align": "center", - "fontSize": 16, - "height": 48 - } + config: { + bgColor: 'rgba(0,0,0,1)', + text: '页脚Footer', + color: 'rgba(255,255,255,1)', + align: 'center', + fontSize: 16, + height: 48, + }, }, - "Image": { - "editData": [ + Image: { + editData: [ { - "key": "imgUrl", - "name": "上传", - "type": "Upload" + key: 'imgUrl', + name: '上传', + type: 'Upload', }, { - "key": "round", - "name": "圆角", - "type": "Number" - } + key: 'round', + name: '圆角', + type: 'Number', + }, ], - "config": { - "imgUrl": [ + config: { + imgUrl: [ { - uid: "001", - name: "image.png", - status: "done", - url: "http://io.nainor.com/uploads/4_1740bf4535c.png", - } + uid: '001', + name: 'image.png', + status: 'done', + url: 'http://io.nainor.com/uploads/4_1740bf4535c.png', + }, ], - "round": 0 - } + round: 0, + }, }, - "Header": { - "editData": [ + Header: { + editData: [ { - "key": "bgColor", - "name": "背景色", - "type": "Color" + key: 'bgColor', + name: '背景色', + type: 'Color', }, { - "key": "height", - "name": "高度", - "type": "Number" + key: 'height', + name: '高度', + type: 'Number', }, { - "key": "logo", - "name": "logo", - "type": "Upload" + key: 'logo', + name: 'logo', + type: 'Upload', }, { - "key": "logoText", - "name": "logo文字", - "type": "Text" + key: 'logoText', + name: 'logo文字', + type: 'Text', }, { - "key": "color", - "name": "文字颜色", - "type": "Color" + key: 'color', + name: '文字颜色', + type: 'Color', }, { - "key": "fontSize", - "name": "文字大小", - "type": "Number" - } + key: 'fontSize', + name: '文字大小', + type: 'Number', + }, ], - "config": { - "bgColor": "rgba(0,0,0,1)", - "logo": [ + config: { + bgColor: 'rgba(0,0,0,1)', + logo: [ { - uid: "001", - name: "image.png", - status: "done", - url: "http://io.nainor.com/uploads/3_1740be8a482.png", - } + uid: '001', + name: 'image.png', + status: 'done', + url: 'http://io.nainor.com/uploads/3_1740be8a482.png', + }, ], - "logoText": "页头Header", - "fontSize": 20, - "color": "rgba(255,255,255,1)", - "height": 50 - } + logoText: '页头Header', + fontSize: 20, + color: 'rgba(255,255,255,1)', + height: 50, + }, }, - "List": { - "editData": [ + List: { + editData: [ { - "key": "sourceData", - "name": "数据源", - "type": "DataList" + key: 'sourceData', + name: '数据源', + type: 'DataList', }, { - "key": "round", - "name": "圆角", - "type": "Number" + key: 'round', + name: '圆角', + type: 'Number', }, { - "key": "imgSize", - "name": "图片大小", - "type": "Select", - "range": [ + key: 'imgSize', + name: '图片大小', + type: 'Select', + range: [ { - "key": 60, - "text": "60 x 60" + key: 60, + text: '60 x 60', }, { - "key": 80, - "text": "80 x 80" + key: 80, + text: '80 x 80', }, { - "key": 100, - "text": "100 x 100" + key: 100, + text: '100 x 100', }, { - "key": 120, - "text": "120 x 120" + key: 120, + text: '120 x 120', }, { - "key": 150, - "text": "150 x 150" - } - ] + key: 150, + text: '150 x 150', + }, + ], }, { - "key": "fontSize", - "name": "文字大小", - "type": "Number" + key: 'fontSize', + name: '文字大小', + type: 'Number', }, { - "key": "color", - "name": "文字颜色", - "type": "Color" - } + key: 'color', + name: '文字颜色', + type: 'Color', + }, ], - "config": { - "sourceData": [ + config: { + sourceData: [ { - "id": "1", - "title": "趣谈小课", - "desc": "致力于打造优质小课程", - "link": "xxxxx", - "imgUrl": [ + id: '1', + title: '趣谈小课', + desc: '致力于打造优质小课程', + link: 'xxxxx', + imgUrl: [ { - "uid": "001", - "name": "image.png", - "status": "done", - "url": "http://io.nainor.com/uploads/1_1740c6fbcd9.png", - } - ] + uid: '001', + name: 'image.png', + status: 'done', + url: 'http://io.nainor.com/uploads/1_1740c6fbcd9.png', + }, + ], }, { - "id": "2", - "title": "趣谈小课", - "desc": "致力于打造优质小课程", - "link": "xxxxx", - "imgUrl": [ + id: '2', + title: '趣谈小课', + desc: '致力于打造优质小课程', + link: 'xxxxx', + imgUrl: [ { - "uid": "002", - "name": "image.png", - "status": "done", - "url": "http://io.nainor.com/uploads/1_1740c6fbcd9.png", - } - ] - } + uid: '002', + name: 'image.png', + status: 'done', + url: 'http://io.nainor.com/uploads/1_1740c6fbcd9.png', + }, + ], + }, ], - "round": 0, - "imgSize": 80, - "fontSize": 16, - "color": "rgba(153,153,153,1)" - } + round: 0, + imgSize: 80, + fontSize: 16, + color: 'rgba(153,153,153,1)', + }, }, - "Video": { - "editData": [ + Video: { + editData: [ { - "key": "poster", - "name": "视频封面", - "type": "Upload" + key: 'poster', + name: '视频封面', + type: 'Upload', }, { - "key": "url", - "name": "视频链接", - "type": "Text" - } + key: 'url', + name: '视频链接', + type: 'Text', + }, ], - "config": { - "poster": [ + config: { + poster: [ { - "uid": "001", - "name": "image.png", - "status": "done", - "url": "http://io.nainor.com/uploads/1_1740c6fbcd9.png", - } + uid: '001', + name: 'image.png', + status: 'done', + url: 'http://io.nainor.com/uploads/1_1740c6fbcd9.png', + }, ], - "url": "" - } + url: '', + }, }, - "XProgress": { - "editData": [ + XProgress: { + editData: [ { - "key": "theme", - "name": "主题", - "type": "Select", - "range": [ + key: 'theme', + name: '主题', + type: 'Select', + range: [ { - "key": "success", - "text": "成功" + key: 'success', + text: '成功', }, { - "key": "warning", - "text": "警告" + key: 'warning', + text: '警告', }, { - "key": "danger", - "text": "危险" - } - ] + key: 'danger', + text: '危险', + }, + ], }, { - "key": "shape", - "name": "形状", - "type": "Radio", - "range": [ + key: 'shape', + name: '形状', + type: 'Radio', + range: [ { - "key": "circle", - "text": "圆形" + key: 'circle', + text: '圆形', }, { - "key": "line", - "text": "线形" + key: 'line', + text: '线形', }, { - "key": "semi-circle", - "text": "半圆形" - } - ] + key: 'semi-circle', + text: '半圆形', + }, + ], }, { - "key": "size", - "name": "大小", - "type": "Number" + key: 'size', + name: '大小', + type: 'Number', }, { - "key": "percent", - "name": "进度值", - "type": "Number", - "range": [0, 100] + key: 'percent', + name: '进度值', + type: 'Number', + range: [0, 100], }, { - "key": "strokeWidth", - "name": "线条粗细", - "type": "Number" - } + key: 'strokeWidth', + name: '线条粗细', + type: 'Number', + }, ], - "config": { - "theme": "success", - "shape": "circle", - "size": 200, - "percent": 30, - "strokeWidth": 10 - } - } -} \ No newline at end of file + config: { + theme: 'success', + shape: 'circle', + size: 200, + percent: 30, + strokeWidth: 10, + }, + }, +}; diff --git a/src/pages/editor/Container.js b/src/pages/editor/Container.js index dfe4062..bb2b112 100644 --- a/src/pages/editor/Container.js +++ b/src/pages/editor/Container.js @@ -1,185 +1,211 @@ -import React, { useState, useEffect, useCallback, memo } from 'react' -import { Slider, Result, Tabs, Alert } from 'antd' +import React, { useState, useEffect, useCallback, memo, useMemo } from 'react'; +import { Slider, Result, Tabs, Alert } from 'antd'; import { PieChartOutlined, ExpandOutlined, PlayCircleOutlined, - HighlightOutlined -} from '@ant-design/icons' -import TextLoop from 'react-text-loop' -import { connect } from 'dva' -import HeaderComponent from './components/Header' -import SourceBox from './SourceBox' -import TargetBox from './TargetBox' -import Calibration from 'components/Calibration' -import DynamicEngine from 'components/DynamicEngine' -import FormEditor from 'components/FormEditor' -import template from 'components/DynamicEngine/template' -import mediaTpl from 'components/DynamicEngine/mediaTpl' -import graphTpl from 'components/DynamicEngine/graphTpl' -import schema from 'components/DynamicEngine/schema' -import { uuid } from 'utils/tool' + HighlightOutlined, +} from '@ant-design/icons'; +import TextLoop from 'react-text-loop'; +import { connect } from 'dva'; +import HeaderComponent from './components/Header'; +import SourceBox from './SourceBox'; +import TargetBox from './TargetBox'; +import Calibration from 'components/Calibration'; +import DynamicEngine from 'components/DynamicEngine'; +import FormEditor from 'components/FormEditor'; +import template from 'components/DynamicEngine/template'; +import mediaTpl from 'components/DynamicEngine/mediaTpl'; +import graphTpl from 'components/DynamicEngine/graphTpl'; +import schema from 'components/DynamicEngine/schema'; +import { uuid } from 'utils/tool'; -import styles from './index.less' +import styles from './index.less'; const { TabPane } = Tabs; -const Container = memo((props) => { - const [ scaleNum , setScale ] = useState(1) +const Container = memo(props => { + const [scaleNum, setScale] = useState(1); - const { pointData, curPoint, dispatch } = props + const { pointData, curPoint, dispatch } = props; // 指定画布的id - let canvasId = 'js_canvas' + let canvasId = 'js_canvas'; const backSize = () => { - setScale(1) - } + setScale(1); + }; const CpIcon = { base: , media: , - visible: - } + visible: , + }; const generateHeader = (type, text) => { - return
{ CpIcon[type] } { text }
- } + return ( +
+ {CpIcon[type]} {text} +
+ ); + }; - const handleSliderChange = (v) => { - setScale(prev => v >= 150 ? 1.5 : (v / 100)) - } + const handleSliderChange = v => { + setScale(prev => (v >= 150 ? 1.5 : v / 100)); + }; - const handleSlider = (type) => { - if(type) { - setScale(prev => prev >= 1.5 ? 1.5 : (prev + 0.1)) - }else { - setScale(prev => prev <= 0.5 ? 0.5 : (prev - 0.1)) + const handleSlider = type => { + if (type) { + setScale(prev => (prev >= 1.5 ? 1.5 : prev + 0.1)); + } else { + setScale(prev => (prev <= 0.5 ? 0.5 : prev - 0.1)); } - } + }; - const handleFormSave = (data) => { + const handleFormSave = data => { dispatch({ type: 'editorModal/modPointData', - payload: { ...curPoint, item: {...curPoint.item, config: data} } - }) - } + payload: { ...curPoint, item: { ...curPoint.item, config: data } }, + }); + }; const clearData = useCallback(() => { - dispatch({ type: 'editorModal/clearAll' }) - }, []) + dispatch({ type: 'editorModal/clearAll' }); + }, []); - const handleDel = (id) => { + const handleDel = id => { dispatch({ type: 'editorModal/delPointData', - payload: { id } - }) - } + payload: { id }, + }); + }; useEffect(() => { - if(window.innerWidth < 1024) { - props.history.push('/mobileTip') + if (window.innerWidth < 1024) { + props.history.push('/mobileTip'); } - // 存储用户唯一信息 - if(!localStorage.getItem('uid') || !sessionStorage.getItem('sid')) { - localStorage.setItem('uid', uuid(8, 10)) - sessionStorage.setItem('sid', uuid(5, 10)) - } - }, []) + }, []); + + const allType = useMemo(() => { + let arr = []; + template.forEach(v => { + arr.push(v.type); + }); + mediaTpl.forEach(v => { + arr.push(v.type); + }); + graphTpl.forEach(v => { + arr.push(v.type); + }); + return arr; + }, []); + // 存储用户唯一信息 + if (!localStorage.getItem('uid') || !sessionStorage.getItem('sid')) { + localStorage.setItem('uid', uuid(8, 10)); + sessionStorage.setItem('sid', uuid(5, 10)); + } return (
-
+
- -
Dooring升级啦!
-
Dooring添加自动保存功能
-
已有500+人使用
-
持续迭代中...
- - } - /> + +
Dooring升级啦!
+
Dooring添加自动保存功能
+
已有500+人使用
+
持续迭代中...
+ + } + />
- - { - template.map((value,i) => - - - - ) - } + + {template.map((value, i) => ( + + + + ))} - - { - mediaTpl.map((value,i) => - - - - ) - } + + {mediaTpl.map((value, i) => ( + + + + ))} - - { - graphTpl.map((value,i) => - - - - ) - } + + {graphTpl.map((value, i) => ( + + + + ))}
-
+
- -
+ +
- +
- +
- + - - - + + + + + + + - + +
+
+
-
- { - pointData.length && curPoint ? + {pointData.length && curPoint ? ( <>
属性设置
- - : -
+ + ) : ( +
- } + )}
-
- ) -}) + ); +}); export default connect(({ editorModal: { pointData, curPoint } }) => ({ - pointData, curPoint -}))(Container) + pointData, + curPoint, +}))(Container); diff --git a/src/pages/editor/SourceBox.js b/src/pages/editor/SourceBox.js index 91b47d0..4d7d39f 100644 --- a/src/pages/editor/SourceBox.js +++ b/src/pages/editor/SourceBox.js @@ -1,79 +1,104 @@ -import React, { memo, useEffect, useState } from 'react' -import { useDrop } from 'react-dnd' -import Draggable from 'react-draggable' -import GridLayout from 'react-grid-layout' -import { Tooltip } from 'antd' -import { connect } from 'dva' -import DynamicEngine from 'components/DynamicEngine' -import styles from './index.less' - -const SourceBox = memo((props) => { - const { pointData, scaleNum, canvasId, dispatch } = props - const [canvasRect, setCanvasRect] = useState([]) - const [isShowTip, setIsShowTip] = useState(true) +import React, { memo, useEffect, useState } from 'react'; +import { useDrop } from 'react-dnd'; +import Draggable from 'react-draggable'; +import GridLayout from 'react-grid-layout'; +import { Tooltip } from 'antd'; +import { connect } from 'dva'; +import DynamicEngine from 'components/DynamicEngine'; +import styles from './index.less'; +import { uuid } from '@/utils/tool'; +const SourceBox = memo(props => { + const { pointData, scaleNum, canvasId, allType, dispatch } = props; + const [canvasRect, setCanvasRect] = useState([]); + const [isShowTip, setIsShowTip] = useState(true); const [{ isOver }, drop] = useDrop({ - accept: [], - collect: (monitor) => ({ + accept: allType, + drop: (item, monitor) => { + let parentDiv = document.getElementById(canvasId), + pointRect = parentDiv.getBoundingClientRect(), + top = pointRect.top, + pointEnd = monitor.getSourceClientOffset(), + y = pointEnd.y - top, + col = 24, // 网格列数 + cellHeight = 2; + // 转换成网格规则的坐标和大小 + 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: col, h: item.h, isBounded: true }, + }, + }); + }, + collect: monitor => ({ isOver: monitor.isOver(), canDrop: monitor.canDrop(), - item: monitor.getItem() - }) - }) + item: monitor.getItem(), + }), + }); const dragStop = (layout, oldItem, newItem, placeholder, e, element) => { - const curPointData = pointData.filter(item => item.id === newItem.i)[0] + const curPointData = pointData.filter(item => item.id === newItem.i)[0]; dispatch({ type: 'editorModal/modPointData', - payload: { ...curPointData, point: newItem } - }) - } + payload: { ...curPointData, point: newItem }, + }); + }; const onDragStart = (layout, oldItem, newItem, placeholder, e, element) => { - const curPointData = pointData.filter(item => item.id === newItem.i)[0] + const curPointData = pointData.filter(item => item.id === newItem.i)[0]; dispatch({ type: 'editorModal/modPointData', - payload: { ...curPointData } - }) - } + payload: { ...curPointData }, + }); + }; const onResizeStop = (layout, oldItem, newItem, placeholder, e, element) => { - const curPointData = pointData.filter(item => item.id === newItem.i)[0] + const curPointData = pointData.filter(item => item.id === newItem.i)[0]; dispatch({ type: 'editorModal/modPointData', - payload: { ...curPointData, point: newItem } - }) - } + payload: { ...curPointData, point: newItem }, + }); + }; useEffect(() => { - let { width, height } = document.getElementById(canvasId).getBoundingClientRect() - setCanvasRect([width, height]) - }, [canvasId]) + let { width, height } = document.getElementById(canvasId).getBoundingClientRect(); + setCanvasRect([width, height]); + }, [canvasId]); useEffect(() => { setTimeout(() => { - setIsShowTip(false) - }, 3000) - }, []) - - const opacity = isOver ? 0.7 : 1 - const backgroundColor = isOver ? 1 : 0.7 + setIsShowTip(false); + }, 3000); + }, []); + const opacity = isOver ? 0.7 : 1; + const backgroundColor = isOver ? 1 : 0.7; return (
-
- -
+
-
{ right: '-10px', top: '0', color: '#fff', - cursor: 'move' + cursor: 'move', }} - /> + /> - - { - pointData.length > 0 ? - 0 ? ( + - { - pointData.map(value => -
- -
- ) - } -
: null - } + {pointData.map(value => ( +
+ +
+ ))} +
+ ) : null}
- ) -}) + ); +}); export default connect(({ editorModal: { pointData } }) => ({ - pointData -}))(SourceBox) + pointData, +}))(SourceBox); diff --git a/src/pages/editor/TargetBox.js b/src/pages/editor/TargetBox.js index 8ea8566..4666be3 100644 --- a/src/pages/editor/TargetBox.js +++ b/src/pages/editor/TargetBox.js @@ -1,61 +1,39 @@ -import React, { useMemo, memo } from 'react' -import { useDrag } from 'react-dnd' -import { connect } from 'dva' -import schema from 'components/DynamicEngine/schema' -import { uuid } from '@/utils/tool'; -import styles from './index.less' +import React, { useMemo, memo } from 'react'; +import { useDrag } from 'react-dnd'; +import { connect } from 'dva'; +import schema from 'components/DynamicEngine/schema'; -const TargetBox = memo((props) => { - const { item, dispatch, canvasId, pointData } = props - const [{ isDragging }, drag] = useDrag({ - item: { type: item.type, config: schema[item.type].config, h: item.h, editableEl: schema[item.type].editData }, - collect: (monitor) => ({ +import styles from './index.less'; + +const TargetBox = memo(props => { + const { item, dispatch, canvasId, pointData } = props; + const [{ isDragging }, drag, preview] = useDrag({ + item: { + type: item.type, + config: schema[item.type].config, + h: item.h, + editableEl: schema[item.type].editData, + }, + collect: monitor => ({ isDragging: monitor.isDragging(), }), - // begin(monitor) { - // getStartPoint(monitor.getSourceClientOffset()) - // }, - end(item, monitor) { - let parentDiv = document.getElementById(canvasId), - pointRect = parentDiv.getBoundingClientRect(), - top = pointRect.top, - pointEnd = monitor.getSourceClientOffset(), - y = pointEnd.y - top, - col = 24, // 网格列数 - cellHeight = 2 - // 转换成网格规则的坐标和大小 - 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: col, h: item.h, isBounded: true } - } - }) - } - }) + }); const containerStyle = useMemo( () => ({ opacity: isDragging ? 0.4 : 1, - cursor: 'move' + cursor: 'move', }), [isDragging], - ) + ); return ( -
- { props.children } +
+ {props.children}
- ) -}) + ); +}); export default connect(({ editorModal: { pointData } }) => ({ - pointData -}))(TargetBox) + pointData, +}))(TargetBox); diff --git a/src/pages/editor/preview.js b/src/pages/editor/preview.js index c07cf8b..7c23155 100644 --- a/src/pages/editor/preview.js +++ b/src/pages/editor/preview.js @@ -1,73 +1,82 @@ -import React, { memo, useEffect, useState } from 'react' -import GridLayout from 'react-grid-layout' -import DynamicEngine from 'components/DynamicEngine' -import req from '@/utils/req' -import styles from './index.less' +import React, { memo, useEffect, useState } from 'react'; +import GridLayout from 'react-grid-layout'; +import DynamicEngine from 'components/DynamicEngine'; +import req from '@/utils/req'; +import styles from './index.less'; // 可视化组件类型 // const componentTypes = ['Column', 'Pie'] -const isMac = navigator.platform.indexOf('Mac') === 0 +const isMac = navigator.platform.indexOf('Mac') === 0; const pcStyle = { width: isMac ? 395 : 412, - margin: '20px auto', - border: '10px solid #000', - borderRadius: '20px', - height: '684px', - overflow: 'auto' -} + margin: '20px auto', + border: '10px solid #000', + borderRadius: '20px', + height: '684px', + overflow: 'auto', +}; -const PreviewPage = memo((props) => { +const PreviewPage = memo(props => { const [pointData, setPointData] = useState(() => { - let pointDataStr = localStorage.getItem('pointData') - let points - - try{ - points = JSON.parse(pointDataStr) || [] - }catch(err) { - points = [] - } - return points.map(item => ({...item, point: {...item.point, isDraggable: false, isResizable: false } })) - }) + let pointDataStr = localStorage.getItem('pointData'); + let points; - const vw = window.innerWidth + try { + points = JSON.parse(pointDataStr) || []; + } catch (err) { + points = []; + } + return points.map(item => ({ + ...item, + point: { ...item.point, isDraggable: false, isResizable: false }, + })); + }); + + const vw = window.innerWidth; useEffect(() => { - const { tid } = props.location.query - const timer = null - req.get('/visible/preview/get', { params: { tid } }).then(res => { - setPointData(res.map(item => ({...item, point: {...item.point, isDraggable: false, isResizable: false } }))) - }).catch(err => { - timer = setTimeout(() => { - window.close() - }, 3000) - }) + const { tid } = props.location.query; + const timer = null; + req + .get('/visible/preview/get', { params: { tid } }) + .then(res => { + setPointData( + res.map(item => ({ + ...item, + point: { ...item.point, isDraggable: false, isResizable: false }, + })), + ); + }) + .catch(err => { + timer = setTimeout(() => { + window.close(); + }, 3000); + }); return () => { - clearTimeout(timer) - } - }, []) + clearTimeout(timer); + }; + }, []); return (
800 ? pcStyle : {}}> - 800 ? 375 :vw } - margin={[0,0]} + 800 ? 375 : vw} + margin={[0, 0]} id="xx" > - { - pointData.map(value => -
- -
- ) - } + {pointData.map(value => ( +
+ +
+ ))}
- ) -}) + ); +}); -export default PreviewPage +export default PreviewPage;