/** * 钟是志 * 2020年5月28日 18:15:56 * 通过绑定3个事件 鼠标down 鼠标move 鼠标up 实现拖到 * 在down 的时候 注册 哪个配置项被点击 * 在move 的时候 计算偏移量 让鼠标的偏移量 和 配置项dom的偏移量一致 * 在up 的时候 更新元素dom的新位置到props * */ import React, { Component, Fragment } from 'react'; import styles from './index.less'; import { InputNumber } from 'antd'; import { imageStyleAll, A4Height, A4Width, styleCount } from './ViewPrint/config'; let domIdTemp = ''; const HandleDetailFunction = ({ isDownObj, updateOnePostion, config }) => { for (let item in isDownObj) { if (isDownObj[item]) { domIdTemp = item; } } if (!domIdTemp) { return null; } const id = domIdTemp.replace('dragKey-', ''); const itemConfig = config.find((y) => { return y.id + '' === id; }); const dom = document.getElementById(domIdTemp); const x = itemConfig.x; const y = itemConfig.y; if(!dom){ return null; } return <Fragment> <span dangerouslySetInnerHTML={{ __html: dom.innerHTML }}/> <span> 偏移量(x,y)</span> <InputNumber precision={0} onChange={(value) => { updateOnePostion({ id, x: value, y }); }} value={x}/> <InputNumber precision={0} onChange={(value) => { updateOnePostion({ id, y: value, x }); }} value={y}/> </Fragment>; }; export default class Index extends Component { constructor(props) { super(props); this.time1 = new Date().getTime(); this.state = { isDownObj: {}, drag: { objX: '0px', objY: '0px', mouseY: 0, mouseX: 0, }, }; } handleOnMouseDown = (e, id) => { // 鼠标按钮 按下 const div = document.getElementById(id); const { isDownObj } = this.state; const newDrag = { objX: div.style.left, objY: div.style.top, mouseX: e.clientX, mouseY: e.clientY, }; for (let item in isDownObj) { isDownObj[item] = false; } isDownObj[id] = true; this.setState({ drag: newDrag, isDownObj, }); }; handleOnMouseMove = (e) => { // 鼠标 移动 const { drag, isDownObj } = this.state; if (new Date().getTime() - this.time1 < 17) { this.time1 = new Date().getTime(); return false; } let id = ''; for (let item in isDownObj) { if (isDownObj[item]) { id = item; } } if (!id) { return false; } let { mouseX, mouseY, objX, objY } = drag; const div = document.getElementById(id); let x = e.clientX; let y = e.clientY; if (isDownObj && isDownObj[id]) { const styleLeft = parseInt(objX, 10) + parseInt(x, 10) - parseInt(mouseX, 10); // 计算偏移量 const styleTop = parseInt(objY, 10) + parseInt(y, 10) - parseInt(mouseY, 10); // 计算偏移量 const dropZone = document.getElementById('dropZone'); if ( // 阻止拖拽到图片外部 styleLeft > dropZone.width - 15 || (styleLeft < 15) || (styleTop > dropZone.height - 15) || styleTop < 15 ) { console.error('拖拽到了图片区域外部,不能进行拖拽'); return false; } div.style.left = styleLeft + 'px'; div.style.top = styleTop + 'px'; } }; updateOnePostion = ({ id, x, y }) => { const { updateConfig } = this.props; updateConfig({ id, x, y, }); }; handleOnMouseUp = (e, id) => { // 鼠标 按钮 收起 更新数据到props const { drag, isDownObj } = this.state; let { mouseX, mouseY, objX, objY } = drag; if (isDownObj[id]) { let x = e.clientX; let y = e.clientY; let div = document.getElementById(id); const styleLeft = parseInt(x, 10) - parseInt(mouseX, 10) + parseInt(objX, 10); const styleTop = parseInt(y, 10) - parseInt(mouseY, 10) + parseInt(objY, 10); div.style.left = `${styleLeft}px`; div.style.top = `${styleTop}px`; mouseX = x; mouseY = y; const { updateConfig } = this.props; updateConfig({ id: id.replace('dragKey-', ''), x: styleLeft, y: styleTop, }); this.setState({ drag: { mouseX, mouseY, objX, objY, }, isDownObj: {}, }); } }; render() { const { backgroundUrl, configAll: { config, wide, high }, } = this.props; const { isDownObj } = this.state; const imageStyle = { height: `${high}cm` || A4Height, width: `${wide}cm` || A4Width, }; return ( <div className={styles.outSideDiv}> <div style={{ marginLeft: '45%', height: '100px' }}> <HandleDetailFunction isDownObj={isDownObj} config={config} updateOnePostion={this.updateOnePostion} /> </div> <div onMouseMove={(e) => { this.handleOnMouseMove(e); }} style={{ ...imageStyle, position: 'relative', }}> <img src={backgroundUrl} id={'dropZone'} draggable={false} className={styles.bgimage} style={imageStyleAll} alt={'背景图'} /> {config.map((item, index) => { const domId = `dragKey-${item.id}`; return ( <div draggable={false} className={styles.inSideItem} key={item.id} onMouseDown={(e) => { this.handleOnMouseDown(e, domId); console.log(domId); }} onMouseUp={(e) => { this.handleOnMouseUp(e, domId); }} id={domId} style={{ top: `${item.y || 20 + index * 40}px`, left: `${item.x || 20}px`, }}> <span style={{ ...styleCount(item), fontWeight: 'bold', }}> {item.title} </span> </div> ); })} </div> </div> ); } }