From 171f46fe0ae96d3d4f8a031427294b5174307c22 Mon Sep 17 00:00:00 2001 From: Dermot Duffy Date: Sat, 10 Jun 2023 14:47:59 -0700 Subject: [PATCH] Allow scrolling when not zoomed in. --- src/utils/zoom/zoom.ts | 11 +++++++++++ tests/utils/zoom.test.ts | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/utils/zoom/zoom.ts b/src/utils/zoom/zoom.ts index 7756cda6..b3fc9d0d 100644 --- a/src/utils/zoom/zoom.ts +++ b/src/utils/zoom/zoom.ts @@ -85,6 +85,10 @@ export class Zoom { ); } + protected _setTouchAction(touchEnabled: boolean): void { + this._element.style.touchAction = touchEnabled ? '' : 'none'; + } + public activate(): void { this._panzoom = Panzoom(this._element, { contain: 'outside', @@ -94,6 +98,11 @@ export class Zoom { // Do not force the cursor style (by default it will always show the // 'move' type cursor whether or not it is zoomed in). cursor: undefined, + + // Disable automatic touchAction setting from Panzoom() as otherwise it + // effectively disables dashboard scrolling. + // See: https://github.com/dermotduffy/frigate-hass-card/issues/1181 + touchAction: '', }); const registerListeners = ( @@ -117,11 +126,13 @@ export class Zoom { // absolute state changes (rather than on every single zoom adjustment). if (this._isScaleNormal((>ev).detail.scale)) { if (this._zoomed) { + this._setTouchAction(true); dispatchFrigateCardEvent(this._element, 'zoom:unzoomed'); } this._zoomed = false; } else { if (!this._zoomed) { + this._setTouchAction(false); dispatchFrigateCardEvent(this._element, 'zoom:zoomed'); } this._zoomed = true; diff --git a/tests/utils/zoom.test.ts b/tests/utils/zoom.test.ts index 16a595af..9c81d8fe 100644 --- a/tests/utils/zoom.test.ts +++ b/tests/utils/zoom.test.ts @@ -192,8 +192,7 @@ describe('Zoom', () => { element.addEventListener('frigate-card:zoom:zoomed', zoomedFunc); element.addEventListener('frigate-card:zoom:unzoomed', unzoomedFunc); - const panzoom = createMockPanZoom(); - vi.mocked(Panzoom).mockReturnValueOnce(panzoom); + vi.mocked(Panzoom).mockReturnValueOnce(createMockPanZoom()); createAndRegisterZoom(element); @@ -222,4 +221,35 @@ describe('Zoom', () => { element.dispatchEvent(ev_2); expect(unzoomedFunc).toBeCalled(); }); + + it('should set touch action on zoom/unzoom', () => { + const element = document.createElement('div'); + vi.mocked(Panzoom).mockReturnValueOnce(createMockPanZoom()); + + createAndRegisterZoom(element); + + const ev_1 = new CustomEvent('panzoomzoom', { + detail: { + x: 0, + y: 0, + scale: 1.2, + isSVG: false, + originalEvent: new PointerEvent('pointermove'), + }, + }); + element.dispatchEvent(ev_1); + expect(element.style.touchAction).toBe('none'); + + const ev_2 = new CustomEvent('panzoomzoom', { + detail: { + x: 0, + y: 0, + scale: 1, + isSVG: false, + originalEvent: new PointerEvent('pointermove'), + }, + }); + element.dispatchEvent(ev_2); + expect(element.style.touchAction).toBeFalsy(); + }); });