【问题标题】:D3 zoom failing on two simultaneous touchesD3 缩放在两次同时触摸时失败
【发布时间】:2016-11-26 07:57:20
【问题描述】:

我在移动设备上使用 D3(第 4 版)时遇到问题,当同时触摸两个元素时,缩放功能似乎不起作用。我测试过的唯一设备是 iPhone 7 (iOS 10.1.1),移动 Safari 和 Chrome 浏览器应用程序都存在问题。

我创建了一个简单的示例(如下),我可以用它来重现这个问题,它只有两个黄色背景上的矩形。在我的 iPhone 上:

  • 如果我用两根手指准确同时触摸它们,当我将手指分开和合拢时,缩放不会改变。
  • 但如果触摸完全在同一时间(甚至稍微分开),则缩放工作正常。

我是否遗漏了导致这种行为的某些东西?我尝试搜索其他有相同问题的人,但找不到任何东西……但鉴于 D3 的受欢迎程度,这一定是我做错了。

这给我的用户带来了问题。很多时候,它的工作原理是触摸事件并不完全在同一时间……但触摸通常是同时发生的,并且在用户看来,缩放被破坏或需要多次尝试才能成功。非常沮丧。

var svg = d3.select('#svgLocation').append('svg')
	.attr('style', 'width:300px;height:300px;background-color:yellow;');

var grp = svg.append("g");
grp.append("path").attr('d','M25,25 275,25 275,125 25,125Z');
grp.append("path").attr('d','M25,175 275,175 275,275 25,275Z');

var zoom = d3.zoom()
  .scaleExtent([1, 10])
  .on("zoom", function() { grp.attr("transform", d3.event.transform) });
svg.call(zoom);
#svgLocation {
  width:100%;
  height:100%;
}
<!DOCTYPE html>
<html>

  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="http://d3js.org/d3.v4.min.js"></script>
  </head>

  <body>
    <div id="svgLocation"></div>
  </body>
  
</html>

【问题讨论】:

  • 我在 d3.v4.js 中添加了一些调试代码,到目前为止已将问题缩小到缩放触摸启动功能。在缩放失败的情况下,它确实看到了两个触摸事件......但由于某种原因,“g”手势在第二个触摸事件到达时没有填充 touch0 值。

标签: ios d3.js


【解决方案1】:

因此,这似乎是 D3v4 中的一个错误,它至少会影响一台设备(运行 iOS 10 的 iPhone 7 设备,Safari 和 Chrome 浏览器)。但它不会影响所有设备:当我在 Windows 7 一体式触控计算机上尝试时,我无法重现该问题。

在 iPhone 上,如果两个触摸同时发生(或几乎同时发生),则会按预期触发两个 touchstarted 事件。然而,在 both 事件中,“touches”属性将包含一个带有 both 触摸的数组。 (“changedTouches”属性将只包含相应的触摸。)

(请注意,在 Windows 触摸设备上,两个事件中第一个事件的“touches”属性只有一个触摸值。)

在 D3 缩放touchstarted 函数中,手势的“开始”仅在触摸计数与 changedTouches 计数匹配时触发...这是由“if”语句 (Commit #17) 中的以下:

var g = gesture(this, arguments),
  touches = event.changedTouches,
  n = touches.length, i, t, p;

[...]

if (event.touches.length === n) {
  touchstarting = setTimeout(function() { touchstarting = null; }, touchDelay);
  interrupt(this);
  g.start();
}

我尝试注释掉“if”语句,所以 g.start() 总是被调用(即使有两次触摸和一次 touchChanged)......它立即开始在 iPhone 上工作。双击缩放也继续工作,这是添加此检查的提交。

但是,我很犹豫是否将其留在我的项目中;显然,由于某种原因,该 if 语句检查被放在那里。我担心通过禁用它,我会打开其他一些我不知道的边缘案例。我会将此问题发布到 Github 项目,希望能找到解决此问题的方法。

【讨论】:

    猜你喜欢
    • 2016-06-25
    • 2013-05-25
    • 1970-01-01
    • 2012-11-07
    • 1970-01-01
    • 2011-04-09
    • 2019-08-07
    • 1970-01-01
    • 2023-04-07
    相关资源
    最近更新 更多