123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926 |
- /* eslint-disable camelcase */
- import React from 'react'
- import {Button, Form, Input, Select, Slider, Switch, Row, Col, InputNumber, Icon, Popover, Modal, message} from 'antd'
- import {Rnd} from 'react-rnd'
- import {ImagePreview, JsonPage} from 'wptpc-design'
- import isEmpty from 'lodash/isEmpty'
- // import { connect } from 'dva'
- import RcColorPicker from 'rc-color-picker'
- import 'rc-color-picker/assets/index.css'
- import {create, fetchDetail, update, fontList} from './service'
- import styles from './index.less'
- const IconFont = Icon.createFromIconfontCN({
- scriptUrl: '//at.alicdn.com/t/font_2018233_fl4w8ponsnu.js',
- });
- const {Option} = Select
- const {confirm} = Modal
- const unique = (arr) => {
- return Array.from(new Set(arr))
- }
- export default class Edit extends React.PureComponent {
- state = {
- name: '',
- description: '',
- bg: {
- type: 'bg',
- w: 750,
- h: 1000,
- c: '#eaeaea'
- },
- element: [],
- activeObjectIndex: 0,
- canvasArea: false,// 鼠标是否在画布区域
- editName: '',
- imgs: [], // 预览图片的url
- previwVisible: false, // 预览框是否展示
- fontList: [],//字体列表
- }
- keyPress = event => {
- const {activeObjectIndex, canvasArea} = this.state
- const activeObject = this.state.element[activeObjectIndex] || {}
- const e = event || window.event;
- const {keyCode} = e;
- const ctrlKey = e.ctrlKey || e.metaKey;
- // console.log("🚀 ~ file: $id$.js ~ line 45 ~ Edit ~ ctrlKey", ctrlKey)
- // console.log("🚀 ~ file: $id$.js ~ line 44 ~ Edit ~ keyCode", keyCode)
- if (ctrlKey && keyCode === 90) {
- e.preventDefault();
- this.reback = true;
- // 撤销
- let list = [];
- if (localStorage.getItem('posterElement') && JSON.parse(localStorage.getItem('posterElement'))?.length > 0) {
- list = JSON.parse(localStorage.getItem('posterElement'));
- if (this.state.id && list.length === 1) {
- this.reback = false;
- return
- }
- list = list.slice(0, -1);
- let obj = list.slice(-1)[0];
- if (!obj) {
- this.setState({
- name: '',
- description: '',
- bg: {
- type: 'bg',
- w: 750,
- h: 1000,
- c: '#eaeaea'
- },
- element: [],
- })
- } else {
- this.setState(obj)
- }
- localStorage.setItem('posterElement', JSON.stringify(list));
- }
- }
- if (!canvasArea) {
- return
- }
- // e.preventDefault(); 不能提取到最外面,有位只有按下方向键才需要阻止默认事件
- if (keyCode === 37) {
- e.preventDefault();
- //左
- this.updateElement(activeObjectIndex, {dx: activeObject.dx - 1})
- }
- if (keyCode === 38) {
- e.preventDefault();
- //上
- this.updateElement(activeObjectIndex, {dy: activeObject.dy - 1})
- }
- if (keyCode === 39) {
- e.preventDefault();
- // 右
- this.updateElement(activeObjectIndex, {dx: activeObject.dx + 1})
- }
- if (keyCode === 40) {
- e.preventDefault();
- //下
- this.updateElement(activeObjectIndex, {dy: activeObject.dy + 1})
- }
- };
- // 添加监听键盘事件 防止长按多次发送用keyup
- addKeyUpEvent = () => {
- window.addEventListener('keydown', this.keyPress);
- };
- // 移除监听键盘事件
- removeKeyUpEvent = () => {
- window.removeEventListener('keydowm', this.keyPress);
- };
- componentDidMount() {
- this.addKeyUpEvent();
- localStorage.setItem("posterElement", '')
- this.setState({posterHeight: document.body.clientHeight - document.getElementById('poster').offsetTop - 35})
- if (this.props.match.params.id) {
- fetchDetail({id: this.props.match.params.id}).then(res => {
- if (!isEmpty(res.data)) {
- const {data: {description, name, id, preview, config: [bg, ...element]}} = res
- this.setState({name: name, description: description, element: element, id: id, bg: bg, imgs: [preview]})
- }
- })
- fontList().then(res => {
- if (res.code === 0) {
- this.setState({fontList: res.data})
- }
- })
- }
- }
- componentDidUpdate(prevProps, prevState) {
- const {name, description, bg, element} = this.state;
- const {name: nameprev, description: descriptionprev, bg: bgprev, element: elementprev} = prevState;
- if (name === nameprev && description === descriptionprev && JSON.stringify(bg) === JSON.stringify(bgprev) && JSON.stringify(element) === JSON.stringify(elementprev)) {
- return
- }
- const temListStr = localStorage.getItem('posterElement');
- let obj = {}
- let list = [];
- if (temListStr) {
- list = JSON.parse(temListStr);
- }
- // 撤销的时候就不再去储存值了
- if (this.reback) {
- this.reback = false;
- return
- }
- list.push({
- element: element,
- name: name,
- description: description,
- bg: bg,
- })
- // 最多储存 30 步的操作
- if (list.length > 30) {
- list = list.slice(-30)
- }
- localStorage.setItem('posterElement', JSON.stringify(list))
- }
- componentWillUnmount() {
- this.removeKeyUpEvent();
- localStorage.setItem('posterElement', '')
- }
- updateBgState = (value) => {
- this.setState({bg: {...this.state.bg, ...value}})
- }
- updateElement = (index, value) => {
- // console.log(index, value);
- const _ele = this.state.element.slice()
- const _tar = _ele[index] // dom
- // console.log(_tar,value);
- _ele[index] = {
- ..._tar,
- ...value,
- }
- this.setState({element: _ele})
- }
- delElement = (index, name) => {
- confirm({
- title: '确定删除' + name + '?',
- okText: 'Yes',
- okType: 'danger',
- cancelText: 'No',
- onOk: () => {
- const _ele = this.state.element.slice()
- _ele.splice(index, 1)
- this.setState({element: _ele})
- }
- })
- }
- // 修改二维码logo
- changeQrLogo = (logo) => {
- let logos = new Map();
- logos.set('wpt_high', 'https://cdn.weipaitang.com/static/20200413eb9effec-3871-ffec3871-cd41-baed9e98535e-W200H200');
- logos.set('youjiang', 'https://cdn.weipaitang.com/static/202004141c0b320a-9cdc-320a9cdc-d090-e4b5964fee9d-W200H200');
- logos.set('cl', 'https://cdn.weipaitang.com/static/20210607d591559f-70e6-559f70e6-7427-f899f240d7a0-W284H285');
- let logoUrl = logos.get(logo);
- // 默认logo
- if (typeof logoUrl === "undefined"){
- logoUrl = "https://cdn.weipaitang.com/static/20200413d4263aa5-6423-3aa56423-4e8d-a96e1d9d93f3-W200H200"
- }
- return `url(` + logoUrl + `)`
- }
- addShape = (type) => {
- const _ele = this.state.element.slice()
- const {dx, dy} = _ele[this.state.activeObjectIndex] || {dx: 0, dy: 45}
- switch (type) {
- case 'text':
- _ele.push({
- content: '我是预览文本',
- type: 'text',
- t: '#text_' + (this.state.element.filter(item => item.type === 'text').length + 1) + '#',
- font: 'pingfang_sc_semibold',
- size: 36,
- dx: dx + 36,
- dy: dy + 36,
- width: 490,
- height: 45,
- c: '%23333333'
- })
- break
- case 'pic':
- _ele.push({
- type: 'pic',
- path: '#pic_' + (this.state.element.filter(item => item.type === 'pic').length + 1) + '#',
- content: 'https://cdn.weipaitang.com/img/20210417B2gW3tnOlVzgfja0TSqvdlE1YhnFV4QOtwswRdvwLiQKqnyDGLxPXHP3I3vXTiL0-W1080H1080/w/640',
- w: '100',
- h: '100',
- dx: dx + 15,
- dy: dy + 15,
- round: 'false'
- // align: 'both-align'
- })
- break
- case 'mat':
- _ele.push({
- type: 'mat',
- path: '#mat_' + (this.state.element.filter(item => item.type === 'mat').length + 1) + '#',
- content: 'https://cdn.weipaitang.com/img/202012147ystzory-b7hg-43vc-kg1g-goacjxmsbimr-W2415H2415/w/640',
- w: '100',
- h: '100',
- dx: dx + 15,
- dy: dy + 15,
- round: 'false'
- // align: 'both-align'
- })
- break
- case 'qr':
- _ele.push({
- content: '我是预览二维码',
- type: 'qr',
- t: '#qr_' + (this.state.element.filter(item => item.type === 'pic').length + 1) + '#',
- dx: dx + 15,
- dy: dy + 15,
- size: 140,
- logo: 'true'
- })
- break
- default:
- break
- }
- this.setState({element: _ele, activeObjectIndex: _ele.length - 1}, () => {
- // this.setState({ activeObjectIndex: this.state.element.length - 1 })
- })
- }
- save = () => {
- const {id, name, description, bg, element} = this.state
- const handleFun = id ? update : create
- element.map(item => {
- delete item.x
- delete item.y
- !item.fixed && (delete item.fixed)
- !item.relative && (delete item.relative)
- !item.group && (delete item.group)
- })
- handleFun({
- id,
- name,
- description,
- config: ([bg]).concat(element)
- }).then(res => {
- if (res.code === 0) {
- if (!id) {
- message.success('添加成功~')
- window.location.href = '/poster/edit/' + res.data.id
- } else {
- message.success('设置成功~')
- this.setState({
- imgs: [res.data.preview],
- previwVisible: true
- })
- }
- }
- })
- }
- // 动态的加载字体
- // loadFonts= async ()=> {
- // const font = new FontFace(
- // "font84",
- // "url(https://cdn.weipaitang.com/static/public/202012016ac3fed2-0fe8-fed20fe8-56d0-cdacb08d7de0.ttf)"
- // );
- // await font.load();
- // document.fonts.add(font);
- // document.body.classList.add("fonts-loaded");
- // }
- render() {
- const {
- bg: {w: bgWidth, h: bgHeight, c: bgColor},
- activeObjectIndex,
- element,
- name,
- description,
- imgs,
- previwVisible
- } = this.state
- const activeObject = element[activeObjectIndex] || {}
- const group = element.map(item => item.group)
- const _element = element.map((item, index) => ({...item, index: index}))
- // console.log('activeObject',activeObject);
- return (
- <div id="poster" style={{height: this.state.posterHeight, display: 'flex', flexDirection: 'column'}}>
- <div className={styles.header}>
- <span>模版:<Input style={{width: '200px'}} value={name} onChange={e => this.setState({name: e.target.value})}/></span>
- <span> 描述:<Input style={{width: '200px'}} value={description}
- onChange={e => this.setState({description: e.target.value})}/></span>
- <span>
- <Button onClick={() => this.setState({previwVisible: true})}>预览</Button>
- <Button type="primary" onClick={this.save}>保存</Button>
- </span>
- </div>
- <div className={styles.content}>
- <div className={styles.left}>
- <div className={styles.box}>
- <h2>背景</h2>
- <Form layout="vertical">
- <Form.Item label="宽度">
- <Input value={bgWidth} onChange={(e) => {
- this.updateBgState({w: Number.parseFloat(e.target.value || 0)})
- }}/>
- </Form.Item>
- <Form.Item label="高度">
- <Input value={bgHeight} onChange={(e) => {
- this.updateBgState({h: Number.parseFloat(e.target.value || 0)})
- }}/>
- </Form.Item>
- <Form.Item label="背景色">
- <div style={{width: '60px'}}>
- <RcColorPicker
- color={bgColor}
- onChange={({color}) => this.updateBgState({c: color})}
- >
- <Input/>
- </RcColorPicker>
- </div>
- </Form.Item>
- </Form>
- </div>
- <div className={styles.box}>
- <h2>元素</h2>
- <div style={{fontSize: 18, cursor: "pointer"}}>
- <Row>
- <Col span={12} onClick={() => this.addShape('text')}><IconFont type='iconwenben'/><span
- style={{display: 'inline-block', margin: 5}}>文本</span></Col>
- <Col span={12} onClick={() => this.addShape('pic')}><Icon type="picture"/><span
- style={{display: 'inline-block', margin: 5}}>图片</span></Col>
- <Col span={12} onClick={() => this.addShape('qr')}><Icon type="qrcode"/><span
- style={{display: 'inline-block', margin: 5}}>二维码</span></Col>
- <Col span={12} onClick={() => this.addShape('mat')}><IconFont type='iconsucai'/><span
- style={{display: 'inline-block', margin: 5}}>素材</span></Col>
- </Row>
- </div>
- {/* <ul className={styles.elem}>
- <li onClick={() => this.addShape('text')}><img src="https://cdn.weipaitang.com/static/20200416b0b57798-76f7-779876f7-9088-1d2665151e70-W200H200" />文字</li>
- <li className={styles.pic} onClick={() => this.addShape('pic')}><img src="https://cdn.weipaitang.com/static/20200416a625b5f0-c5a1-b5f0c5a1-7472-58fbb8d4fb83-W200H200"/>图片</li>
- <li className={styles.qr} onClick={() => this.addShape('qr')}><img src="https://cdn.weipaitang.com/static/20200416360ff7ff-c855-f7ffc855-0070-1542fd7ea01e-W200H200"/>二维码</li>
- </ul> */}
- </div>
- <div className={styles.box}>
- <h2>图层列表</h2>
- <ul className={styles.layer}>
- {
- unique(group).map((_item) => {
- console.log(_element, '_element');
- return <React.Fragment>
- <div>分组:{_item || '未分组'}</div>
- {
- _element.filter(item => item.group === _item).map((item, index) => (
- <li
- className={`${activeObjectIndex === item.index ? styles.selected : ''} ${styles[item.type]}`}
- onClick={() => this.setState({activeObjectIndex: item.index})}>
- <div className={styles.tem}
- style={{display: 'inline-block', verticalAlign: -2, backgroundColor: '#1890ff05'}}>
- {item.type === 'pic' && <Icon type="picture"/>}
- {item.type === 'mat' && <IconFont type="iconsucai"/>}
- {item.type === 'text' && <IconFont type="iconwenben"/>}
- {item.type === 'qr' && <Icon type="qrcode"/>}
- {item.isTemplate ? <IconFont type="iconmu"/> : <IconFont type="iconkongbai"/>}
- </div>
- {((item.type === 'pic' || item.type === 'mat') ? item.path : item.t || '').toString().replace(/#/g, '')}
- <Popover placement="right" content={<div><p onClick={() => this.setState({
- visible: true,
- editIndex: item.index,
- editType: item.type,
- editName: (item.type === 'pic' || item.type === 'mat') ? item.path : item.t || ''
- })}>重命名</p><p
- onClick={() => this.delElement(item.index, item.type === 'pic' ? item.path : item.t)}>删除</p>
- </div>}>
- <Icon type="setting" theme="filled"/>
- </Popover>
- </li>
- ))
- }
- </React.Fragment>
- })
- }
- </ul>
- </div>
- </div>
- <div className={styles.middle} onMouseEnter={() => {
- this.setState({canvasArea: true})
- }} onMouseLeave={() => {
- this.setState({canvasArea: false})
- }}>
- <div id="canvas" style={{
- position: 'relative',
- width: Number(bgWidth),
- height: Number(bgHeight),
- lineHeight: 1.3,
- backgroundColor: bgColor,
- marginBottom: '190px',
- margin: '0 auto'
- }}
- >
- {
- element.map((item, index) => {
- const clampLine = Number((Number(item.height) / Number(item.size)).toFixed(0)) - 1 || 1
- if (item.type === 'text') {
- return (
- <Rnd
- disableDragging={item.fixed}
- size={{width: Number.parseFloat(item.weight), height: Number.parseFloat(item.height)}}
- position={{x: item.dx, y: item.dy - item.size}}
- onDragStop={(e, d) => {
- this.updateElement(index, {dx: d.x, dy: d.y + item.size})
- }}
- onResizeStop={(e, direction, ref, delta, position) => { // 单击、双击文字框 出现白屏
- if (ref.style.width && ref.style.height) this.updateElement(index, {
- width: Number.parseFloat(ref.style.width || 0),
- height: Number.parseFloat(ref.style.height || 0), ...position
- })
- }}
- bounds="parent"
- className={
- activeObjectIndex === index ? styles.outline : ""
- }
- // enableResizing={{
- // top:false, right:true, bottom:false, left:false, topRight:false, bottomRight:false, bottomLeft:false, topLeft:false
- // }}
- >
- <div
- className={styles.textRnd}
- onClick={() =>
- this.setState({activeObjectIndex: index})
- }
- style={{
- WebkitLineClamp: clampLine,
- // width: item.float_x === 'center' ? (Number.parseFloat(bgWidth) - Number.parseFloat(item.dx)) + 'px' : (Number.parseFloat(item.width) || 'auto'),
- width: Number.parseFloat(item.width) || 'auto',
- height: Number.parseFloat(item.height) || 'auto',
- fontFamily: item.font,
- fontSize: item.size,
- color: item.c,
- opacity: item.opacity,
- position: 'relative',
- textAlign: item.float_x,
- writingMode: item.vertical && "vertical-lr",
- display: item.vertical && "inline-block" || item.float_x === 'center' && "inline-block",
- // left: (Number.parseFloat(bgWidth) - Number.parseFloat(item.dx) - Number.parseFloat(item.width)) / 2 + 'px'
- }}
- >
- {item.content}
- </div>
- </Rnd>
- );
- }
- if (item.type === 'pic' || item.type === 'mat') {
- return (
- <Rnd
- size={{width: Number.parseFloat(item.w), height: Number.parseFloat(item.h)}}
- position={{x: item.dx, y: item.dy}}
- onDragStop={(e, d) => {
- this.updateElement(index, {dx: d.x, dy: d.y})
- }}
- onResizeStop={(e, direction, ref, delta, position) => {
- this.updateElement(index, {
- w: Number.parseFloat(ref.style.width),
- h: Number.parseFloat(ref.style.height), ...position
- })
- }}
- bounds="parent"
- className={activeObjectIndex === index ? styles.outline : ''}
- >
- <div
- onClick={() => this.setState({activeObjectIndex: index})}
- style={{
- backgroundRepeat: 'no-repeat',
- backgroundSize: 'cover',
- backgroundImage: `url(${item.content})`,
- backgroundPosition: (item.align === 'horizontal-align') ? 'top center' : (item.align === 'vertical-align' ? 'center left' : 'center center'),
- width: Number.parseFloat(item.w || 0) + 'px',
- height: Number.parseFloat(item.h || 0) + 'px',
- borderRadius: ((item.round || '').toString() === 'true') ? '100%' : (`${item.corner || 0}px ${item.corner || 0}px` || 0),
- filter: `blur(${(item.gauss || '').split(',')[0] / 2}px)`
- }}
- >
- </div>
- </Rnd>
- )
- }
- if (item.type === 'qr') {
- console.log(item)
- return (
- <Rnd
- size={{width: Number.parseFloat(item.size), height: Number.parseFloat(item.size)}}
- position={{x: item.dx, y: item.dy}}
- onDragStop={(e, d) => {
- this.updateElement(index, {dx: d.x, dy: d.y})
- }}
- onResizeStop={(e, direction, ref, delta, position) => {
- this.updateElement(index, {size: Number.parseFloat(ref.style.width), ...position})
- }}
- bounds="parent"
- className={activeObjectIndex === index ? styles.outline : ''}
- >
- {/*<div*/}
- {/* onClick={() => this.setState({activeObjectIndex: index})}*/}
- {/* style={{*/}
- {/* backgroundRepeat: 'no-repeat',*/}
- {/* backgroundSize: 'cover',*/}
- {/* backgroundImage: `url(${item.logo === 'wpt_high' || item.logo === 'youjiang' || item.logo === 'cl'*/}
- {/* ? (item.logo === 'wpt_high'*/}
- {/* ? 'https://cdn.weipaitang.com/static/20200413eb9effec-3871-ffec3871-cd41-baed9e98535e-W200H200'*/}
- {/* : 'https://cdn.weipaitang.com/static/202004141c0b320a-9cdc-320a9cdc-d090-e4b5964fee9d-W200H200')*/}
- {/* : 'https://cdn.weipaitang.com/static/20200413d4263aa5-6423-3aa56423-4e8d-a96e1d9d93f3-W200H200'})`,*/}
- {/* width: Number.parseFloat(item.size || '0') + 'px',*/}
- {/* height: Number.parseFloat(item.size || '0') + 'px'*/}
- {/* }}*/}
- {/*>*/}
- {/*</div>*/}
- <div
- onClick={() => this.setState({activeObjectIndex: index})}
- style={{
- backgroundRepeat: 'no-repeat',
- backgroundSize: 'cover',
- backgroundImage: this.changeQrLogo(item.logo),
- width: Number.parseFloat(item.size || '0') + 'px',
- height: Number.parseFloat(item.size || '0') + 'px'
- }}
- >
- </div>
- </Rnd>
- )
- }
- })
- }
- </div>
- </div>
- <div className={styles.right}>
- {
- activeObject.type === 'text' && (
- <div className={styles.box}>
- <h2>
- <span>文字</span>
- <span style={{float: 'right', fontSize: 14}}>
- <span style={{marginRight: 5}}>设置为模板</span>
- <Switch checked={activeObject.isTemplate || false}
- onChange={(checked) => this.updateElement(activeObjectIndex, {isTemplate: checked})}/>
- </span>
- </h2>
- <Form layout="vertical">
- <Form.Item label="内容">
- <Input.TextArea rows={3} value={activeObject.content}
- onChange={(e) => this.updateElement(activeObjectIndex, {content: e.target.value})}/>
- </Form.Item>
- <Form.Item label="字体">
- <Select value={activeObject.font}
- onChange={(value) => this.updateElement(activeObjectIndex, {font: value})}>
- {(this.state.fontList || []).map(item => {
- return <Option value={item.value}>{item.option}</Option>
- })}
- </Select>
- </Form.Item>
- <div style={{display: 'flex'}}>
- <Form.Item label="字体大小" style={{flex: 1}}>
- <InputNumber style={{width: 80}} min={12} max={100} value={activeObject.size}
- onChange={(value) => this.updateElement(activeObjectIndex, {size: value})}/>
- </Form.Item>
- <Form.Item label="字体颜色" style={{flex: 1}}>
- <div style={{width: '60px'}}
- >
- <RcColorPicker
- color={activeObject.c}
- onChange={({color}) => this.updateElement(activeObjectIndex, {c: color})}
- >
- <Input/>
- </RcColorPicker>
- </div>
- </Form.Item>
- </div>
- <div style={{display: 'flex'}}>
- <Form.Item label="X偏移" style={{flex: 1}}>
- <InputNumber style={{width: 80}} value={activeObject.dx}
- onChange={(value) => this.updateElement(activeObjectIndex, {dx: value})}/>
- </Form.Item>
- <Form.Item label="Y偏移" style={{flex: 1}}>
- <InputNumber style={{width: 80}} value={activeObject.dy}
- onChange={(value) => this.updateElement(activeObjectIndex, {dy: value})}/>
- </Form.Item>
- </div>
- <div style={{display: 'flex'}}>
- <Form.Item label="文字宽度" style={{flex: 1}}>
- <InputNumber value={activeObject.width} style={{width: 80}}
- onChange={(value) => this.updateElement(activeObjectIndex, {width: value})}/>
- </Form.Item>
- <Form.Item label="文字高度" style={{flex: 1}}>
- <InputNumber value={activeObject.height} style={{width: 80}}
- onChange={(value) => this.updateElement(activeObjectIndex, {height: value})}/>
- </Form.Item>
- </div>
- <div style={{display: 'flex'}}>
- <Form.Item label="X居中" style={{flex: 1}}>
- <Select value={activeObject.float_x || ""} style={{width: 80}}
- onChange={(value) => this.updateElement(activeObjectIndex, {float_x: value})}>
- <Option value="">不居中</Option>
- <Option value="center">居中</Option>
- {/* <Option value="right">right</Option> */}
- <Option value="left">居左</Option>
- </Select>
- </Form.Item>
- <Form.Item label="文字垂直" style={{flex: 1}}>
- <Switch
- checked={activeObject.vertical}
- onChange={(checked) => this.updateElement(activeObjectIndex, {vertical: checked})}
- checkedChildren="开"
- unCheckedChildren="关"
- />
- </Form.Item>
- </div>
- <Form.Item label="不透明">
- <Slider
- min={0}
- max={1}
- step="0.1"
- onChange={(value) => this.updateElement(activeObjectIndex, {opacity: value})}
- value={activeObject.opacity}
- />
- </Form.Item>
- <div style={{display: 'flex'}}>
- <Form.Item label="固定位置" style={{flex: 1}}>
- <Switch
- checked={activeObject.fixed}
- onChange={(checked) => this.updateElement(activeObjectIndex, {fixed: checked})}
- checkedChildren="开"
- unCheckedChildren="关"
- />
- </Form.Item>
- <Form.Item label="浮动位置" style={{flex: 1}}>
- <Switch
- checked={activeObject.relative}
- onChange={(checked) => this.updateElement(activeObjectIndex, {relative: checked})}
- checkedChildren="开"
- unCheckedChildren="关"
- />
- </Form.Item>
- </div>
- <Form.Item label="分组" style={{flex: 1}}>
- <InputNumber
- style={{width: 100}}
- value={activeObject.group}
- onChange={(value) => this.updateElement(activeObjectIndex, {group: value || undefined})}
- />
- </Form.Item>
- </Form>
- </div>
- )
- }
- {
- activeObject.type === 'qr' && (
- <div className={styles.box}>
- <h2>
- <span>二维码</span>
- <span style={{float: 'right', fontSize: 14}}>
- <span style={{marginRight: 5}}>设置为模版</span>
- <Switch checked={activeObject.isTemplate || false}
- onChange={(checked) => this.updateElement(activeObjectIndex, {isTemplate: checked})}/>
- </span>
- </h2>
- <Form layout="vertical">
- <Form.Item label="内容">
- <Input value={activeObject.content}
- onChange={(e) => this.updateElement(activeObjectIndex, {content: e.target.value})}/>
- </Form.Item>
- <div style={{display: 'flex'}}>
- <Form.Item label="X偏移" style={{flex: 1}}>
- <InputNumber style={{width: 80}} value={activeObject.dx}
- onChange={(value) => this.updateElement(activeObjectIndex, {dx: value})}/>
- </Form.Item>
- <Form.Item label="Y偏移" style={{flex: 1}}>
- <InputNumber style={{width: 80}} value={activeObject.dy}
- onChange={(value) => this.updateElement(activeObjectIndex, {dy: value})}/>
- </Form.Item>
- </div>
- <Form.Item label="LOGO">
- <Switch
- checked={activeObject.logo === 'wpt_high' || activeObject.logo === 'youjiang' || activeObject.logo === 'cl'}
- onChange={(checked) => this.updateElement(activeObjectIndex, {logo: checked ? 'wpt_high' : false})}
- checkedChildren="开"
- unCheckedChildren="关"
- />
- {
- (activeObject.logo === 'wpt_high' || activeObject.logo === 'youjiang' || activeObject.logo === 'cl') && (
- <Select value={activeObject.logo} style={{width: 120, marginLeft: '5px'}}
- onChange={value => this.updateElement(activeObjectIndex, {logo: value})}>
- <Option value="wpt_high">微拍堂</Option>
- <Option value="youjiang">有匠</Option>
- <Option value="cl">彩礼</Option>
- </Select>
- )
- }
- </Form.Item>
- <Form.Item label="大小">
- <InputNumber style={{width: 100}} value={activeObject.size}
- onChange={(value) => this.updateElement(activeObjectIndex, {size: value})}/>
- </Form.Item>
- <div style={{display: 'flex'}}>
- <Form.Item label="固定位置" style={{flex: 1}}>
- <Switch
- checked={activeObject.fixed}
- onChange={(checked) => this.updateElement(activeObjectIndex, {fixed: checked})}
- checkedChildren="开"
- unCheckedChildren="关"
- />
- </Form.Item>
- <Form.Item label="浮动位置" style={{flex: 1}}>
- <Switch
- checked={activeObject.relative}
- onChange={(checked) => this.updateElement(activeObjectIndex, {relative: checked})}
- checkedChildren="开"
- unCheckedChildren="关"
- />
- </Form.Item>
- </div>
- <Form.Item label="分组" style={{flex: 1}}>
- <InputNumber
- style={{width: 100}}
- value={activeObject.group}
- onChange={(value) => this.updateElement(activeObjectIndex, {group: value || undefined})}
- />
- </Form.Item>
- </Form>
- </div>
- )
- }
- {
- (activeObject.type === 'pic' || activeObject.type === 'mat') && (
- <div className={styles.box}>
- <h2>
- <span>{activeObject.type === 'pic' ? "图片" : "素材"}</span>
- <span style={{float: 'right', fontSize: 14}}>
- <span style={{marginRight: 5}}>设置为模板</span>
- <Switch checked={activeObject.isTemplate || false}
- onChange={(checked) => this.updateElement(activeObjectIndex, {isTemplate: checked})}/>
- </span>
- </h2>
- <Form layout="vertical">
- <Form.Item label="路径">
- <Input value={activeObject.content}
- onChange={(e) => this.updateElement(activeObjectIndex, {content: e.target.value})}/>
- </Form.Item>
- <div style={{display: 'flex'}}>
- <Form.Item label="宽" style={{flex: 1}}>
- <InputNumber style={{width: 80}} value={activeObject.w}
- onChange={(value) => this.updateElement(activeObjectIndex, {w: value})}/>
- </Form.Item>
- <Form.Item label="高" style={{flex: 1}}>
- <InputNumber style={{width: 80}} value={activeObject.h}
- onChange={(value) => this.updateElement(activeObjectIndex, {h: value})}/>
- </Form.Item>
- </div>
- <div style={{display: 'flex'}}>
- <Form.Item label="X偏移" style={{flex: 1}}>
- <InputNumber style={{width: 80}} value={activeObject.dx}
- onChange={(value) => this.updateElement(activeObjectIndex, {dx: value})}/>
- </Form.Item>
- <Form.Item label="Y偏移" style={{flex: 1}}>
- <InputNumber style={{width: 80}} value={activeObject.dy}
- onChange={(value) => this.updateElement(activeObjectIndex, {dy: value})}/>
- </Form.Item>
- </div>
- <div style={{display: 'flex'}}>
- <Form.Item label="圆形" style={{flex: 1}}>
- <Switch checked={(activeObject.round || '').toString() === 'true'} onChange={(checked) => {
- if (checked) {
- this.updateElement(activeObjectIndex, {round: 'true'})
- } else {
- this.updateElement(activeObjectIndex, {round: 'false'})
- }
- }} checkedChildren="开" unCheckedChildren="关"/>
- </Form.Item>
- <Form.Item label="圆角" style={{flex: 1}}>
- <Input
- placeholder="圆角半径"
- style={{width: 100}}
- value={activeObject.corner}
- onChange={(e) => this.updateElement(activeObjectIndex, {corner: e.target.value})}
- />
- </Form.Item>
- </div>
- <Form.Item label="高斯模糊">
- <Input
- value={activeObject.gauss}
- onChange={(e) => this.updateElement(activeObjectIndex, {gauss: e.target.value})}
- />
- </Form.Item>
- <Form.Item label="图片裁剪选项">
- {activeObject.align}
- <Select value={activeObject.align}
- onChange={(value) => this.updateElement(activeObjectIndex, {align: value})}>
- <Option value="">为空不选</Option>
- <Option value="vertical-align">垂直居中</Option>
- <Option value="horizontal-align">水平居中</Option>
- <Option value="both-align">垂直水平居中</Option>
- </Select>
- </Form.Item>
- <div style={{display: 'flex'}}>
- <Form.Item label="固定位置" style={{flex: 1}}>
- <Switch
- checked={activeObject.fixed}
- onChange={(checked) => this.updateElement(activeObjectIndex, {fixed: checked})}
- checkedChildren="开"
- unCheckedChildren="关"
- />
- </Form.Item>
- <Form.Item label="浮动位置" style={{flex: 1}}>
- <Switch
- checked={activeObject.relative}
- onChange={(checked) => this.updateElement(activeObjectIndex, {relative: checked})}
- checkedChildren="开"
- unCheckedChildren="关"
- />
- </Form.Item>
- {activeObject.type === 'pic' && <Form.Item label="使用原图" style={{flex: 1}}>
- <Switch
- checked={activeObject.original}
- onChange={(checked) => this.updateElement(activeObjectIndex, {original: checked})}
- checkedChildren="开"
- unCheckedChildren="关"
- />
- </Form.Item>}
- </div>
- <Form.Item label="分组" style={{flex: 1}}>
- <InputNumber
- style={{width: 100}}
- value={activeObject.group}
- onChange={(value) => this.updateElement(activeObjectIndex, {group: value || undefined})}
- />
- </Form.Item>
- </Form>
- </div>
- )
- }
- </div>
- </div>
- <Modal
- title="重命名"
- visible={this.state.visible}
- onOk={() => {
- this.updateElement(this.state.editIndex, {[(this.state.editType === 'pic' || this.state.editType === 'mat') ? 'path' : 't']: '#' + this.state.editName + '#'})
- this.setState({visible: false})
- }}
- onCancel={() => this.setState({visible: false})}
- >
- <Input value={this.state.editName.replace(/#/g, '')}
- onChange={e => this.setState({editName: e.target.value})}/>
- </Modal>
- <ImagePreview
- images={imgs}
- visible={previwVisible}
- onClose={() => {
- this.setState({previwVisible: false})
- }}
- />
- </div>
- )
- }
- }
|