以鼠标中心放大或缩小目标盒子(图片),盒子(图片)跟随鼠标移动,原理以及代码,原生js完成

核心原理就是推算出放大或者缩小后,鼠标位置相对于原本位置的偏移量,这个自己画个图,以x轴与轴的偏移量,算一下就能得到这个公式:

// 相对偏移量left= 盒子(图片)距离浏览器最左侧距离 - (鼠标位置 - 盒子(图片)距离浏览器最左侧距离)* 倍率

// 相对偏移量top= 盒子(图片)距离浏览器最上侧距离 - (鼠标位置 - 盒子(图片)距离浏览器最上侧距离)* 倍率

效果演示:(鼠标位置没被录制下来,实际操作鼠标在哪就应该以哪里为中心放大,图片以鼠标为中心,向四周放大延申不同的距离)

附源代码:也就不到 100行,两个功能,一个是 跟随鼠标移动,一个是放大缩小

<!DOCTYPE html>
 
<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>
 
        * {
 
            margin: 0;
 
            padding: 0;
 
        }
 
        .box {
 
            width: 100px;
 
            height: 100px;
 
            border: 1px solid black;
 
            position: absolute;
 
            background-image: url('../images/0.jpg');/* 图片自己换一下*/
 
            background-size: contain;
 
            background-repeat: no-repeat;
 
            /* transform: scale(1,1); */
 
            /* transform: translate(45px, 25px); */
 
        }
        .mywarp {
            width: 1000px;
            height: 500px;
            overflow: hidden;
            position: relative;
        }
    </style>
</head>
<body>
    <div class="mywarp">
        <div id="box" class="box"></div>
    </div>
    <script>
 
        let box = document.getElementById('box');
 
        // 只负责移动,这个是可以随意移动盒子的代码,不需要可以不要
 
        box.onmousedown = function (e) {
 
            // 先跟随鼠标移动
 
            var mouseDownX = e.clientX;//鼠标x轴位置
 
            var mouseDownY = e.clientY;//鼠标y轴位置
 
                //getComputedStyle  是浏览器自带的一个方法,用于获取节点的所有style属性
 
            var boxDownTop = parseFloat(getComputedStyle(box).top);
 
            var boxDownLeft = parseFloat(getComputedStyle(box).left);
 
            console.log(mouseDownX, mouseDownY)
 
            function mouseMove(e) {
 
                e.stopPropagation();
 
                e.preventDefault();
 
                // 触发移动事件
 
                let mouseX = e.clientX;//鼠标x轴位置
 
                let mouseY = e.clientY;//鼠标y轴位置
 
                //获取点击位置必须是这个box 的距离最左侧与最上方可视区域位置
 
                let boxTop = parseFloat(getComputedStyle(box).top);
 
                let boxLeft = parseFloat(getComputedStyle(box).left);
 
                // 用鼠标位置  减去  盒子的  上左距离就是 实际鼠标在盒子内部的偏差值
 
                let wantX = mouseX - boxLeft;
 
                let wantY = mouseY - boxTop;
 
                //让盒子跟随鼠标动,x,y值立刻改变,但是默认状态是0,所以,第一步盒子的x,y是等于鼠标位置的
 
                // 第二步的时候,盒子更新位置,是第一次的位置,导致了始终无法同步位置
 
                // 鼠标点击位置,记录下来,用于计算偏移量
 
                box.style.top = mouseY - (mouseDownY - boxDownTop) + 'px';
 
                box.style.left = mouseX - (mouseDownX - boxDownLeft) + 'px';
 
            }
 
            function mouseUp(e) {
 
                document.removeEventListener('mousemove', mouseMove, {passive: false})
 
            }
 
            document.addEventListener('mousemove', mouseMove, {passive: false})
 
            document.addEventListener('mouseup', mouseUp, {passive: false})
 
        }
 
       
        let scale = 1;
        // 只负责 在盒子(图片)上放大缩小
 
        var mouseWheelStatus = true;//这个参数用与防抖控制,因为鼠标滚一下,实际上会被触发几十次,加个50毫秒延时,可以有效阻止
        
        box.onmousemove = function (e) {
            if (mouseWheelStatus) {
                mouseWheelStatus = false;
                function onWheel (e) {
                    setTimeout(() => {
                        if (e.altKey) {
                            let thatWidth = box.getBoundingClientRect().width;
                            let thatHeight = box.getBoundingClientRect().height;
                            // 放大与缩小 的标志
                            var delta = e.deltaY > 0 ? -0.1 : 0.1;
                            var maxScale = 3, minScale = 0.05;
                            var x = e.clientX, y = e.clientY;
                            var bound = box.getBoundingClientRect();
                            var imgX = x - bound.left, imgY = y - bound.top;
                            scale = Math.min(maxScale, Math.max(minScale, scale * (1 + delta)));
                            var newWidth = 640 * scale;
                            var newHeight = 480 * scale;
                            var perX = imgX / thatWidth, perY = imgY / thatHeight;
                            resize(newWidth, newHeight, perX, perY);
                            e.stopPropagation();
                            e.preventDefault();
                            mouseWheelStatus = true;
                        }
                    }, 50);  
                }
            }
            box.addEventListener('mousewheel', onWheel, {passive: false})
        };
        var resize = function (width, height, perX, perY) {
            var that = this;
            var boxWarp = box;
            var bound = boxWarp.getBoundingClientRect();
            boxWarp.style.height = width + 'px';
            boxWarp.style.width = width + 'px';
            boxWarp.width = width;
            boxWarp.height = height;
            var style = getComputedStyle(boxWarp);
            var marginLeft = parseFloat(style.marginLeft);
            var marginTop = parseFloat(style.marginTop);
            boxWarp.style.width = width + 'px';
            boxWarp.style.height = height + 'px';
            var newBound = boxWarp.getBoundingClientRect();
            //这段是核心,原理差不多,根据缩放比列来完成图像的位置控制,保证缩放后鼠标还在原地
            boxWarp.style.marginLeft = marginLeft - perX * (newBound.right - bound.right) - (1 - perX) * (newBound.left - bound.left) + 'px';
            boxWarp.style.marginTop = marginTop - perY * (newBound.bottom - bound.bottom) - (1 - perY) * (newBound.top - bound.top) + 'px';
        }
    </script>
 
</body>
 
</html>

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值