From bb2bb0d053d793f618925a6a57aab3838cce55c8 Mon Sep 17 00:00:00 2001 From: Anton Vorobev Date: Thu, 16 Nov 2023 15:31:21 +0300 Subject: [PATCH 1/3] feat: add fast scroll touch event for mobile --- .../canvas-input-listener.component.ts | 46 ++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/src/chart/inputlisteners/canvas-input-listener.component.ts b/src/chart/inputlisteners/canvas-input-listener.component.ts index 89965473..62da909d 100644 --- a/src/chart/inputlisteners/canvas-input-listener.component.ts +++ b/src/chart/inputlisteners/canvas-input-listener.component.ts @@ -53,6 +53,7 @@ export class CanvasInputListenerComponent extends ChartBaseElement { private wheelSubject = new Subject(); private touchStartSubject = new Subject(); + private touchStartTimestamp = 0; private touchMoveSubject = new Subject(); private touchEndSubject = new Subject(); private touchCancelSubject = new Subject(); @@ -63,6 +64,7 @@ export class CanvasInputListenerComponent extends ChartBaseElement { private pinchSubject = new Subject(); private scrollGestureSubject = new Subject(); + private fastScrollTouch = new Subject(); mouseLeavesCanvasSubject = new Subject(); @@ -290,6 +292,31 @@ export class CanvasInputListenerComponent extends ChartBaseElement { this.addSubscription( subscribeListener(this.element, (e: TouchEvent) => longTouchListeners(e), 'touchstart'), ); + + const fastScrollListenerProducer = (e: TouchEvent) => { + e.preventDefault(); + // should work only if dragged to the left + if (this.prevDragPoint.x > this.dragStartPoint.x) { + // in percent, perhaps should be changed to just pixels, + // because landscape and portait orientations would give different % results + const minDistance = 35; + // in ms, should be lower to detect as "fast" + const minTime = 200; + + const touchStartTs = this.touchStartTimestamp; + const touchEndTs = Date.now(); + const time = touchEndTs - touchStartTs; + + const distance = ((this.prevDragPoint.x - this.dragStartPoint.x) / this.canvasBounds.width) * 100; + const isMinDistance = distance > minDistance; + const isMinTime = time <= minTime; + + if (isMinDistance && isMinTime) { + this.fastScrollTouch.next(e); + } + } + }; + this.addSubscription(subscribeListener(this.element, fastScrollListenerProducer, 'touchend')); } this.addSubscription( @@ -301,7 +328,14 @@ export class CanvasInputListenerComponent extends ChartBaseElement { ); this.addSubscription( - subscribeListener(this.element, (e: TouchEvent) => this.touchStartSubject.next(e), 'touchstart'), + subscribeListener( + this.element, + (e: TouchEvent) => { + this.touchStartSubject.next(e); + this.touchStartTimestamp = Date.now(); + }, + 'touchstart', + ), ); this.addSubscription( subscribeListener(this.element, (e: TouchEvent) => this.touchMoveSubject.next(e), 'touchmove', true), @@ -793,6 +827,16 @@ export class CanvasInputListenerComponent extends ChartBaseElement { .pipe(filter(() => hitBoundsTest(this.currentPoint.x, this.currentPoint.y))); } + /** + * Returns an Observable that emits a Touch whenever a fast scroll is detected. + * Fast scroll happens whenever chart or any other pane were moved faster than usual + * The Observable is created from a Subject that is subscribed to by the component's template. + * @returns {Observable} An Observable that emits a TouchEvent whenever a fast scroll gesture is detected. + */ + public observeFastScrollTouch(): Observable { + return this.fastScrollTouch.asObservable(); + } + /** * Returns the current point of the object. * @returns {Point} The current point of the object. From c921309e6846f9c797330b67f3ccb60bef0b1437 Mon Sep 17 00:00:00 2001 From: Anton Vorobev Date: Thu, 16 Nov 2023 15:45:57 +0300 Subject: [PATCH 2/3] feat: add fast scroll touch event for mobile --- .../inputlisteners/canvas-input-listener.component.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/chart/inputlisteners/canvas-input-listener.component.ts b/src/chart/inputlisteners/canvas-input-listener.component.ts index 62da909d..e0686f7e 100644 --- a/src/chart/inputlisteners/canvas-input-listener.component.ts +++ b/src/chart/inputlisteners/canvas-input-listener.component.ts @@ -301,17 +301,17 @@ export class CanvasInputListenerComponent extends ChartBaseElement { // because landscape and portait orientations would give different % results const minDistance = 35; // in ms, should be lower to detect as "fast" - const minTime = 200; + const maxTime = 200; const touchStartTs = this.touchStartTimestamp; const touchEndTs = Date.now(); const time = touchEndTs - touchStartTs; const distance = ((this.prevDragPoint.x - this.dragStartPoint.x) / this.canvasBounds.width) * 100; - const isMinDistance = distance > minDistance; - const isMinTime = time <= minTime; + const isRightDistance = distance > minDistance; + const isRightTime = time <= maxTime; - if (isMinDistance && isMinTime) { + if (isRightDistance && isRightTime) { this.fastScrollTouch.next(e); } } From ee513f0d6c5c5bd01e67bf88e39fc9e9b18c8173 Mon Sep 17 00:00:00 2001 From: Anton Vorobev Date: Thu, 16 Nov 2023 21:51:02 +0300 Subject: [PATCH 3/3] feat: add fast scroll touch event for mobile --- .../canvas-input-listener.component.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/chart/inputlisteners/canvas-input-listener.component.ts b/src/chart/inputlisteners/canvas-input-listener.component.ts index e0686f7e..0c5fcf4e 100644 --- a/src/chart/inputlisteners/canvas-input-listener.component.ts +++ b/src/chart/inputlisteners/canvas-input-listener.component.ts @@ -64,7 +64,7 @@ export class CanvasInputListenerComponent extends ChartBaseElement { private pinchSubject = new Subject(); private scrollGestureSubject = new Subject(); - private fastScrollTouch = new Subject(); + private fastTouchScroll = new Subject(); mouseLeavesCanvasSubject = new Subject(); @@ -301,7 +301,7 @@ export class CanvasInputListenerComponent extends ChartBaseElement { // because landscape and portait orientations would give different % results const minDistance = 35; // in ms, should be lower to detect as "fast" - const maxTime = 200; + const maxTime = 250; const touchStartTs = this.touchStartTimestamp; const touchEndTs = Date.now(); @@ -312,7 +312,7 @@ export class CanvasInputListenerComponent extends ChartBaseElement { const isRightTime = time <= maxTime; if (isRightDistance && isRightTime) { - this.fastScrollTouch.next(e); + this.fastTouchScroll.next(e); } } }; @@ -831,10 +831,12 @@ export class CanvasInputListenerComponent extends ChartBaseElement { * Returns an Observable that emits a Touch whenever a fast scroll is detected. * Fast scroll happens whenever chart or any other pane were moved faster than usual * The Observable is created from a Subject that is subscribed to by the component's template. - * @returns {Observable} An Observable that emits a TouchEvent whenever a fast scroll gesture is detected. + * @returns {Observable} An Observable that emits a TouchEvent whenever a fast scroll is detected. */ - public observeFastScrollTouch(): Observable { - return this.fastScrollTouch.asObservable(); + public observeFastTouchScroll(hitBoundsTest: HitBoundsTest = () => true): Observable { + return this.fastTouchScroll + .asObservable() + .pipe(filter(() => hitBoundsTest(this.currentPoint.x, this.currentPoint.y))); } /**