触摸移动非常缓慢

4
我正在开发一个类似画图的功能,用户可以画线,但在我的设备(安卓手机)上,touchmove事件响应非常慢,导致线条变得锯齿状。只要我将设备通过USB调试连接到电脑并打开Chrome DevTools,一切都正常了。在桌面版Chrome中的手机模拟器上没有任何问题。
这里是一个截图。内圆是用缓慢的触摸事件绘制的,而外圆是我将设备连接到电脑后绘制的。

Screenshot

这是另一张截图,显示了“touchmove”事件调用之间的持续时间。顶部部分(绿色数值)是在开发工具打开时发生的,底部部分(红色数值)是在关闭后发生的。

Screenshot

代码:

function DrawingCanvas(/* ... */) {
    // ...

    const handleTouchMove = (event) => {
        handleMouseMove(event.touches[0])
    }

    const handleMouseMove = ({ clientX, clientY }) => {
        if (!isDrawing) {
            return
        }

        const canvasRect = canvas.getBoundingClientRect()
        const x = clientX - canvasRect.x
        const y = clientY - canvasRect.y

        currentPath.current.addPoint([x, y])
        update()
    }

    const update = () => {
        clearCanvas()
        drawPath()
    }

    // ...

    useEffect(() => {
        const drawingCanvas = drawingCanvasRef.current

        // ...

        drawingCanvas.addEventListener("touchstart", handleDrawStart)
        drawingCanvas.addEventListener("touchend", handleDrawEnd)
        drawingCanvas.addEventListener("touchcancel", handleDrawEnd)
        drawingCanvas.addEventListener("touchmove", handleTouchMove)
        
        drawingCanvas.addEventListener("mousedown", handleDrawStart)
        drawingCanvas.addEventListener("mouseup", handleDrawEnd)
        drawingCanvas.addEventListener("mousemove", handleMouseMove)
        
        return () => {
            drawingCanvas.removeEventListener("touchstart", handleDrawStart)
            drawingCanvas.removeEventListener("touchmove", handleTouchMove)
            drawingCanvas.removeEventListener("touchend", handleDrawEnd)
            drawingCanvas.removeEventListener("touchcancel", handleDrawEnd)

            drawingCanvas.removeEventListener("mousedown", handleDrawStart)
            drawingCanvas.removeEventListener("mouseup", handleDrawEnd)
            drawingCanvas.removeEventListener("mousemove", handleMouseMove)
        }
    })

    return <canvas /* ... */ />
}

有人知道如何修复这个问题吗?
你可以在网站上自行测试:https://www.easymeme69.com/editor

4个回答

6
一些方法,调用 event.preventDefault() 以修复触摸移动事件。

3

我也遇到过完全相同的问题,甚至使用USB调试也无法复现。除了使用e.preventDefault()这个技巧之外,你还可以在CSS中设置触摸元素的touch-action: none;


3
我面临完全相同的情况,我正在开发一个React应用程序,并实现了一些在 touchmove 上执行动作的触摸功能。
所有测试都在基于Debian的Raspberry OS发行版上的Chrome中进行。
这导致使用真正的触摸屏幕时UI非常卡顿......除非(这是非常有趣的地方!)在Chrome移动模拟器中打开控制台,此时即使我尝试在真正的触摸屏幕上玩耍也不会有问题。 touch-action:noneevent.stopPropagation hack已经存在于我的代码中,并没有改变游戏规则。
关于这个问题,有两个结论:
1. 触摸屏幕(及其驱动程序)很好。 2. CPU能够处理负载。
目前,这个谜还是不透明的。
我的感觉是,某种程度上,Chrome故意增加/减少触摸事件速率,具体取决于我们是否处于真实使用情况或者是否在模拟器上。我创建了一个简单的fiddle来验证这个假设:https://jsfiddle.net/ncgtjesh/20/show 因为我可以清楚地看到启用模拟器的模式输出240个事件/秒,而真正的非模拟接口则固定为120个,所以这似乎是事实。
我很惊讶上面的响应中实施的修复措施能起作用了,因为它似乎是浏览器实现的选择。

1

我曾经遇到过同样的问题。在手机或Firefox上没有冻结,只有在Chromium上出现了这种情况。要么在chrome-flags中禁用touchpad-overscroll-history-navigation,要么使用e.preventDefault()可以解决该问题。


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