From d838777e04099971d21ee443ab771363a4ef2939 Mon Sep 17 00:00:00 2001 From: Lasse Lauwerys <65569591+Iemand005@users.noreply.github.com> Date: Wed, 13 Nov 2024 16:14:11 +0100 Subject: [PATCH] Touch support bug fixes (#1527) * Improved touch support * Fix touch support scaling error * Fix touch scaling precision on all zoom levels * Improved touch experiene, fixed zooming on textarea elements and fixed context menu. * Minor bug fix --- src/extensions/core/simpleTouchSupport.ts | 73 ++++++++++------------- 1 file changed, 32 insertions(+), 41 deletions(-) diff --git a/src/extensions/core/simpleTouchSupport.ts b/src/extensions/core/simpleTouchSupport.ts index 43f5ff894..8f88cefdb 100644 --- a/src/extensions/core/simpleTouchSupport.ts +++ b/src/extensions/core/simpleTouchSupport.ts @@ -8,7 +8,7 @@ let touchCount = 0 app.registerExtension({ name: 'Comfy.SimpleTouchSupport', setup() { - let zoomPos + let touchDist let touchTime let lastTouch let lastScale @@ -26,7 +26,7 @@ app.registerExtension({ } } - app.canvasEl.addEventListener( + app.canvasEl.parentElement.addEventListener( 'touchstart', (e: TouchEvent) => { touchCount++ @@ -43,7 +43,7 @@ app.registerExtension({ lastScale = app.canvas.ds.scale lastTouch = getMultiTouchCenter(e) - zoomPos = getMultiTouchPos(e) + touchDist = getMultiTouchPos(e) app.canvas.pointer_is_down = false } } @@ -51,56 +51,47 @@ app.registerExtension({ true ) - app.canvasEl.addEventListener('touchend', (e: TouchEvent) => { - touchCount = e.touches?.length ?? touchCount - 1 + app.canvasEl.parentElement.addEventListener('touchend', (e: TouchEvent) => { + touchCount-- if (e.touches?.length !== 1) touchZooming = false if (touchTime && !e.touches?.length) { if (new Date().getTime() - touchTime > 600) { - try { - // hack to get litegraph to use this event - e.constructor = CustomEvent - } catch (error) {} - // @ts-expect-error - e.clientX = lastTouch.clientX - // @ts-expect-error - e.clientY = lastTouch.clientY - - app.canvas.pointer_is_down = true - // @ts-expect-error - app.canvas._mousedown_callback(e) + if (e.target === app.canvasEl) { + app.canvasEl.dispatchEvent( + new PointerEvent('pointerdown', { + button: 2, + clientX: e.changedTouches[0].clientX, + clientY: e.changedTouches[0].clientY + }) + ) + e.preventDefault() + } } touchTime = null } }) - app.canvasEl.addEventListener( + app.canvasEl.parentElement.addEventListener( 'touchmove', (e) => { touchTime = null - if (e.touches?.length === 2) { + if (e.touches?.length === 2 && lastTouch && !e.ctrlKey && !e.shiftKey) { + e.preventDefault() // Prevent browser from zooming when two textareas are touched app.canvas.pointer_is_down = false touchZooming = true - // @ts-expect-error - LiteGraph.closeAllContextMenus() + + LiteGraph.closeAllContextMenus(window) // @ts-expect-error app.canvas.search_box?.close() - const newZoomPos = getMultiTouchPos(e) + const newTouchDist = getMultiTouchPos(e) const center = getMultiTouchCenter(e) - let scale = app.canvas.ds.scale - const diff = zoomPos - newZoomPos + let scale = (lastScale * newTouchDist) / touchDist - scale = lastScale - diff / 100 - - const newX = ((center.clientX - lastTouch.clientX) * 1) / scale - const newY = ((center.clientY - lastTouch.clientY) * 1) / scale - - const convertCanvasToOffset = (pos, scale) => [ - pos[0] / scale - app.canvas.ds.offset[0], - pos[1] / scale - app.canvas.ds.offset[1] - ] + const newX = (center.clientX - lastTouch.clientX) / scale + const newY = (center.clientY - lastTouch.clientY) / scale // Code from LiteGraph if (scale < app.canvas.ds.min_scale) { @@ -113,20 +104,19 @@ app.registerExtension({ app.canvas.ds.scale = scale + // Code from LiteGraph if (Math.abs(app.canvas.ds.scale - 1) < 0.01) { app.canvas.ds.scale = 1 } const newScale = app.canvas.ds.scale - var oldCenter = convertCanvasToOffset( - [center.clientX, center.clientY], - oldScale - ) - var newCenter = convertCanvasToOffset( - [center.clientX, center.clientY], - newScale - ) + const convertScaleToOffset = (scale) => [ + center.clientX / scale - app.canvas.ds.offset[0], + center.clientY / scale - app.canvas.ds.offset[1] + ] + var oldCenter = convertScaleToOffset(oldScale) + var newCenter = convertScaleToOffset(newScale) app.canvas.ds.offset[0] += newX + newCenter[0] - oldCenter[0] app.canvas.ds.offset[1] += newY + newCenter[1] - oldCenter[1] @@ -147,6 +137,7 @@ LGraphCanvas.prototype.processMouseDown = function (e) { if (touchZooming || touchCount) { return } + app.canvas.pointer_is_down = false // Prevent context menu from opening on second tap return processMouseDown.apply(this, arguments) }