龙空技术网

React:拖拽既可改变容器的大小又可改变容器的位置

烦恼一一 67

前言:

而今姐妹们对“react const let”大体比较看重,小伙伴们都想要了解一些“react const let”的相关资讯。那么小编在网络上搜集了一些对于“react const let””的相关内容,希望姐妹们能喜欢,咱们一起来了解一下吧!

re-resizable组件提供了8个方向(上(top)、下(bottom)、左(left)、右(right)、左上(leftTop)、右上(rightTop)、右下(rightBottom)、左下(leftBottom))上的拉伸操作,但无论从哪个方向上拉伸效果都是可视容器的原点(x:0,y:0)固定,然后沿着横轴和纵轴拉伸或缩放,但有的场景需要可视容器要离开原点位置,例如像窗口一样的拖到效果,即在任何一个方向拖动都是顺着鼠标拖动方向改变大小的。

基本思路:

原点固定相当于容器的left和top是固定的,那我们可以控制可视容器的样式,控制它在横轴和纵轴上的偏移,这就要用到transform样式属性.

先上代码

import React,{Component} from 'react';import ReactDOM from 'react-dom';import {Resizable} from 're-resizable';interface Position {    x:number;    y:number;}interface BaseReferProps {    }interface BaseReferInnerProps {    resizePosition?:Position;}class BaseRefer extends Component<BaseReferProps,BaseReferInnerProps> {    position:Position | null;    constructor(props:BaseReferProps){        super(props);        this.state ={}        this.position = null;        this.onResize = this.onResize.bind(this);		this.onResizeStop = this.onResizeStop.bind(this);    }    /**	 * @param e {object} 事件源	 * @param direction {string} 拖动方向	 * @param ref {dom} 拖动的元素	 * @param d {object} 移动偏移量	 */	onResize(e:any, direction:any, ref:any, d:any) {		let { resizePosition } = this.state;		/* resize 之前的值 */		let originX = resizePosition?resizePosition.x:0;		let originY = resizePosition?resizePosition.y:0;		/* 移动的位移 */		let moveW = d.width;		let moveH = d.height;		/* 移动的位移 */		let x = null;		let y = null;		/* 处理上边缘 */		if (/left/i.test(direction)) {			x = originX - moveW;			y = originY;			this.position = { x, y };			/* 处理左边缘 */		} else if (/top/i.test(direction)) {			x = originX;			y = originY - moveH;			this.position = { x, y };		} else {			this.position = null;		}		if (x || y) {			ref.style.transform = `translate(${x}px, ${y}px)`;		}	}    onResizeStop(e:any, direction:any, ref:any, d:any) {		if (this.position) {			this.setState({				resizePosition: this.position			});		}	}    render(): React.ReactNode {        const referPopContainer: React.CSSProperties = {            top: 0,            left: 0,            overflow: 'auto',            position: 'fixed',            height: '100%',            width: '100%',            alignItems:'center',            flexDirection: 'column',            zIndex: 300,            backgroundColor:'rgba(0, 0, 0, 0.5)',        }                return <>            {ReactDOM.createPortal(                <div style={referPopContainer}>                    <Resizable                         style={{background:'red'}}                         onResize={this.onResize}                        onResizeStop={this.onResizeStop}                        defaultSize={{width: 400,height:400}}                        >                        hello.                    </Resizable>                </div>,                document.body                )             }        </>    }}export default BaseRefer;

可视容器初始化大小宽高各400,在不提供onResize、onResizeStop方法的时候Resizable无论网哪个方向拖拽原点都是不动的,如下图:

初始位置

视频加载中...

下面是提供onResize、onResizeStop方法的效果

视频加载中...

直接从重点开始讲起,看下面代码:

<div style={referPopContainer}>    <Resizable 	style={{background:'red'}} 	onResize={this.onResize}	onResizeStop={this.onResizeStop}	defaultSize={{width: 400,height:400}}	>	hello.    </Resizable></div>,

外层div是作为可视容器外包的一层,它受样式类referPopContainer的控制,fixed固定位置,left,top都是0固定在容器的原点,高度和宽度都是100%,调用ReactDOM.createPortal方法时父容器指定的是document.body,左右它会充满整个body。

onResize方法:

当鼠标进行拖动时,会调用该方法,其中第4个参数会传递拖拽的位移,根据该位移可以计算可视化容器的平移大小。第3个参数为可视化容器的引用,通过其可以改变它的样式(ref.style.transform = `translate(${x}px, ${y}px)`;)

因为可视容器的left,top是不变的我们只控制它的平移,所以只关心逻辑上需要引起left,top会发生变化的方向,

this.position记录拖拽后的最终偏移量。

/**	 * @param e {object} 事件源	 * @param direction {string} 拖动方向	 * @param ref {dom} 拖动的元素	 * @param d {object} 移动偏移量	 */	onResize(e:any, direction:any, ref:any, d:any) {		let { resizePosition } = this.state;		/* resize 之前的值 */		let originX = resizePosition?resizePosition.x:0;		let originY = resizePosition?resizePosition.y:0;		/* 移动的位移 */		let moveW = d.width;		let moveH = d.height;		/* 移动的位移 */		let x = null;		let y = null;		/* 处理上边缘 */		if (/left/i.test(direction)) {			x = originX - moveW;			y = originY;			this.position = { x, y };			/* 处理左边缘 */		} else if (/top/i.test(direction)) {			x = originX;			y = originY - moveH;			this.position = { x, y };		} else {			this.position = null;		}		if (x || y) {			ref.style.transform = `translate(${x}px, ${y}px)`;		}	}

onResizeStop方法

当鼠标拖拽松开后触发,主要记录本次的偏移量,再进行拖放操作的时候根据上一次的偏移量进行计算。

onResizeStop(e:any, direction:any, ref:any, d:any) {		if (this.position) {			this.setState({				resizePosition: this.position			});		}	}

标签: #react const let #react引用css文件 #react局部css