如何在给定鼠标坐标的情况下检测重叠(旋转)的 DOM 元素?

2023-12-15

我使用以下脚本来获取鼠标单击坐标处重叠的 DIV 元素的列表。

在此示例中,如果 DIV 未旋转,则脚本可以正常工作:

http://jsfiddle.net/eyxt2tt1/2/

If I apply a rotation在 DIV 上并用户单击(本例中靠近红色标记)

http://jsfiddle.net/eyxt2tt1/3/

该脚本将始终返回两个 DIV,而它应该只考虑一个。

我需要知道:

  • 在我的计算中如何考虑旋转?
  • 您知道更好的方法/替代方案吗?

Notes:

  • 我无法使用 Document.elementFromPoint()
  • 他们对SO有类似的问题,但我认为这是不同的,因为我特别需要解决“轮换问题”。
  • 我很感激你在 jsfiddle 中的想法

$(document).click(function (e) {
    var hitElements = getHitElements(e);
    var output = $('#output');
    output.html('');
    for (var i = 0; i < hitElements.length; ++i) {
        output.html(output.html() + '<br />' + hitElements[i][0].tagName + ' ' + hitElements[i][0].id);

    };

});

var getHitElements = function (e) {
    var x = e.pageX;
    var y = e.pageY;
    var hitElements = [];
    $(':visible').each(function () {
        console.log($(this).attr("id"), $(this).outerWidth());
        var offset = $(this).offset();
        console.log('+++++++++++++++++++++');
        console.log('pageX: ' + x);
        console.log('pageY: ' + y);
        console.log($(this).attr("id"), $(this).offset());
        console.log('+++++++++++++++++++++');
        if (offset.left < x && (offset.left + $(this).outerWidth() > x) && (offset.top < y && (offset.top + $(this).outerHeight() > y))) {
            console.log('included: ', $(this).attr("id"));
            console.log('from 0p far x: ', $(this).attr("id"), offset.left + $(this).outerWidth());
            console.log('from 0p far y: ', $(this).attr("id"), offset.top + $(this).outerHeight());
            hitElements.push($(this));
        }
    });

    return hitElements;

}

你必须使用线性代数。

我修改了你的小提琴 -http://jsfiddle.net/pcdk2s0g/

var getHitElements = function (e) {
    var mx = e.pageX;
    var my = e.pageY;
    var hitElements = [];

    $(':visible').each(function () {

        //Parse CSS matrix
        var matrix = [];
        var matrixVal = $(this).css('transform');

        if(matrixVal != "none"){
            var matrixParsed = matrixVal.substr(7, matrixVal.length - 8).split(',');
            for(var i in matrixParsed) matrix[i] = parseFloat(matrixParsed[i]);
        } else {
            matrix = [1, 0, 0, 1, 0, 0];
        }

        var hW = this.offsetWidth / 2; //Half of width
        var hH = this.offsetHeight / 2; //Half of height
        var o = { x: this.offsetLeft + hW, y: this.offsetTop + this.offsetHeight / 2} //Transform origin

        //Define shape points and transform by matrix
        var p1 = {
            x: o.x + matrix[0] * -hW + matrix[2] * -hH + matrix[4],
            y: o.y + matrix[1] * -hW + matrix[3] * -hH + matrix[5]
        }; //Left top

        var p2 = {
            x: o.x + matrix[0] * +hW + matrix[2] * -hH + matrix[4],
            y: o.y + matrix[1] * +hW + matrix[3] * -hH + matrix[5]
        }; //Right top

        var p3 = {
            x: o.x + matrix[0] * +hW + matrix[2] * +hH + matrix[4],
            y: o.y + matrix[1] * +hW + matrix[3] * +hH + matrix[5]
        }; //Right bottom

        var p4 = {
            x: o.x + matrix[0] * -hW + matrix[2] * +hH + matrix[4],
            y: o.y + matrix[1] * -hW + matrix[3] * +hH + matrix[5]
        }; //Left bottom

        //Calculate edge normal vectors & C vars
        var v1 = { x: -(p2.y - p1.y), y: (p2.x - p1.x) }; //Top
        var v2 = { x: -(p3.y - p2.y), y: (p3.x - p2.x) }; //Right
        var v3 = { x: -(p4.y - p3.y), y: (p4.x - p3.x) }; //Bottom
        var v4 = { x: -(p1.y - p4.y), y: (p1.x - p4.x) }; //Left

        var c1 = -(v1.x * p1.x + v1.y * p1.y);
        var c2 = -(v2.x * p2.x + v2.y * p2.y);
        var c3 = -(v3.x * p3.x + v3.y * p3.y);
        var c4 = -(v4.x * p4.x + v4.y * p4.y);

        //Check cursor distance from edge using general line quation: ax + by + c = 0
        var isInner = function(v, c, x, y){
            return (v.x * x + v.y * y + c) / Math.sqrt( v.x*v.x + v.y*v.y )  > 0;
        }

        //Check if mouse point is in shape coords using general line equation
        if(isInner(v1, c1, mx, my) && isInner(v2, c2, mx, my) && isInner(v3, c3, mx, my) && isInner(v4, c4, mx, my))        
            hitElements.push($(this));

    });

    return hitElements;

}

它使用 CSS 变换属性,通过浏览器将其转换为 CSS 矩阵。

代码解析 CSS 矩阵,计算新的边缘点并检查光标是否位于翻译的元素中。

它适用于任何角度或 CSS 转换。

代码可以改进,例如你也可以解析CSS的transform-origin属性。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在给定鼠标坐标的情况下检测重叠(旋转)的 DOM 元素? 的相关文章

随机推荐

  • Tesseract + opencv 3.0 + windows,文本模块尺寸小,链接错误

    我两天前在answers opencv org 上发布了这篇文章 现在我也将其发布在这里 http answers opencv org question 68634 text contrib module and tesseract 大家
  • 将窗口对象存储在本地存储中

    我需要能够保留窗口对象 我尝试对窗口对象进行字符串化 但在尝试将窗口对象转换为 JSON 时收到错误 将循环结构转换为 JSON 错误 无论如何 我可以将 window open 中的窗口对象存储在本地存储中吗 var myWindow w
  • 将列附加到 pandas 数据框

    这可能很简单 但我有以下数据 在数据框 1 中 index dat1 0 9 1 5 在数据框 2 中 index dat2 0 7 1 6 我想要一个具有以下形式的数据框 index dat1 dat2 0 9 7 1 5 6 我尝试过使
  • 在 C++ 中创建稀疏数组的最佳方法是什么?

    我正在研究一个需要操作巨大矩阵的项目 特别是用于连接计算的金字塔求和 简而言之 我需要跟踪矩阵 多维数组 中大量零的相对少量的值 通常为 1 在极少数情况下超过 1 稀疏数组允许用户存储少量值 并假设所有未定义的记录都是预设值 由于物理上不
  • PHP 显示中文字符:SET NAMES 'utf8' 不起作用

    我正在尝试使用我拥有的数据库 但无法在其中显示中文字符 数据库实际上首先是一个 MS Access 文件 我用程序将其转换为 mysql 无论如何 很多行中都有中文字符 我无法让它们在任何浏览器中正确显示 否则我可以很好地显示汉字 如果我使
  • 配置旁遮普向 Openfire 发送 xmpp 请求

    我正在尝试将旁遮普连接管理器与 Openfire 一起使用 我已经有一个正在运行的 Openfire 服务器 我还安装了 punjab 并且服务器正常启动 允许我导航到本地主机上的端口 5280 虽然http localhost 5280
  • 将整数和文本字符串等数据从手机发送到网络数据库

    我有一个项目 我应该将整数 浮点数和文本字符串等数据从 Android 应用程序发送到 Web 数据库 但是我不知道如何做到这一点 有人可以解释一下吗 任何建议或帮助将不胜感激 您需要编写一些服务器端逻辑 通过POST或GET方法接受参数k
  • 使用角度2中的viewchild更新元素的innerhtml

    我有像这样的html元素 section class span title span span class value span section 我使用访问组件中的元素 ViewChild hiddenElement hiddenEleme
  • 在 ftp 服务器中不递归地列出文件、目录、子文件和子目录的想法

    我正在尝试生成 ftp 服务器中给定目录及其子目录的文件列表 服务器工作正常 我已经成功地生成了当前目录的文件列表 当我尝试列出子目录及其文件时 事情就变得复杂了 我被要求不要使用递归算法 所以我自己做了一些研究 我尝试过使用线程 对于找到
  • FutureTask 获取与运行,任务永远不会完成

    我正在学习 Callables 并决定制作一个非常简单的程序 问题是当我调用 getFutureTask 时线程被阻塞 Thread State TIMED WAITING 在对象监视器上 您能否告诉我为什么会这样以及为什么当我在 futu
  • 替换字符串中字符的实例

    这个简单地尝试用冒号替换分号 在特定位置 的简单代码不起作用 for i in range 0 len line if line i and i in rightindexarray line i 它给出了错误 line i TypeErr
  • 当“OrdinalBase”字段设置为 1 时,“kernel32.dll”如何导出序数 0?

    查看加载到内存中的 kernel32 dll 我看到以下导出序数表 gdb x 400hd eax 0x776334b0
  • 通过 shell 脚本拒绝 cat 的权限[重复]

    这个问题在这里已经有答案了 我在 bin rclone sync ACD log 中的日志文件上的 shell 脚本中运行 cat 时遇到问题 这是 shell 脚本中的行 RESULT cat LOGFILE tail 1 但是当运行脚本
  • 时区代码到时区信息

    在我们的 MS Dynamics CRM 项目中 我们创建了一个海量用户上传批次 该批处理从 Excel 文件读取并批量上传用户 该批次需要设置的内容之一是时区代码 在 Excel 文件中 时区将写为 UTC 1 CRM 使用的代码似乎是
  • 查找数组中最接近的值

    int array new int 5 5 7 8 15 20 int TargetNumber 13 对于目标数字 我想找到数组中最接近的数字 例如 当目标数字为 13 时 上面数组中最接近它的数字是 15 我如何在 C 中以编程方式实现
  • Linux打开设备时串口缓冲区不为空

    我有一个系统 我在串行端口上看到了我意想不到的奇怪行为 我以前曾在 USB 转串口适配器上偶尔看到过这种情况 但现在我也在本机串行端口上看到过这种情况 而且频率要高得多 该系统被设置为运行自动化测试 并且将首先执行一些任务 这些任务会导致在
  • 如何在ios模拟器中安装IPA?

    我建了一个 ipa使用后Xcode存档然后分发为ad hoc通常我会将其复制到真实的 ios 设备 但今天它失败了 说 安装失败 问题是使用 xcode gt 窗口 gt 设备和模拟器 不向我显示正在运行的模拟器 我有一个正在运行的 ios
  • 如何使用 eventBus 作为总线来将更新传递给 Vue 组件中的视图?

    监听组件 b 中总线的自定义事件 然而 在组件a中分派事件后 它访问组件b 执行了组件b的监听函数 但是msg数据功能未更新 请不要说Vuex 相关代码基于Vue CLi3 这里的代码 A组份
  • Bash 脚本检查图像是否为动画 png (apng)

    试图在我的 bash 脚本中找出一种方法来检查文件是否是动画 PNG apng 文件 就我而言 如果是的话 我想忽略它 有任何想法吗 更新 下面使用 pngcheck 的答案允许我检查图像是否是动画 此外 我还会检查文件的大小 如果它 大
  • 如何在给定鼠标坐标的情况下检测重叠(旋转)的 DOM 元素?

    我使用以下脚本来获取鼠标单击坐标处重叠的 DIV 元素的列表 在此示例中 如果 DIV 未旋转 则脚本可以正常工作 http jsfiddle net eyxt2tt1 2 If I apply a rotation在 DIV 上并用户单击