js 以鼠标滚轮位置为中心缩放、放大以及边界判断

这篇具有很好参考价值的文章主要介绍了js 以鼠标滚轮位置为中心缩放、放大以及边界判断。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

项目需求为页面上实现拖拽节点和可以在页面中通过滑动滚轮来缩放节点显示(以鼠标位置为缩放中心点)从而放大到可以看到详细的信息,节点有10000个。特此记录下实现细节

效果图

js 以鼠标滚轮位置为中心缩放、放大以及边界判断

js

初始化变量

    const container = document.querySelector('.container');
    const ul = document.querySelector('.ul');
    // 变量
    let result,
        x = 0,
        y = 0,
        scale = 1,
        ulWidth = 1500,
        ulHeight = 1200,
        minScale = 1,
        maxScale = 4,
        isDown = false, // 按下标识
        diff = { x: 0, y: 0 }, // 相对于上一次lastPointermove移动差值
        lastPointermove = { x: 0, y: 0 }; // 用于计算diff
    ul.style.width = ulWidth + 'px';
    ul.style.height = ulHeight + 'px';
    ul.style.transform = 'matrix(1, 0, 0, 1, 0, 0)';

为节点绑定拖拽事件,拖拽事件的边界使用Math进行判断,比起if判断更加清晰快捷。

鼠标抬起采用document全局判断,避免鼠标移动到节点外未触发鼠标抬起事件

 // 绑定鼠标点击
    ul.addEventListener('mousedown', function (e) {
        e.preventDefault();
        e.stopPropagation();
        isDown = true;
        lastPointermove = { x: e.clientX, y: e.clientY };

    });
    // 绑定鼠标移动
    ul.addEventListener('mousemove', function (e) {
        e.preventDefault();
        e.stopPropagation();
        if (isDown) {
            const current1 = { x: e.clientX, y: e.clientY };
            diff.x = current1.x - lastPointermove.x;
            diff.y = current1.y - lastPointermove.y;
            lastPointermove = { x: current1.x, y: current1.y };
            x += diff.x;
            y += diff.y;
            //边界判断
            let offsetX = Math.min(Math.max(x, ulWidth - ulWidth * (scale + 1) / 2), + ulWidth * (scale - 1) / 2);
            let offsetY = Math.min(Math.max(y, ulHeight - ulHeight * (scale + 1) / 2), + ulHeight * (scale - 1) / 2);
            ul.style.transform = `matrix(${scale}, 0, 0, ${scale}, ${offsetX}, ${offsetY})`;
        }

    });
    // 绑定鼠标抬起
    document.addEventListener('mouseup', () => {
        isDown = false;
    })

滚轮缩放、放大逻辑

X轴的(window.innerWidth - ulWidth) * 0.5)主要判断节点距离左边边距,y轴同样

同样采用Math判断边界

ul.addEventListener('wheel', function (e) {
        let ratio = 1.1;
        // 缩小
        if (e.deltaY > 0) {
            ratio = 1 / 1.1;
        }
        // 限制缩放倍数
        const onscale = scale * ratio;
        if (onscale > maxScale) {
            ratio = maxScale / scale;
            scale = maxScale;
        } else if (onscale < minScale) {
            ratio = minScale / scale;
            scale = minScale;
        } else {
            scale = onscale;
        }
        const origin = {
            x: (ratio - 1) * ulWidth * 0.5,
            y: (ratio - 1) * ulHeight * 0.5
        };
        // 计算偏移量
        x -= (ratio - 1) * (e.clientX - x - (window.innerWidth - ulWidth) * 0.5) - origin.x;
        y -= (ratio - 1) * (e.clientY - y) - origin.y;
        let offsetX = Math.min(Math.max(x, ulWidth - ulWidth * (scale + 1) / 2), ulWidth * (scale - 1) / 2);
        let offsetY = Math.min(Math.max(y, ulHeight - ulHeight * (scale + 1) / 2), + ulHeight * (scale - 1) / 2);
        x = offsetX;
        y = offsetY;
        ul.style.transform = `matrix(${scale}, 0, 0, ${scale}, ${offsetX}, ${offsetY})`;

    });

总结

自此功能开发完毕,使用原生方法实现也是加深对js的理解,基本上js上面能实现的移植到React、Vue也是一样的道理。小弟才疏学浅,大佬们见笑了,有帮到你的小伙伴可以点个赞,谢谢。

全部代码文章来源地址https://www.toymoban.com/news/detail-511637.html

<!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>
</head>
<style>
    body {
        margin: 0;
        padding: 0;
    }
    .main {
        width: 100%;
        display: flex;
        justify-content: center;
    }
    ul {
        width: 1500px;
        height: 1200px;
        background-color: antiquewhite;
        list-style: none;
        display: flex;
        flex-wrap: wrap;
        justify-content: space-between;
        margin: 0;
        padding: 0;
    }
    li {
        width: 100px;
        height: 80px;
        background-color: orange;
        margin-right: 20px;
    }
    li:nth-child(12n) {
        margin-right: 0px;
    }

    li:hover {
        background-color: darkblue;
    }
    .container {
        position: relative;
        width: 1500px;
        height: 1200px;
        overflow: hidden;
    }
</style>
<body>
    <div class="main">
        <div class="container">
            <ul class="ul">
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
            </ul>

        </div>
    </div>
</body>
<script>
    const container = document.querySelector('.container');
    const ul = document.querySelector('.ul');
    // 变量
    let result,
        x = 0,
        y = 0,
        scale = 1,
        ulWidth = 1500,
        ulHeight = 1200,
        minScale = 1,
        maxScale = 4,
        isDown = false, // 按下标识
        diff = { x: 0, y: 0 }, // 相对于上一次lastPointermove移动差值
        lastPointermove = { x: 0, y: 0 }; // 用于计算diff
    ul.style.width = ulWidth + 'px';
    ul.style.height = ulHeight + 'px';
    ul.style.transform = 'matrix(1, 0, 0, 1, 0, 0)';

    // 拖拽查看
    // 绑定鼠标点击
    ul.addEventListener('mousedown', function (e) {
        e.preventDefault();
        e.stopPropagation();
        isDown = true;
        lastPointermove = { x: e.clientX, y: e.clientY };
    });
    // 绑定鼠标移动
    ul.addEventListener('mousemove', function (e) {
        e.preventDefault();
        e.stopPropagation();
        if (isDown) {
            const current1 = { x: e.clientX, y: e.clientY };
            diff.x = current1.x - lastPointermove.x;
            diff.y = current1.y - lastPointermove.y;
            lastPointermove = { x: current1.x, y: current1.y };
            x += diff.x;
            y += diff.y;
            //边界判断
            let offsetX = Math.min(Math.max(x, ulWidth - ulWidth * (scale + 1) / 2), + ulWidth * (scale - 1) / 2);
            let offsetY = Math.min(Math.max(y, ulHeight - ulHeight * (scale + 1) / 2), + ulHeight * (scale - 1) / 2);
            ul.style.transform = `matrix(${scale}, 0, 0, ${scale}, ${offsetX}, ${offsetY})`;
        }
    });
    // 绑定鼠标抬起
    document.addEventListener('mouseup', () => {
        isDown = false;
    })

    // 滚轮缩放、放大逻辑
    ul.addEventListener('wheel', function (e) {
        // e.preventDefault();
        let ratio = 1.1;
        // 缩小
        if (e.deltaY > 0) {
            ratio = 1 / 1.1;
        }
        // 限制缩放倍数
        const onscale = scale * ratio;
        if (onscale > maxScale) {
            ratio = maxScale / scale;
            scale = maxScale;
        } else if (onscale < minScale) {
            ratio = minScale / scale;
            scale = minScale;
        } else {
            scale = onscale;
        }
        const origin = {
            x: (ratio - 1) * ulWidth * 0.5,
            y: (ratio - 1) * ulHeight * 0.5
        };
        // 计算偏移量
        x -= (ratio - 1) * (e.clientX - x - (window.innerWidth - ulWidth) * 0.5) - origin.x;
        y -= (ratio - 1) * (e.clientY - y) - origin.y;
        let offsetX = Math.min(Math.max(x, ulWidth - ulWidth * (scale + 1) / 2), ulWidth * (scale - 1) / 2);
        let offsetY = Math.min(Math.max(y, ulHeight - ulHeight * (scale + 1) / 2), + ulHeight * (scale - 1) / 2);
        x = offsetX;
        y = offsetY;
        ul.style.transform = `matrix(${scale}, 0, 0, ${scale}, ${offsetX}, ${offsetY})`;

    });
</script>

</html>

到了这里,关于js 以鼠标滚轮位置为中心缩放、放大以及边界判断的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包