如何根据屏幕尺寸重新计算 x 和 y 坐标

33

我有一个热力图应用程序,存储了点击的x、y坐标以及视口宽度和高度。两次点击的真实数据:

x,   y,   width, height
433, 343, 1257,  959
331, 823, 1257,  959
当我在响应式网站上调整屏幕大小时,显示的点击位置都不正确了。我在搜索中找不到答案,是否有公式或算法可以重新计算不同分辨率下的x和y坐标。例如,如果宽度从1257变为990,高度从959变为400,则如何重新计算x和y,使它们放置在同一位置?
编辑:我向数据库添加了两个字段,width_percentage和height_percentage,来存储宽度的x百分比和高度的y百分比。因此,如果x是433而屏幕宽度是1257,则x距离屏幕左侧的距离为35%。我然后对高度使用相同的理论进行计算,但它没有像我想象的那样按比例缩放点击点以达到相同的位置。我通过在全分辨率1257宽度下单击,然后在900宽度下重新打开进行测试。请参阅以下代码以显示较低分辨率下的点击点。
Ajax PHP
while ($row = mysql_fetch_array($results)) { 
  if( $_GET['w'] < $row['width'] ) {
    $xcorr = $row['width_percentage'] * $_GET['w'];
    $ycorr = $row['y']; 
  }
}

在页面加载时,此代码使用$_GET变量传递屏幕分辨率的宽度和高度。然后,它从数据库获取点击点作为$results。由于我只将分辨率宽度从1257缩放到900,所以我没有计算高度,并且其像素与初始点击相同。我将新宽度乘以百分比并设置该百分比距屏幕左侧的点。由于百分比为35%,所以新的x坐标为900 * .35 = 315px。但是它没有起作用,我仍然在思考如何在响应式网站上保持点击相同位置的问题。


2
你需要展示一些代码。然而,可能的解决方案是在document上添加一个resize监听器,并使用element.getBoundingClientRect()进行一些魔法操作。请参考以下问题的答案:检索HTML元素的位置(X,Y) - zero298
3
除了x.y坐标之外,还要保存事件目标元素。现在在文档上保留一些调整大小的监听器,并在调整大小事件上重新计算保存元素的x、y坐标。 - Rama Rao M
1
让我进行一些转储和重新测试,然后告诉您结果。 - Naterade
1
我可以有一个演示,以便我可以进行调试吗? - Mitul
1
我似乎弄不清楚为什么需要重新计算 xy 坐标。只有宽度和高度可能会改变。但由于坐标从左上角开始,所以 xy 始终具有相同的值(除了它们应该比宽度和高度小)。 - Goowik
显示剩余3条评论
7个回答

23

你尝试过使用这个数学公式来改变数字的范围吗?

FormulaX

FormulaY

还有一种替代方法,可以将数据存储为:

x,   y,   width, height
433, 343, 1257,  959
331, 823, 1257,  959

您可以将其标准化为 01 之间的值,以便它适用于任何 width/height(通过将每个 x 除以其 width,并将每个 y 除以其 height 计算):

x,     y
0.344, 0.357
0.263, 0.858

那么您不需要知道存储它们时使用的width/height,当您想将它们转换为当前屏幕大小时,只需将每个尺寸乘以当前的 width/height


10
你可以通过 jQuery 实现这个功能:

$( window ).resize(function() {
  //ur code
});

JavaScript

window.onresize = resize;

function resize()
{
 alert("resize event detected!");
}

如果您正在使用移动设备,请同时使用此项

$(window).on("orientationchange",function(event){
  alert("Orientation is: " + event.orientation);
});

3
注意绑定$(window).resize事件时要小心。使用debouncethrottle来控制,否则界面会变得非常卡顿、迟缓。resize事件在调整大小过程中不断触发,除非你想每10毫秒重新计算一次,否则应将其限制在250ms或其他你认为必要的时间间隔内。 参考链接:http://davidwalsh.name/javascript-debounce-function 和 https://remysharp.com/2010/07/21/throttling-function-calls - Adrian Oprea

3

我认为你在百分比方面走在了正确的轨道上。你是否包括地图图像的偏移量?我想知道你的算法是否有效,但视觉表示似乎出现了问题,因为偏移量在视口中发生了变化。

$(window).resize(function() {
    var offset = yourMap.offset();
    myLeft = offset.left();
    myTop = offset.top();
});

您需要每次添加偏移量以获得正确的位置。

3

以下是你应该做的。有时当文档被解析时,调整大小事件会触发。最好将代码放在一个onload事件函数中。方向更改函数取自@Arun的答案。

window.onload = function() {

  $(window).on("orientationchange", function(event) {
    alert("Orientation is: " + event.orientation);
  });

  window.onresize = function() {
    alert('window resized; recalculate');
  };

};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


2
为此,您需要进行一些计算。以下是根据高度和宽度返回新x和y位置的函数。
function getNewX(xVlaue, oldWidth, newWidth){
   return xVlaue * newWidth / oldWidth;
}
newX = getNewX(10, 150, 100); // Use

您可以使用通用的高度和宽度计算函数。 演示

0
整个问题高度取决于您要在哪个页面上使用它。 大多数页面都有一个居中的块和/或一些自适应(即“响应式”)元素。如果页面不太响应,例如具有固定宽度,则您的工作会更轻松。如果页面是居中的,则您可能希望保存光标相对于页面中心的X位置。这样窗口宽度就不重要了。同样的情况也适用于左对齐和右对齐的页面 - 在这种情况下,您将保存相对于窗口左侧或右侧边缘的X位置。 下面的图像显示了一个中心导向的单击位置。请注意,如果调整窗口大小,此处单击的x和y属性不会改变。

explanation of center-oriented position

现在来看更通用的方法

如果您保存了窗口尺寸、光标位置和滚动偏移量,则很可能能够在布局旁边重现它,但您需要为每个唯一的尺寸集重新生成。如果您使用了上面的技巧,您可能可以将所有布局叠加在一起并找到一个共同点。例如,如果您的页面居中于窗口,具有最大宽度,并且您保存了相对于窗口中心的X位置,则可以叠加发生在至少该宽度的窗口中的所有单击。

然而,您可以进行一些诡计,并将已经保存的信息与点击元素一起保存。如果您还保存了相对于元素的单击位置,则可以将此数据评估为“提交按钮通常在右下角被按下”或“人们经常在那个下拉列表的远端单击,有时会误点几个像素”之类的内容。


0

请尝试以下两种方法:

1. 填充和边距可能不会自动缩放。在样式表的末尾使用 "* {padding:0;margin:0}",并检查是否解决了问题。

2. 确保外部和内部(即所有)元素都能够自动缩放。任何一个元素无法自动缩放都会导致其他许多元素错位。这通常发生在文本输入框中。在样式表的末尾使用 "*{border:solid 2}" 来观察每个元素的缩放效果。

我相信您的问题将得到解决。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接