feat: Support touch pan & zoom
This commit is contained in:
Vendored
+4
@@ -16,7 +16,11 @@
|
|||||||
"mindmap",
|
"mindmap",
|
||||||
"Pageview",
|
"Pageview",
|
||||||
"pako",
|
"pako",
|
||||||
|
"panmove",
|
||||||
|
"panstart",
|
||||||
"panzoom",
|
"panzoom",
|
||||||
|
"pinchmove",
|
||||||
|
"pinchstart",
|
||||||
"pzoom",
|
"pzoom",
|
||||||
"roughjs",
|
"roughjs",
|
||||||
"Serde",
|
"Serde",
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
"@sveltejs/adapter-static": "3.0.8",
|
"@sveltejs/adapter-static": "3.0.8",
|
||||||
"@sveltejs/kit": "2.20.3",
|
"@sveltejs/kit": "2.20.3",
|
||||||
"@sveltejs/vite-plugin-svelte": "^4.0.4",
|
"@sveltejs/vite-plugin-svelte": "^4.0.4",
|
||||||
|
"@types/hammerjs": "^2.0.46",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/node": "^22.14.1",
|
"@types/node": "^22.14.1",
|
||||||
"@types/pako": "2.0.3",
|
"@types/pako": "2.0.3",
|
||||||
@@ -90,6 +91,7 @@
|
|||||||
"@mermaid-js/mermaid-zenuml": "^0.2.0",
|
"@mermaid-js/mermaid-zenuml": "^0.2.0",
|
||||||
"codemirror": "^6.0.1",
|
"codemirror": "^6.0.1",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
|
"hammerjs": "^2.0.8",
|
||||||
"js-base64": "3.7.7",
|
"js-base64": "3.7.7",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"mermaid": "^11.6.0",
|
"mermaid": "^11.6.0",
|
||||||
|
|||||||
Generated
+17
@@ -35,6 +35,9 @@ importers:
|
|||||||
dayjs:
|
dayjs:
|
||||||
specifier: ^1.11.13
|
specifier: ^1.11.13
|
||||||
version: 1.11.13
|
version: 1.11.13
|
||||||
|
hammerjs:
|
||||||
|
specifier: ^2.0.8
|
||||||
|
version: 2.0.8
|
||||||
js-base64:
|
js-base64:
|
||||||
specifier: 3.7.7
|
specifier: 3.7.7
|
||||||
version: 3.7.7
|
version: 3.7.7
|
||||||
@@ -90,6 +93,9 @@ importers:
|
|||||||
'@sveltejs/vite-plugin-svelte':
|
'@sveltejs/vite-plugin-svelte':
|
||||||
specifier: ^4.0.4
|
specifier: ^4.0.4
|
||||||
version: 4.0.4(svelte@5.26.1)(vite@5.4.16(@types/node@22.14.1))
|
version: 4.0.4(svelte@5.26.1)(vite@5.4.16(@types/node@22.14.1))
|
||||||
|
'@types/hammerjs':
|
||||||
|
specifier: ^2.0.46
|
||||||
|
version: 2.0.46
|
||||||
'@types/lodash-es':
|
'@types/lodash-es':
|
||||||
specifier: ^4.17.12
|
specifier: ^4.17.12
|
||||||
version: 4.17.12
|
version: 4.17.12
|
||||||
@@ -907,6 +913,9 @@ packages:
|
|||||||
'@types/geojson@7946.0.16':
|
'@types/geojson@7946.0.16':
|
||||||
resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==}
|
resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==}
|
||||||
|
|
||||||
|
'@types/hammerjs@2.0.46':
|
||||||
|
resolution: {integrity: sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw==}
|
||||||
|
|
||||||
'@types/istanbul-lib-coverage@2.0.6':
|
'@types/istanbul-lib-coverage@2.0.6':
|
||||||
resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==}
|
resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==}
|
||||||
|
|
||||||
@@ -2070,6 +2079,10 @@ packages:
|
|||||||
hachure-fill@0.5.2:
|
hachure-fill@0.5.2:
|
||||||
resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==}
|
resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==}
|
||||||
|
|
||||||
|
hammerjs@2.0.8:
|
||||||
|
resolution: {integrity: sha512-tSQXBXS/MWQOn/RKckawJ61vvsDpCom87JgxiYdGwHdOa0ht0vzUWDlfioofFCRU0L+6NGDt6XzbgoJvZkMeRQ==}
|
||||||
|
engines: {node: '>=0.8.0'}
|
||||||
|
|
||||||
has-flag@4.0.0:
|
has-flag@4.0.0:
|
||||||
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
|
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -4493,6 +4506,8 @@ snapshots:
|
|||||||
|
|
||||||
'@types/geojson@7946.0.16': {}
|
'@types/geojson@7946.0.16': {}
|
||||||
|
|
||||||
|
'@types/hammerjs@2.0.46': {}
|
||||||
|
|
||||||
'@types/istanbul-lib-coverage@2.0.6': {}
|
'@types/istanbul-lib-coverage@2.0.6': {}
|
||||||
|
|
||||||
'@types/json-schema@7.0.15': {}
|
'@types/json-schema@7.0.15': {}
|
||||||
@@ -5891,6 +5906,8 @@ snapshots:
|
|||||||
|
|
||||||
hachure-fill@0.5.2: {}
|
hachure-fill@0.5.2: {}
|
||||||
|
|
||||||
|
hammerjs@2.0.8: {}
|
||||||
|
|
||||||
has-flag@4.0.0: {}
|
has-flag@4.0.0: {}
|
||||||
|
|
||||||
has-symbols@1.1.0: {}
|
has-symbols@1.1.0: {}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { State } from '$/types';
|
import type { State } from '$/types';
|
||||||
|
import Hammer from 'hammerjs';
|
||||||
import type { Point } from 'mermaid/dist/types.js';
|
import type { Point } from 'mermaid/dist/types.js';
|
||||||
import panzoom from 'svg-pan-zoom';
|
import panzoom from 'svg-pan-zoom';
|
||||||
type PanZoom = typeof panzoom;
|
type PanZoom = typeof panzoom;
|
||||||
@@ -24,9 +25,50 @@ export class PanZoomState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public updateElement(diagramView: SVGElement, { pan, zoom }: Pick<State, 'pan' | 'zoom'>) {
|
public updateElement(diagramView: SVGElement, { pan, zoom }: Pick<State, 'pan' | 'zoom'>) {
|
||||||
|
this.pzoom?.destroy();
|
||||||
|
let hammer: HammerManager | undefined;
|
||||||
this.pzoom = panzoom(diagramView, {
|
this.pzoom = panzoom(diagramView, {
|
||||||
center: true,
|
center: true,
|
||||||
controlIconsEnabled: false,
|
controlIconsEnabled: false,
|
||||||
|
customEventsHandler: {
|
||||||
|
haltEventListeners: ['touchstart', 'touchend', 'touchmove', 'touchleave', 'touchcancel'],
|
||||||
|
init: function (options) {
|
||||||
|
const instance = options.instance;
|
||||||
|
let initialScale = 1;
|
||||||
|
let pannedX = 0;
|
||||||
|
let pannedY = 0;
|
||||||
|
hammer = new Hammer(options.svgElement);
|
||||||
|
hammer.get('pinch').set({ enable: true });
|
||||||
|
hammer.on('panstart panmove', function (event) {
|
||||||
|
if (event.type === 'panstart') {
|
||||||
|
pannedX = 0;
|
||||||
|
pannedY = 0;
|
||||||
|
}
|
||||||
|
instance.panBy({ x: event.deltaX - pannedX, y: event.deltaY - pannedY });
|
||||||
|
pannedX = event.deltaX;
|
||||||
|
pannedY = event.deltaY;
|
||||||
|
});
|
||||||
|
hammer.on('pinchstart pinchmove', function (event) {
|
||||||
|
if (event.type === 'pinchstart') {
|
||||||
|
initialScale = instance.getZoom();
|
||||||
|
instance.zoomAtPoint(initialScale * event.scale, {
|
||||||
|
x: event.center.x,
|
||||||
|
y: event.center.y
|
||||||
|
});
|
||||||
|
}
|
||||||
|
instance.zoomAtPoint(initialScale * event.scale, {
|
||||||
|
x: event.center.x,
|
||||||
|
y: event.center.y
|
||||||
|
});
|
||||||
|
});
|
||||||
|
options.svgElement.addEventListener('touchmove', function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
destroy: function () {
|
||||||
|
hammer?.destroy();
|
||||||
|
}
|
||||||
|
},
|
||||||
fit: true,
|
fit: true,
|
||||||
maxZoom: 12,
|
maxZoom: 12,
|
||||||
minZoom: 0.2,
|
minZoom: 0.2,
|
||||||
|
|||||||
Reference in New Issue
Block a user