防止物体滚动(Matter.js)

4

背景

我正在尝试实现一个东西,但它真的让我发疯。所以任何帮助都将不胜感激!

我在 Matter.js 中创建了一个场景,并将其放置在页面下方的容器中。我希望访问者能够与场景交互,拖动和放置物体。但是允许交互会产生问题,即每当鼠标位于画布上方时,Matter.js 就会阻止用户滚动。

为了解决这个问题,我正在使用以下代码:

mouseConstraint.mouse.element.removeEventListener("mousewheel", mouseConstraint.mouse.mousewheel);
mouseConstraint.mouse.element.removeEventListener("DOMMouseScroll", mouseConstraint.mouse.mousewheel);

这样可以使用户在浏览页面时仍能通过单击和拖动物体与场景进行交互,因为仅移除滚动事件侦听器。至少在桌面上是这样的。 问题 然而,在移动设备上,触摸事件使用户能够在页面上滚动,所以我还需要从Matter.js中的鼠标限制中移除“touchmove”,“touchstart”和“touchend”事件侦听器。像这样:
mouseConstraint.mouse.element.removeEventListener('touchmove', mouseConstraint.mouse.mousemove);
mouseConstraint.mouse.element.removeEventListener('touchstart', mouseConstraint.mouse.mousedown);
mouseConstraint.mouse.element.removeEventListener('touchend', mouseConstraint.mouse.mouseup);

问题出在这里。如果我移除触摸事件,用户可以通过画布滚动,但是用户不能与场景交互,因为这需要激活触摸事件。

所以我想知道是否有办法添加触摸事件,但只允许它们在场景中的某些物体上工作?我发现我可以使用mouseConstraint.body作为布尔值来判断一个物体是否已被点击/触摸。这个基础上能否以某种方式使用它?

Matter.Events.on(mouseConstraint, "mousedown", function(event) {
   if (mouseConstraint.body) {
      console.log("Body clicked!");
   }        
});

你找到解决方案了吗,tobiasg? - Diego Oriani
我不记得我是否做过,不幸的是。 - tobiasg
真遗憾,但还是非常感谢你。 - Diego Oriani
FYI,最近版本中mouseConstraint.body包含实际的物体而不是布尔值。 - ggorlen
1个回答

0

这是我想出来的解决方案。它不是完美的,但总比什么都没有要好。

 let touchStart;
  mouseConstraint.mouse.element.addEventListener('touchstart', (event) => {
    if (!mouseConstraint.body) {
      touchStart = event;
    }
  });

  mouseConstraint.mouse.element.addEventListener('touchend', (event) => {
    if (!mouseConstraint.body) {
      const startY = touchStart.changedTouches[0].clientY;
      const endY = event.changedTouches[0].clientY;
      const delta = Math.abs(startY - endY);

      if (delta > 80) {
        window.scrollTo(0, 600);
      }
    }
  });

你需要监听触摸开始事件并将其存储在一个变量中。然后在触摸结束事件中,你需要检查滑动是否足够大以构成滚动,然后滚动到内容区域。

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