🚸 优化图片组件, 增加文字编辑功能 🆕 添加坐标编辑控件Pos

This commit is contained in:
xujiang 2020-10-03 14:13:50 +08:00
parent 2e07ec1414
commit 75facb2b2a
7 changed files with 243 additions and 5 deletions

View File

@ -1,7 +1,20 @@
import React, { memo } from 'react';
import { IImageConfig } from './schema';
const Image = memo((props: IImageConfig) => {
const { imgUrl, round = 0 } = props;
const {
imgUrl,
round = 0,
translate,
align,
titText,
titFontSize,
titColor,
titFontWeight,
subTitText,
subTitFontSize,
subTitColor,
subTitFontWeight,
} = props;
return (
<>
{props.isTpl && (
@ -35,8 +48,35 @@ const Image = memo((props: IImageConfig) => {
width: '100%',
textAlign: 'center',
overflow: 'hidden',
position: 'relative',
}}
>
<div
style={{
position: 'absolute',
width: '100%',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
marginLeft: translate[0],
marginTop: translate[1],
textAlign: align,
}}
>
<div style={{ fontSize: titFontSize, color: titColor, fontWeight: +titFontWeight }}>
{titText}
</div>
<div
style={{
fontSize: subTitFontSize,
color: subTitColor,
fontWeight: +subTitFontWeight,
lineHeight: 2.6,
}}
>
{subTitText}
</div>
</div>
<img src={imgUrl && imgUrl[0].url} alt="" style={{ width: '100%' }} />
</div>
</div>

View File

@ -3,11 +3,40 @@ import {
IUploadConfigType,
TNumberDefaultType,
TUploadDefaultType,
IColorConfigType,
TColorDefaultType,
ISelectConfigType,
TSelectDefaultType,
IPosConfigType,
TPosDefaultType,
TTextDefaultType,
ITextConfigType,
} from '@/components/PanelComponents/FormEditor/types';
import { baseConfig, baseDefault, ICommonBaseType } from '../../common';
export type TImageEditData = Array<IUploadConfigType | INumberConfigType>;
export type TTextSelectKeyType = 'left' | 'right' | 'center';
export type TTextWeightSelectKeyType = '300' | '400' | '500' | '600';
export type TImageEditData = Array<
| IUploadConfigType
| INumberConfigType
| IPosConfigType
| ISelectConfigType<TTextSelectKeyType | TTextWeightSelectKeyType>
| IColorConfigType
| ITextConfigType
>;
export interface IImageConfig extends ICommonBaseType {
translate: TPosDefaultType;
align: TSelectDefaultType<TTextSelectKeyType>;
titText: TTextDefaultType;
titColor: TColorDefaultType;
titFontSize: TNumberDefaultType;
titFontWeight: TSelectDefaultType<TTextWeightSelectKeyType>;
subTitText: TTextDefaultType;
subTitColor: TColorDefaultType;
subTitFontSize: TNumberDefaultType;
subTitFontWeight: TSelectDefaultType<TTextWeightSelectKeyType>;
imgUrl: TUploadDefaultType;
round: TNumberDefaultType;
}
@ -20,9 +49,109 @@ export interface IImageSchema {
const Image: IImageSchema = {
editData: [
...baseConfig,
{
key: 'translate',
name: '文字偏移',
type: 'Pos',
},
{
key: 'align',
name: '对齐方式',
type: 'Select',
range: [
{
key: 'left',
text: '左对齐',
},
{
key: 'center',
text: '居中对齐',
},
{
key: 'right',
text: '右对齐',
},
],
},
{
key: 'titText',
name: '标题文字',
type: 'Text',
},
{
key: 'titFontSize',
name: '标题大小',
type: 'Number',
},
{
key: 'titColor',
name: '标题颜色',
type: 'Color',
},
{
key: 'titFontWeight',
name: '标题粗细',
type: 'Select',
range: [
{
key: '300',
text: '300 x 300',
},
{
key: '400',
text: '400 x 400',
},
{
key: '500',
text: '500 x 500',
},
{
key: '600',
text: '600 x 600',
},
],
},
{
key: 'subTitText',
name: '副标题文字',
type: 'Text',
},
{
key: 'subTitFontSize',
name: '副标题大小',
type: 'Number',
},
{
key: 'subTitColor',
name: '副标题颜色',
type: 'Color',
},
{
key: 'subTitFontWeight',
name: '副标题粗细',
type: 'Select',
range: [
{
key: '300',
text: '300 x 300',
},
{
key: '400',
text: '400 x 400',
},
{
key: '500',
text: '500 x 500',
},
{
key: '600',
text: '600 x 600',
},
],
},
{
key: 'imgUrl',
name: '上传',
name: '上传图片',
type: 'Upload',
isCrop: false,
},
@ -33,12 +162,22 @@ const Image: IImageSchema = {
},
],
config: {
translate: [0, 0],
align: 'center',
titText: '',
titFontSize: 20,
titColor: 'rgba(0,0,0,1)',
titFontWeight: '400',
subTitText: '',
subTitFontSize: 16,
subTitColor: 'rgba(0,0,0,1)',
subTitFontWeight: '400',
imgUrl: [
{
uid: '001',
name: 'image.png',
status: 'done',
url: 'http://io.nainor.com/uploads/4_1740bf4535c.png',
url: 'http://io.nainor.com/uploads/bg_174e470dc22.png',
},
],
round: 0,

View File

@ -1,5 +1,5 @@
const template = {
type: 'Image',
h: 188,
h: 80,
};
export default template;

View File

@ -6,6 +6,7 @@ import MutiText from '../MutiText';
import Color from '../Color';
import CardPicker from '../CardPicker';
import Table from '../Table';
import Pos from '../Pos';
import { Store } from 'antd/lib/form/interface';
import FormItems from '../FormItems';
// import styles from './index.less';
@ -143,6 +144,11 @@ const FormEditor = (props: FormEditorProps) => {
<Table data={item.data} />
</Form.Item>
)}
{item.type === 'Pos' && (
<Form.Item label={item.name} name={item.key}>
<Pos />
</Form.Item>
)}
{item.type === 'FormItems' && (
<Form.Item label={item.name} name={item.key} valuePropName="formList">
<FormItems data={item.data} />

View File

@ -127,6 +127,17 @@ export type TTableDefaultType = Array<{
value: number;
}>;
// position input control
export interface IPosConfigType {
key: string;
name: string;
type: 'Pos';
}
export type TPosItem = number | undefined;
export type TPosDefaultType = [TPosItem, TPosItem];
//////////////////
export interface IFormItemsConfigType {
key: string;

View File

@ -0,0 +1,9 @@
.posIpt {
display: flex;
.posItem {
margin-right: 10px;
span {
margin-right: 3px;
}
}
}

View File

@ -0,0 +1,33 @@
import React, { memo, useState, useEffect } from 'react';
import { InputNumber } from 'antd';
import styles from './index.less';
import { TPosDefaultType, TPosItem } from '../FormEditor/types';
type PosProps = {
value?: TPosDefaultType;
onChange?: (v: TPosItem | string) => void;
};
export default memo(function Pos(props: PosProps) {
const { value, onChange } = props;
let _this: typeof Pos = Pos;
const handleChange = (index: number, v: TPosItem | string) => {
let arr: any = value || [];
arr[index] = v;
onChange && onChange(arr);
};
return (
<div className={styles.posIpt}>
<div className={styles.posItem}>
<span>x: </span>
<InputNumber defaultValue={value && value[0]} onChange={handleChange.bind(_this, 0)} />
</div>
<div className={styles.posItem}>
<span>y: </span>
<InputNumber defaultValue={value && value[1]} onChange={handleChange.bind(_this, 1)} />
</div>
</div>
);
});