React 实现拖动缩放和旋转效果

本文介绍如何在React应用中实现选择框的拖动、缩放和旋转功能,详细阐述了针对框内元素如视频、文字、图片等内容进行操作的方法,包括通过四个控制点进行缩放和旋转后的坐标修正。

 用React框架实现了选择框的操作,可以通过4个点缩放框内的视频、文字、图片等内容,旋转后自动修订坐标点。

import React from 'react';
import ReactDOM from 'react-dom';

const rightDown = {
    position: "absolute",
    background: "#000000",
    width: "10px",
    height: "10px",
    zIndex: 5,
    fontSize: 0,
    cursor: "nw-resize",
    right: "-4px",
    bottom: "-4px"
}

const leftDown = {
    position: "absolute",
    background: "#000000",
    width: "10px",
    height: "10px",
    zIndex: 5,
    fontSize: 0,
    cursor: "ne-resize",
    left: "-4px",
    bottom: "-4px"
}

const rightUp = {
    position: "absolute",
    background: "#000000",
    width: "10px",
    height: "10px",
    zIndex: 5,
    fontSize: 0,
    cursor: "ne-resize",
    right: "-4px",
    top: "-4px"
}

const leftUp = {
    position: "absolute",
    background: "#000000",
    width: "10px",
    height: "10px",
    zIndex: 5,
    fontSize: 0,
    cursor: "nw-resize",
    left: "-4px",
    top: "-4px"
}

const right = {
    position: "absolute",
    background: "#000000",
    width: "10px",
    height: "10px",
    zIndex: 5,
    fontSize: 0,
    cursor: "e-resize",
    right: "-4px",
    top: "50%",
    marginTop: "-4px"
}

const left = {
    position: "absolute",
    background: "#000000",
    width: "10px",
    height: "10px",
    zIndex: 5,
    fontSize: 0,
    cursor: "e-resize",
    left: "-4px",
    top: "50%",
    marginTop: "-4px"
}

const up = {
    position: "absolute",
    background: "#000000",
    width: "10px",
    height: "10px",
    zIndex: 5,
    fontSize: 0,
    cursor: "n-resize",
    top: "-4px",
    left: "50%",
    marginLeft: "-4px"
}

const down = {
    position: "absolute",
    background: "#000000",
    width: "10px",
    height: "10px",
    zIndex: 5,
    fontSize: 0,
    cursor: "n-resize",
    bottom: "-4px",
    left: "50%",
    marginLeft: "-4px"
}



class JDrag extends React.Component {

    constructor(props) {
        super(props)
        this.state = {
            top: this.props.x,
            left: this.props.y,
            width: this.props.width,
            height: this.props.height,
            rotate: this.props.rotate,
            isZoom: false,
            isDrag: false,
        }
        this.clickId = "";
		this.buttonArray = ['rightDown', 'leftDown', 'rightUp', 'leftUp']
		console.log(this.buttonArray)
    }

    onmousedown = (e) => {
        this.setState({
            isDrag: true
        })
		console.log(this.state.left + ":" + this.state.top)
        e.stopPropagation()
        e.nativeEvent.stopPropagation()
        e.nativeEvent.stopImmediatePropagation()
        console.log("onmousedown")
    }

    onmousemove = (e) => {
        e.nativeEvent.stopPropagation()
        if (this.state.isDrag) {
            let width = Number(this.state.width.replace("px", ""))
            let height = Number(this.state.height.replace("px", ""))
            this.setState({
                left: e.clientX - width / 2,
                top: e.clientY - height / 2,
            })
        }
    }

    onmouseup = (e) => {
        this.setState({
            isDrag: false
        })
        e.nativeEvent.stopPropagation()
    }

    onDragDown = (e) => {
        e.stopPropagation()
        this.setState({
            isZoom: true
        })
        let width = Number(this.state.width.replace("px", ""))
        let height = Number(this.state.height.replace("px", ""))
		
        this.sideLeft = e.clientX - width
        this.sideRight = e.clientX + width
        this.sideUp = e.clientY - height
        this.sideDown = e.clientY + height
        this.fixLeft = this.styleLeft + this.styleWidth;
        this.fixTop = this.styleTop + this.styleHeight;
        this.clickId = e.currentTarget.id;
        this.clickPos = e.clientX
    }

    onDragMove = (e) => {
        if (this.state.isZoom) {
            switch (this.clickId) {
                case "right": {
					console.log(e.clientX + ":" + (e.clientX - this.sideLeft))
                    let x = e.clientX - this.sideLeft
                    this.setState({
                        width: x + "px"
                    })
                    break
                }
                case "left": {
                    let x = this.sideRight - e.clientX
                    this.setState({
                        width: x + "px",
                        left: e.clientX + "px"
                    })
                    break
                }
                case "up": {
                    let y = this.sideDown - e.clientY
                    this.setState({
                        height: y + "px",
                        top: e.clientY
                    })
                    break
                }
                case "down": {
                    let y = e.clientY - this.sideUp
                    this.setState({
                        height: y + "px"
                    })
                    break
                } 

                case "rightDown": {
                    let x = e.clientX - this.sideLeft
                    let y = e.clientY - this.sideUp
                    this.setState({
                        width: x + "px",
                        height: y + "px"
                    })  
                    break
                }
                case "leftDown": {
                    let x = this.sideRight - e.clientX
                    let y = e.clientY - this.sideUp
                    this.setState({
                        width: x + "px",
                        height: y + "px",
                        left: e.clientX
                    })
                    break
                }
                case "rightUp": {
                    let x = e.clientX - this.sideLeft
                    let y = this.sideDown - e.clientY
                    this.setState({
                        width: x + "px",
                        height: y + "px",
                        top: e.clientY + "px"
                    })
                    break
                }
                case "leftUp": {
                    let x = this.sideRight - e.clientX
                    let y = this.sideDown - e.clientY
                    this.setState({
                        width: x + "px",
                        height: y + "px",
                        left: e.clientX + "px",
                        top: e.clientY + "px"
                    })
                    break
                }
                case "rotate": {
					console.log(this.state.rotate)
                    let rotate = this.state.rotate
                    if(e.clientX < this.clickPos) {
                        rotate++;

                    }
                    if(e.clientX > this.clickPos) {
                        rotate--;
                    }
					
					switch(rotate) {
						case 45:{
							this.buttonArray = ['leftDown',  'leftUp', 'rightDown', 'rightUp']
							break;
						} 
						case -90:{
							this.buttonArray = ['rightUp','rightDown', 'leftUp', 'leftDown']
							break;
						}
						case 135:{
							this.buttonArray = ['leftUp', 'rightUp', 'leftDown','rightDown']
							break;
						}
						case -180:{
							this.buttonArray = ['leftUp', 'rightUp', 'leftDown','rightDown']
							break;
						}
						case 225:{
							this.buttonArray = ['rightUp', 'rightDown', 'leftUp', 'leftDown']
							break;
						}
						case -270:{
							this.buttonArray = ['leftDown', 'leftUp', 'rightDown', 'rightUp']
							break;
						}
						case 315:{
							this.buttonArray =  ['rightDown', 'leftDown', 'rightUp', 'leftUp']
							break;
						}
					}
					if(rotate >= 360) {
						rotate = 0;
					}
                    this.setState({
                        rotate:rotate
                    })
                   
                    break
                }
            }
        }
    }

    onDragUp = (e) => {
        this.setState({
            isZoom: false
        })
        e.nativeEvent.stopPropagation()
    }

    render = () => {
        const draDiv = {
            border: "1px solid #000000",
            width: this.state.width,
            height: this.state.height,
            top: this.state.top,
            left: this.state.left,
            background: "#fff",
            position: "absolute",
            transform: "rotate(" + this.state.rotate + "deg)"
			
        }

        const rotate = {
            position: "absolute",
            background: "url(./assetRotate.svg) 50% no-repeat",
            width: "28px",
            height: "28px",
            zIndex: 5,
            fontSize: 0,
            cursor: "e-resize",
            bottom:"-35px",
			left:"50%",
			marginLeft:"-14px"
        }
        

        const stage = {
            border: "5px solid #000000",
            background: "#F5F5F5",
            width: "1920px",
            height: "1080px"
        }

        return <div id="stage" style={stage} onMouseMove={this.state.isZoom ? this.onDragMove : undefined} onMouseUp={this.state.isZoom ? this.onDragUp : undefined}>
                <div id="dragDiv" style={draDiv} onMouseDown={this.onmousedown} onMouseMove={this.state.isDrag ? this.onmousemove : undefined} onMouseUp={this.state.isDrag ? this.onmouseup : undefined}>   
					<button id={this.buttonArray[0]} style={rightDown} onMouseDown={this.onDragDown}> </button>
					<button id={this.buttonArray[1]} style={leftDown} onMouseDown={this.onDragDown}> </button>
					<button id={this.buttonArray[2]} style={rightUp} onMouseDown={this.onDragDown}> </button>
					<button id={this.buttonArray[3]} style={leftUp} onMouseDown={this.onDragDown}> </button>
                <div id="rotate" style={rotate} onMouseDown={this.onDragDown}></div>
                <video autoplay="autoplay" loop="loop" muted="muted" width={this.state.width} height={this.state.height}>
							<source src="http://127.0.0.1/app/res/1.mp4" type="video/mp4"/>
				</video>
            </div>
        </div>

    }

}
export default JDrag;

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值