3-10 实现拖拽缩放盒子的效果

需求讲解

画一个矩形,拖拽矩形的4个角可以将矩形缩放(缩小到顶点时,顶点需要固定),在矩形上按住拖动,可以移动该矩形的位置

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .outer {
            /* 默认宽度 */
            width: 200px;
            height: 200px;
            border: 1px solid black;
            position: absolute;
        }
        .outer:hover {
            cursor: move;
        }
        .outer .it{
            position: absolute;
            width: 8px;
            height: 8px;
            display: block;
            border: 1px solid black;
            background-color: #fff;
        }
        .outer .it:nth-child(1) {
            top: 0;
            left: 0;
            transform: translateX(-50%) translateY(-50%);
        }
        .outer .it:nth-child(2) {
            top: 0;
            right: 0;
            transform: translateX(50%) translateY(-50%);
        }
        .outer .it:nth-child(3) {
            left: 0;
            bottom: 0;
            transform: translateX(-50%) translateY(50%);
        }
        .outer .it:nth-child(4) {
            right: 0;
            bottom: 0;
            transform: translateX(50%) translateY(50%);
        }
    </style>
</head>
<body>
    <!-- 手写面试题 -->
    <div class="outer">
        <span class="it" data-direction="lt"></span>
        <span class="it" data-direction="rt"></span>
        <span class="it" data-direction="lb"></span>
        <span class="it" data-direction="rb"></span>
    </div>

    <!-- 
        1. 距型,长按住拖动可以移动位置
        2. 4 个角可以让距型缩放
     -->

    <script>
        // 1. 获取到需要的元素
        // 2. 
        let outer = document.querySelector('.outer')
        let its = document.querySelectorAll('.it')

        let x = 0;
        let y = 0;
        let diffX = 0;
        let diffY = 0;
        let width = 0;
        let height = 0;
        let state = false;
        let moveX = 0;
        let moveY = 0;
        function mousedown(event) {
            // 拿到初始位置
            diffX = event.clientX - outer.offsetLeft;
            diffY = event.clientY - outer.offsetTop;
            state = true;

            if(state) {
                document.addEventListener('mousemove', mousemove, false)
            }
        }

        function mousemove(event) {
            moveX = event.clientX - diffX;
            moveY = event.clientY - diffY;

            console.log(moveX,'moveX')

            if(moveX < 0){
                moveX = 0
            }else if(moveX > window.innerWidth - outer.offsetWidth){
                moveX = window.innerWidth - outer.offsetWidth
            }
            if(moveY < 0){
                moveY = 0
            }else if(moveY > window.innerHeight - outer.offsetHeight){
                moveY =  window.innerHeight - outer.offsetHeight
            }
            outer.style.left = moveX + 'px';
            outer.style.top = moveY + 'px'
        }

        function mouseup() {
            state = false;
            document.removeEventListener('mousemove', mousemove)
        }

        outer.addEventListener('mousedown', mousedown, false)
        document.addEventListener('mouseup', mouseup, false)

        document.addEventListener('onunload', function() {
            outer.removeEventListener('mouseup', mouseup)
        })

        // 
        function itsMousedown(event) {
            // 问题2 : 默认大小是 200初始大小,除右下角符合 ,其他3个角的位置都有问题
            event.stopPropagation()
            // 做一个标识
            const key = event.target.dataset.direction ?? 'rb'
            width = getComputedStyle(event.target).width.replace('px', '') * 1
            height = getComputedStyle(event.target).height.replace('px', '') * 1
            // 鼠标按下的位置
            var disX = event.clientX;
            var disY = event.clientY;
            

            function move(ev) {
                var oEvent = ev || event;
                // 问题:拖拽移动到一个位置后,鼠标在 document 是一个很大的值,不能直接给 outer 了
                // 解决:oEvent.clientX - moveX  : 鼠标按下的位置减去 拖拽移动的距离
                outer.style.width = oEvent.clientX - moveX + 'px';
                outer.style.height = oEvent.clientY - moveY + 'px';
            }

            document.addEventListener('mousemove', move, false)

            function up(){
                document.removeEventListener('mousemove', move)
                document.removeEventListener('mouseup', up)
            }
            document.addEventListener('mouseup', up, false)
        }

        its[0].addEventListener('mousedown', itsMousedown, false)
        its[1].addEventListener('mousedown', itsMousedown, false)
        its[2].addEventListener('mousedown', itsMousedown, false)
        its[3].addEventListener('mousedown', itsMousedown, false)

    </script>
</body>
</html>

bug

  1. 问题一:当我们拖拽移动盒子到一个距离,后,进行缩放,此时,鼠标获取到的位置信息,如果直接给盒子的大小的话,会直接让盒子变大
    ‘解决: 就是拿鼠标按下时的位置信息,减去 盒子移动的距离,即可

  2. 问题二:当4个角,都添加了缩放的逻辑后,除右下角,无碍,其他角,都会不正常,是因为,设置盒子大小拿的是 鼠标的位置信息减移动的距离,这样位置就对不上

目前没有想到办法,。。。。

posted @ 2022-03-10 18:13  林见夕  阅读(216)  评论(0)    收藏  举报