Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions src/CanvasPointer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,19 @@ export class CanvasPointer {
/** {@link maxClickDrift} squared. Used to calculate click drift without `sqrt`. */
static #maxClickDrift2 = this.#maxClickDrift ** 2

/** Assume that "wheel" events with both deltaX and deltaY less than this value are trackpad gestures. */
static trackpadThreshold = 60

/**
* The minimum time between "wheel" events to allow switching between trackpad
* and mouse modes.
*
* This prevents trackpad "flick" panning from registering as regular mouse wheel.
* After a flick gesture is complete, the automatic wheel events are sent with
* reduced frequency, but much higher deltaX and deltaY values.
*/
static trackpadMaxGap = 200

/** The element this PointerState should capture input against when dragging. */
element: Element
/** Pointer ID used by drag capture. */
Expand Down Expand Up @@ -78,6 +91,9 @@ export class CanvasPointer {
/** The last pointerup event for the primary button */
eUp?: CanvasPointerEvent

/** The last pointermove event that was treated as a trackpad gesture. */
lastTrackpadEvent?: WheelEvent

/**
* If set, as soon as the mouse moves outside the click drift threshold, this action is run once.
* @param pointer [DEPRECATED] This parameter will be removed in a future release.
Expand Down Expand Up @@ -255,6 +271,33 @@ export class CanvasPointer {
delete this.onDragStart
}

/**
* Checks if the given wheel event is part of a continued trackpad gesture.
* @param e The wheel event to check
* @returns `true` if the event is part of a continued trackpad gesture, otherwise `false`
*/
#isContinuationOfGesture(e: WheelEvent): boolean {
const { lastTrackpadEvent } = this
if (!lastTrackpadEvent) return false

return e.timeStamp - lastTrackpadEvent.timeStamp < CanvasPointer.trackpadMaxGap
}

/**
* Checks if the given wheel event is part of a trackpad gesture.
* @param e The wheel event to check
* @returns `true` if the event is part of a trackpad gesture, otherwise `false`
*/
isTrackpadGesture(e: WheelEvent): boolean {
if (this.#isContinuationOfGesture(e)) {
this.lastTrackpadEvent = e
return true
}

const threshold = CanvasPointer.trackpadThreshold
return Math.abs(e.deltaX) < threshold && Math.abs(e.deltaY) < threshold
}

/**
* Resets the state of this {@link CanvasPointer} instance.
*
Expand Down
29 changes: 8 additions & 21 deletions src/LGraphCanvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3181,35 +3181,22 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
processMouseWheel(e: WheelEvent): void {
if (!this.graph || !this.allow_dragcanvas) return

// TODO: Mouse wheel zoom rewrite
// @ts-expect-error
const delta = e.wheelDeltaY ?? e.detail * -60

this.adjustMouseEvent(e)

const pos: Point = [e.clientX, e.clientY]
if (this.viewport && !isPointInRect(pos, this.viewport)) return

let { scale } = this.ds

if (
LiteGraph.macTrackpadGestures &&
(!LiteGraph.macGesturesRequireMac || navigator.userAgent.includes("Mac"))
) {
if (e.ctrlKey) {
scale *= 1 + e.deltaY * (1 - this.zoom_speed) * 0.18
this.ds.changeScale(scale, [e.clientX, e.clientY], false)
} else {
this.ds.offset[0] -= e.deltaX * 1.18 * (1 / scale)
this.ds.offset[1] -= e.deltaY * 1.18 * (1 / scale)
}
// 1 / 120 for wheel, 1 / (50 / 9) for trackpad
const factor = this.pointer.isTrackpadGesture(e) ? 0.18 : 0.008_333

if (e.ctrlKey) {
scale *= 1 + e.deltaY * (1 - this.zoom_speed) * factor
this.ds.changeScale(scale, [e.clientX, e.clientY], false)
} else {
if (delta > 0) {
scale *= this.zoom_speed
} else if (delta < 0) {
scale *= 1 / (this.zoom_speed)
}
this.ds.changeScale(scale, [e.clientX, e.clientY])
this.ds.offset[0] -= e.deltaX * (1 + factor) * (1 / scale)
this.ds.offset[1] -= e.deltaY * (1 + factor) * (1 / scale)
}

this.graph.change()
Expand Down
2 changes: 2 additions & 0 deletions src/LiteGraphGlobal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ export class LiteGraphGlobal {
onDeprecationWarning: ((message: string, source?: object) => void)[] = [console.warn]

/**
* @deprecated Removed; has no effect.
* If `true`, mouse wheel events will be interpreted as trackpad gestures.
* Tested on MacBook M4 Pro.
* @default false
Expand All @@ -288,6 +289,7 @@ export class LiteGraphGlobal {
macTrackpadGestures: boolean = false

/**
* @deprecated Removed; has no effect.
* If both this setting and {@link macTrackpadGestures} are `true`, trackpad gestures will
* only be enabled when the browser user agent includes "Mac".
* @default true
Expand Down
Loading