feat: add pic fix drag

This commit is contained in:
yehuozhili 2020-10-09 05:10:35 +08:00
parent 4655f0cbac
commit 95e62a985d
38 changed files with 205 additions and 252 deletions

BIN
src/assets/01-轮播.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

BIN
src/assets/02-页脚.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
src/assets/03-表单.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
src/assets/04-页头.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/assets/05-图标.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
src/assets/07-列表.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
src/assets/08-长文本.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
src/assets/09-通知.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
src/assets/10-二维码.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

BIN
src/assets/11-切换页.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
src/assets/12-文本.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
src/assets/13-空白.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
src/assets/14-视频.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
src/assets/15-进度.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -2,9 +2,9 @@ import React, { memo } from 'react';
import { Carousel } from 'zarm';
import styles from './index.less';
import { ICarouselConfig } from './schema';
import logo from '@/assets/01-轮播.png';
const XCarousel = memo((props: ICarouselConfig) => {
const { direction, swipeable, autoPlay, isTpl, imgList, tplImg } = props;
const { direction, swipeable, autoPlay, isTpl, imgList } = props;
const contentRender = () => {
return imgList.map((item, i) => {
return (
@ -18,7 +18,7 @@ const XCarousel = memo((props: ICarouselConfig) => {
<>
{isTpl ? (
<div className={styles.carousel__item__pic}>
<img src={tplImg} alt="" />
<img src={logo} alt="" />
</div>
) : (
<div

View File

@ -22,7 +22,6 @@ export interface ICarouselConfig extends ICommonBaseType {
swipeable: TSwitchDefaultType;
autoPlay: TSwitchDefaultType;
imgList: TDataListDefaultType;
tplImg: string;
}
export interface ICarouselSchema {
@ -100,7 +99,6 @@ const Carousel: ICarouselSchema = {
},
],
...baseDefault,
tplImg: 'http://io.nainor.com/uploads/carousal_17442e1420f.png',
},
};
export default Carousel;

View File

@ -1,22 +1,14 @@
import React, { memo } from 'react';
import { IFooterConfig } from './schema';
import logo from '@/assets/02-页脚.png';
const Footer = memo((props: IFooterConfig) => {
const { bgColor, text, color, align, fontSize, height } = props;
return (
<>
{props.isTpl && (
<footer
style={{
backgroundColor: bgColor,
color,
fontSize,
textAlign: align,
height,
lineHeight: height + 'px',
}}
>
{text}
</footer>
<div>
<img src={logo} alt="" />
</div>
)}
{!props.isTpl && (
<div

View File

@ -3,8 +3,8 @@ import { Button } from 'zarm';
import BaseForm from './BaseForm';
import styles from './index.less';
import { IFormConfig } from './schema';
const FormComponent = (props: IFormConfig) => {
import logo from '@/assets/03-表单.png';
const FormComponent = (props: IFormConfig & { isTpl: boolean }) => {
const { title, bgColor, fontSize, titColor, btnColor, btnTextColor, api, formControls } = props;
const formData: Record<string, any> = {};
const handleChange = useCallback(
@ -29,29 +29,8 @@ const FormComponent = (props: IFormConfig) => {
return (
<>
{props.isTpl && (
<div className={styles.formWrap} style={{ backgroundColor: bgColor }}>
{title && (
<div className={styles.title} style={{ fontSize, color: titColor }}>
{title}
</div>
)}
<div className={styles.formContent}>
{formControls.map(item => {
const FormItem = BaseForm[item.type];
return <FormItem onChange={handleChange.bind(this, item)} {...item} key={item.id} />;
})}
<div style={{ textAlign: 'center', padding: '16px 0' }}>
<Button
theme="primary"
size="sm"
block
onClick={handleSubmit}
style={{ backgroundColor: btnColor, borderColor: btnColor, color: btnTextColor }}
>
</Button>
</div>
</div>
<div>
<img src={logo} alt="" />
</div>
)}
{!props.isTpl && (
@ -61,12 +40,6 @@ const FormComponent = (props: IFormConfig) => {
backgroundColor: bgColor,
overflow: 'hidden',
position: 'absolute',
width: `${props.baseWidth}%`,
height: `${props.baseHeight}%`,
borderRadius: props.baseRadius,
transform: `translate(${props.baseLeft}px,${props.baseTop}px)
scale(${props.baseScale / 100})
rotate(${props.baseRotate}deg)`,
}}
>
{title && (

View File

@ -2,20 +2,15 @@ import { memo } from 'react';
import styles from './index.less';
import React from 'react';
import { IHeaderConfig } from './schema';
import logos from '@/assets/04-页头.png';
const Header = memo((props: IHeaderConfig) => {
const { bgColor, logo, logoText, fontSize, color } = props;
return (
<>
{props.isTpl && (
<header className={styles.header} style={{ backgroundColor: bgColor }}>
<div className={styles.logo}>
<img src={logo && logo[0].url} alt={logoText} />
</div>
<div className={styles.title} style={{ fontSize, color }}>
{logoText}
</div>
</header>
<div>
<img src={logos} alt="" />
</div>
)}
{!props.isTpl && (
<header

View File

@ -1,10 +1,9 @@
import React, { memo } from 'react';
import * as Icon from '@ant-design/icons';
import IconImg from 'assets/icon.png';
import { AntdIconProps } from '@ant-design/icons/lib/components/AntdIcon';
import { AntdIconType } from './icon';
import { IIconConfig } from './schema';
import logo from '@/assets/05-图标.png';
interface IconType extends IIconConfig {
isTpl?: boolean;
}
@ -15,9 +14,8 @@ const XIcon = memo((props: IconType) => {
React.RefAttributes<HTMLSpanElement>> = Icon[type];
return isTpl ? (
<div style={{ textAlign: 'center' }}>
<img style={{ verticalAlign: '-20px', width: '82px' }} src={IconImg} alt={type} />
<div>
<img src={logo} alt="" />
</div>
) : (
<MyIcon twoToneColor={color} style={{ fontSize: size }} spin={spin} />

View File

@ -1,5 +1,6 @@
import React, { memo } from 'react';
import { IImageConfig } from './schema';
import logo from '@/assets/06-图片组件.png';
const Image = memo((props: IImageConfig) => {
const {
imgUrl,
@ -18,15 +19,8 @@ const Image = memo((props: IImageConfig) => {
return (
<>
{props.isTpl && (
<div
style={{
borderRadius: round,
width: '100%',
textAlign: 'center',
overflow: 'hidden',
}}
>
<img src={imgUrl && imgUrl[0].url} alt="" style={{ width: '100%' }} />
<div>
<img src={logo} alt="" />
</div>
)}
{!props.isTpl && (

View File

@ -1,51 +1,14 @@
import React, { memo } from 'react';
import styles from './index.less';
import { IListConfig } from './schema';
import logo from '@/assets/07-列表.png';
const List = memo((props: IListConfig) => {
const { round, sourceData, imgSize, fontSize, color } = props;
return (
<>
{props.isTpl && (
<div className={styles.list}>
<div className={styles.sourceList}>
{sourceData.map((item, i) => {
return (
<div className={styles.sourceItem} key={i}>
<div className={styles.imgWrap}>
<img
src={
item.imgUrl[0]
? item.imgUrl[0].url
: 'http://io.nainor.com/uploads/01_173e15d3493.png'
}
alt={item.desc}
style={{
width: parseFloat(imgSize),
height: imgSize,
objectFit: 'cover',
borderRadius: round,
}}
/>
</div>
<div className={styles.content}>
<a
className={styles.tit}
style={{ fontSize, color }}
href={item.link ? item.link : '#'}
>
{item.title}
<div
className={styles.desc}
style={{ fontSize: fontSize * 0.8, color: 'rgba(0,0,0, .3)' }}
>
{item.desc}
</div>
</a>
</div>
</div>
);
})}
</div>
<div>
<img src={logo} alt="" />
</div>
)}
{!props.isTpl && (

View File

@ -1,15 +1,24 @@
import React, { memo } from 'react';
import styles from './index.less';
import { ILongTextConfig } from './schema';
const LongText = memo((props: ILongTextConfig) => {
const { text, fontSize, color, indent, lineHeight, textAlign } = props;
import logo from '@/assets/08-长文本.png';
const LongText = memo((props: ILongTextConfig & { isTpl: boolean }) => {
const { text, fontSize, color, indent, lineHeight, textAlign, isTpl } = props;
return (
<div
className={styles.textWrap}
style={{ color, textIndent: indent + 'px', fontSize, lineHeight, textAlign }}
>
{text}
</div>
<>
{isTpl ? (
<div>
<img src={logo} alt=""></img>
</div>
) : (
<div
className={styles.textWrap}
style={{ color, textIndent: indent + 'px', fontSize, lineHeight, textAlign }}
>
{text}
</div>
)}
</>
);
});
export default LongText;

View File

@ -1,12 +1,21 @@
import { NoticeBar } from 'zarm';
import React, { memo } from 'react';
import { INoticeConfig } from './schema';
const Notice = memo((props: INoticeConfig) => {
const { text, speed, theme, isClose = false } = props;
import logo from '@/assets/09-通知.png';
const Notice = memo((props: INoticeConfig & { isTpl: boolean }) => {
const { text, speed, theme, isClose = false, isTpl } = props;
return (
<NoticeBar theme={theme === 'default' ? undefined : theme} closable={isClose} speed={speed}>
<span style={{ color: 'inherit' }}>{text}</span>
</NoticeBar>
<>
{isTpl ? (
<div>
<img src={logo} alt=""></img>
</div>
) : (
<NoticeBar theme={theme === 'default' ? undefined : theme} closable={isClose} speed={speed}>
<span style={{ color: 'inherit' }}>{text}</span>
</NoticeBar>
)}
</>
);
});

View File

@ -1,13 +1,21 @@
import React, { memo } from 'react';
import { IQrcodeConfig } from './schema';
const Qrcode = memo((props: IQrcodeConfig) => {
const { qrcode, text, color, fontSize = 14 } = props;
import logo from '@/assets/10-二维码.png';
const Qrcode = memo((props: IQrcodeConfig & { isTpl: boolean }) => {
const { qrcode, text, color, fontSize = 14, isTpl } = props;
return (
<div style={{ width: '240px', margin: '16px auto' }}>
<img src={qrcode && qrcode[0].url} alt={text} style={{ width: '100%' }} />
<div style={{ textAlign: 'center', color, fontSize, paddingTop: '8px' }}>{text}</div>
</div>
<>
{isTpl ? (
<div>
<img src={logo} alt=""></img>
</div>
) : (
<div style={{ width: '240px', margin: '16px auto' }}>
<img src={qrcode && qrcode[0].url} alt={text} style={{ width: '100%' }} />
<div style={{ textAlign: 'center', color, fontSize, paddingTop: '8px' }}>{text}</div>
</div>
)}
</>
);
});

View File

@ -1,12 +1,12 @@
import React, { useEffect, useRef } from 'react';
import React, { memo, useEffect, useRef } from 'react';
import { Tabs } from 'zarm';
import styles from './index.less';
import { ITabConfig } from './schema';
import logo from '@/assets/11-切换页.png';
const { Panel } = Tabs;
const XTab = (props: ITabConfig) => {
const { tabs = ['分类一', '分类二'], activeColor, color, fontSize, sourceData } = props;
const XTab = (props: ITabConfig & { isTpl: boolean }) => {
const { tabs = ['分类一', '分类二'], activeColor, color, fontSize, sourceData, isTpl } = props;
const tabWrapRef = useRef<HTMLDivElement>(null);
@ -20,45 +20,48 @@ const XTab = (props: ITabConfig) => {
}, [activeColor]);
return (
<div className={styles.tabWrap} ref={tabWrapRef}>
<Tabs
scrollThreshold={3}
onChange={i => {
console.log(i);
}}
>
{tabs.map((item, i) => {
return (
<Panel title={item} key={i}>
<div className={styles.content}>
{sourceData
.filter(item => item.type === i)
.map((item, i) => {
return (
<div className={styles.item} key={i}>
<a className={styles.imgWrap} href={item.link} title={item.desc}>
<img
src={
item.imgUrl[0]
? item.imgUrl[0].url
: 'http://io.nainor.com/uploads/01_173e15d3493.png'
}
alt={item.title}
/>
<div className={styles.title} style={{ fontSize, color }}>
{item.title}
<>
{isTpl ? (
<div>
<img src={logo} alt=""></img>
</div>
) : (
<div className={styles.tabWrap} ref={tabWrapRef}>
<Tabs scrollThreshold={3}>
{tabs.map((item, i) => {
return (
<Panel title={item} key={i}>
<div className={styles.content}>
{sourceData
.filter(item => item.type === i)
.map((item, i) => {
return (
<div className={styles.item} key={i}>
<a className={styles.imgWrap} href={item.link} title={item.desc}>
<img
src={
item.imgUrl[0]
? item.imgUrl[0].url
: 'http://io.nainor.com/uploads/01_173e15d3493.png'
}
alt={item.title}
/>
<div className={styles.title} style={{ fontSize, color }}>
{item.title}
</div>
</a>
</div>
</a>
</div>
);
})}
</div>
</Panel>
);
})}
</Tabs>
</div>
);
})}
</div>
</Panel>
);
})}
</Tabs>
</div>
)}
</>
);
};
export default XTab;
export default memo(XTab);

View File

@ -1,13 +1,21 @@
import React, { memo } from 'react';
import styles from './index.less';
import { ITextConfig } from './schema';
const Text = memo((props: ITextConfig) => {
const { align, text, fontSize, color, lineHeight } = props;
import logo from '@/assets/12-文本.png';
const Text = memo((props: ITextConfig & { isTpl: boolean }) => {
const { align, text, fontSize, color, lineHeight, isTpl } = props;
return (
<div className={styles.textWrap} style={{ color, textAlign: align, fontSize, lineHeight }}>
{text}
</div>
<>
{isTpl ? (
<div>
<img src={logo} alt=""></img>
</div>
) : (
<div className={styles.textWrap} style={{ color, textAlign: align, fontSize, lineHeight }}>
{text}
</div>
)}
</>
);
});
export default Text;

View File

@ -2,7 +2,7 @@ import { memo } from 'react';
import styles from './index.less';
import React from 'react';
import { IWhiteTplConfig } from './schema';
import logo from '@/assets/13-空白.png';
interface IProps extends IWhiteTplConfig {
isTpl: boolean;
}
@ -10,14 +10,22 @@ interface IProps extends IWhiteTplConfig {
const WhiteTpl = memo((props: IProps) => {
const { bgColor, text, fontSize, color, height, isTpl } = props;
return (
<div
className={styles.whiteTpl}
style={{ backgroundColor: bgColor, height, lineHeight: height + 'px' }}
>
<div className={styles.title} style={{ fontSize, color }}>
{isTpl ? '空白模版' : text}
</div>
</div>
<>
{isTpl ? (
<div>
<img src={logo} alt=""></img>
</div>
) : (
<div
className={styles.whiteTpl}
style={{ backgroundColor: bgColor, height, lineHeight: height + 'px' }}
>
<div className={styles.title} style={{ fontSize, color }}>
{text}
</div>
</div>
)}
</>
);
});

View File

@ -2,19 +2,27 @@ import React, { memo } from 'react';
import { Player, BigPlayButton } from 'video-react';
import './index.css';
import { IVideoConfig } from './schema';
const VideoPlayer = memo((props: IVideoConfig) => {
const { poster, url } = props;
import logo from '@/assets/14-视频.png';
const VideoPlayer = memo((props: IVideoConfig & { isTpl: boolean }) => {
const { poster, url, isTpl } = props;
return (
<div>
<Player
playsInline
poster={poster[0].url}
src={url || 'https://gossv.vcg.com/cmsUploadVideo/creative/1移轴/7月移轴.mp4'}
>
<BigPlayButton position="center" />
</Player>
</div>
<>
{isTpl ? (
<div>
<img src={logo} alt=""></img>
</div>
) : (
<div>
<Player
playsInline
poster={poster[0].url}
src={url || 'https://gossv.vcg.com/cmsUploadVideo/creative/1移轴/7月移轴.mp4'}
>
<BigPlayButton position="center" />
</Player>
</div>
)}
</>
);
});

View File

@ -2,19 +2,27 @@ import React, { memo } from 'react';
import { Progress } from 'zarm';
import styles from './index.less';
import { IXProgressConfig } from './schema';
const XProgress = memo((props: IXProgressConfig) => {
const { theme, size, shape, percent, strokeWidth } = props;
import logo from '@/assets/15-进度.png';
const XProgress = memo((props: IXProgressConfig & { isTpl: boolean }) => {
const { theme, size, shape, percent, strokeWidth, isTpl } = props;
return (
<div className={styles.textWrap} style={{ textAlign: 'center' }}>
<Progress
shape={shape}
size={size}
percent={percent}
theme={theme}
strokeWidth={strokeWidth}
/>
</div>
<>
{isTpl ? (
<div>
<img src={logo} alt=""></img>
</div>
) : (
<div className={styles.textWrap} style={{ textAlign: 'center' }}>
<Progress
shape={shape}
size={size}
percent={percent}
theme={theme}
strokeWidth={strokeWidth}
/>
</div>
)}
</>
);
});

View File

@ -1,6 +1,6 @@
const template = {
type: 'XProgress',
h: 102,
displayName: '圆型进度条组件',
displayName: '进度条组件',
};
export default template;

View File

@ -21,12 +21,7 @@ const XTab = (props: ITabConfig) => {
return (
<div className={styles.tabWrap} ref={tabWrapRef}>
<Tabs
scrollThreshold={3}
onChange={i => {
console.log(i);
}}
>
<Tabs scrollThreshold={3}>
{tabs.map((item, i) => {
return (
<Panel title={item} key={i}>

View File

@ -34,7 +34,6 @@ const EditorModal: FC<EditorModalProps> = props => {
form
.validateFields()
.then(values => {
console.log(values);
if (item) {
values.id = item.id;
onSave && onSave(values);

View File

@ -1,5 +1,3 @@
import { type } from 'os';
////////////////////
export interface IUploadConfigType {
key: string;
@ -200,14 +198,7 @@ export type baseFormDateTpl = {
label: string;
placeholder: string;
};
export type baseFormButtonTpl = {
key: string;
name: string;
type: 'Button';
icons: Array<any>;
};
//类型不要乱加这部分是FormItems的类型定义只有新增formItems的配置项才需要加
export type baseFormUnion =
| baseFormTextTpl
| baseFormNumberTpl
@ -215,8 +206,7 @@ export type baseFormUnion =
| baseFormMyRadioTpl
| baseFormMyCheckboxTpl
| baseFormMySelectTpl
| baseFormDateTpl
| baseFormButtonTpl;
| baseFormDateTpl;
export type baseFormUnionType =
| baseFormTextTpl['type']
| baseFormNumberTpl['type']
@ -224,7 +214,6 @@ export type baseFormUnionType =
| baseFormMyRadioTpl['type']
| baseFormMyCheckboxTpl['type']
| baseFormMySelectTpl['type']
| baseFormDateTpl['type']
| baseFormButtonTpl['type'];
| baseFormDateTpl['type'];
export type TFormItemsDefaultType = Array<baseFormUnion>;

View File

@ -192,14 +192,12 @@ class EditableTable extends React.Component<any, any> {
};
handleOk = (e: React.MouseEvent<HTMLElement, MouseEvent>) => {
console.log(e);
this.setState({
visible: false,
});
};
handleCancel = (e: React.MouseEvent<HTMLElement, MouseEvent>) => {
console.log(e);
this.setState({
visible: false,
});

View File

@ -70,6 +70,7 @@ body {
flex-wrap: wrap;
padding-left: 10px!important;
padding-right: 10px!important;
padding-bottom: 40px;
}
.ant-form-item-label > label {

View File

@ -198,7 +198,7 @@ const Container = (props: {
if (pstate.curPoint && pstate.curPoint.status === 'inToCanvas' && rightColla) {
changeRightColla(false);
}
}, [pstate.curPoint]);
}, [changeRightColla, pstate.curPoint, rightColla]);
const allType = useMemo(() => {
let arr: string[] = [];
@ -377,11 +377,10 @@ const Container = (props: {
if (diffmove.move) {
let diffx: number;
let diffy: number;
const d = 5;
const newX = e.clientX;
const newY = e.clientY;
newX - diffmove.start.x > 0 ? (diffx = d) : (diffx = -d);
newY - diffmove.start.y > 0 ? (diffy = d) : (diffy = -d);
diffx = newX - diffmove.start.x;
diffy = newY - diffmove.start.y;
setDiffMove({
start: {
x: newX,
@ -401,26 +400,24 @@ const Container = (props: {
const mouseupfn = useMemo(() => {
return () => {
if (diffmove.move) {
setDiffMove({
start: { x: 0, y: 0 },
move: false,
});
}
setDiffMove({
start: { x: 0, y: 0 },
move: false,
});
};
}, [diffmove.move]);
}, []);
const onwheelFn = useMemo(() => {
return (e: React.WheelEvent<HTMLDivElement>) => {
if (e.deltaY > 0) {
if (e.deltaY < 0) {
setDragState(prev => ({
x: prev.x,
y: prev.y + 10,
y: prev.y + 40,
}));
} else {
setDragState(prev => ({
x: prev.x,
y: prev.y - 10,
y: prev.y - 40,
}));
}
};
@ -512,7 +509,7 @@ const Container = (props: {
className={styles.sliderBtn}
onClick={handleSlider.bind(this, 1)}
style={
scaleNum == 1
scaleNum === 1
? { pointerEvents: 'none' }
: { display: 'initial', marginLeft: '13px' }
}
@ -522,7 +519,7 @@ const Container = (props: {
<span>{scaleNum * 100}%</span>
<span
className={styles.sliderBtn}
style={scaleNum == 0.1 ? { pointerEvents: 'none' } : { display: 'initial' }}
style={scaleNum === 0.1 ? { pointerEvents: 'none' } : { display: 'initial' }}
onClick={handleSlider.bind(this, 0)}
>
-