前言:
而今姐妹们对“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 }); } }