Improved touch support (#1519)

* Improved touch support

* Fix touch support scaling error
This commit is contained in:
Lasse Lauwerys
2024-11-12 22:19:59 +01:00
committed by GitHub
parent 05ba526388
commit 1a8900de1f

View File

@@ -11,7 +11,7 @@ app.registerExtension({
let zoomPos
let touchTime
let lastTouch
let lastScale
function getMultiTouchPos(e) {
return Math.hypot(
e.touches[0].clientX - e.touches[1].clientX,
@@ -19,11 +19,19 @@ app.registerExtension({
)
}
function getMultiTouchCenter(e) {
return {
clientX: (e.touches[0].clientX + e.touches[1].clientX) / 2,
clientY: (e.touches[0].clientY + e.touches[1].clientY) / 2
}
}
app.canvasEl.addEventListener(
'touchstart',
(e) => {
(e: TouchEvent) => {
touchCount++
lastTouch = null
lastScale = null
if (e.touches?.length === 1) {
// Store start time for press+hold for context menu
touchTime = new Date()
@@ -32,6 +40,9 @@ app.registerExtension({
touchTime = null
if (e.touches?.length === 2) {
// Store center pos for zoom
lastScale = app.canvas.ds.scale
lastTouch = getMultiTouchCenter(e)
zoomPos = getMultiTouchPos(e)
app.canvas.pointer_is_down = false
}
@@ -41,8 +52,9 @@ app.registerExtension({
)
app.canvasEl.addEventListener('touchend', (e: TouchEvent) => {
touchZooming = false
touchCount = e.touches?.length ?? touchCount - 1
if (e.touches?.length !== 1) touchZooming = false
if (touchTime && !e.touches?.length) {
if (new Date().getTime() - touchTime > 600) {
try {
@@ -75,19 +87,54 @@ app.registerExtension({
app.canvas.search_box?.close()
const newZoomPos = getMultiTouchPos(e)
const midX = (e.touches[0].clientX + e.touches[1].clientX) / 2
const midY = (e.touches[0].clientY + e.touches[1].clientY) / 2
const center = getMultiTouchCenter(e)
let scale = app.canvas.ds.scale
const diff = zoomPos - newZoomPos
if (diff > 0.5) {
scale *= 1 / 1.07
} else if (diff < -0.5) {
scale *= 1.07
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]
]
// Code from LiteGraph
if (scale < app.canvas.ds.min_scale) {
scale = app.canvas.ds.min_scale
} else if (scale > app.canvas.ds.max_scale) {
scale = app.canvas.ds.max_scale
}
app.canvas.ds.changeScale(scale, [midX, midY])
const oldScale = app.canvas.ds.scale
app.canvas.ds.scale = scale
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
)
app.canvas.ds.offset[0] += newX + newCenter[0] - oldCenter[0]
app.canvas.ds.offset[1] += newY + newCenter[1] - oldCenter[1]
lastTouch.clientX = center.clientX
lastTouch.clientY = center.clientY
app.canvas.setDirty(true, true)
zoomPos = newZoomPos
}
},
true